Flatten objects' tiles ourselves instead of having Rayon do it.
A prerequisite for clips.
This commit is contained in:
parent
84ffc3151e
commit
31becb1570
|
@ -34,12 +34,12 @@ impl DemoExecutor {
|
|||
}
|
||||
|
||||
impl Executor for DemoExecutor {
|
||||
fn flatten_into_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> Vec<T> + Send + Sync {
|
||||
fn build_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> T + Send + Sync {
|
||||
if self.sequential_mode {
|
||||
SequentialExecutor.flatten_into_vector(length, builder)
|
||||
SequentialExecutor.build_vector(length, builder)
|
||||
} else {
|
||||
RayonExecutor.flatten_into_vector(length, builder)
|
||||
RayonExecutor.build_vector(length, builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! Packs data onto the GPU.
|
||||
|
||||
use crate::concurrent::executor::Executor;
|
||||
use crate::gpu_data::{AlphaTile, BuiltObject, FillBatchPrimitive, RenderCommand};
|
||||
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, RenderCommand, TileObjectPrimitive};
|
||||
use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
||||
use crate::paint::{PaintInfo, PaintMetadata};
|
||||
use crate::scene::Scene;
|
||||
|
@ -23,7 +23,6 @@ use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
|||
use pathfinder_geometry::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::util;
|
||||
use pathfinder_simd::default::{F32x4, I32x4};
|
||||
use std::i16;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::time::Instant;
|
||||
use std::u16;
|
||||
|
@ -68,7 +67,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
self.listener.send(RenderCommand::AddPaintData(paint_data));
|
||||
|
||||
let effective_view_box = self.scene.effective_view_box(self.built_options);
|
||||
let alpha_tiles = executor.flatten_into_vector(path_count, |path_index| {
|
||||
let built_objects = executor.build_vector(path_count, |path_index| {
|
||||
self.build_path(path_index,
|
||||
effective_view_box,
|
||||
&self.built_options,
|
||||
|
@ -76,7 +75,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
&paint_metadata)
|
||||
});
|
||||
|
||||
self.finish_building(&paint_metadata, alpha_tiles);
|
||||
self.finish_building(&paint_metadata, built_objects);
|
||||
|
||||
let build_time = Instant::now() - start_time;
|
||||
self.listener.send(RenderCommand::Finish { build_time });
|
||||
|
@ -89,7 +88,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
built_options: &PreparedBuildOptions,
|
||||
scene: &Scene,
|
||||
paint_metadata: &[PaintMetadata],
|
||||
) -> Vec<AlphaTile> {
|
||||
) -> BuiltObject {
|
||||
let path_object = &scene.paths[path_index];
|
||||
let outline = scene.apply_render_options(path_object.outline(), built_options);
|
||||
let paint_id = path_object.paint();
|
||||
|
@ -102,33 +101,27 @@ impl<'a> SceneBuilder<'a> {
|
|||
|
||||
tiler.generate_tiles();
|
||||
|
||||
self.listener.send(RenderCommand::AddFills(tiler.built_object.fills));
|
||||
tiler.built_object.alpha_tiles
|
||||
self.listener.send(RenderCommand::AddFills(tiler.object_builder.fills));
|
||||
tiler.object_builder.built_object
|
||||
}
|
||||
|
||||
fn cull_alpha_tiles(&self, alpha_tiles: &mut Vec<AlphaTile>) {
|
||||
for alpha_tile in alpha_tiles {
|
||||
fn cull_tiles(&self, built_objects: Vec<BuiltObject>) -> CulledTiles {
|
||||
let mut culled_tiles = CulledTiles { alpha_tiles: vec![] };
|
||||
|
||||
for built_object in built_objects {
|
||||
for alpha_tile in built_object.alpha_tiles {
|
||||
let alpha_tile_coords = alpha_tile.upper_left.tile_position();
|
||||
if self
|
||||
.z_buffer
|
||||
.test(alpha_tile_coords, alpha_tile.upper_left.object_index as u32)
|
||||
{
|
||||
continue;
|
||||
if self.z_buffer.test(alpha_tile_coords,
|
||||
alpha_tile.upper_left.object_index as u32) {
|
||||
culled_tiles.alpha_tiles.push(alpha_tile);
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): Clean this up.
|
||||
alpha_tile.upper_left.tile_x = i16::MIN;
|
||||
alpha_tile.upper_left.tile_y = i16::MIN;
|
||||
alpha_tile.upper_right.tile_x = i16::MIN;
|
||||
alpha_tile.upper_right.tile_y = i16::MIN;
|
||||
alpha_tile.lower_left.tile_x = i16::MIN;
|
||||
alpha_tile.lower_left.tile_y = i16::MIN;
|
||||
alpha_tile.lower_right.tile_x = i16::MIN;
|
||||
alpha_tile.lower_right.tile_y = i16::MIN;
|
||||
}
|
||||
}
|
||||
|
||||
fn pack_alpha_tiles(&mut self, paint_metadata: &[PaintMetadata], alpha_tiles: Vec<AlphaTile>) {
|
||||
culled_tiles
|
||||
}
|
||||
|
||||
fn pack_tiles(&mut self, paint_metadata: &[PaintMetadata], culled_tiles: CulledTiles) {
|
||||
let path_count = self.scene.paths.len() as u32;
|
||||
let solid_tiles = self.z_buffer.build_solid_tiles(&self.scene.paths,
|
||||
paint_metadata,
|
||||
|
@ -136,17 +129,17 @@ impl<'a> SceneBuilder<'a> {
|
|||
if !solid_tiles.is_empty() {
|
||||
self.listener.send(RenderCommand::SolidTile(solid_tiles));
|
||||
}
|
||||
if !alpha_tiles.is_empty() {
|
||||
self.listener.send(RenderCommand::AlphaTile(alpha_tiles));
|
||||
if !culled_tiles.alpha_tiles.is_empty() {
|
||||
self.listener.send(RenderCommand::AlphaTile(culled_tiles.alpha_tiles));
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_building(&mut self,
|
||||
paint_metadata: &[PaintMetadata],
|
||||
mut alpha_tiles: Vec<AlphaTile>) {
|
||||
built_objects: Vec<BuiltObject>) {
|
||||
self.listener.send(RenderCommand::FlushFills);
|
||||
self.cull_alpha_tiles(&mut alpha_tiles);
|
||||
self.pack_alpha_tiles(paint_metadata, alpha_tiles);
|
||||
let culled_tiles = self.cull_tiles(built_objects);
|
||||
self.pack_tiles(paint_metadata, culled_tiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,14 +151,14 @@ pub struct TileStats {
|
|||
|
||||
// Utilities for built objects
|
||||
|
||||
impl BuiltObject {
|
||||
pub(crate) fn new(bounds: RectF) -> BuiltObject {
|
||||
impl ObjectBuilder {
|
||||
pub(crate) fn new(bounds: RectF) -> ObjectBuilder {
|
||||
let tile_rect = tiles::round_rect_out_to_tile_bounds(bounds);
|
||||
let tiles = DenseTileMap::new(tile_rect);
|
||||
BuiltObject {
|
||||
ObjectBuilder {
|
||||
built_object: BuiltObject { alpha_tiles: vec![] },
|
||||
bounds,
|
||||
fills: vec![],
|
||||
alpha_tiles: vec![],
|
||||
tiles,
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +170,7 @@ impl BuiltObject {
|
|||
|
||||
fn add_fill(
|
||||
&mut self,
|
||||
builder: &SceneBuilder,
|
||||
scene_builder: &SceneBuilder,
|
||||
segment: LineSegment2F,
|
||||
tile_coords: Vector2I,
|
||||
) {
|
||||
|
@ -207,7 +200,7 @@ impl BuiltObject {
|
|||
}
|
||||
|
||||
// Allocate global tile if necessary.
|
||||
let alpha_tile_index = self.get_or_allocate_alpha_tile_index(builder, tile_coords);
|
||||
let alpha_tile_index = self.get_or_allocate_alpha_tile_index(scene_builder, tile_coords);
|
||||
|
||||
// Pack whole pixels.
|
||||
let px = (segment & I32x4::splat(0xf00)).to_u32x4();
|
||||
|
@ -229,7 +222,7 @@ impl BuiltObject {
|
|||
|
||||
fn get_or_allocate_alpha_tile_index(
|
||||
&mut self,
|
||||
builder: &SceneBuilder,
|
||||
scene_builder: &SceneBuilder,
|
||||
tile_coords: Vector2I,
|
||||
) -> u16 {
|
||||
let local_tile_index = self.tiles.coords_to_index_unchecked(tile_coords);
|
||||
|
@ -238,7 +231,7 @@ impl BuiltObject {
|
|||
return alpha_tile_index;
|
||||
}
|
||||
|
||||
let alpha_tile_index = builder
|
||||
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;
|
||||
|
@ -247,7 +240,7 @@ impl BuiltObject {
|
|||
|
||||
pub(crate) fn add_active_fill(
|
||||
&mut self,
|
||||
builder: &SceneBuilder,
|
||||
scene_builder: &SceneBuilder,
|
||||
left: f32,
|
||||
right: f32,
|
||||
mut winding: i32,
|
||||
|
@ -272,7 +265,7 @@ impl BuiltObject {
|
|||
);
|
||||
|
||||
while winding != 0 {
|
||||
self.add_fill(builder, segment, tile_coords);
|
||||
self.add_fill(scene_builder, segment, tile_coords);
|
||||
if winding < 0 {
|
||||
winding += 1
|
||||
} else {
|
||||
|
@ -283,7 +276,7 @@ impl BuiltObject {
|
|||
|
||||
pub(crate) fn generate_fill_primitives_for_line(
|
||||
&mut self,
|
||||
builder: &SceneBuilder,
|
||||
scene_builder: &SceneBuilder,
|
||||
mut segment: LineSegment2F,
|
||||
tile_y: i32,
|
||||
) {
|
||||
|
@ -331,7 +324,7 @@ impl BuiltObject {
|
|||
|
||||
let fill_segment = LineSegment2F::new(fill_from, fill_to);
|
||||
let fill_tile_coords = Vector2I::new(subsegment_tile_x, tile_y);
|
||||
self.add_fill(builder, fill_segment, fill_tile_coords);
|
||||
self.add_fill(scene_builder, fill_segment, fill_tile_coords);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,3 +338,20 @@ impl BuiltObject {
|
|||
self.tiles.index_to_coords(tile_index as usize)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct BuiltObject {
|
||||
pub alpha_tiles: Vec<AlphaTile>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ObjectBuilder {
|
||||
pub built_object: BuiltObject,
|
||||
pub fills: Vec<FillBatchPrimitive>,
|
||||
pub tiles: DenseTileMap<TileObjectPrimitive>,
|
||||
pub bounds: RectF,
|
||||
}
|
||||
|
||||
struct CulledTiles {
|
||||
alpha_tiles: Vec<AlphaTile>,
|
||||
}
|
||||
|
|
|
@ -15,17 +15,17 @@ pub trait Executor {
|
|||
/// Like the Rayon snippet:
|
||||
///
|
||||
/// ```norun
|
||||
/// (0..length).into_par_iter().flat_map(builder).collect()
|
||||
/// (0..length).into_par_iter().map(builder).collect()
|
||||
/// ```
|
||||
fn flatten_into_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> Vec<T> + Send + Sync;
|
||||
fn build_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> T + Send + Sync;
|
||||
}
|
||||
|
||||
pub struct SequentialExecutor;
|
||||
|
||||
impl Executor for SequentialExecutor {
|
||||
fn flatten_into_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> Vec<T> + Send + Sync {
|
||||
(0..length).into_iter().flat_map(builder).collect()
|
||||
fn build_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> T + Send + Sync {
|
||||
(0..length).into_iter().map(builder).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
|||
pub struct RayonExecutor;
|
||||
|
||||
impl Executor for RayonExecutor {
|
||||
fn flatten_into_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> Vec<T> + Send + Sync {
|
||||
(0..length).into_par_iter().flat_map(builder).collect()
|
||||
fn build_vector<T, F>(&self, length: usize, builder: F) -> Vec<T>
|
||||
where T: Send, F: Fn(usize) -> T + Send + Sync {
|
||||
(0..length).into_par_iter().map(builder).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,22 +11,12 @@
|
|||
//! Packed data ready to be sent to the GPU.
|
||||
|
||||
use crate::options::BoundingQuad;
|
||||
use crate::tile_map::DenseTileMap;
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_geometry::line_segment::{LineSegmentU4, LineSegmentU8};
|
||||
use pathfinder_geometry::rect::RectF;
|
||||
use pathfinder_geometry::vector::Vector2I;
|
||||
use std::fmt::{Debug, Formatter, Result as DebugResult};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct BuiltObject {
|
||||
pub bounds: RectF,
|
||||
pub fills: Vec<FillBatchPrimitive>,
|
||||
pub alpha_tiles: Vec<AlphaTile>,
|
||||
pub tiles: DenseTileMap<TileObjectPrimitive>,
|
||||
}
|
||||
|
||||
pub enum RenderCommand {
|
||||
Start { path_count: usize, bounding_quad: BoundingQuad },
|
||||
AddPaintData(PaintData),
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use crate::builder::SceneBuilder;
|
||||
use crate::builder::{ObjectBuilder, SceneBuilder};
|
||||
use crate::gpu::renderer::MASK_TILES_ACROSS;
|
||||
use crate::gpu_data::{AlphaTile, AlphaTileVertex, BuiltObject, TileObjectPrimitive};
|
||||
use crate::gpu_data::{AlphaTile, AlphaTileVertex, TileObjectPrimitive};
|
||||
use crate::paint::PaintMetadata;
|
||||
use pathfinder_content::outline::{Contour, Outline, PointIndex};
|
||||
use pathfinder_content::segment::Segment;
|
||||
|
@ -28,9 +28,9 @@ pub const TILE_WIDTH: u32 = 16;
|
|||
pub const TILE_HEIGHT: u32 = 16;
|
||||
|
||||
pub(crate) struct Tiler<'a> {
|
||||
builder: &'a SceneBuilder<'a>,
|
||||
scene_builder: &'a SceneBuilder<'a>,
|
||||
pub(crate) object_builder: ObjectBuilder,
|
||||
outline: &'a Outline,
|
||||
pub built_object: BuiltObject,
|
||||
paint_metadata: &'a PaintMetadata,
|
||||
object_index: u16,
|
||||
|
||||
|
@ -42,7 +42,7 @@ pub(crate) struct Tiler<'a> {
|
|||
impl<'a> Tiler<'a> {
|
||||
#[allow(clippy::or_fun_call)]
|
||||
pub(crate) fn new(
|
||||
builder: &'a SceneBuilder<'a>,
|
||||
scene_builder: &'a SceneBuilder<'a>,
|
||||
outline: &'a Outline,
|
||||
view_box: RectF,
|
||||
object_index: u16,
|
||||
|
@ -52,12 +52,12 @@ impl<'a> Tiler<'a> {
|
|||
.bounds()
|
||||
.intersection(view_box)
|
||||
.unwrap_or(RectF::default());
|
||||
let built_object = BuiltObject::new(bounds);
|
||||
let object_builder = ObjectBuilder::new(bounds);
|
||||
|
||||
Tiler {
|
||||
builder,
|
||||
scene_builder,
|
||||
object_builder,
|
||||
outline,
|
||||
built_object,
|
||||
object_index,
|
||||
paint_metadata,
|
||||
|
||||
|
@ -76,7 +76,7 @@ impl<'a> Tiler<'a> {
|
|||
self.old_active_edges.clear();
|
||||
|
||||
// Generate strips.
|
||||
let tile_rect = self.built_object.tile_rect();
|
||||
let tile_rect = self.object_builder.tile_rect();
|
||||
for strip_origin_y in tile_rect.min_y()..tile_rect.max_y() {
|
||||
self.generate_strip(strip_origin_y);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl<'a> Tiler<'a> {
|
|||
self.pack_and_cull();
|
||||
|
||||
// Done!
|
||||
debug!("{:#?}", self.built_object);
|
||||
debug!("{:#?}", self.object_builder.built_object);
|
||||
}
|
||||
|
||||
fn generate_strip(&mut self, strip_origin_y: i32) {
|
||||
|
@ -108,10 +108,8 @@ impl<'a> Tiler<'a> {
|
|||
}
|
||||
|
||||
fn pack_and_cull(&mut self) {
|
||||
for (tile_index, tile) in self.built_object.tiles.data.iter().enumerate() {
|
||||
let tile_coords = self
|
||||
.built_object
|
||||
.local_tile_index_to_coords(tile_index as u32);
|
||||
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);
|
||||
|
||||
if tile.is_solid() {
|
||||
// Blank tiles are always skipped.
|
||||
|
@ -121,12 +119,12 @@ impl<'a> Tiler<'a> {
|
|||
|
||||
// If this is a solid tile, poke it into the Z-buffer and stop here.
|
||||
if self.paint_metadata.is_opaque {
|
||||
self.builder.z_buffer.update(tile_coords, self.object_index);
|
||||
self.scene_builder.z_buffer.update(tile_coords, self.object_index);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
self.built_object.alpha_tiles.push(AlphaTile {
|
||||
self.object_builder.built_object.alpha_tiles.push(AlphaTile {
|
||||
upper_left: AlphaTileVertex::new(tile_coords,
|
||||
tile.alpha_tile_index as u16,
|
||||
Vector2I::default(),
|
||||
|
@ -156,7 +154,7 @@ impl<'a> Tiler<'a> {
|
|||
}
|
||||
|
||||
fn process_old_active_edges(&mut self, tile_y: i32) {
|
||||
let mut current_tile_x = self.built_object.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_winding = 0;
|
||||
|
||||
|
@ -208,8 +206,8 @@ impl<'a> Tiler<'a> {
|
|||
(i32::from(current_tile_x) * TILE_WIDTH as i32) as f32 + current_subtile_x;
|
||||
let tile_right_x = ((i32::from(current_tile_x) + 1) * TILE_WIDTH as i32) as f32;
|
||||
let current_tile_coords = Vector2I::new(current_tile_x, tile_y);
|
||||
self.built_object.add_active_fill(
|
||||
self.builder,
|
||||
self.object_builder.add_active_fill(
|
||||
self.scene_builder,
|
||||
current_x,
|
||||
tile_right_x,
|
||||
current_winding,
|
||||
|
@ -226,12 +224,10 @@ impl<'a> Tiler<'a> {
|
|||
current_winding, current_tile_x
|
||||
);
|
||||
let current_tile_coords = Vector2I::new(current_tile_x, tile_y);
|
||||
if let Some(tile_index) = self
|
||||
.built_object
|
||||
.tile_coords_to_local_index(current_tile_coords)
|
||||
{
|
||||
if let Some(tile_index) = self.object_builder
|
||||
.tile_coords_to_local_index(current_tile_coords) {
|
||||
// FIXME(pcwalton): Handle winding overflow.
|
||||
self.built_object.tiles.data[tile_index as usize].backdrop =
|
||||
self.object_builder.tiles.data[tile_index as usize].backdrop =
|
||||
current_winding as i8;
|
||||
}
|
||||
|
||||
|
@ -247,8 +243,8 @@ impl<'a> Tiler<'a> {
|
|||
let current_x =
|
||||
(i32::from(current_tile_x) * TILE_WIDTH as i32) as f32 + current_subtile_x;
|
||||
let current_tile_coords = Vector2I::new(current_tile_x, tile_y);
|
||||
self.built_object.add_active_fill(
|
||||
self.builder,
|
||||
self.object_builder.add_active_fill(
|
||||
self.scene_builder,
|
||||
current_x,
|
||||
segment_x,
|
||||
current_winding,
|
||||
|
@ -263,7 +259,7 @@ impl<'a> Tiler<'a> {
|
|||
// Process the edge.
|
||||
debug!("about to process existing active edge {:#?}", active_edge);
|
||||
debug_assert!(f32::abs(active_edge.crossing.y() - tile_top) < 0.1);
|
||||
active_edge.process(self.builder, &mut self.built_object, tile_y);
|
||||
active_edge.process(self.scene_builder, &mut self.object_builder, tile_y);
|
||||
if !active_edge.segment.is_none() {
|
||||
self.active_edges.push(active_edge);
|
||||
}
|
||||
|
@ -299,8 +295,8 @@ impl<'a> Tiler<'a> {
|
|||
contour,
|
||||
prev_endpoint_index,
|
||||
&mut self.active_edges,
|
||||
self.builder,
|
||||
&mut self.built_object,
|
||||
self.scene_builder,
|
||||
&mut self.object_builder,
|
||||
tile_y,
|
||||
);
|
||||
|
||||
|
@ -323,8 +319,8 @@ impl<'a> Tiler<'a> {
|
|||
contour,
|
||||
point_index.point(),
|
||||
&mut self.active_edges,
|
||||
self.builder,
|
||||
&mut self.built_object,
|
||||
self.scene_builder,
|
||||
&mut self.object_builder,
|
||||
tile_y,
|
||||
);
|
||||
|
||||
|
@ -381,12 +377,12 @@ fn process_active_segment(
|
|||
from_endpoint_index: u32,
|
||||
active_edges: &mut SortedVector<ActiveEdge>,
|
||||
builder: &SceneBuilder,
|
||||
built_object: &mut BuiltObject,
|
||||
object_builder: &mut ObjectBuilder,
|
||||
tile_y: i32,
|
||||
) {
|
||||
let mut active_edge = ActiveEdge::from_segment(&contour.segment_after(from_endpoint_index));
|
||||
debug!("... process_active_segment({:#?})", active_edge);
|
||||
active_edge.process(builder, built_object, tile_y);
|
||||
active_edge.process(builder, object_builder, tile_y);
|
||||
if !active_edge.segment.is_none() {
|
||||
debug!("... ... pushing resulting active edge: {:#?}", active_edge);
|
||||
active_edges.push(active_edge);
|
||||
|
@ -433,7 +429,10 @@ impl ActiveEdge {
|
|||
ActiveEdge { segment: *segment, crossing }
|
||||
}
|
||||
|
||||
fn process(&mut self, builder: &SceneBuilder, built_object: &mut BuiltObject, tile_y: i32) {
|
||||
fn process(&mut self,
|
||||
builder: &SceneBuilder,
|
||||
object_builder: &mut ObjectBuilder,
|
||||
tile_y: i32) {
|
||||
let tile_bottom = ((i32::from(tile_y) + 1) * TILE_HEIGHT as i32) as f32;
|
||||
debug!(
|
||||
"process_active_edge({:#?}, tile_y={}({}))",
|
||||
|
@ -446,7 +445,7 @@ impl ActiveEdge {
|
|||
if segment.is_line() {
|
||||
let line_segment = segment.as_line_segment();
|
||||
self.segment =
|
||||
match self.process_line_segment(line_segment, builder, built_object, tile_y) {
|
||||
match self.process_line_segment(line_segment, builder, object_builder, tile_y) {
|
||||
Some(lower_part) => Segment::line(lower_part),
|
||||
None => Segment::none(),
|
||||
};
|
||||
|
@ -462,10 +461,8 @@ impl ActiveEdge {
|
|||
if self.crossing.y() < segment.baseline.min_y() {
|
||||
let first_line_segment =
|
||||
LineSegment2F::new(self.crossing, segment.baseline.upper_point()).orient(winding);
|
||||
if self
|
||||
.process_line_segment(first_line_segment, builder, built_object, tile_y)
|
||||
.is_some()
|
||||
{
|
||||
if self.process_line_segment(first_line_segment, builder, object_builder, tile_y)
|
||||
.is_some() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +491,7 @@ impl ActiveEdge {
|
|||
);
|
||||
|
||||
let line = before_segment.baseline.orient(winding);
|
||||
match self.process_line_segment(line, builder, built_object, tile_y) {
|
||||
match self.process_line_segment(line, builder, object_builder, tile_y) {
|
||||
Some(lower_part) if split_t == 1.0 => {
|
||||
self.segment = Segment::line(lower_part);
|
||||
return;
|
||||
|
@ -516,7 +513,7 @@ impl ActiveEdge {
|
|||
&mut self,
|
||||
line_segment: LineSegment2F,
|
||||
builder: &SceneBuilder,
|
||||
built_object: &mut BuiltObject,
|
||||
object_builder: &mut ObjectBuilder,
|
||||
tile_y: i32,
|
||||
) -> Option<LineSegment2F> {
|
||||
let tile_bottom = ((i32::from(tile_y) + 1) * TILE_HEIGHT as i32) as f32;
|
||||
|
@ -526,12 +523,12 @@ impl ActiveEdge {
|
|||
);
|
||||
|
||||
if line_segment.max_y() <= tile_bottom {
|
||||
built_object.generate_fill_primitives_for_line(builder, line_segment, tile_y);
|
||||
object_builder.generate_fill_primitives_for_line(builder, line_segment, tile_y);
|
||||
return None;
|
||||
}
|
||||
|
||||
let (upper_part, lower_part) = line_segment.split_at_y(tile_bottom);
|
||||
built_object.generate_fill_primitives_for_line(builder, upper_part, tile_y);
|
||||
object_builder.generate_fill_primitives_for_line(builder, upper_part, tile_y);
|
||||
self.crossing = lower_part.upper_point();
|
||||
Some(lower_part)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue