Clip entire tiles appropriately.
This doesn't composite masks together, so it's currently incomplete.
This commit is contained in:
parent
a8019a1a1a
commit
0d3bbbd506
|
@ -42,7 +42,6 @@ pub(crate) struct SceneBuilder<'a> {
|
|||
pub(crate) struct ObjectBuilder {
|
||||
pub built_path: BuiltPath,
|
||||
pub fills: Vec<FillBatchPrimitive>,
|
||||
pub tiles: DenseTileMap<TileObjectPrimitive>,
|
||||
pub bounds: RectF,
|
||||
}
|
||||
|
||||
|
@ -50,6 +49,7 @@ pub(crate) struct ObjectBuilder {
|
|||
pub(crate) struct BuiltPath {
|
||||
pub mask_tiles: Vec<MaskTile>,
|
||||
pub alpha_tiles: Vec<AlphaTile>,
|
||||
pub tiles: DenseTileMap<TileObjectPrimitive>,
|
||||
}
|
||||
|
||||
impl<'a> SceneBuilder<'a> {
|
||||
|
@ -226,16 +226,15 @@ impl ObjectBuilder {
|
|||
let tile_rect = tiles::round_rect_out_to_tile_bounds(bounds);
|
||||
let tiles = DenseTileMap::new(tile_rect);
|
||||
ObjectBuilder {
|
||||
built_path: BuiltPath { mask_tiles: vec![], alpha_tiles: vec![] },
|
||||
built_path: BuiltPath { mask_tiles: vec![], alpha_tiles: vec![], tiles },
|
||||
bounds,
|
||||
fills: vec![],
|
||||
tiles,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn tile_rect(&self) -> RectI {
|
||||
self.tiles.rect
|
||||
self.built_path.tiles.rect
|
||||
}
|
||||
|
||||
fn add_fill(
|
||||
|
@ -295,8 +294,8 @@ impl ObjectBuilder {
|
|||
scene_builder: &SceneBuilder,
|
||||
tile_coords: Vector2I,
|
||||
) -> u16 {
|
||||
let local_tile_index = self.tiles.coords_to_index_unchecked(tile_coords);
|
||||
let alpha_tile_index = self.tiles.data[local_tile_index].alpha_tile_index;
|
||||
let local_tile_index = self.built_path.tiles.coords_to_index_unchecked(tile_coords);
|
||||
let alpha_tile_index = self.built_path.tiles.data[local_tile_index].alpha_tile_index;
|
||||
if alpha_tile_index != !0 {
|
||||
return alpha_tile_index;
|
||||
}
|
||||
|
@ -304,7 +303,7 @@ impl ObjectBuilder {
|
|||
let alpha_tile_index = scene_builder
|
||||
.next_alpha_tile_index
|
||||
.fetch_add(1, Ordering::Relaxed) as u16;
|
||||
self.tiles.data[local_tile_index].alpha_tile_index = alpha_tile_index;
|
||||
self.built_path.tiles.data[local_tile_index].alpha_tile_index = alpha_tile_index;
|
||||
alpha_tile_index
|
||||
}
|
||||
|
||||
|
@ -400,18 +399,18 @@ impl ObjectBuilder {
|
|||
|
||||
#[inline]
|
||||
pub(crate) fn tile_coords_to_local_index(&self, coords: Vector2I) -> Option<u32> {
|
||||
self.tiles.coords_to_index(coords).map(|index| index as u32)
|
||||
self.built_path.tiles.coords_to_index(coords).map(|index| index as u32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn local_tile_index_to_coords(&self, tile_index: u32) -> Vector2I {
|
||||
self.tiles.index_to_coords(tile_index as usize)
|
||||
self.built_path.tiles.index_to_coords(tile_index as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl BuiltPath {
|
||||
pub(crate) fn push_mask_tile(&mut self, tile: &TileObjectPrimitive, object_index: u16) {
|
||||
self.mask_tiles.push(MaskTile {
|
||||
pub(crate) fn push_mask_tile(mask_tiles: &mut Vec<MaskTile>,
|
||||
tile: &TileObjectPrimitive,
|
||||
object_index: u16) {
|
||||
mask_tiles.push(MaskTile {
|
||||
upper_left: MaskTileVertex::new(tile.alpha_tile_index as u16,
|
||||
Vector2I::default(),
|
||||
object_index,
|
||||
|
@ -431,12 +430,12 @@ impl BuiltPath {
|
|||
});
|
||||
}
|
||||
|
||||
pub(crate) fn push_alpha_tile(&mut self,
|
||||
pub(crate) fn push_alpha_tile(alpha_tiles: &mut Vec<AlphaTile>,
|
||||
tile: &TileObjectPrimitive,
|
||||
tile_coords: Vector2I,
|
||||
object_index: u16,
|
||||
paint_metadata: &PaintMetadata) {
|
||||
self.alpha_tiles.push(AlphaTile {
|
||||
alpha_tiles.push(AlphaTile {
|
||||
upper_left: AlphaTileVertex::new(tile_coords,
|
||||
tile.alpha_tile_index as u16,
|
||||
Vector2I::default(),
|
||||
|
|
|
@ -42,6 +42,11 @@ impl<T> DenseTileMap<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self, coords: Vector2I) -> Option<&T> {
|
||||
self.coords_to_index(coords).and_then(|index| self.data.get(index))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn coords_to_index(&self, coords: Vector2I) -> Option<usize> {
|
||||
if self.rect.contains_point(coords) {
|
||||
|
|
|
@ -114,7 +114,7 @@ impl<'a> Tiler<'a> {
|
|||
|
||||
fn pack_and_cull(&mut self) {
|
||||
match self.path_info {
|
||||
TilingPathInfo::Clip => unimplemented!(),
|
||||
TilingPathInfo::Clip => self.pack_and_cull_clip_path(),
|
||||
TilingPathInfo::Draw { .. } => self.pack_and_cull_draw_path(),
|
||||
}
|
||||
}
|
||||
|
@ -127,12 +127,43 @@ impl<'a> Tiler<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
for (tile_index, tile) in self.object_builder.tiles.data.iter().enumerate() {
|
||||
let tile_coords = self.object_builder.local_tile_index_to_coords(tile_index as u32);
|
||||
for (draw_tile_index, draw_tile) in self.object_builder
|
||||
.built_path
|
||||
.tiles
|
||||
.data
|
||||
.iter()
|
||||
.enumerate() {
|
||||
let tile_coords = self.object_builder
|
||||
.local_tile_index_to_coords(draw_tile_index as u32);
|
||||
|
||||
if tile.is_solid() {
|
||||
// Figure out what clip tile we need, if any.
|
||||
let clip_tile = match built_clip_path {
|
||||
None => None,
|
||||
Some(built_clip_path) => {
|
||||
match built_clip_path.tiles.get(tile_coords) {
|
||||
None => {
|
||||
// This tile is outside of the bounds of the clip path entirely. We can
|
||||
// cull it.
|
||||
continue;
|
||||
}
|
||||
Some(clip_tile) if clip_tile.is_solid() => {
|
||||
if clip_tile.backdrop != 0 {
|
||||
// The clip tile is fully opaque, so this tile isn't clipped at
|
||||
// all.
|
||||
None
|
||||
} else {
|
||||
// This tile is completely clipped out. Cull it.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Some(clip_tile) => Some(clip_tile),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if clip_tile.is_none() && draw_tile.is_solid() {
|
||||
// Blank tiles are always skipped.
|
||||
if tile.backdrop == 0 {
|
||||
if draw_tile.backdrop == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -143,14 +174,23 @@ impl<'a> Tiler<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
self.object_builder.built_path.push_mask_tile(tile, self.object_index);
|
||||
self.object_builder.built_path.push_alpha_tile(tile,
|
||||
tile_coords,
|
||||
self.object_index,
|
||||
paint_metadata);
|
||||
ObjectBuilder::push_mask_tile(&mut self.object_builder.built_path.mask_tiles,
|
||||
draw_tile,
|
||||
self.object_index);
|
||||
ObjectBuilder::push_alpha_tile(&mut self.object_builder.built_path.alpha_tiles,
|
||||
draw_tile,
|
||||
tile_coords,
|
||||
self.object_index,
|
||||
paint_metadata);
|
||||
|
||||
// TODO(pcwalton): Add the clip tile if necessary.
|
||||
}
|
||||
}
|
||||
|
||||
fn pack_and_cull_clip_path(&mut self) {
|
||||
// TODO(pcwalton)
|
||||
}
|
||||
|
||||
fn process_old_active_edges(&mut self, tile_y: i32) {
|
||||
let mut current_tile_x = self.object_builder.tile_rect().min_x();
|
||||
let mut current_subtile_x = 0.0;
|
||||
|
@ -225,7 +265,7 @@ impl<'a> Tiler<'a> {
|
|||
if let Some(tile_index) = self.object_builder
|
||||
.tile_coords_to_local_index(current_tile_coords) {
|
||||
// FIXME(pcwalton): Handle winding overflow.
|
||||
self.object_builder.tiles.data[tile_index as usize].backdrop =
|
||||
self.object_builder.built_path.tiles.data[tile_index as usize].backdrop =
|
||||
current_winding as i8;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue