From 7a02b78b3d4bf894c1fe3ff6c04d4cc3d58e6f84 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 14 May 2019 14:28:21 -0700 Subject: [PATCH] Explicitly specify color texture coordinates for alpha and solid tiles. This is groundwork for gradients and images. This commit also refactors the interface for vertex attributes to use named parameters (via structs), for clarity. --- demo/common/src/device.rs | 11 +- gl/src/lib.rs | 60 ++-- gpu/src/lib.rs | 37 ++- renderer/src/gpu/renderer.rs | 288 +++++++++++-------- renderer/src/gpu_data.rs | 4 + renderer/src/lib.rs | 1 + renderer/src/paint.rs | 37 +++ renderer/src/scene.rs | 26 +- renderer/src/tiles.rs | 9 +- renderer/src/z_buffer.rs | 25 +- resources/shaders/tile_alpha_vertex.inc.glsl | 9 +- resources/shaders/tile_monochrome.inc.glsl | 2 +- resources/shaders/tile_multicolor.inc.glsl | 10 +- resources/shaders/tile_solid_vertex.inc.glsl | 5 +- ui/src/lib.rs | 48 ++-- 15 files changed, 333 insertions(+), 239 deletions(-) create mode 100644 renderer/src/paint.rs diff --git a/demo/common/src/device.rs b/demo/common/src/device.rs index ccd0b877..17b14e9a 100644 --- a/demo/common/src/device.rs +++ b/demo/common/src/device.rs @@ -11,7 +11,7 @@ //! GPU rendering code specifically for the demo. use pathfinder_gpu::resources::ResourceLoader; -use pathfinder_gpu::{BufferTarget, Device, VertexAttrType}; +use pathfinder_gpu::{BufferTarget, Device, VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; pub struct GroundProgram where @@ -67,7 +67,14 @@ where device.bind_vertex_array(&vertex_array); device.use_program(&ground_program.program); device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr(&position_attr, 2, VertexAttrType::U8, false, 0, 0, 0); + device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U8, + stride: 0, + offset: 0, + divisor: 0, + }); GroundVertexArray { vertex_array } } diff --git a/gl/src/lib.rs b/gl/src/lib.rs index 5522083e..cb4e002a 100644 --- a/gl/src/lib.rs +++ b/gl/src/lib.rs @@ -18,7 +18,8 @@ use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::rect::RectI32; use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearParams}; use pathfinder_gpu::{DepthFunc, Device, Primitive, RenderState, ShaderKind, StencilFunc}; -use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrType}; +use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrClass}; +use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_simd::default::F32x4; use rustache::{HashBuilder, Render}; use std::ffi::CString; @@ -327,40 +328,33 @@ impl Device for GLDevice { } } - fn configure_float_vertex_attr(&self, - attr: &GLVertexAttr, - size: usize, - attr_type: VertexAttrType, - normalized: bool, - stride: usize, - offset: usize, - divisor: u32) { + fn configure_vertex_attr(&self, attr: &GLVertexAttr, descriptor: &VertexAttrDescriptor) { unsafe { - gl::VertexAttribPointer(attr.attr, - size as GLint, - attr_type.to_gl_type(), - if normalized { gl::TRUE } else { gl::FALSE }, - stride as GLint, - offset as *const GLvoid); ck(); - gl::VertexAttribDivisor(attr.attr, divisor); ck(); - gl::EnableVertexAttribArray(attr.attr); ck(); - } - } + let attr_type = descriptor.attr_type.to_gl_type(); + match descriptor.class { + VertexAttrClass::Float | VertexAttrClass::FloatNorm => { + let normalized = if descriptor.class == VertexAttrClass::FloatNorm { + gl::TRUE + } else { + gl::FALSE + }; + gl::VertexAttribPointer(attr.attr, + descriptor.size as GLint, + attr_type, + normalized, + descriptor.stride as GLint, + descriptor.offset as *const GLvoid); ck(); + } + VertexAttrClass::Int => { + gl::VertexAttribIPointer(attr.attr, + descriptor.size as GLint, + attr_type, + descriptor.stride as GLint, + descriptor.offset as *const GLvoid); ck(); + } + } - fn configure_int_vertex_attr(&self, - attr: &GLVertexAttr, - size: usize, - attr_type: VertexAttrType, - stride: usize, - offset: usize, - divisor: u32) { - unsafe { - gl::VertexAttribIPointer(attr.attr, - size as GLint, - attr_type.to_gl_type(), - stride as GLint, - offset as *const GLvoid); ck(); - gl::VertexAttribDivisor(attr.attr, divisor); ck(); + gl::VertexAttribDivisor(attr.attr, descriptor.divisor); ck(); gl::EnableVertexAttribArray(attr.attr); ck(); } } diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs index 7282eab1..ec418cee 100644 --- a/gpu/src/lib.rs +++ b/gpu/src/lib.rs @@ -52,25 +52,7 @@ pub trait Device { fn get_vertex_attr(&self, program: &Self::Program, name: &str) -> Self::VertexAttr; fn get_uniform(&self, program: &Self::Program, name: &str) -> Self::Uniform; fn use_program(&self, program: &Self::Program); - fn configure_float_vertex_attr( - &self, - attr: &Self::VertexAttr, - size: usize, - attr_type: VertexAttrType, - normalized: bool, - stride: usize, - offset: usize, - divisor: u32, - ); - fn configure_int_vertex_attr( - &self, - attr: &Self::VertexAttr, - size: usize, - attr_type: VertexAttrType, - stride: usize, - offset: usize, - divisor: u32, - ); + fn configure_vertex_attr(&self, attr: &Self::VertexAttr, descriptor: &VertexAttrDescriptor); fn set_uniform(&self, uniform: &Self::Uniform, data: UniformData); fn create_framebuffer(&self, texture: Self::Texture) -> Self::Framebuffer; fn create_buffer(&self) -> Self::Buffer; @@ -340,6 +322,23 @@ impl UniformData { } } +#[derive(Clone, Copy, Debug)] +pub struct VertexAttrDescriptor { + pub size: usize, + pub class: VertexAttrClass, + pub attr_type: VertexAttrType, + pub stride: usize, + pub offset: usize, + pub divisor: u32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum VertexAttrClass { + Float, + FloatNorm, + Int, +} + fn load_shader_include(resources: &dyn ResourceLoader, include_name: &str) -> String { let resource = resources .slurp(&format!("shaders/{}.inc.glsl", include_name)) diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index bd34980f..96a5dc55 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -20,7 +20,8 @@ use pathfinder_geometry::color::ColorF; use pathfinder_gpu::resources::ResourceLoader; use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearParams}; use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc}; -use pathfinder_gpu::{StencilState, TextureFormat, UniformData, VertexAttrType}; +use pathfinder_gpu::{StencilState, TextureFormat, UniformData, VertexAttrClass}; +use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_simd::default::{F32x4, I32x4}; use std::cmp; use std::collections::VecDeque; @@ -37,8 +38,8 @@ const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 * 256; // TODO(pcwalton): Replace with `mem::size_of` calls? const FILL_INSTANCE_SIZE: usize = 8; -const SOLID_TILE_INSTANCE_SIZE: usize = 6; -const MASK_TILE_INSTANCE_SIZE: usize = 8; +const SOLID_TILE_INSTANCE_SIZE: usize = 10; +const MASK_TILE_INSTANCE_SIZE: usize = 12; const MAX_FILLS_PER_BATCH: usize = 0x4000; @@ -918,55 +919,57 @@ where device.bind_vertex_array(&vertex_array); device.use_program(&fill_program.program); device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr(&tess_coord_attr, 2, VertexAttrType::U8, false, 0, 0, 0); + device.configure_vertex_attr(&tess_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U8, + stride: 0, + offset: 0, + divisor: 0, + }); device.bind_buffer(&vertex_buffer, BufferTarget::Vertex); - device.configure_int_vertex_attr( - &from_px_attr, - 1, - VertexAttrType::U8, - FILL_INSTANCE_SIZE, - 0, - 1, - ); - device.configure_int_vertex_attr( - &to_px_attr, - 1, - VertexAttrType::U8, - FILL_INSTANCE_SIZE, - 1, - 1, - ); - device.configure_float_vertex_attr( - &from_subpx_attr, - 2, - VertexAttrType::U8, - true, - FILL_INSTANCE_SIZE, - 2, - 1, - ); - device.configure_float_vertex_attr( - &to_subpx_attr, - 2, - VertexAttrType::U8, - true, - FILL_INSTANCE_SIZE, - 4, - 1, - ); - device.configure_int_vertex_attr( - &tile_index_attr, - 1, - VertexAttrType::U16, - FILL_INSTANCE_SIZE, - 6, - 1, - ); + device.configure_vertex_attr(&from_px_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U8, + stride: FILL_INSTANCE_SIZE, + offset: 0, + divisor: 1, + }); + device.configure_vertex_attr(&to_px_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U8, + stride: FILL_INSTANCE_SIZE, + offset: 1, + divisor: 1, + }); + device.configure_vertex_attr(&from_subpx_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::FloatNorm, + attr_type: VertexAttrType::U8, + stride: FILL_INSTANCE_SIZE, + offset: 2, + divisor: 1, + }); + device.configure_vertex_attr(&to_subpx_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::FloatNorm, + attr_type: VertexAttrType::U8, + stride: FILL_INSTANCE_SIZE, + offset: 4, + divisor: 1, + }); + device.configure_vertex_attr(&tile_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U16, + stride: FILL_INSTANCE_SIZE, + offset: 6, + divisor: 1, + }); - FillVertexArray { - vertex_array, - vertex_buffer, - } + FillVertexArray { vertex_array, vertex_buffer } } } @@ -994,51 +997,65 @@ where let backdrop_attr = device.get_vertex_attr(&alpha_tile_program.program, "Backdrop"); let object_attr = device.get_vertex_attr(&alpha_tile_program.program, "Object"); let tile_index_attr = device.get_vertex_attr(&alpha_tile_program.program, "TileIndex"); + let color_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program, + "ColorTexCoord"); // NB: The object must be of type `I16`, not `U16`, to work around a macOS Radeon // driver bug. device.bind_vertex_array(&vertex_array); device.use_program(&alpha_tile_program.program); device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr(&tess_coord_attr, 2, VertexAttrType::U8, false, 0, 0, 0); + device.configure_vertex_attr(&tess_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U8, + stride: 0, + offset: 0, + divisor: 0, + }); device.bind_buffer(&vertex_buffer, BufferTarget::Vertex); - device.configure_int_vertex_attr( - &tile_origin_attr, - 3, - VertexAttrType::U8, - MASK_TILE_INSTANCE_SIZE, - 0, - 1, - ); - device.configure_int_vertex_attr( - &backdrop_attr, - 1, - VertexAttrType::I8, - MASK_TILE_INSTANCE_SIZE, - 3, - 1, - ); - device.configure_int_vertex_attr( - &object_attr, - 1, - VertexAttrType::I16, - MASK_TILE_INSTANCE_SIZE, - 4, - 1, - ); - device.configure_int_vertex_attr( - &tile_index_attr, - 1, - VertexAttrType::I16, - MASK_TILE_INSTANCE_SIZE, - 6, - 1, - ); + device.configure_vertex_attr(&tile_origin_attr, &VertexAttrDescriptor { + size: 3, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U8, + stride: MASK_TILE_INSTANCE_SIZE, + offset: 0, + divisor: 1, + }); + device.configure_vertex_attr(&backdrop_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I8, + stride: MASK_TILE_INSTANCE_SIZE, + offset: 3, + divisor: 1, + }); + device.configure_vertex_attr(&object_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: MASK_TILE_INSTANCE_SIZE, + offset: 4, + divisor: 1, + }); + device.configure_vertex_attr(&tile_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: MASK_TILE_INSTANCE_SIZE, + offset: 6, + divisor: 1, + }); + device.configure_vertex_attr(&color_tex_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::FloatNorm, + attr_type: VertexAttrType::U16, + stride: MASK_TILE_INSTANCE_SIZE, + offset: 8, + divisor: 1, + }); - AlphaTileVertexArray { - vertex_array, - vertex_buffer, - } + AlphaTileVertexArray { vertex_array, vertex_buffer } } } @@ -1064,36 +1081,49 @@ where let tess_coord_attr = device.get_vertex_attr(&solid_tile_program.program, "TessCoord"); let tile_origin_attr = device.get_vertex_attr(&solid_tile_program.program, "TileOrigin"); let object_attr = device.get_vertex_attr(&solid_tile_program.program, "Object"); + let color_tex_coord_attr = device.get_vertex_attr(&solid_tile_program.program, + "ColorTexCoord"); // NB: The object must be of type short, not unsigned short, to work around a macOS // Radeon driver bug. device.bind_vertex_array(&vertex_array); device.use_program(&solid_tile_program.program); device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr(&tess_coord_attr, 2, VertexAttrType::U8, false, 0, 0, 0); + device.configure_vertex_attr(&tess_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U8, + stride: 0, + offset: 0, + divisor: 0, + }); device.bind_buffer(&vertex_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr( - &tile_origin_attr, - 2, - VertexAttrType::I16, - false, - SOLID_TILE_INSTANCE_SIZE, - 0, - 1, - ); - device.configure_int_vertex_attr( - &object_attr, - 1, - VertexAttrType::I16, - SOLID_TILE_INSTANCE_SIZE, - 4, - 1, - ); + device.configure_vertex_attr(&tile_origin_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::I16, + stride: SOLID_TILE_INSTANCE_SIZE, + offset: 0, + divisor: 1, + }); + device.configure_vertex_attr(&color_tex_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::FloatNorm, + attr_type: VertexAttrType::U16, + stride: SOLID_TILE_INSTANCE_SIZE, + offset: 4, + divisor: 1, + }); + device.configure_vertex_attr(&object_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: SOLID_TILE_INSTANCE_SIZE, + offset: 8, + divisor: 1, + }); - SolidTileVertexArray { - vertex_array, - vertex_buffer, - } + SolidTileVertexArray { vertex_array, vertex_buffer } } } @@ -1361,7 +1391,14 @@ where device.bind_vertex_array(&vertex_array); device.use_program(&postprocess_program.program); device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr(&position_attr, 2, VertexAttrType::U8, false, 0, 0, 0); + device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U8, + stride: 0, + offset: 0, + divisor: 0, + }); PostprocessVertexArray { vertex_array } } @@ -1404,20 +1441,16 @@ where device.bind_vertex_array(&vertex_array); device.use_program(&stencil_program.program); device.bind_buffer(&vertex_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr( - &position_attr, - 3, - VertexAttrType::F32, - false, - 4 * 4, - 0, - 0, - ); + device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor { + size: 3, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::F32, + stride: 4 * 4, + offset: 0, + divisor: 0, + }); - StencilVertexArray { - vertex_array, - vertex_buffer, - } + StencilVertexArray { vertex_array, vertex_buffer } } } @@ -1473,7 +1506,14 @@ where device.bind_vertex_array(&vertex_array); device.use_program(&reprojection_program.program); device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_float_vertex_attr(&position_attr, 2, VertexAttrType::U8, false, 0, 0, 0); + device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U8, + stride: 0, + offset: 0, + divisor: 0, + }); ReprojectionVertexArray { vertex_array } } diff --git a/renderer/src/gpu_data.rs b/renderer/src/gpu_data.rs index 55ecb7f8..48520986 100644 --- a/renderer/src/gpu_data.rs +++ b/renderer/src/gpu_data.rs @@ -72,6 +72,8 @@ pub struct FillBatchPrimitive { pub struct SolidTileBatchPrimitive { pub tile_x: i16, pub tile_y: i16, + pub origin_u: u16, + pub origin_v: u16, pub object_index: u16, } @@ -84,6 +86,8 @@ pub struct AlphaTileBatchPrimitive { pub backdrop: i8, pub object_index: u16, pub tile_index: u16, + pub origin_u: u16, + pub origin_v: u16, } impl Debug for RenderCommand { diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 803e5e13..0f80405e 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -17,6 +17,7 @@ pub mod concurrent; pub mod gpu; pub mod gpu_data; pub mod options; +pub mod paint; pub mod post; pub mod scene; diff --git a/renderer/src/paint.rs b/renderer/src/paint.rs new file mode 100644 index 00000000..306c5312 --- /dev/null +++ b/renderer/src/paint.rs @@ -0,0 +1,37 @@ +// pathfinder/renderer/src/paint.rs +// +// Copyright © 2019 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::gpu_data::PaintData; +use crate::scene::Scene; +use pathfinder_geometry::basic::point::Point2DI32; + +const PAINT_TEXTURE_WIDTH: i32 = 256; +const PAINT_TEXTURE_HEIGHT: i32 = 256; + +impl Scene { + 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 object_index_to_paint_coords(object_index: u16) -> Point2DI32 { + let tex_coords = Point2DI32::new(object_index as i32 % PAINT_TEXTURE_WIDTH, + object_index as i32 / PAINT_TEXTURE_WIDTH); + tex_coords.scale(256) + Point2DI32::new(128, 128) +} diff --git a/renderer/src/scene.rs b/renderer/src/scene.rs index 79100553..8497575e 100644 --- a/renderer/src/scene.rs +++ b/renderer/src/scene.rs @@ -12,24 +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, Point2DI32}; +use pathfinder_geometry::basic::point::Point2DF32; 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}; -const PAINT_TEXTURE_WIDTH: i32 = 256; -const PAINT_TEXTURE_HEIGHT: i32 = 256; - #[derive(Clone)] pub struct Scene { pub(crate) paths: Vec, - paints: Vec, + pub(crate) paints: Vec, paint_cache: HashMap, bounds: RectF32, view_box: RectF32, @@ -89,19 +85,6 @@ impl Scene { self.view_box = new_view_box; } - 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( &self, original_outline: &Outline, @@ -233,6 +216,11 @@ impl PathObject { pub fn outline(&self) -> &Outline { &self.outline } + + #[inline] + pub(crate) fn paint(&self) -> PaintId { + self.paint + } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] diff --git a/renderer/src/tiles.rs b/renderer/src/tiles.rs index 0dd99eb1..a09be5b4 100644 --- a/renderer/src/tiles.rs +++ b/renderer/src/tiles.rs @@ -10,6 +10,7 @@ use crate::builder::SceneBuilder; use crate::gpu_data::{AlphaTileBatchPrimitive, BuiltObject, TileObjectPrimitive}; +use crate::paint; use crate::sorted_vector::SortedVector; use pathfinder_geometry::basic::line_segment::LineSegmentF32; use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32}; @@ -114,11 +115,14 @@ impl<'a> Tiler<'a> { continue; } + let origin_uv = paint::object_index_to_paint_coords(self.object_index); + let alpha_tile = AlphaTileBatchPrimitive::new( tile_coords, tile.backdrop, self.object_index, tile.alpha_tile_index as u16, + origin_uv, ); self.built_object.alpha_tiles.push(alpha_tile); @@ -521,7 +525,8 @@ impl AlphaTileBatchPrimitive { fn new(tile_coords: Point2DI32, backdrop: i8, object_index: u16, - tile_index: u16) + tile_index: u16, + origin_uv: Point2DI32) -> AlphaTileBatchPrimitive { AlphaTileBatchPrimitive { tile_x_lo: (tile_coords.x() & 0xff) as u8, @@ -530,6 +535,8 @@ impl AlphaTileBatchPrimitive { backdrop, object_index, tile_index, + origin_u: origin_uv.x() as u16, + origin_v: origin_uv.y() as u16, } } diff --git a/renderer/src/z_buffer.rs b/renderer/src/z_buffer.rs index a523bd9e..4a70865a 100644 --- a/renderer/src/z_buffer.rs +++ b/renderer/src/z_buffer.rs @@ -11,6 +11,7 @@ //! Software occlusion culling. use crate::gpu_data::SolidTileBatchPrimitive; +use crate::paint; use crate::tile_map::DenseTileMap; use crate::tiles; use pathfinder_geometry::basic::point::Point2DI32; @@ -67,13 +68,27 @@ impl ZBuffer { if object_index < object_range.start || object_index >= object_range.end { continue; } - solid_tiles.push(SolidTileBatchPrimitive { - tile_x: (tile_coords.x() + self.buffer.rect.min_x()) as i16, - tile_y: (tile_coords.y() + self.buffer.rect.min_y()) as i16, - object_index: object_index as u16, - }); + + let origin_uv = paint::object_index_to_paint_coords(object_index as u16); + + solid_tiles.push(SolidTileBatchPrimitive::new(tile_coords + self.buffer.rect.origin(), + object_index as u16, + origin_uv)); } solid_tiles } } + +impl SolidTileBatchPrimitive { + fn new(tile_coords: Point2DI32, object_index: u16, origin_uv: Point2DI32) + -> SolidTileBatchPrimitive { + SolidTileBatchPrimitive { + tile_x: tile_coords.x() as i16, + tile_y: tile_coords.y() as i16, + object_index: object_index, + origin_u: origin_uv.x() as u16, + origin_v: origin_uv.y() as u16, + } + } +} diff --git a/resources/shaders/tile_alpha_vertex.inc.glsl b/resources/shaders/tile_alpha_vertex.inc.glsl index f9e7e5ba..9a13b146 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 getColor(uint object); +vec4 getColor(); vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); @@ -35,11 +35,12 @@ void computeVaryings() { vec2 origin = vec2(aTileOrigin.xy) + vec2(aTileOrigin.z & 15u, aTileOrigin.z >> 4u) * 256.0; vec2 pixelPosition = (origin + aTessCoord) * uTileSize + uViewBoxOrigin; vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0); - vec2 texCoord = computeTileOffset(aTileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize; + vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize.x); + vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize; - vTexCoord = texCoord / uStencilTextureSize; + vTexCoord = maskTexCoord / uStencilTextureSize; vBackdrop = float(aBackdrop); - vColor = getColor(aObject); + vColor = getColor(); 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 632c7694..7b10b25b 100644 --- a/resources/shaders/tile_monochrome.inc.glsl +++ b/resources/shaders/tile_monochrome.inc.glsl @@ -10,6 +10,6 @@ uniform vec4 uColor; -vec4 getColor(uint object) { +vec4 getColor() { return uColor; } diff --git a/resources/shaders/tile_multicolor.inc.glsl b/resources/shaders/tile_multicolor.inc.glsl index 4c4f65dd..a374bbee 100644 --- a/resources/shaders/tile_multicolor.inc.glsl +++ b/resources/shaders/tile_multicolor.inc.glsl @@ -11,12 +11,8 @@ uniform sampler2D uPaintTexture; uniform vec2 uPaintTextureSize; -vec2 computePaintTexCoord(uint object, vec2 textureSize) { - uint width = uint(textureSize.x); - return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize; -} +in vec2 aColorTexCoord; -vec4 getColor(uint object) { - vec2 colorTexCoord = computePaintTexCoord(object, uPaintTextureSize); - return texture(uPaintTexture, colorTexCoord); +vec4 getColor() { + return texture(uPaintTexture, aColorTexCoord); } diff --git a/resources/shaders/tile_solid_vertex.inc.glsl b/resources/shaders/tile_solid_vertex.inc.glsl index a0eea554..04aa3109 100644 --- a/resources/shaders/tile_solid_vertex.inc.glsl +++ b/resources/shaders/tile_solid_vertex.inc.glsl @@ -18,12 +18,13 @@ in uint aObject; out vec4 vColor; -vec4 getColor(uint object); +vec4 getColor(); void computeVaryings() { vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin; vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0); - vColor = getColor(aObject); + vColor = getColor(); + //vColor = vec4(1.0, 0.0, 0.0, 1.0); gl_Position = vec4(position, 0.0, 1.0); } diff --git a/ui/src/lib.rs b/ui/src/lib.rs index c7796d5d..eaff03be 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -22,7 +22,8 @@ use pathfinder_geometry::basic::rect::RectI32; use pathfinder_geometry::color::ColorU; use pathfinder_gpu::resources::ResourceLoader; use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, Device, Primitive}; -use pathfinder_gpu::{RenderState, UniformData, VertexAttrType}; +use pathfinder_gpu::{RenderState, UniformData, VertexAttrClass}; +use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_simd::default::F32x4; use serde_json; use std::mem; @@ -591,20 +592,22 @@ impl DebugTextureVertexArray where D: Device { device.use_program(&debug_texture_program.program); device.bind_buffer(&vertex_buffer, BufferTarget::Vertex); device.bind_buffer(&index_buffer, BufferTarget::Index); - device.configure_float_vertex_attr(&position_attr, - 2, - VertexAttrType::U16, - false, - DEBUG_TEXTURE_VERTEX_SIZE, - 0, - 0); - device.configure_float_vertex_attr(&tex_coord_attr, - 2, - VertexAttrType::U16, - false, - DEBUG_TEXTURE_VERTEX_SIZE, - 4, - 0); + device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U16, + stride: DEBUG_TEXTURE_VERTEX_SIZE, + offset: 0, + divisor: 0, + }); + device.configure_vertex_attr(&tex_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U16, + stride: DEBUG_TEXTURE_VERTEX_SIZE, + offset: 4, + divisor: 0, + }); DebugTextureVertexArray { vertex_array, vertex_buffer, index_buffer } } @@ -626,13 +629,14 @@ impl DebugSolidVertexArray where D: Device { device.use_program(&debug_solid_program.program); device.bind_buffer(&vertex_buffer, BufferTarget::Vertex); device.bind_buffer(&index_buffer, BufferTarget::Index); - device.configure_float_vertex_attr(&position_attr, - 2, - VertexAttrType::U16, - false, - DEBUG_SOLID_VERTEX_SIZE, - 0, - 0); + device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Float, + attr_type: VertexAttrType::U16, + stride: DEBUG_SOLID_VERTEX_SIZE, + offset: 0, + divisor: 0, + }); DebugSolidVertexArray { vertex_array, vertex_buffer, index_buffer } }