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 } }