From 62a3fefca4a782a76f1a7095f203344b2324d68b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 18 Apr 2019 15:09:37 -0700 Subject: [PATCH] Reenable the tile and fill counts in the debug display --- demo/common/src/lib.rs | 21 ++++------ gl/src/lib.rs | 3 +- renderer/src/builder.rs | 12 ++++-- renderer/src/gpu/debug.rs | 42 +++++++------------- renderer/src/gpu/renderer.rs | 74 +++++++++++++++++++++++++++--------- renderer/src/gpu_data.rs | 48 +---------------------- renderer/src/scene.rs | 19 ++++++++- 7 files changed, 106 insertions(+), 113 deletions(-) diff --git a/demo/common/src/lib.rs b/demo/common/src/lib.rs index a9811abf..8f2ce9a4 100644 --- a/demo/common/src/lib.rs +++ b/demo/common/src/lib.rs @@ -26,10 +26,10 @@ use pathfinder_gpu::resources::ResourceLoader; use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc}; use pathfinder_gpu::{StencilState, UniformData}; use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder}; -use pathfinder_renderer::gpu::renderer::{RenderMode, Renderer}; -use pathfinder_renderer::gpu_data::{BuiltScene, RenderCommand, Stats}; +use pathfinder_renderer::gpu::renderer::{RenderMode, RenderStats, Renderer}; +use pathfinder_renderer::gpu_data::RenderCommand; use pathfinder_renderer::post::{DEFRINGING_KERNEL_CORE_GRAPHICS, STEM_DARKENING_FACTORS}; -use pathfinder_renderer::scene::Scene; +use pathfinder_renderer::scene::{Scene, SceneDescriptor}; use pathfinder_svg::BuiltSVG; use pathfinder_ui::{MousePosition, UIEvent}; use rayon::ThreadPoolBuilder; @@ -413,7 +413,7 @@ impl DemoApp where W: Window { } if !frame.scene_stats.is_empty() || !frame.scene_rendering_times.is_empty() { - let zero = Stats::default(); + let zero = RenderStats::default(); let aggregate_stats = frame.scene_stats.iter().fold(zero, |sum, item| sum + *item); let total_rendering_time = if frame.scene_rendering_times.is_empty() { None @@ -557,8 +557,6 @@ impl DemoApp where W: Window { _ => panic!("Expected `BeginRenderScene`!"), }; - self.current_frame.as_mut().unwrap().scene_stats.push(built_scene.stats()); - match self.monochrome_scene_color { None => self.renderer.set_render_mode(RenderMode::Multicolor), Some(fg_color) => { @@ -592,6 +590,7 @@ impl DemoApp where W: Window { } } + self.current_frame.as_mut().unwrap().scene_stats.push(self.renderer.stats); self.renderer.end_scene(); } @@ -742,7 +741,7 @@ struct BuildOptions { enum SceneToMainMsg { BeginFrame { transforms: Vec }, EndFrame { tile_time: Duration }, - BeginRenderScene(BuiltScene), + BeginRenderScene(SceneDescriptor), Execute(RenderCommand), EndRenderScene, } @@ -779,11 +778,7 @@ fn build_scene(scene: &Scene, }; let built_options = render_options.prepare(scene.bounds); - let quad = built_options.quad(); - - let mut built_scene = BuiltScene::new(scene.view_box, &quad, scene.objects.len() as u32); - built_scene.shaders = scene.build_shaders(); - sink.send(SceneToMainMsg::BeginRenderScene(built_scene)).unwrap(); + sink.send(SceneToMainMsg::BeginRenderScene(scene.build_descriptor(&built_options))).unwrap(); let inner_sink = AssertUnwindSafe(sink.clone()); let result = panic::catch_unwind(move || { @@ -1086,7 +1081,7 @@ struct Frame { transforms: Vec, ui_events: Vec, scene_rendering_times: Vec, - scene_stats: Vec, + scene_stats: Vec, } impl Frame { diff --git a/gl/src/lib.rs b/gl/src/lib.rs index 01d5c092..26907c9c 100644 --- a/gl/src/lib.rs +++ b/gl/src/lib.rs @@ -10,8 +10,7 @@ //! An OpenGL implementation of the device abstraction. -use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLintptr, GLsizei, GLsizeiptr}; -use gl::types::{GLuint, GLvoid}; +use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid}; use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::rect::RectI32; use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, DepthFunc, Device}; diff --git a/renderer/src/builder.rs b/renderer/src/builder.rs index e8510a89..3fe90684 100644 --- a/renderer/src/builder.rs +++ b/renderer/src/builder.rs @@ -66,7 +66,7 @@ impl<'a> SceneBuilder<'a> { &self.scene) }).collect(); - self.finish_building(alpha_tiles); + self.finish_building(alpha_tiles) } pub fn build_in_parallel(&mut self) { @@ -79,7 +79,7 @@ impl<'a> SceneBuilder<'a> { &self.scene) }).collect(); - self.finish_building(alpha_tiles); + self.finish_building(alpha_tiles) } fn build_object(&self, @@ -219,7 +219,7 @@ pub struct PreparedRenderOptions { impl PreparedRenderOptions { #[inline] - pub fn quad(&self) -> [Point3DF32; 4] { + pub fn bounding_quad(&self) -> [Point3DF32; 4] { match self.transform { PreparedRenderTransform::Perspective { quad, .. } => quad, _ => [Point3DF32::default(); 4], @@ -247,3 +247,9 @@ impl RenderCommandListener for F where F: Fn(RenderCommand) + Send + Sync { #[inline] fn send(&self, command: RenderCommand) { (*self)(command) } } + +#[derive(Clone, Copy, Debug, Default)] +pub struct TileStats { + pub solid_tile_count: u32, + pub alpha_tile_count: u32, +} diff --git a/renderer/src/gpu/debug.rs b/renderer/src/gpu/debug.rs index 0d6bd58a..65e3fc58 100644 --- a/renderer/src/gpu/debug.rs +++ b/renderer/src/gpu/debug.rs @@ -15,7 +15,7 @@ //! //! The debug font atlas was generated using: https://evanw.github.io/font-texture-generator/ -use crate::gpu_data::Stats; +use crate::gpu::renderer::RenderStats; use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::rect::RectI32; use pathfinder_gpu::Device; @@ -45,7 +45,7 @@ impl DebugUI where D: Device { } pub fn add_sample(&mut self, - stats: Stats, + stats: RenderStats, tile_time: Duration, rendering_time: Option) { self.cpu_samples.push(CPUSample { stats, elapsed: tile_time }); @@ -96,11 +96,11 @@ impl DebugUI where D: Device { } } -struct SampleBuffer where S: Add + Div + Clone + Default { +struct SampleBuffer where S: Add + Div + Clone + Default { samples: VecDeque, } -impl SampleBuffer where S: Add + Div + Clone + Default { +impl SampleBuffer where S: Add + Div + Clone + Default { fn new() -> SampleBuffer { SampleBuffer { samples: VecDeque::with_capacity(SAMPLE_BUFFER_SIZE) } } @@ -122,43 +122,27 @@ impl SampleBuffer where S: Add + Div + Clone + mean = mean + (*time).clone(); } - mean / self.samples.len() as u32 + mean / self.samples.len() } } #[derive(Clone, Default)] struct CPUSample { elapsed: Duration, - stats: Stats, + stats: RenderStats, } impl Add for CPUSample { type Output = CPUSample; fn add(self, other: CPUSample) -> CPUSample { - CPUSample { - elapsed: self.elapsed + other.elapsed, - stats: Stats { - object_count: self.stats.object_count + other.stats.object_count, - solid_tile_count: self.stats.solid_tile_count + other.stats.solid_tile_count, - alpha_tile_count: self.stats.alpha_tile_count + other.stats.alpha_tile_count, - fill_count: self.stats.fill_count + other.stats.fill_count, - }, - } + CPUSample { elapsed: self.elapsed + other.elapsed, stats: self.stats + other.stats } } } -impl Div for CPUSample { +impl Div for CPUSample { type Output = CPUSample; - fn div(self, divisor: u32) -> CPUSample { - CPUSample { - elapsed: self.elapsed / divisor, - stats: Stats { - object_count: self.stats.object_count / divisor, - solid_tile_count: self.stats.solid_tile_count / divisor, - alpha_tile_count: self.stats.alpha_tile_count / divisor, - fill_count: self.stats.fill_count / divisor, - }, - } + fn div(self, divisor: usize) -> CPUSample { + CPUSample { elapsed: self.elapsed / (divisor as u32), stats: self.stats / divisor } } } @@ -174,10 +158,10 @@ impl Add for GPUSample { } } -impl Div for GPUSample { +impl Div for GPUSample { type Output = GPUSample; - fn div(self, divisor: u32) -> GPUSample { - GPUSample { elapsed: self.elapsed / divisor } + fn div(self, divisor: usize) -> GPUSample { + GPUSample { elapsed: self.elapsed / (divisor as u32) } } } diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index c6bbc468..2c128708 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -9,10 +9,10 @@ // except according to those terms. use crate::gpu::debug::DebugUI; -use crate::gpu_data::{AlphaTileBatchPrimitive, BuiltScene, FillBatchPrimitive}; +use crate::gpu_data::{AlphaTileBatchPrimitive, FillBatchPrimitive}; use crate::gpu_data::{RenderCommand, SolidTileBatchPrimitive}; use crate::post::DefringingKernel; -use crate::scene::ObjectShader; +use crate::scene::{ObjectShader, SceneDescriptor}; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32}; use pathfinder_geometry::basic::rect::RectI32; @@ -24,6 +24,7 @@ use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrType}; use pathfinder_simd::default::{F32x4, I32x4}; use std::cmp; use std::collections::VecDeque; +use std::ops::{Add, Div}; use std::time::Duration; use std::u32; @@ -73,7 +74,12 @@ pub struct Renderer where D: Device { stencil_program: StencilProgram, stencil_vertex_array: StencilVertexArray, + // Rendering state + mask_framebuffer_cleared: bool, + buffered_fills: Vec, + // Debug + pub stats: RenderStats, current_timer_query: Option, pending_timer_queries: VecDeque, free_timer_queries: Vec, @@ -83,10 +89,6 @@ pub struct Renderer where D: Device { viewport: RectI32, render_mode: RenderMode, use_depth: bool, - - // Rendering state - mask_framebuffer_cleared: bool, - buffered_fills: Vec, } impl Renderer where D: Device { @@ -175,22 +177,22 @@ impl Renderer where D: Device { stencil_program, stencil_vertex_array, + stats: RenderStats::default(), current_timer_query: None, pending_timer_queries: VecDeque::new(), free_timer_queries: vec![], - debug_ui, + mask_framebuffer_cleared: false, + buffered_fills: vec![], + viewport, render_mode: RenderMode::default(), use_depth: false, - - mask_framebuffer_cleared: false, - buffered_fills: vec![], } } - pub fn begin_scene(&mut self, built_scene: &BuiltScene) { + pub fn begin_scene(&mut self, scene: &SceneDescriptor) { self.init_postprocessing_framebuffer(); let timer_query = self.free_timer_queries @@ -199,13 +201,15 @@ impl Renderer where D: Device { self.device.begin_timer_query(&timer_query); self.current_timer_query = Some(timer_query); - self.upload_shaders(&built_scene.shaders); + self.upload_shaders(&scene.shaders); if self.use_depth { - self.draw_stencil(&built_scene.quad); + self.draw_stencil(&scene.bounding_quad); } self.mask_framebuffer_cleared = false; + + self.stats = RenderStats { object_count: scene.object_count, ..RenderStats::default() }; } pub fn render_command(&mut self, command: &RenderCommand) { @@ -213,14 +217,16 @@ impl Renderer where D: Device { RenderCommand::AddFills(ref fills) => self.add_fills(fills), RenderCommand::FlushFills => self.draw_buffered_fills(), RenderCommand::SolidTile(ref solid_tiles) => { - let count = solid_tiles.len() as u32; + let count = solid_tiles.len(); + self.stats.solid_tile_count += count; self.upload_solid_tiles(solid_tiles); - self.draw_solid_tiles(count); + self.draw_solid_tiles(count as u32); } RenderCommand::AlphaTile(ref alpha_tiles) => { - let count = alpha_tiles.len() as u32; + let count = alpha_tiles.len(); + self.stats.alpha_tile_count += count; self.upload_alpha_tiles(alpha_tiles); - self.draw_alpha_tiles(count); + self.draw_alpha_tiles(count as u32); } } } @@ -319,6 +325,8 @@ impl Renderer where D: Device { return; } + self.stats.fill_count += fills.len(); + while !fills.is_empty() { let count = cmp::min(fills.len(), MAX_FILLS_PER_BATCH - self.buffered_fills.len()); self.buffered_fills.extend_from_slice(&fills[0..count]); @@ -1088,3 +1096,35 @@ impl Default for RenderMode { RenderMode::Multicolor } } + +#[derive(Clone, Copy, Debug, Default)] +pub struct RenderStats { + pub object_count: usize, + pub fill_count: usize, + pub alpha_tile_count: usize, + pub solid_tile_count: usize, +} + +impl Add for RenderStats { + type Output = RenderStats; + fn add(self, other: RenderStats) -> RenderStats { + RenderStats { + object_count: self.object_count + other.object_count, + solid_tile_count: self.solid_tile_count + other.solid_tile_count, + alpha_tile_count: self.alpha_tile_count + other.alpha_tile_count, + fill_count: self.fill_count + other.fill_count, + } + } +} + +impl Div for RenderStats { + type Output = RenderStats; + fn div(self, divisor: usize) -> RenderStats { + RenderStats { + object_count: self.object_count / divisor, + solid_tile_count: self.solid_tile_count / divisor, + alpha_tile_count: self.alpha_tile_count / divisor, + fill_count: self.fill_count / divisor, + } + } +} diff --git a/renderer/src/gpu_data.rs b/renderer/src/gpu_data.rs index 94eecdce..cc578f38 100644 --- a/renderer/src/gpu_data.rs +++ b/renderer/src/gpu_data.rs @@ -11,16 +11,14 @@ //! Packed data ready to be sent to the GPU. use crate::builder::SceneBuilder; -use crate::scene::ObjectShader; use crate::tile_map::DenseTileMap; use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH}; use pathfinder_geometry::basic::line_segment::{LineSegmentF32, LineSegmentU4, LineSegmentU8}; -use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32}; +use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32}; use pathfinder_geometry::basic::rect::{RectF32, RectI32}; use pathfinder_geometry::util; use pathfinder_simd::default::{F32x4, I32x4}; use std::fmt::{Debug, Formatter, Result as DebugResult}; -use std::ops::Add; use std::sync::atomic::Ordering; #[derive(Debug)] @@ -31,14 +29,6 @@ pub(crate) struct BuiltObject { pub tiles: DenseTileMap, } -#[derive(Debug)] -pub struct BuiltScene { - pub view_box: RectF32, - pub quad: [Point3DF32; 4], - pub object_count: u32, - pub shaders: Vec, -} - pub enum RenderCommand { AddFills(Vec), FlushFills, @@ -90,14 +80,6 @@ pub struct AlphaTileBatchPrimitive { pub tile_index: u16, } -#[derive(Clone, Copy, Debug, Default)] -pub struct Stats { - pub object_count: u32, - pub solid_tile_count: u32, - pub alpha_tile_count: u32, - pub fill_count: u32, -} - // Utilities for built objects impl BuiltObject { @@ -258,22 +240,6 @@ impl BuiltObject { } } -impl BuiltScene { - #[inline] - pub fn new(view_box: RectF32, quad: &[Point3DF32; 4], object_count: u32) -> BuiltScene { - BuiltScene { view_box, quad: *quad, object_count, shaders: vec![] } - } - - pub fn stats(&self) -> Stats { - Stats { - object_count: self.object_count, - solid_tile_count: 0, - alpha_tile_count: 0, - fill_count: 0, - } - } -} - impl Default for TileObjectPrimitive { #[inline] fn default() -> TileObjectPrimitive { @@ -323,15 +289,3 @@ impl Debug for RenderCommand { } } } - -impl Add for Stats { - type Output = Stats; - fn add(self, other: Stats) -> Stats { - Stats { - object_count: other.object_count, - solid_tile_count: other.solid_tile_count, - alpha_tile_count: other.alpha_tile_count, - fill_count: other.fill_count, - } - } -} diff --git a/renderer/src/scene.rs b/renderer/src/scene.rs index 061a92b4..d2b0a8e8 100644 --- a/renderer/src/scene.rs +++ b/renderer/src/scene.rs @@ -12,7 +12,7 @@ use crate::builder::{PreparedRenderOptions, PreparedRenderTransform}; use hashbrown::HashMap; -use pathfinder_geometry::basic::point::Point2DF32; +use pathfinder_geometry::basic::point::{Point2DF32, Point3DF32}; use pathfinder_geometry::basic::rect::RectF32; use pathfinder_geometry::basic::transform2d::Transform2DF32; use pathfinder_geometry::color::ColorU; @@ -52,7 +52,15 @@ impl Scene { paint_id } - pub fn build_shaders(&self) -> Vec { + pub fn build_descriptor(&self, built_options: &PreparedRenderOptions) -> SceneDescriptor { + SceneDescriptor { + shaders: self.build_shaders(), + bounding_quad: built_options.bounding_quad(), + object_count: self.objects.len(), + } + } + + fn build_shaders(&self) -> Vec { self.objects.iter().map(|object| { let paint = &self.paints[object.paint.0 as usize]; ObjectShader { fill_color: paint.color } @@ -154,6 +162,13 @@ impl Debug for Scene { } } +#[derive(Clone, Debug)] +pub struct SceneDescriptor { + pub shaders: Vec, + pub bounding_quad: [Point3DF32; 4], + pub object_count: usize, +} + #[derive(Clone, Debug)] pub struct PathObject { outline: Outline,