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(crate) struct ObjectBuilder {
|
||||||
pub built_path: BuiltPath,
|
pub built_path: BuiltPath,
|
||||||
pub fills: Vec<FillBatchPrimitive>,
|
pub fills: Vec<FillBatchPrimitive>,
|
||||||
pub tiles: DenseTileMap<TileObjectPrimitive>,
|
|
||||||
pub bounds: RectF,
|
pub bounds: RectF,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +49,7 @@ pub(crate) struct ObjectBuilder {
|
||||||
pub(crate) struct BuiltPath {
|
pub(crate) struct BuiltPath {
|
||||||
pub mask_tiles: Vec<MaskTile>,
|
pub mask_tiles: Vec<MaskTile>,
|
||||||
pub alpha_tiles: Vec<AlphaTile>,
|
pub alpha_tiles: Vec<AlphaTile>,
|
||||||
|
pub tiles: DenseTileMap<TileObjectPrimitive>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SceneBuilder<'a> {
|
impl<'a> SceneBuilder<'a> {
|
||||||
|
@ -226,16 +226,15 @@ impl ObjectBuilder {
|
||||||
let tile_rect = tiles::round_rect_out_to_tile_bounds(bounds);
|
let tile_rect = tiles::round_rect_out_to_tile_bounds(bounds);
|
||||||
let tiles = DenseTileMap::new(tile_rect);
|
let tiles = DenseTileMap::new(tile_rect);
|
||||||
ObjectBuilder {
|
ObjectBuilder {
|
||||||
built_path: BuiltPath { mask_tiles: vec![], alpha_tiles: vec![] },
|
built_path: BuiltPath { mask_tiles: vec![], alpha_tiles: vec![], tiles },
|
||||||
bounds,
|
bounds,
|
||||||
fills: vec![],
|
fills: vec![],
|
||||||
tiles,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn tile_rect(&self) -> RectI {
|
pub(crate) fn tile_rect(&self) -> RectI {
|
||||||
self.tiles.rect
|
self.built_path.tiles.rect
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_fill(
|
fn add_fill(
|
||||||
|
@ -295,8 +294,8 @@ impl ObjectBuilder {
|
||||||
scene_builder: &SceneBuilder,
|
scene_builder: &SceneBuilder,
|
||||||
tile_coords: Vector2I,
|
tile_coords: Vector2I,
|
||||||
) -> u16 {
|
) -> u16 {
|
||||||
let local_tile_index = self.tiles.coords_to_index_unchecked(tile_coords);
|
let local_tile_index = self.built_path.tiles.coords_to_index_unchecked(tile_coords);
|
||||||
let alpha_tile_index = self.tiles.data[local_tile_index].alpha_tile_index;
|
let alpha_tile_index = self.built_path.tiles.data[local_tile_index].alpha_tile_index;
|
||||||
if alpha_tile_index != !0 {
|
if alpha_tile_index != !0 {
|
||||||
return alpha_tile_index;
|
return alpha_tile_index;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +303,7 @@ impl ObjectBuilder {
|
||||||
let alpha_tile_index = scene_builder
|
let alpha_tile_index = scene_builder
|
||||||
.next_alpha_tile_index
|
.next_alpha_tile_index
|
||||||
.fetch_add(1, Ordering::Relaxed) as u16;
|
.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
|
alpha_tile_index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,18 +399,18 @@ impl ObjectBuilder {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn tile_coords_to_local_index(&self, coords: Vector2I) -> Option<u32> {
|
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]
|
#[inline]
|
||||||
pub(crate) fn local_tile_index_to_coords(&self, tile_index: u32) -> Vector2I {
|
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(mask_tiles: &mut Vec<MaskTile>,
|
||||||
pub(crate) fn push_mask_tile(&mut self, tile: &TileObjectPrimitive, object_index: u16) {
|
tile: &TileObjectPrimitive,
|
||||||
self.mask_tiles.push(MaskTile {
|
object_index: u16) {
|
||||||
|
mask_tiles.push(MaskTile {
|
||||||
upper_left: MaskTileVertex::new(tile.alpha_tile_index as u16,
|
upper_left: MaskTileVertex::new(tile.alpha_tile_index as u16,
|
||||||
Vector2I::default(),
|
Vector2I::default(),
|
||||||
object_index,
|
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: &TileObjectPrimitive,
|
||||||
tile_coords: Vector2I,
|
tile_coords: Vector2I,
|
||||||
object_index: u16,
|
object_index: u16,
|
||||||
paint_metadata: &PaintMetadata) {
|
paint_metadata: &PaintMetadata) {
|
||||||
self.alpha_tiles.push(AlphaTile {
|
alpha_tiles.push(AlphaTile {
|
||||||
upper_left: AlphaTileVertex::new(tile_coords,
|
upper_left: AlphaTileVertex::new(tile_coords,
|
||||||
tile.alpha_tile_index as u16,
|
tile.alpha_tile_index as u16,
|
||||||
Vector2I::default(),
|
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]
|
#[inline]
|
||||||
pub fn coords_to_index(&self, coords: Vector2I) -> Option<usize> {
|
pub fn coords_to_index(&self, coords: Vector2I) -> Option<usize> {
|
||||||
if self.rect.contains_point(coords) {
|
if self.rect.contains_point(coords) {
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl<'a> Tiler<'a> {
|
||||||
|
|
||||||
fn pack_and_cull(&mut self) {
|
fn pack_and_cull(&mut self) {
|
||||||
match self.path_info {
|
match self.path_info {
|
||||||
TilingPathInfo::Clip => unimplemented!(),
|
TilingPathInfo::Clip => self.pack_and_cull_clip_path(),
|
||||||
TilingPathInfo::Draw { .. } => self.pack_and_cull_draw_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() {
|
for (draw_tile_index, draw_tile) in self.object_builder
|
||||||
let tile_coords = self.object_builder.local_tile_index_to_coords(tile_index as u32);
|
.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.
|
// Blank tiles are always skipped.
|
||||||
if tile.backdrop == 0 {
|
if draw_tile.backdrop == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,14 +174,23 @@ impl<'a> Tiler<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.object_builder.built_path.push_mask_tile(tile, self.object_index);
|
ObjectBuilder::push_mask_tile(&mut self.object_builder.built_path.mask_tiles,
|
||||||
self.object_builder.built_path.push_alpha_tile(tile,
|
draw_tile,
|
||||||
tile_coords,
|
self.object_index);
|
||||||
self.object_index,
|
ObjectBuilder::push_alpha_tile(&mut self.object_builder.built_path.alpha_tiles,
|
||||||
paint_metadata);
|
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) {
|
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_tile_x = self.object_builder.tile_rect().min_x();
|
||||||
let mut current_subtile_x = 0.0;
|
let mut current_subtile_x = 0.0;
|
||||||
|
@ -225,7 +265,7 @@ impl<'a> Tiler<'a> {
|
||||||
if let Some(tile_index) = self.object_builder
|
if let Some(tile_index) = self.object_builder
|
||||||
.tile_coords_to_local_index(current_tile_coords) {
|
.tile_coords_to_local_index(current_tile_coords) {
|
||||||
// FIXME(pcwalton): Handle winding overflow.
|
// 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;
|
current_winding as i8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue