Split shaders out into a separate module.
This commit is contained in:
parent
90445bac7e
commit
84ffc3151e
|
@ -173,9 +173,11 @@ impl CanvasRenderingContext2D {
|
||||||
|
|
||||||
let mut stroke_style = self.current_state.resolve_stroke_style();
|
let mut stroke_style = self.current_state.resolve_stroke_style();
|
||||||
|
|
||||||
// the smaller scale is relevant here, as we multiply by it and want to ensure it is always bigger than HAIRLINE_STROKE_WIDTH
|
// The smaller scale is relevant here, as we multiply by it and want to ensure it is always
|
||||||
let transform_scale = f32::min(self.current_state.transform.m11(), self.current_state.transform.m22());
|
// bigger than `HAIRLINE_STROKE_WIDTH`.
|
||||||
// avoid the division in the normal case of sufficient thickness
|
let transform_scale = f32::min(self.current_state.transform.m11(),
|
||||||
|
self.current_state.transform.m22());
|
||||||
|
// Avoid the division in the normal case of sufficient thickness.
|
||||||
if stroke_style.line_width * transform_scale < HAIRLINE_STROKE_WIDTH {
|
if stroke_style.line_width * transform_scale < HAIRLINE_STROKE_WIDTH {
|
||||||
stroke_style.line_width = HAIRLINE_STROKE_WIDTH / transform_scale;
|
stroke_style.line_width = HAIRLINE_STROKE_WIDTH / transform_scale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,9 @@ fn export_pdf<W: Write>(scene: &Scene, writer: &mut W) -> io::Result<()> {
|
||||||
Paint::Gradient(_) => {
|
Paint::Gradient(_) => {
|
||||||
// TODO(pcwalton): Gradients.
|
// TODO(pcwalton): Gradients.
|
||||||
}
|
}
|
||||||
|
Paint::Pattern(_) => {
|
||||||
|
// TODO(pcwalton): Patterns.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for contour in outline.contours() {
|
for contour in outline.contours() {
|
||||||
|
@ -184,6 +187,9 @@ fn export_ps<W: Write>(scene: &Scene, writer: &mut W) -> io::Result<()> {
|
||||||
Paint::Gradient(_) => {
|
Paint::Gradient(_) => {
|
||||||
// TODO(pcwalton): Gradients.
|
// TODO(pcwalton): Gradients.
|
||||||
}
|
}
|
||||||
|
Paint::Pattern(_) => {
|
||||||
|
// TODO(pcwalton): Patterns.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln!(writer, "fill")?;
|
writeln!(writer, "fill")?;
|
||||||
|
|
|
@ -13,3 +13,5 @@
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
|
||||||
|
pub(crate) mod shaders;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// pathfinder/renderer/src/gpu/renderer.rs
|
// pathfinder/renderer/src/gpu/renderer.rs
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
@ -10,6 +10,10 @@
|
||||||
|
|
||||||
use crate::gpu::debug::DebugUIPresenter;
|
use crate::gpu::debug::DebugUIPresenter;
|
||||||
use crate::gpu::options::{DestFramebuffer, RendererOptions};
|
use crate::gpu::options::{DestFramebuffer, RendererOptions};
|
||||||
|
use crate::gpu::shaders::{FillProgram, AlphaTileProgram, AlphaTileVertexArray, FillVertexArray};
|
||||||
|
use crate::gpu::shaders::{MAX_FILLS_PER_BATCH, PostprocessProgram, PostprocessVertexArray};
|
||||||
|
use crate::gpu::shaders::{ReprojectionProgram, ReprojectionVertexArray, SolidTileProgram};
|
||||||
|
use crate::gpu::shaders::{SolidTileVertexArray, StencilProgram, StencilVertexArray};
|
||||||
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, PaintData, RenderCommand, SolidTileVertex};
|
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, PaintData, RenderCommand, SolidTileVertex};
|
||||||
use crate::post::DefringingKernel;
|
use crate::post::DefringingKernel;
|
||||||
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||||
|
@ -20,8 +24,8 @@ use pathfinder_geometry::transform3d::Transform4F;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, ClearOps};
|
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, ClearOps};
|
||||||
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderOptions, RenderState};
|
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderOptions, RenderState};
|
||||||
use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureDataRef, TextureFormat};
|
use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureDataRef};
|
||||||
use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{TextureFormat, UniformData};
|
||||||
use pathfinder_simd::default::{F32x2, F32x4};
|
use pathfinder_simd::default::{F32x2, F32x4};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -40,13 +44,6 @@ pub(crate) const MASK_TILES_DOWN: u32 = 256;
|
||||||
const MASK_FRAMEBUFFER_WIDTH: i32 = TILE_WIDTH as i32 * MASK_TILES_ACROSS as i32;
|
const MASK_FRAMEBUFFER_WIDTH: i32 = TILE_WIDTH as i32 * MASK_TILES_ACROSS as i32;
|
||||||
const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 * MASK_TILES_DOWN as i32;
|
const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 * MASK_TILES_DOWN as i32;
|
||||||
|
|
||||||
// TODO(pcwalton): Replace with `mem::size_of` calls?
|
|
||||||
const FILL_INSTANCE_SIZE: usize = 8;
|
|
||||||
const SOLID_TILE_VERTEX_SIZE: usize = 12;
|
|
||||||
const MASK_TILE_VERTEX_SIZE: usize = 16;
|
|
||||||
|
|
||||||
const MAX_FILLS_PER_BATCH: usize = 0x4000;
|
|
||||||
|
|
||||||
pub struct Renderer<D>
|
pub struct Renderer<D>
|
||||||
where
|
where
|
||||||
D: Device,
|
D: Device,
|
||||||
|
@ -836,8 +833,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mask_viewport(&self) -> RectI {
|
fn mask_viewport(&self) -> RectI {
|
||||||
let texture = self.device.framebuffer_texture(&self.mask_framebuffer);
|
RectI::new(Vector2I::default(),
|
||||||
RectI::new(Vector2I::default(), self.device.texture_size(texture))
|
Vector2I::new(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocate_timer_query(&mut self) -> D::TimerQuery {
|
fn allocate_timer_query(&mut self) -> D::TimerQuery {
|
||||||
|
@ -860,512 +857,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FillVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
vertex_array: D::VertexArray,
|
|
||||||
vertex_buffer: D::Buffer,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> FillVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(
|
|
||||||
device: &D,
|
|
||||||
fill_program: &FillProgram<D>,
|
|
||||||
quad_vertex_positions_buffer: &D::Buffer,
|
|
||||||
quad_vertex_indices_buffer: &D::Buffer,
|
|
||||||
) -> FillVertexArray<D> {
|
|
||||||
let vertex_array = device.create_vertex_array();
|
|
||||||
|
|
||||||
let vertex_buffer = device.create_buffer();
|
|
||||||
let vertex_buffer_data: BufferData<FillBatchPrimitive> =
|
|
||||||
BufferData::Uninitialized(MAX_FILLS_PER_BATCH);
|
|
||||||
device.allocate_buffer(
|
|
||||||
&vertex_buffer,
|
|
||||||
vertex_buffer_data,
|
|
||||||
BufferTarget::Vertex,
|
|
||||||
BufferUploadMode::Dynamic,
|
|
||||||
);
|
|
||||||
|
|
||||||
let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap();
|
|
||||||
let from_px_attr = device.get_vertex_attr(&fill_program.program, "FromPx").unwrap();
|
|
||||||
let to_px_attr = device.get_vertex_attr(&fill_program.program, "ToPx").unwrap();
|
|
||||||
let from_subpx_attr = device.get_vertex_attr(&fill_program.program, "FromSubpx").unwrap();
|
|
||||||
let to_subpx_attr = device.get_vertex_attr(&fill_program.program, "ToSubpx").unwrap();
|
|
||||||
let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap();
|
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::U16,
|
|
||||||
stride: 4,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &from_px_attr, &VertexAttrDescriptor {
|
|
||||||
size: 1,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::U8,
|
|
||||||
stride: FILL_INSTANCE_SIZE,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 1,
|
|
||||||
buffer_index: 1,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &to_px_attr, &VertexAttrDescriptor {
|
|
||||||
size: 1,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::U8,
|
|
||||||
stride: FILL_INSTANCE_SIZE,
|
|
||||||
offset: 1,
|
|
||||||
divisor: 1,
|
|
||||||
buffer_index: 1,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &from_subpx_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::FloatNorm,
|
|
||||||
attr_type: VertexAttrType::U8,
|
|
||||||
stride: FILL_INSTANCE_SIZE,
|
|
||||||
offset: 2,
|
|
||||||
divisor: 1,
|
|
||||||
buffer_index: 1,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &to_subpx_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::FloatNorm,
|
|
||||||
attr_type: VertexAttrType::U8,
|
|
||||||
stride: FILL_INSTANCE_SIZE,
|
|
||||||
offset: 4,
|
|
||||||
divisor: 1,
|
|
||||||
buffer_index: 1,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor {
|
|
||||||
size: 1,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::U16,
|
|
||||||
stride: FILL_INSTANCE_SIZE,
|
|
||||||
offset: 6,
|
|
||||||
divisor: 1,
|
|
||||||
buffer_index: 1,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
|
||||||
|
|
||||||
FillVertexArray { vertex_array, vertex_buffer }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AlphaTileVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
vertex_array: D::VertexArray,
|
|
||||||
vertex_buffer: D::Buffer,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> AlphaTileVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(
|
|
||||||
device: &D,
|
|
||||||
alpha_tile_program: &AlphaTileProgram<D>,
|
|
||||||
quads_vertex_indices_buffer: &D::Buffer,
|
|
||||||
) -> AlphaTileVertexArray<D> {
|
|
||||||
let (vertex_array, vertex_buffer) = (device.create_vertex_array(), device.create_buffer());
|
|
||||||
|
|
||||||
let tile_position_attr =
|
|
||||||
device.get_vertex_attr(&alpha_tile_program.program, "TilePosition").unwrap();
|
|
||||||
let color_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
|
||||||
"ColorTexCoord").unwrap();
|
|
||||||
let mask_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
|
||||||
"MaskTexCoord").unwrap();
|
|
||||||
let backdrop_attr = device.get_vertex_attr(&alpha_tile_program.program, "Backdrop")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::I16,
|
|
||||||
stride: MASK_TILE_VERTEX_SIZE,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &color_tex_coord_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::FloatNorm,
|
|
||||||
attr_type: VertexAttrType::U16,
|
|
||||||
stride: MASK_TILE_VERTEX_SIZE,
|
|
||||||
offset: 4,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &mask_tex_coord_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::FloatNorm,
|
|
||||||
attr_type: VertexAttrType::U16,
|
|
||||||
stride: MASK_TILE_VERTEX_SIZE,
|
|
||||||
offset: 8,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array, &backdrop_attr, &VertexAttrDescriptor {
|
|
||||||
size: 1,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::I16,
|
|
||||||
stride: MASK_TILE_VERTEX_SIZE,
|
|
||||||
offset: 12,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
|
||||||
|
|
||||||
AlphaTileVertexArray { vertex_array, vertex_buffer }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SolidTileVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
vertex_array: D::VertexArray,
|
|
||||||
vertex_buffer: D::Buffer,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> SolidTileVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(
|
|
||||||
device: &D,
|
|
||||||
solid_tile_program: &SolidTileProgram<D>,
|
|
||||||
quads_vertex_indices_buffer: &D::Buffer,
|
|
||||||
) -> SolidTileVertexArray<D> {
|
|
||||||
let (vertex_array, vertex_buffer) = (device.create_vertex_array(), device.create_buffer());
|
|
||||||
|
|
||||||
let tile_position_attr =
|
|
||||||
device.get_vertex_attr(&solid_tile_program.program, "TilePosition").unwrap();
|
|
||||||
let color_tex_coord_attr =
|
|
||||||
device.get_vertex_attr(&solid_tile_program.program, "ColorTexCoord").unwrap();
|
|
||||||
|
|
||||||
// NB: The tile origin must be of type short, not unsigned short, to work around a macOS
|
|
||||||
// Radeon driver bug.
|
|
||||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::I16,
|
|
||||||
stride: SOLID_TILE_VERTEX_SIZE,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.configure_vertex_attr(&vertex_array,
|
|
||||||
&color_tex_coord_attr,
|
|
||||||
&VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::FloatNorm,
|
|
||||||
attr_type: VertexAttrType::U16,
|
|
||||||
stride: SOLID_TILE_VERTEX_SIZE,
|
|
||||||
offset: 4,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
|
||||||
|
|
||||||
SolidTileVertexArray { vertex_array, vertex_buffer }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FillProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
program: D::Program,
|
|
||||||
framebuffer_size_uniform: D::Uniform,
|
|
||||||
tile_size_uniform: D::Uniform,
|
|
||||||
area_lut_uniform: D::Uniform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> FillProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgram<D> {
|
|
||||||
let program = device.create_program(resources, "fill");
|
|
||||||
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
|
||||||
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
|
||||||
let area_lut_uniform = device.get_uniform(&program, "AreaLUT");
|
|
||||||
FillProgram {
|
|
||||||
program,
|
|
||||||
framebuffer_size_uniform,
|
|
||||||
tile_size_uniform,
|
|
||||||
area_lut_uniform,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SolidTileProgram<D> where D: Device {
|
|
||||||
program: D::Program,
|
|
||||||
transform_uniform: D::Uniform,
|
|
||||||
tile_size_uniform: D::Uniform,
|
|
||||||
paint_texture_uniform: D::Uniform,
|
|
||||||
paint_texture_size_uniform: D::Uniform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> SolidTileProgram<D> where D: Device {
|
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> SolidTileProgram<D> {
|
|
||||||
let program = device.create_program(resources, "tile_solid");
|
|
||||||
let transform_uniform = device.get_uniform(&program, "Transform");
|
|
||||||
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
|
||||||
let paint_texture_uniform = device.get_uniform(&program, "PaintTexture");
|
|
||||||
let paint_texture_size_uniform = device.get_uniform(&program, "PaintTextureSize");
|
|
||||||
SolidTileProgram {
|
|
||||||
program,
|
|
||||||
transform_uniform,
|
|
||||||
tile_size_uniform,
|
|
||||||
paint_texture_uniform,
|
|
||||||
paint_texture_size_uniform,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AlphaTileProgram<D> where D: Device {
|
|
||||||
program: D::Program,
|
|
||||||
transform_uniform: D::Uniform,
|
|
||||||
tile_size_uniform: D::Uniform,
|
|
||||||
stencil_texture_uniform: D::Uniform,
|
|
||||||
stencil_texture_size_uniform: D::Uniform,
|
|
||||||
paint_texture_uniform: D::Uniform,
|
|
||||||
paint_texture_size_uniform: D::Uniform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> AlphaTileProgram<D> where D: Device {
|
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> AlphaTileProgram<D> {
|
|
||||||
let program = device.create_program(resources, "tile_alpha");
|
|
||||||
let transform_uniform = device.get_uniform(&program, "Transform");
|
|
||||||
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
|
||||||
let stencil_texture_uniform = device.get_uniform(&program, "StencilTexture");
|
|
||||||
let stencil_texture_size_uniform = device.get_uniform(&program, "StencilTextureSize");
|
|
||||||
let paint_texture_uniform = device.get_uniform(&program, "PaintTexture");
|
|
||||||
let paint_texture_size_uniform = device.get_uniform(&program, "PaintTextureSize");
|
|
||||||
AlphaTileProgram {
|
|
||||||
program,
|
|
||||||
transform_uniform,
|
|
||||||
tile_size_uniform,
|
|
||||||
stencil_texture_uniform,
|
|
||||||
stencil_texture_size_uniform,
|
|
||||||
paint_texture_uniform,
|
|
||||||
paint_texture_size_uniform,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PostprocessProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
program: D::Program,
|
|
||||||
source_uniform: D::Uniform,
|
|
||||||
source_size_uniform: D::Uniform,
|
|
||||||
framebuffer_size_uniform: D::Uniform,
|
|
||||||
kernel_uniform: D::Uniform,
|
|
||||||
gamma_lut_uniform: D::Uniform,
|
|
||||||
gamma_correction_enabled_uniform: D::Uniform,
|
|
||||||
fg_color_uniform: D::Uniform,
|
|
||||||
bg_color_uniform: D::Uniform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> PostprocessProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> PostprocessProgram<D> {
|
|
||||||
let program = device.create_program(resources, "post");
|
|
||||||
let source_uniform = device.get_uniform(&program, "Source");
|
|
||||||
let source_size_uniform = device.get_uniform(&program, "SourceSize");
|
|
||||||
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
|
||||||
let kernel_uniform = device.get_uniform(&program, "Kernel");
|
|
||||||
let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT");
|
|
||||||
let gamma_correction_enabled_uniform = device.get_uniform(&program,
|
|
||||||
"GammaCorrectionEnabled");
|
|
||||||
let fg_color_uniform = device.get_uniform(&program, "FGColor");
|
|
||||||
let bg_color_uniform = device.get_uniform(&program, "BGColor");
|
|
||||||
PostprocessProgram {
|
|
||||||
program,
|
|
||||||
source_uniform,
|
|
||||||
source_size_uniform,
|
|
||||||
framebuffer_size_uniform,
|
|
||||||
kernel_uniform,
|
|
||||||
gamma_lut_uniform,
|
|
||||||
gamma_correction_enabled_uniform,
|
|
||||||
fg_color_uniform,
|
|
||||||
bg_color_uniform,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PostprocessVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
vertex_array: D::VertexArray,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> PostprocessVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(
|
|
||||||
device: &D,
|
|
||||||
postprocess_program: &PostprocessProgram<D>,
|
|
||||||
quad_vertex_positions_buffer: &D::Buffer,
|
|
||||||
quad_vertex_indices_buffer: &D::Buffer,
|
|
||||||
) -> PostprocessVertexArray<D> {
|
|
||||||
let vertex_array = device.create_vertex_array();
|
|
||||||
let position_attr = device.get_vertex_attr(&postprocess_program.program, "Position")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::I16,
|
|
||||||
stride: 4,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
|
||||||
|
|
||||||
PostprocessVertexArray { vertex_array }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StencilProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
program: D::Program,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> StencilProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram<D> {
|
|
||||||
let program = device.create_program(resources, "stencil");
|
|
||||||
StencilProgram { program }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StencilVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
vertex_array: D::VertexArray,
|
|
||||||
vertex_buffer: D::Buffer,
|
|
||||||
index_buffer: D::Buffer,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> StencilVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(device: &D, stencil_program: &StencilProgram<D>) -> StencilVertexArray<D> {
|
|
||||||
let vertex_array = device.create_vertex_array();
|
|
||||||
let (vertex_buffer, index_buffer) = (device.create_buffer(), device.create_buffer());
|
|
||||||
|
|
||||||
let position_attr = device.get_vertex_attr(&stencil_program.program, "Position").unwrap();
|
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
|
||||||
size: 3,
|
|
||||||
class: VertexAttrClass::Float,
|
|
||||||
attr_type: VertexAttrType::F32,
|
|
||||||
stride: 4 * 4,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
|
|
||||||
|
|
||||||
StencilVertexArray { vertex_array, vertex_buffer, index_buffer }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ReprojectionProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
program: D::Program,
|
|
||||||
old_transform_uniform: D::Uniform,
|
|
||||||
new_transform_uniform: D::Uniform,
|
|
||||||
texture_uniform: D::Uniform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> ReprojectionProgram<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> ReprojectionProgram<D> {
|
|
||||||
let program = device.create_program(resources, "reproject");
|
|
||||||
let old_transform_uniform = device.get_uniform(&program, "OldTransform");
|
|
||||||
let new_transform_uniform = device.get_uniform(&program, "NewTransform");
|
|
||||||
let texture_uniform = device.get_uniform(&program, "Texture");
|
|
||||||
|
|
||||||
ReprojectionProgram {
|
|
||||||
program,
|
|
||||||
old_transform_uniform,
|
|
||||||
new_transform_uniform,
|
|
||||||
texture_uniform,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ReprojectionVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
vertex_array: D::VertexArray,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> ReprojectionVertexArray<D>
|
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
fn new(
|
|
||||||
device: &D,
|
|
||||||
reprojection_program: &ReprojectionProgram<D>,
|
|
||||||
quad_vertex_positions_buffer: &D::Buffer,
|
|
||||||
quad_vertex_indices_buffer: &D::Buffer,
|
|
||||||
) -> ReprojectionVertexArray<D> {
|
|
||||||
let vertex_array = device.create_vertex_array();
|
|
||||||
let position_attr = device.get_vertex_attr(&reprojection_program.program, "Position")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
|
||||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
|
||||||
size: 2,
|
|
||||||
class: VertexAttrClass::Int,
|
|
||||||
attr_type: VertexAttrType::I16,
|
|
||||||
stride: 4,
|
|
||||||
offset: 0,
|
|
||||||
divisor: 0,
|
|
||||||
buffer_index: 0,
|
|
||||||
});
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
|
||||||
|
|
||||||
ReprojectionVertexArray { vertex_array }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct PostprocessOptions {
|
pub struct PostprocessOptions {
|
||||||
pub fg_color: ColorF,
|
pub fg_color: ColorF,
|
||||||
|
@ -1374,6 +865,8 @@ pub struct PostprocessOptions {
|
||||||
pub gamma_correction: bool,
|
pub gamma_correction: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render stats
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct RenderStats {
|
pub struct RenderStats {
|
||||||
pub path_count: usize,
|
pub path_count: usize,
|
||||||
|
|
|
@ -0,0 +1,526 @@
|
||||||
|
// pathfinder/renderer/src/gpu/shaders.rs
|
||||||
|
//
|
||||||
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use crate::gpu_data::FillBatchPrimitive;
|
||||||
|
use pathfinder_gpu::{BufferData, BufferTarget, BufferUploadMode, Device, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
||||||
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
|
|
||||||
|
// TODO(pcwalton): Replace with `mem::size_of` calls?
|
||||||
|
const FILL_INSTANCE_SIZE: usize = 8;
|
||||||
|
const SOLID_TILE_VERTEX_SIZE: usize = 12;
|
||||||
|
const MASK_TILE_VERTEX_SIZE: usize = 16;
|
||||||
|
|
||||||
|
pub const MAX_FILLS_PER_BATCH: usize = 0x4000;
|
||||||
|
|
||||||
|
pub struct FillVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
pub vertex_buffer: D::Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> FillVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
device: &D,
|
||||||
|
fill_program: &FillProgram<D>,
|
||||||
|
quad_vertex_positions_buffer: &D::Buffer,
|
||||||
|
quad_vertex_indices_buffer: &D::Buffer,
|
||||||
|
) -> FillVertexArray<D> {
|
||||||
|
let vertex_array = device.create_vertex_array();
|
||||||
|
|
||||||
|
let vertex_buffer = device.create_buffer();
|
||||||
|
let vertex_buffer_data: BufferData<FillBatchPrimitive> =
|
||||||
|
BufferData::Uninitialized(MAX_FILLS_PER_BATCH);
|
||||||
|
device.allocate_buffer(
|
||||||
|
&vertex_buffer,
|
||||||
|
vertex_buffer_data,
|
||||||
|
BufferTarget::Vertex,
|
||||||
|
BufferUploadMode::Dynamic,
|
||||||
|
);
|
||||||
|
|
||||||
|
let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap();
|
||||||
|
let from_px_attr = device.get_vertex_attr(&fill_program.program, "FromPx").unwrap();
|
||||||
|
let to_px_attr = device.get_vertex_attr(&fill_program.program, "ToPx").unwrap();
|
||||||
|
let from_subpx_attr = device.get_vertex_attr(&fill_program.program, "FromSubpx").unwrap();
|
||||||
|
let to_subpx_attr = device.get_vertex_attr(&fill_program.program, "ToSubpx").unwrap();
|
||||||
|
let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap();
|
||||||
|
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::U16,
|
||||||
|
stride: 4,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &from_px_attr, &VertexAttrDescriptor {
|
||||||
|
size: 1,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::U8,
|
||||||
|
stride: FILL_INSTANCE_SIZE,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 1,
|
||||||
|
buffer_index: 1,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &to_px_attr, &VertexAttrDescriptor {
|
||||||
|
size: 1,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::U8,
|
||||||
|
stride: FILL_INSTANCE_SIZE,
|
||||||
|
offset: 1,
|
||||||
|
divisor: 1,
|
||||||
|
buffer_index: 1,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &from_subpx_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::FloatNorm,
|
||||||
|
attr_type: VertexAttrType::U8,
|
||||||
|
stride: FILL_INSTANCE_SIZE,
|
||||||
|
offset: 2,
|
||||||
|
divisor: 1,
|
||||||
|
buffer_index: 1,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &to_subpx_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::FloatNorm,
|
||||||
|
attr_type: VertexAttrType::U8,
|
||||||
|
stride: FILL_INSTANCE_SIZE,
|
||||||
|
offset: 4,
|
||||||
|
divisor: 1,
|
||||||
|
buffer_index: 1,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor {
|
||||||
|
size: 1,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::U16,
|
||||||
|
stride: FILL_INSTANCE_SIZE,
|
||||||
|
offset: 6,
|
||||||
|
divisor: 1,
|
||||||
|
buffer_index: 1,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
FillVertexArray { vertex_array, vertex_buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AlphaTileVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
pub vertex_buffer: D::Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> AlphaTileVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
device: &D,
|
||||||
|
alpha_tile_program: &AlphaTileProgram<D>,
|
||||||
|
quads_vertex_indices_buffer: &D::Buffer,
|
||||||
|
) -> AlphaTileVertexArray<D> {
|
||||||
|
let (vertex_array, vertex_buffer) = (device.create_vertex_array(), device.create_buffer());
|
||||||
|
|
||||||
|
let tile_position_attr =
|
||||||
|
device.get_vertex_attr(&alpha_tile_program.program, "TilePosition").unwrap();
|
||||||
|
let color_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
||||||
|
"ColorTexCoord").unwrap();
|
||||||
|
let mask_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
||||||
|
"MaskTexCoord").unwrap();
|
||||||
|
let backdrop_attr = device.get_vertex_attr(&alpha_tile_program.program, "Backdrop")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::I16,
|
||||||
|
stride: MASK_TILE_VERTEX_SIZE,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &mask_tex_coord_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::FloatNorm,
|
||||||
|
attr_type: VertexAttrType::U16,
|
||||||
|
stride: MASK_TILE_VERTEX_SIZE,
|
||||||
|
offset: 4,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &color_tex_coord_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::FloatNorm,
|
||||||
|
attr_type: VertexAttrType::U16,
|
||||||
|
stride: MASK_TILE_VERTEX_SIZE,
|
||||||
|
offset: 8,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &backdrop_attr, &VertexAttrDescriptor {
|
||||||
|
size: 1,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::I16,
|
||||||
|
stride: MASK_TILE_VERTEX_SIZE,
|
||||||
|
offset: 12,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
AlphaTileVertexArray { vertex_array, vertex_buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SolidTileVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
pub vertex_buffer: D::Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> SolidTileVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
device: &D,
|
||||||
|
solid_tile_program: &SolidTileProgram<D>,
|
||||||
|
quads_vertex_indices_buffer: &D::Buffer,
|
||||||
|
) -> SolidTileVertexArray<D> {
|
||||||
|
let (vertex_array, vertex_buffer) = (device.create_vertex_array(), device.create_buffer());
|
||||||
|
|
||||||
|
let tile_position_attr =
|
||||||
|
device.get_vertex_attr(&solid_tile_program.program, "TilePosition").unwrap();
|
||||||
|
let color_tex_coord_attr =
|
||||||
|
device.get_vertex_attr(&solid_tile_program.program, "ColorTexCoord").unwrap();
|
||||||
|
|
||||||
|
// NB: The tile origin must be of type short, not unsigned short, to work around a macOS
|
||||||
|
// Radeon driver bug.
|
||||||
|
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::I16,
|
||||||
|
stride: SOLID_TILE_VERTEX_SIZE,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array,
|
||||||
|
&color_tex_coord_attr,
|
||||||
|
&VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::FloatNorm,
|
||||||
|
attr_type: VertexAttrType::U16,
|
||||||
|
stride: SOLID_TILE_VERTEX_SIZE,
|
||||||
|
offset: 4,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
SolidTileVertexArray { vertex_array, vertex_buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FillProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub program: D::Program,
|
||||||
|
pub framebuffer_size_uniform: D::Uniform,
|
||||||
|
pub tile_size_uniform: D::Uniform,
|
||||||
|
pub area_lut_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> FillProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgram<D> {
|
||||||
|
let program = device.create_program(resources, "fill");
|
||||||
|
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
|
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
||||||
|
let area_lut_uniform = device.get_uniform(&program, "AreaLUT");
|
||||||
|
FillProgram {
|
||||||
|
program,
|
||||||
|
framebuffer_size_uniform,
|
||||||
|
tile_size_uniform,
|
||||||
|
area_lut_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SolidTileProgram<D> where D: Device {
|
||||||
|
pub program: D::Program,
|
||||||
|
pub transform_uniform: D::Uniform,
|
||||||
|
pub tile_size_uniform: D::Uniform,
|
||||||
|
pub paint_texture_uniform: D::Uniform,
|
||||||
|
pub paint_texture_size_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> SolidTileProgram<D> where D: Device {
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> SolidTileProgram<D> {
|
||||||
|
let program = device.create_program(resources, "tile_solid");
|
||||||
|
let transform_uniform = device.get_uniform(&program, "Transform");
|
||||||
|
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
||||||
|
let paint_texture_uniform = device.get_uniform(&program, "PaintTexture");
|
||||||
|
let paint_texture_size_uniform = device.get_uniform(&program, "PaintTextureSize");
|
||||||
|
SolidTileProgram {
|
||||||
|
program,
|
||||||
|
transform_uniform,
|
||||||
|
tile_size_uniform,
|
||||||
|
paint_texture_uniform,
|
||||||
|
paint_texture_size_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AlphaTileProgram<D> where D: Device {
|
||||||
|
pub program: D::Program,
|
||||||
|
pub transform_uniform: D::Uniform,
|
||||||
|
pub tile_size_uniform: D::Uniform,
|
||||||
|
pub stencil_texture_uniform: D::Uniform,
|
||||||
|
pub stencil_texture_size_uniform: D::Uniform,
|
||||||
|
pub paint_texture_uniform: D::Uniform,
|
||||||
|
pub paint_texture_size_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> AlphaTileProgram<D> where D: Device {
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> AlphaTileProgram<D> {
|
||||||
|
let program = device.create_program(resources, "tile_alpha");
|
||||||
|
let transform_uniform = device.get_uniform(&program, "Transform");
|
||||||
|
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
||||||
|
let stencil_texture_uniform = device.get_uniform(&program, "StencilTexture");
|
||||||
|
let stencil_texture_size_uniform = device.get_uniform(&program, "StencilTextureSize");
|
||||||
|
let paint_texture_uniform = device.get_uniform(&program, "PaintTexture");
|
||||||
|
let paint_texture_size_uniform = device.get_uniform(&program, "PaintTextureSize");
|
||||||
|
AlphaTileProgram {
|
||||||
|
program,
|
||||||
|
transform_uniform,
|
||||||
|
tile_size_uniform,
|
||||||
|
stencil_texture_uniform,
|
||||||
|
stencil_texture_size_uniform,
|
||||||
|
paint_texture_uniform,
|
||||||
|
paint_texture_size_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PostprocessProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub program: D::Program,
|
||||||
|
pub source_uniform: D::Uniform,
|
||||||
|
pub source_size_uniform: D::Uniform,
|
||||||
|
pub framebuffer_size_uniform: D::Uniform,
|
||||||
|
pub kernel_uniform: D::Uniform,
|
||||||
|
pub gamma_lut_uniform: D::Uniform,
|
||||||
|
pub gamma_correction_enabled_uniform: D::Uniform,
|
||||||
|
pub fg_color_uniform: D::Uniform,
|
||||||
|
pub bg_color_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> PostprocessProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> PostprocessProgram<D> {
|
||||||
|
let program = device.create_program(resources, "post");
|
||||||
|
let source_uniform = device.get_uniform(&program, "Source");
|
||||||
|
let source_size_uniform = device.get_uniform(&program, "SourceSize");
|
||||||
|
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
|
let kernel_uniform = device.get_uniform(&program, "Kernel");
|
||||||
|
let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT");
|
||||||
|
let gamma_correction_enabled_uniform = device.get_uniform(&program,
|
||||||
|
"GammaCorrectionEnabled");
|
||||||
|
let fg_color_uniform = device.get_uniform(&program, "FGColor");
|
||||||
|
let bg_color_uniform = device.get_uniform(&program, "BGColor");
|
||||||
|
PostprocessProgram {
|
||||||
|
program,
|
||||||
|
source_uniform,
|
||||||
|
source_size_uniform,
|
||||||
|
framebuffer_size_uniform,
|
||||||
|
kernel_uniform,
|
||||||
|
gamma_lut_uniform,
|
||||||
|
gamma_correction_enabled_uniform,
|
||||||
|
fg_color_uniform,
|
||||||
|
bg_color_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PostprocessVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> PostprocessVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
device: &D,
|
||||||
|
postprocess_program: &PostprocessProgram<D>,
|
||||||
|
quad_vertex_positions_buffer: &D::Buffer,
|
||||||
|
quad_vertex_indices_buffer: &D::Buffer,
|
||||||
|
) -> PostprocessVertexArray<D> {
|
||||||
|
let vertex_array = device.create_vertex_array();
|
||||||
|
let position_attr = device.get_vertex_attr(&postprocess_program.program, "Position")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::I16,
|
||||||
|
stride: 4,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
PostprocessVertexArray { vertex_array }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StencilProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub program: D::Program,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> StencilProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram<D> {
|
||||||
|
let program = device.create_program(resources, "stencil");
|
||||||
|
StencilProgram { program }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StencilVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
pub vertex_buffer: D::Buffer,
|
||||||
|
pub index_buffer: D::Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> StencilVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(device: &D, stencil_program: &StencilProgram<D>) -> StencilVertexArray<D> {
|
||||||
|
let vertex_array = device.create_vertex_array();
|
||||||
|
let (vertex_buffer, index_buffer) = (device.create_buffer(), device.create_buffer());
|
||||||
|
|
||||||
|
let position_attr = device.get_vertex_attr(&stencil_program.program, "Position").unwrap();
|
||||||
|
|
||||||
|
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||||
|
size: 3,
|
||||||
|
class: VertexAttrClass::Float,
|
||||||
|
attr_type: VertexAttrType::F32,
|
||||||
|
stride: 4 * 4,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
StencilVertexArray { vertex_array, vertex_buffer, index_buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ReprojectionProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub program: D::Program,
|
||||||
|
pub old_transform_uniform: D::Uniform,
|
||||||
|
pub new_transform_uniform: D::Uniform,
|
||||||
|
pub texture_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> ReprojectionProgram<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> ReprojectionProgram<D> {
|
||||||
|
let program = device.create_program(resources, "reproject");
|
||||||
|
let old_transform_uniform = device.get_uniform(&program, "OldTransform");
|
||||||
|
let new_transform_uniform = device.get_uniform(&program, "NewTransform");
|
||||||
|
let texture_uniform = device.get_uniform(&program, "Texture");
|
||||||
|
|
||||||
|
ReprojectionProgram {
|
||||||
|
program,
|
||||||
|
old_transform_uniform,
|
||||||
|
new_transform_uniform,
|
||||||
|
texture_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ReprojectionVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> ReprojectionVertexArray<D>
|
||||||
|
where
|
||||||
|
D: Device,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
device: &D,
|
||||||
|
reprojection_program: &ReprojectionProgram<D>,
|
||||||
|
quad_vertex_positions_buffer: &D::Buffer,
|
||||||
|
quad_vertex_indices_buffer: &D::Buffer,
|
||||||
|
) -> ReprojectionVertexArray<D> {
|
||||||
|
let vertex_array = device.create_vertex_array();
|
||||||
|
let position_attr = device.get_vertex_attr(&reprojection_program.program, "Position")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::I16,
|
||||||
|
stride: 4,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
ReprojectionVertexArray { vertex_array }
|
||||||
|
}
|
||||||
|
}
|
|
@ -93,10 +93,10 @@ pub struct AlphaTile {
|
||||||
pub struct AlphaTileVertex {
|
pub struct AlphaTileVertex {
|
||||||
pub tile_x: i16,
|
pub tile_x: i16,
|
||||||
pub tile_y: i16,
|
pub tile_y: i16,
|
||||||
pub color_u: u16,
|
|
||||||
pub color_v: u16,
|
|
||||||
pub mask_u: u16,
|
pub mask_u: u16,
|
||||||
pub mask_v: u16,
|
pub mask_v: u16,
|
||||||
|
pub color_u: u16,
|
||||||
|
pub color_v: u16,
|
||||||
pub backdrop: i16,
|
pub backdrop: i16,
|
||||||
pub object_index: u16,
|
pub object_index: u16,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue