Apply path transforms to paints
This commit is contained in:
parent
12574101e5
commit
2beb2bb126
|
@ -20,15 +20,15 @@ use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
|||
use crate::paint::{PaintInfo, PaintMetadata};
|
||||
use crate::scene::{DisplayItem, Scene};
|
||||
use crate::tile_map::DenseTileMap;
|
||||
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH, Tiler, TilingPathInfo};
|
||||
use crate::z_buffer::ZBuffer;
|
||||
use crate::tiles::{self, DrawTilingPathInfo, TILE_HEIGHT, TILE_WIDTH, Tiler, TilingPathInfo};
|
||||
use crate::z_buffer::{DepthMetadata, ZBuffer};
|
||||
use pathfinder_content::effects::BlendMode;
|
||||
use pathfinder_content::fill::FillRule;
|
||||
use pathfinder_content::pattern::RenderTargetId;
|
||||
use pathfinder_geometry::line_segment::{LineSegment2F, LineSegmentU4, LineSegmentU8};
|
||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||
use pathfinder_geometry::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::util;
|
||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||
use pathfinder_gpu::TextureSamplingFlags;
|
||||
use pathfinder_simd::default::{F32x4, I32x4};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
@ -170,8 +170,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
built_clip_paths: &[BuiltPath],
|
||||
) -> BuiltDrawPath {
|
||||
let path_object = &scene.paths[path_index];
|
||||
let mut outline = scene.apply_render_options(path_object.outline(), built_options);
|
||||
outline.transform(&path_object.transform());
|
||||
let outline = scene.apply_render_options(path_object.outline(), built_options);
|
||||
|
||||
let paint_id = path_object.paint();
|
||||
let paint_metadata = &paint_metadata[paint_id.0 as usize];
|
||||
|
@ -183,12 +182,13 @@ impl<'a> SceneBuilder<'a> {
|
|||
path_object.fill_rule(),
|
||||
view_box,
|
||||
path_index as u16,
|
||||
TilingPathInfo::Draw {
|
||||
TilingPathInfo::Draw(DrawTilingPathInfo {
|
||||
paint_metadata,
|
||||
blend_mode: path_object.blend_mode(),
|
||||
opacity: path_object.opacity(),
|
||||
built_clip_path,
|
||||
});
|
||||
transform_inv: path_object.transform().inverse(),
|
||||
}));
|
||||
|
||||
tiler.generate_tiles();
|
||||
|
||||
|
@ -357,8 +357,12 @@ impl<'a> SceneBuilder<'a> {
|
|||
built_draw_paths[start_index..end_index].iter().enumerate() {
|
||||
let solid_tiles = &built_draw_path.path.solid_tiles;
|
||||
let path_index = (path_subindex + start_index) as u32;
|
||||
let paint = self.scene.paths[path_index as usize].paint();
|
||||
z_buffer.update(solid_tiles, current_depth, paint);
|
||||
let path = &self.scene.paths[path_index as usize];
|
||||
let metadata = DepthMetadata {
|
||||
paint_id: path.paint(),
|
||||
transform: path.transform(),
|
||||
};
|
||||
z_buffer.update(solid_tiles, current_depth, metadata);
|
||||
current_depth += 1;
|
||||
}
|
||||
}
|
||||
|
@ -701,33 +705,28 @@ impl ObjectBuilder {
|
|||
mask_tile_index: u16,
|
||||
tile_coords: Vector2I,
|
||||
object_index: u16,
|
||||
opacity: u8,
|
||||
paint_metadata: &PaintMetadata) {
|
||||
draw_tiling_path_info: &DrawTilingPathInfo) {
|
||||
alpha_tiles.push(AlphaTile {
|
||||
upper_left: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::default(),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
draw_tiling_path_info),
|
||||
upper_right: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::new(1, 0),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
draw_tiling_path_info),
|
||||
lower_left: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::new(0, 1),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
draw_tiling_path_info),
|
||||
lower_right: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::splat(1),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
draw_tiling_path_info),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -759,11 +758,12 @@ impl AlphaTileVertex {
|
|||
tile_index: u16,
|
||||
tile_offset: Vector2I,
|
||||
object_index: u16,
|
||||
opacity: u8,
|
||||
paint_metadata: &PaintMetadata)
|
||||
draw_tiling_path_info: &DrawTilingPathInfo)
|
||||
-> AlphaTileVertex {
|
||||
let tile_position = tile_origin + tile_offset;
|
||||
let color_uv = paint_metadata.calculate_tex_coords(tile_position);
|
||||
let transform_inv = draw_tiling_path_info.transform_inv;
|
||||
let color_uv = draw_tiling_path_info.paint_metadata.calculate_tex_coords(tile_position,
|
||||
transform_inv);
|
||||
let mask_uv = calculate_mask_uv(tile_index, tile_offset);
|
||||
AlphaTileVertex {
|
||||
tile_x: tile_position.x() as i16,
|
||||
|
@ -773,7 +773,7 @@ impl AlphaTileVertex {
|
|||
mask_u: mask_uv.x() as u16,
|
||||
mask_v: mask_uv.y() as u16,
|
||||
object_index,
|
||||
opacity,
|
||||
opacity: draw_tiling_path_info.opacity,
|
||||
pad: 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -525,9 +525,13 @@ impl Palette {
|
|||
|
||||
impl PaintMetadata {
|
||||
// TODO(pcwalton): Apply clamp/repeat to tile rect.
|
||||
pub(crate) fn calculate_tex_coords(&self, tile_position: Vector2I) -> Vector2F {
|
||||
pub(crate) fn calculate_tex_coords(&self,
|
||||
tile_position: Vector2I,
|
||||
path_transform_inv: Transform2F)
|
||||
-> Vector2F {
|
||||
let tile_size = Vector2I::new(TILE_WIDTH as i32, TILE_HEIGHT as i32);
|
||||
let tex_coords = self.tex_transform * tile_position.scale_xy(tile_size).to_f32();
|
||||
let position = tile_position.scale_xy(tile_size).to_f32();
|
||||
let tex_coords = self.tex_transform * path_transform_inv * position;
|
||||
tex_coords
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,9 @@ impl Scene {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn push_path(&mut self, path: DrawPath) {
|
||||
pub fn push_path(&mut self, mut path: DrawPath) {
|
||||
path.outline.transform(&path.transform());
|
||||
|
||||
self.bounds = self.bounds.union_rect(path.outline.bounds());
|
||||
self.paths.push(path);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ use pathfinder_content::segment::Segment;
|
|||
use pathfinder_content::sorted_vector::SortedVector;
|
||||
use pathfinder_geometry::line_segment::LineSegment2F;
|
||||
use pathfinder_geometry::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::transform2d::Transform2F;
|
||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||
use std::cmp::Ordering;
|
||||
use std::mem;
|
||||
|
@ -43,12 +44,19 @@ pub(crate) struct Tiler<'a> {
|
|||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum TilingPathInfo<'a> {
|
||||
Clip,
|
||||
Draw {
|
||||
paint_metadata: &'a PaintMetadata,
|
||||
blend_mode: BlendMode,
|
||||
opacity: u8,
|
||||
built_clip_path: Option<&'a BuiltPath>,
|
||||
},
|
||||
Draw(DrawTilingPathInfo<'a>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct DrawTilingPathInfo<'a> {
|
||||
pub(crate) paint_metadata: &'a PaintMetadata,
|
||||
pub(crate) blend_mode: BlendMode,
|
||||
pub(crate) opacity: u8,
|
||||
// The inverse of the path transform.
|
||||
//
|
||||
// We calculate texture transforms with this.
|
||||
pub(crate) transform_inv: Transform2F,
|
||||
pub(crate) built_clip_path: Option<&'a BuiltPath>,
|
||||
}
|
||||
|
||||
impl<'a> Tiler<'a> {
|
||||
|
@ -128,11 +136,9 @@ impl<'a> Tiler<'a> {
|
|||
}
|
||||
|
||||
fn pack_and_cull_draw_path(&mut self) {
|
||||
let (paint_metadata, blend_mode, opacity, built_clip_path) = match self.path_info {
|
||||
let draw_tiling_path_info = match self.path_info {
|
||||
TilingPathInfo::Clip => unreachable!(),
|
||||
TilingPathInfo::Draw { paint_metadata, blend_mode, opacity, built_clip_path } => {
|
||||
(paint_metadata, blend_mode, opacity, built_clip_path)
|
||||
}
|
||||
TilingPathInfo::Draw(draw_tiling_path_info) => draw_tiling_path_info,
|
||||
};
|
||||
|
||||
for (draw_tile_index, draw_tile) in self.object_builder
|
||||
|
@ -145,7 +151,7 @@ impl<'a> Tiler<'a> {
|
|||
.local_tile_index_to_coords(draw_tile_index as u32);
|
||||
|
||||
// Figure out what clip tile we need, if any.
|
||||
let clip_tile = match built_clip_path {
|
||||
let clip_tile = match draw_tiling_path_info.built_clip_path {
|
||||
None => None,
|
||||
Some(built_clip_path) => {
|
||||
match built_clip_path.tiles.get(tile_coords) {
|
||||
|
@ -182,7 +188,9 @@ impl<'a> Tiler<'a> {
|
|||
|
||||
// Next, if this is a solid tile that completely occludes the background, record
|
||||
// that fact and stop here.
|
||||
if paint_metadata.is_opaque && blend_mode.occludes_backdrop() && opacity == !0 {
|
||||
if draw_tiling_path_info.paint_metadata.is_opaque &&
|
||||
draw_tiling_path_info.blend_mode.occludes_backdrop() &&
|
||||
draw_tiling_path_info.opacity == !0 {
|
||||
self.object_builder.built_path.solid_tiles.push(SolidTile::new(tile_coords));
|
||||
continue;
|
||||
}
|
||||
|
@ -210,8 +218,7 @@ impl<'a> Tiler<'a> {
|
|||
mask_tile_index,
|
||||
tile_coords,
|
||||
self.object_index,
|
||||
opacity,
|
||||
paint_metadata);
|
||||
&draw_tiling_path_info);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,24 +16,30 @@ use crate::paint::{PaintId, PaintMetadata};
|
|||
use crate::tile_map::DenseTileMap;
|
||||
use crate::tiles;
|
||||
use pathfinder_geometry::rect::RectF;
|
||||
use pathfinder_geometry::transform2d::Transform2F;
|
||||
use pathfinder_geometry::vector::Vector2I;
|
||||
use vec_map::VecMap;
|
||||
|
||||
pub(crate) struct ZBuffer {
|
||||
buffer: DenseTileMap<u32>,
|
||||
depth_to_paint_id: VecMap<PaintId>,
|
||||
depth_metadata: VecMap<DepthMetadata>,
|
||||
}
|
||||
|
||||
pub(crate) struct SolidTiles {
|
||||
pub(crate) batches: Vec<SolidTileBatch>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct DepthMetadata {
|
||||
pub(crate) paint_id: PaintId,
|
||||
pub(crate) transform: Transform2F,
|
||||
}
|
||||
impl ZBuffer {
|
||||
pub(crate) fn new(view_box: RectF) -> ZBuffer {
|
||||
let tile_rect = tiles::round_rect_out_to_tile_bounds(view_box);
|
||||
ZBuffer {
|
||||
buffer: DenseTileMap::from_builder(|_| 0, tile_rect),
|
||||
depth_to_paint_id: VecMap::new(),
|
||||
depth_metadata: VecMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,8 +48,11 @@ impl ZBuffer {
|
|||
self.buffer.data[tile_index as usize] < depth
|
||||
}
|
||||
|
||||
pub(crate) fn update(&mut self, solid_tiles: &[SolidTile], depth: u32, paint_id: PaintId) {
|
||||
self.depth_to_paint_id.insert(depth as usize, paint_id);
|
||||
pub(crate) fn update(&mut self,
|
||||
solid_tiles: &[SolidTile],
|
||||
depth: u32,
|
||||
metadata: DepthMetadata) {
|
||||
self.depth_metadata.insert(depth as usize, metadata);
|
||||
for solid_tile in solid_tiles {
|
||||
let tile_index = self.buffer.coords_to_index_unchecked(solid_tile.coords);
|
||||
let z_dest = &mut self.buffer.data[tile_index as usize];
|
||||
|
@ -62,8 +71,9 @@ impl ZBuffer {
|
|||
|
||||
let tile_coords = self.buffer.index_to_coords(tile_index);
|
||||
|
||||
let paint_id = self.depth_to_paint_id[depth as usize];
|
||||
let paint_metadata = &paint_metadata[paint_id.0 as usize];
|
||||
let depth_metadata = self.depth_metadata[depth as usize];
|
||||
let paint_metadata = &paint_metadata[depth_metadata.paint_id.0 as usize];
|
||||
let transform = depth_metadata.transform;
|
||||
|
||||
let tile_position = tile_coords + self.buffer.rect.origin();
|
||||
|
||||
|
@ -83,10 +93,16 @@ impl ZBuffer {
|
|||
|
||||
let batch = solid_tiles.batches.last_mut().unwrap();
|
||||
batch.vertices.extend_from_slice(&[
|
||||
SolidTileVertex::new(tile_position, paint_metadata),
|
||||
SolidTileVertex::new(tile_position + Vector2I::new(1, 0), paint_metadata),
|
||||
SolidTileVertex::new(tile_position + Vector2I::new(0, 1), paint_metadata),
|
||||
SolidTileVertex::new(tile_position + Vector2I::new(1, 1), paint_metadata),
|
||||
SolidTileVertex::new(tile_position, transform, paint_metadata),
|
||||
SolidTileVertex::new(tile_position + Vector2I::new(1, 0),
|
||||
transform,
|
||||
paint_metadata),
|
||||
SolidTileVertex::new(tile_position + Vector2I::new(0, 1),
|
||||
transform,
|
||||
paint_metadata),
|
||||
SolidTileVertex::new(tile_position + Vector2I::new(1, 1),
|
||||
transform,
|
||||
paint_metadata),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -95,8 +111,9 @@ impl ZBuffer {
|
|||
}
|
||||
|
||||
impl SolidTileVertex {
|
||||
fn new(tile_position: Vector2I, paint_metadata: &PaintMetadata) -> SolidTileVertex {
|
||||
let color_uv = paint_metadata.calculate_tex_coords(tile_position);
|
||||
fn new(tile_position: Vector2I, transform: Transform2F, paint_metadata: &PaintMetadata)
|
||||
-> SolidTileVertex {
|
||||
let color_uv = paint_metadata.calculate_tex_coords(tile_position, transform);
|
||||
SolidTileVertex {
|
||||
tile_x: tile_position.x() as i16,
|
||||
tile_y: tile_position.y() as i16,
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
# When you add a new resource, make sure to add it to this file.
|
||||
|
||||
debug-fonts/regular.json
|
||||
shaders/gl3/blit.fs.glsl
|
||||
shaders/gl3/blit.vs.glsl
|
||||
shaders/gl3/debug_solid.fs.glsl
|
||||
shaders/gl3/debug_solid.vs.glsl
|
||||
shaders/gl3/debug_texture.fs.glsl
|
||||
|
@ -11,10 +13,6 @@ shaders/gl3/demo_ground.fs.glsl
|
|||
shaders/gl3/demo_ground.vs.glsl
|
||||
shaders/gl3/fill.fs.glsl
|
||||
shaders/gl3/fill.vs.glsl
|
||||
shaders/gl3/filter.vs.glsl
|
||||
shaders/gl3/filter_basic.fs.glsl
|
||||
shaders/gl3/filter_blur.fs.glsl
|
||||
shaders/gl3/filter_text.fs.glsl
|
||||
shaders/gl3/mask.vs.glsl
|
||||
shaders/gl3/mask_evenodd.fs.glsl
|
||||
shaders/gl3/mask_winding.fs.glsl
|
||||
|
@ -37,6 +35,9 @@ shaders/gl3/tile_alpha_overlay.fs.glsl
|
|||
shaders/gl3/tile_alpha_softlight.fs.glsl
|
||||
shaders/gl3/tile_copy.fs.glsl
|
||||
shaders/gl3/tile_copy.vs.glsl
|
||||
shaders/gl3/tile_filter.vs.glsl
|
||||
shaders/gl3/tile_filter_blur.fs.glsl
|
||||
shaders/gl3/tile_filter_text.fs.glsl
|
||||
shaders/gl3/tile_solid.fs.glsl
|
||||
shaders/gl3/tile_solid.vs.glsl
|
||||
shaders/gl3/tile_solid_monochrome.vs.glsl
|
||||
|
|
Loading…
Reference in New Issue