diff --git a/renderer/src/builder.rs b/renderer/src/builder.rs index 86818da6..85060bd5 100644 --- a/renderer/src/builder.rs +++ b/renderer/src/builder.rs @@ -59,7 +59,7 @@ impl<'a> SceneBuilder<'a> { let path_count = self.scene.paths.len(); self.listener.send(RenderCommand::Start { bounding_quad, path_count }); - self.listener.send(RenderCommand::AddShaders(self.scene.build_shaders())); + self.listener.send(RenderCommand::AddPaintData(self.scene.build_paint_data())); let effective_view_box = self.scene.effective_view_box(self.built_options); let alpha_tiles = executor.flatten_into_vector(path_count, |path_index| { diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index b355215d..f6c20bed 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -9,10 +9,10 @@ // except according to those terms. use crate::gpu::debug::DebugUIPresenter; -use crate::gpu_data::{AlphaTileBatchPrimitive, FillBatchPrimitive}; +use crate::gpu_data::{AlphaTileBatchPrimitive, FillBatchPrimitive, PaintData}; use crate::gpu_data::{RenderCommand, SolidTileBatchPrimitive}; use crate::post::DefringingKernel; -use crate::scene::ObjectShader; +use crate::scene::{PAINT_TEXTURE_HEIGHT, PAINT_TEXTURE_WIDTH}; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32}; use pathfinder_geometry::basic::rect::RectI32; @@ -41,9 +41,6 @@ const FILL_INSTANCE_SIZE: usize = 8; const SOLID_TILE_INSTANCE_SIZE: usize = 6; const MASK_TILE_INSTANCE_SIZE: usize = 8; -const FILL_COLORS_TEXTURE_WIDTH: i32 = 256; -const FILL_COLORS_TEXTURE_HEIGHT: i32 = 256; - const MAX_FILLS_PER_BATCH: usize = 0x4000; pub struct Renderer @@ -68,7 +65,7 @@ where quad_vertex_positions_buffer: D::Buffer, fill_vertex_array: FillVertexArray, mask_framebuffer: D::Framebuffer, - fill_colors_texture: D::Texture, + paint_texture: D::Texture, // Postprocessing shader postprocess_source_framebuffer: Option, @@ -171,9 +168,8 @@ where device.create_texture(TextureFormat::R16F, mask_framebuffer_size); let mask_framebuffer = device.create_framebuffer(mask_framebuffer_texture); - let fill_colors_size = - Point2DI32::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT); - let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size); + let paint_size = Point2DI32::new(PAINT_TEXTURE_WIDTH, PAINT_TEXTURE_HEIGHT); + let paint_texture = device.create_texture(TextureFormat::RGBA8, paint_size); let window_size = dest_framebuffer.window_size(&device); let debug_ui_presenter = DebugUIPresenter::new(&device, resources, window_size); @@ -195,7 +191,7 @@ where quad_vertex_positions_buffer, fill_vertex_array, mask_framebuffer, - fill_colors_texture, + paint_texture, postprocess_source_framebuffer: None, postprocess_program, @@ -242,7 +238,7 @@ where } self.stats.path_count = path_count; } - RenderCommand::AddShaders(ref shaders) => self.upload_shaders(shaders), + RenderCommand::AddPaintData(ref paint_data) => self.upload_paint_data(paint_data), RenderCommand::AddFills(ref fills) => self.add_fills(fills), RenderCommand::FlushFills => { self.begin_composite_timer_query(); @@ -345,17 +341,8 @@ where &self.quad_vertex_positions_buffer } - fn upload_shaders(&mut self, shaders: &[ObjectShader]) { - let size = Point2DI32::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT); - let mut fill_colors = vec![0; size.x() as usize * size.y() as usize * 4]; - for (shader_index, shader) in shaders.iter().enumerate() { - fill_colors[shader_index * 4 + 0] = shader.fill_color.r; - fill_colors[shader_index * 4 + 1] = shader.fill_color.g; - fill_colors[shader_index * 4 + 2] = shader.fill_color.b; - fill_colors[shader_index * 4 + 3] = shader.fill_color.a; - } - self.device - .upload_to_texture(&self.fill_colors_texture, size, &fill_colors); + fn upload_paint_data(&mut self, paint_data: &PaintData) { + self.device.upload_to_texture(&self.paint_texture, paint_data.size, &paint_data.texels); } fn upload_solid_tiles(&mut self, solid_tiles: &[SolidTileBatchPrimitive]) { @@ -493,32 +480,27 @@ where match self.render_mode { RenderMode::Multicolor => { - self.device.bind_texture(&self.fill_colors_texture, 1); + self.device.bind_texture(&self.paint_texture, 1); self.device.set_uniform( - &self - .alpha_multicolor_tile_program - .fill_colors_texture_uniform, + &self.alpha_multicolor_tile_program.paint_texture_uniform, UniformData::TextureUnit(1), ); self.device.set_uniform( - &self - .alpha_multicolor_tile_program - .fill_colors_texture_size_uniform, + &self.alpha_multicolor_tile_program.paint_texture_size_uniform, UniformData::Vec2( - I32x4::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT, 0, 0) - .to_f32x4(), + I32x4::new(PAINT_TEXTURE_WIDTH, PAINT_TEXTURE_HEIGHT, 0, 0).to_f32x4() ), ); } RenderMode::Monochrome { .. } if self.postprocessing_needed() => { self.device.set_uniform( - &self.alpha_monochrome_tile_program.fill_color_uniform, + &self.alpha_monochrome_tile_program.color_uniform, UniformData::Vec4(F32x4::splat(1.0)), ); } RenderMode::Monochrome { fg_color, .. } => { self.device.set_uniform( - &self.alpha_monochrome_tile_program.fill_color_uniform, + &self.alpha_monochrome_tile_program.color_uniform, UniformData::Vec4(fg_color.0), ); } @@ -558,32 +540,32 @@ where match self.render_mode { RenderMode::Multicolor => { - self.device.bind_texture(&self.fill_colors_texture, 0); + self.device.bind_texture(&self.paint_texture, 0); self.device.set_uniform( &self .solid_multicolor_tile_program - .fill_colors_texture_uniform, + .paint_texture_uniform, UniformData::TextureUnit(0), ); self.device.set_uniform( &self .solid_multicolor_tile_program - .fill_colors_texture_size_uniform, + .paint_texture_size_uniform, UniformData::Vec2( - I32x4::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT, 0, 0) + I32x4::new(PAINT_TEXTURE_WIDTH, PAINT_TEXTURE_HEIGHT, 0, 0) .to_f32x4(), ), ); } RenderMode::Monochrome { .. } if self.postprocessing_needed() => { self.device.set_uniform( - &self.solid_monochrome_tile_program.fill_color_uniform, + &self.solid_monochrome_tile_program.color_uniform, UniformData::Vec4(F32x4::splat(1.0)), ); } RenderMode::Monochrome { fg_color, .. } => { self.device.set_uniform( - &self.solid_monochrome_tile_program.fill_color_uniform, + &self.solid_monochrome_tile_program.color_uniform, UniformData::Vec4(fg_color.0), ); } @@ -1177,8 +1159,8 @@ where D: Device, { solid_tile_program: SolidTileProgram, - fill_colors_texture_uniform: D::Uniform, - fill_colors_texture_size_uniform: D::Uniform, + paint_texture_uniform: D::Uniform, + paint_texture_size_uniform: D::Uniform, } impl SolidTileMulticolorProgram @@ -1187,14 +1169,14 @@ where { fn new(device: &D, resources: &dyn ResourceLoader) -> SolidTileMulticolorProgram { let solid_tile_program = SolidTileProgram::new(device, "tile_solid_multicolor", resources); - let fill_colors_texture_uniform = - device.get_uniform(&solid_tile_program.program, "FillColorsTexture"); - let fill_colors_texture_size_uniform = - device.get_uniform(&solid_tile_program.program, "FillColorsTextureSize"); + let paint_texture_uniform = + device.get_uniform(&solid_tile_program.program, "PaintTexture"); + let paint_texture_size_uniform = + device.get_uniform(&solid_tile_program.program, "PaintTextureSize"); SolidTileMulticolorProgram { solid_tile_program, - fill_colors_texture_uniform, - fill_colors_texture_size_uniform, + paint_texture_uniform, + paint_texture_size_uniform, } } } @@ -1204,7 +1186,7 @@ where D: Device, { solid_tile_program: SolidTileProgram, - fill_color_uniform: D::Uniform, + color_uniform: D::Uniform, } impl SolidTileMonochromeProgram @@ -1213,10 +1195,10 @@ where { fn new(device: &D, resources: &dyn ResourceLoader) -> SolidTileMonochromeProgram { let solid_tile_program = SolidTileProgram::new(device, "tile_solid_monochrome", resources); - let fill_color_uniform = device.get_uniform(&solid_tile_program.program, "FillColor"); + let color_uniform = device.get_uniform(&solid_tile_program.program, "Color"); SolidTileMonochromeProgram { solid_tile_program, - fill_color_uniform, + color_uniform, } } } @@ -1265,8 +1247,8 @@ where D: Device, { alpha_tile_program: AlphaTileProgram, - fill_colors_texture_uniform: D::Uniform, - fill_colors_texture_size_uniform: D::Uniform, + paint_texture_uniform: D::Uniform, + paint_texture_size_uniform: D::Uniform, } impl AlphaTileMulticolorProgram @@ -1275,14 +1257,14 @@ where { fn new(device: &D, resources: &dyn ResourceLoader) -> AlphaTileMulticolorProgram { let alpha_tile_program = AlphaTileProgram::new(device, "tile_alpha_multicolor", resources); - let fill_colors_texture_uniform = - device.get_uniform(&alpha_tile_program.program, "FillColorsTexture"); - let fill_colors_texture_size_uniform = - device.get_uniform(&alpha_tile_program.program, "FillColorsTextureSize"); + let paint_texture_uniform = + device.get_uniform(&alpha_tile_program.program, "PaintTexture"); + let paint_texture_size_uniform = + device.get_uniform(&alpha_tile_program.program, "PaintTextureSize"); AlphaTileMulticolorProgram { alpha_tile_program, - fill_colors_texture_uniform, - fill_colors_texture_size_uniform, + paint_texture_uniform, + paint_texture_size_uniform, } } } @@ -1292,7 +1274,7 @@ where D: Device, { alpha_tile_program: AlphaTileProgram, - fill_color_uniform: D::Uniform, + color_uniform: D::Uniform, } impl AlphaTileMonochromeProgram @@ -1301,10 +1283,10 @@ where { fn new(device: &D, resources: &dyn ResourceLoader) -> AlphaTileMonochromeProgram { let alpha_tile_program = AlphaTileProgram::new(device, "tile_alpha_monochrome", resources); - let fill_color_uniform = device.get_uniform(&alpha_tile_program.program, "FillColor"); + let color_uniform = device.get_uniform(&alpha_tile_program.program, "Color"); AlphaTileMonochromeProgram { alpha_tile_program, - fill_color_uniform, + color_uniform, } } } diff --git a/renderer/src/gpu_data.rs b/renderer/src/gpu_data.rs index c130abd6..55ecb7f8 100644 --- a/renderer/src/gpu_data.rs +++ b/renderer/src/gpu_data.rs @@ -11,9 +11,9 @@ //! Packed data ready to be sent to the GPU. use crate::options::BoundingQuad; -use crate::scene::ObjectShader; use crate::tile_map::DenseTileMap; use pathfinder_geometry::basic::line_segment::{LineSegmentU4, LineSegmentU8}; +use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::rect::RectF32; use std::fmt::{Debug, Formatter, Result as DebugResult}; use std::time::Duration; @@ -28,7 +28,7 @@ pub(crate) struct BuiltObject { pub enum RenderCommand { Start { path_count: usize, bounding_quad: BoundingQuad }, - AddShaders(Vec), + AddPaintData(PaintData), AddFills(Vec), FlushFills, AlphaTile(Vec), @@ -36,6 +36,12 @@ pub enum RenderCommand { Finish { build_time: Duration }, } +#[derive(Clone, Debug)] +pub struct PaintData { + pub size: Point2DI32, + pub texels: Vec, +} + #[derive(Clone, Copy, Debug)] pub struct FillObjectPrimitive { pub px: LineSegmentU4, @@ -84,8 +90,8 @@ impl Debug for RenderCommand { fn fmt(&self, formatter: &mut Formatter) -> DebugResult { match *self { RenderCommand::Start { .. } => write!(formatter, "Start"), - RenderCommand::AddShaders(ref shaders) => { - write!(formatter, "AddShaders(x{})", shaders.len()) + RenderCommand::AddPaintData(ref paint_data) => { + write!(formatter, "AddPaintData({}x{})", paint_data.size.x(), paint_data.size.y()) } RenderCommand::AddFills(ref fills) => write!(formatter, "AddFills(x{})", fills.len()), RenderCommand::FlushFills => write!(formatter, "FlushFills"), diff --git a/renderer/src/scene.rs b/renderer/src/scene.rs index b06af40c..7d4916f4 100644 --- a/renderer/src/scene.rs +++ b/renderer/src/scene.rs @@ -12,16 +12,20 @@ use crate::builder::SceneBuilder; use crate::concurrent::executor::Executor; +use crate::gpu_data::PaintData; use crate::options::{PreparedRenderOptions, PreparedRenderTransform}; use crate::options::{RenderCommandListener, RenderOptions}; use hashbrown::HashMap; -use pathfinder_geometry::basic::point::Point2DF32; +use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32}; use pathfinder_geometry::basic::rect::RectF32; use pathfinder_geometry::basic::transform2d::Transform2DF32; use pathfinder_geometry::color::ColorU; use pathfinder_geometry::outline::Outline; use std::io::{self, Write}; +pub const PAINT_TEXTURE_WIDTH: i32 = 256; +pub const PAINT_TEXTURE_HEIGHT: i32 = 256; + #[derive(Clone)] pub struct Scene { pub(crate) paths: Vec, @@ -85,13 +89,17 @@ impl Scene { self.view_box = new_view_box; } - pub fn build_shaders(&self) -> Vec { - self.paths - .iter() - .map(|path_object| { - ObjectShader { fill_color: self.paints[path_object.paint.0 as usize].color } - }) - .collect() + pub fn build_paint_data(&self) -> PaintData { + let size = Point2DI32::new(PAINT_TEXTURE_WIDTH, PAINT_TEXTURE_HEIGHT); + let mut texels = vec![0; size.x() as usize * size.y() as usize * 4]; + for (path_object_index, path_object) in self.paths.iter().enumerate() { + let paint = &self.paints[path_object.paint.0 as usize]; + texels[path_object_index * 4 + 0] = paint.color.r; + texels[path_object_index * 4 + 1] = paint.color.g; + texels[path_object_index * 4 + 2] = paint.color.b; + texels[path_object_index * 4 + 3] = paint.color.a; + } + PaintData { size, texels } } pub(crate) fn apply_render_options( @@ -234,8 +242,3 @@ pub struct Paint { #[derive(Clone, Copy, PartialEq, Debug)] pub struct PaintId(pub u16); - -#[derive(Clone, Copy, Debug, Default)] -pub struct ObjectShader { - pub fill_color: ColorU, -} diff --git a/resources/shaders/tile_alpha_vertex.inc.glsl b/resources/shaders/tile_alpha_vertex.inc.glsl index c339f926..f9e7e5ba 100644 --- a/resources/shaders/tile_alpha_vertex.inc.glsl +++ b/resources/shaders/tile_alpha_vertex.inc.glsl @@ -23,7 +23,7 @@ out vec2 vTexCoord; out float vBackdrop; out vec4 vColor; -vec4 getFillColor(uint object); +vec4 getColor(uint object); vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); @@ -39,7 +39,7 @@ void computeVaryings() { vTexCoord = texCoord / uStencilTextureSize; vBackdrop = float(aBackdrop); - vColor = getFillColor(aObject); + vColor = getColor(aObject); gl_Position = vec4(position, 0.0, 1.0); } diff --git a/resources/shaders/tile_monochrome.inc.glsl b/resources/shaders/tile_monochrome.inc.glsl index b8d255fc..632c7694 100644 --- a/resources/shaders/tile_monochrome.inc.glsl +++ b/resources/shaders/tile_monochrome.inc.glsl @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -uniform vec4 uFillColor; +uniform vec4 uColor; -vec4 getFillColor(uint object) { - return uFillColor; +vec4 getColor(uint object) { + return uColor; } diff --git a/resources/shaders/tile_multicolor.inc.glsl b/resources/shaders/tile_multicolor.inc.glsl index a66a3f56..4c4f65dd 100644 --- a/resources/shaders/tile_multicolor.inc.glsl +++ b/resources/shaders/tile_multicolor.inc.glsl @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -uniform sampler2D uFillColorsTexture; -uniform vec2 uFillColorsTextureSize; +uniform sampler2D uPaintTexture; +uniform vec2 uPaintTextureSize; -vec2 computeFillColorTexCoord(uint object, vec2 textureSize) { +vec2 computePaintTexCoord(uint object, vec2 textureSize) { uint width = uint(textureSize.x); return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize; } -vec4 getFillColor(uint object) { - vec2 colorTexCoord = computeFillColorTexCoord(object, uFillColorsTextureSize); - return texture(uFillColorsTexture, colorTexCoord); +vec4 getColor(uint object) { + vec2 colorTexCoord = computePaintTexCoord(object, uPaintTextureSize); + return texture(uPaintTexture, colorTexCoord); } diff --git a/resources/shaders/tile_solid_vertex.inc.glsl b/resources/shaders/tile_solid_vertex.inc.glsl index 3c56f2d5..a0eea554 100644 --- a/resources/shaders/tile_solid_vertex.inc.glsl +++ b/resources/shaders/tile_solid_vertex.inc.glsl @@ -18,12 +18,12 @@ in uint aObject; out vec4 vColor; -vec4 getFillColor(uint object); +vec4 getColor(uint object); void computeVaryings() { vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin; vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0); - vColor = getFillColor(aObject); + vColor = getColor(aObject); gl_Position = vec4(position, 0.0, 1.0); }