Add a scene field to render target IDs to reduce the chance of misuse

This commit is contained in:
Patrick Walton 2020-04-16 16:54:52 -07:00
parent 0b43f629cd
commit 07ce2a2536
4 changed files with 30 additions and 14 deletions

View File

@ -11,4 +11,7 @@
//! Render targets. //! Render targets.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct RenderTargetId(pub u32); pub struct RenderTargetId {
pub scene: u32,
pub render_target: u32,
}

View File

@ -472,12 +472,12 @@ where
fn declare_render_target(&mut self, fn declare_render_target(&mut self,
render_target_id: RenderTargetId, render_target_id: RenderTargetId,
location: TextureLocation) { location: TextureLocation) {
while self.render_targets.len() < render_target_id.0 as usize + 1 { while self.render_targets.len() < render_target_id.render_target as usize + 1 {
self.render_targets.push(RenderTargetInfo { self.render_targets.push(RenderTargetInfo {
location: TextureLocation { page: TexturePageId(!0), rect: RectI::default() }, location: TextureLocation { page: TexturePageId(!0), rect: RectI::default() },
}); });
} }
let mut render_target = &mut self.render_targets[render_target_id.0 as usize]; let mut render_target = &mut self.render_targets[render_target_id.render_target as usize];
debug_assert_eq!(render_target.location.page, TexturePageId(!0)); debug_assert_eq!(render_target.location.page, TexturePageId(!0));
render_target.location = location; render_target.location = location;
} }
@ -1078,7 +1078,7 @@ where
} }
fn render_target_location(&self, render_target_id: RenderTargetId) -> TextureLocation { fn render_target_location(&self, render_target_id: RenderTargetId) -> TextureLocation {
self.render_targets[render_target_id.0 as usize].location self.render_targets[render_target_id.render_target as usize].location
} }
fn texture_page_framebuffer(&self, id: TexturePageId) -> &D::Framebuffer { fn texture_page_framebuffer(&self, id: TexturePageId) -> &D::Framebuffer {

View File

@ -11,7 +11,7 @@
use crate::allocator::{AllocationMode, TextureAllocator}; use crate::allocator::{AllocationMode, TextureAllocator};
use crate::gpu_data::{RenderCommand, TextureLocation, TextureMetadataEntry, TexturePageDescriptor}; use crate::gpu_data::{RenderCommand, TextureLocation, TextureMetadataEntry, TexturePageDescriptor};
use crate::gpu_data::{TexturePageId, TileBatchTexture}; use crate::gpu_data::{TexturePageId, TileBatchTexture};
use crate::scene::RenderTarget; use crate::scene::{RenderTarget, SceneId};
use hashbrown::HashMap; use hashbrown::HashMap;
use pathfinder_color::ColorU; use pathfinder_color::ColorU;
use pathfinder_content::effects::{Filter, PatternFilter}; use pathfinder_content::effects::{Filter, PatternFilter};
@ -37,6 +37,7 @@ pub struct Palette {
pub(crate) paints: Vec<Paint>, pub(crate) paints: Vec<Paint>,
pub(crate) render_targets: Vec<RenderTarget>, pub(crate) render_targets: Vec<RenderTarget>,
cache: HashMap<Paint, PaintId>, cache: HashMap<Paint, PaintId>,
scene_id: SceneId,
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
@ -84,8 +85,8 @@ impl Debug for PaintContents {
impl Palette { impl Palette {
#[inline] #[inline]
pub fn new() -> Palette { pub fn new(scene_id: SceneId) -> Palette {
Palette { paints: vec![], render_targets: vec![], cache: HashMap::new() } Palette { paints: vec![], render_targets: vec![], cache: HashMap::new(), scene_id }
} }
} }
@ -336,9 +337,9 @@ impl Palette {
} }
pub fn push_render_target(&mut self, render_target: RenderTarget) -> RenderTargetId { pub fn push_render_target(&mut self, render_target: RenderTarget) -> RenderTargetId {
let id = RenderTargetId(self.render_targets.len() as u32); let id = self.render_targets.len() as u32;
self.render_targets.push(render_target); self.render_targets.push(render_target);
id RenderTargetId { scene: self.scene_id.0, render_target: id }
} }
pub fn build_paint_info(&self, render_transform: Transform2F) -> PaintInfo { pub fn build_paint_info(&self, render_transform: Transform2F) -> PaintInfo {
@ -377,8 +378,8 @@ impl Palette {
let location; let location;
match *pattern.source() { match *pattern.source() {
PatternSource::RenderTarget { id: render_target_id, .. } => { PatternSource::RenderTarget { id: render_target_id, .. } => {
location = let index = render_target_id.render_target as usize;
render_target_metadata[render_target_id.0 as usize].location; location = render_target_metadata[index].location;
} }
PatternSource::Image(ref image) => { PatternSource::Image(ref image) => {
// TODO(pcwalton): We should be able to use tile cleverness to // TODO(pcwalton): We should be able to use tile cleverness to
@ -510,7 +511,7 @@ impl Palette {
RenderCommand::AllocateTexturePages(texture_page_descriptors), RenderCommand::AllocateTexturePages(texture_page_descriptors),
]; ];
for (index, metadata) in render_target_metadata.iter().enumerate() { for (index, metadata) in render_target_metadata.iter().enumerate() {
let id = RenderTargetId(index as u32); let id = RenderTargetId { scene: self.scene_id.0, render_target: index as u32 };
render_commands.push(RenderCommand::DeclareRenderTarget { render_commands.push(RenderCommand::DeclareRenderTarget {
id, id,
location: metadata.location, location: metadata.location,

View File

@ -24,6 +24,9 @@ use pathfinder_geometry::rect::RectF;
use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::transform2d::Transform2F;
use pathfinder_geometry::vector::{Vector2I, vec2f}; use pathfinder_geometry::vector::{Vector2I, vec2f};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::atomic::{AtomicUsize, Ordering};
static NEXT_SCENE_ID: AtomicUsize = AtomicUsize::new(0);
#[derive(Clone)] #[derive(Clone)]
pub struct Scene { pub struct Scene {
@ -33,18 +36,24 @@ pub struct Scene {
palette: Palette, palette: Palette,
bounds: RectF, bounds: RectF,
view_box: RectF, view_box: RectF,
id: SceneId,
} }
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SceneId(pub u32);
impl Scene { impl Scene {
#[inline] #[inline]
pub fn new() -> Scene { pub fn new() -> Scene {
let scene_id = SceneId(NEXT_SCENE_ID.fetch_add(1, Ordering::Relaxed) as u32);
Scene { Scene {
display_list: vec![], display_list: vec![],
paths: vec![], paths: vec![],
clip_paths: vec![], clip_paths: vec![],
palette: Palette::new(), palette: Palette::new(scene_id),
bounds: RectF::default(), bounds: RectF::default(),
view_box: RectF::default(), view_box: RectF::default(),
id: scene_id,
} }
} }
@ -94,7 +103,10 @@ impl Scene {
.render_targets .render_targets
.into_iter() .into_iter()
.enumerate() { .enumerate() {
let old_render_target_id = RenderTargetId(old_render_target_index as u32); let old_render_target_id = RenderTargetId {
scene: scene.id.0,
render_target: old_render_target_index as u32,
};
let new_render_target_id = self.palette.push_render_target(render_target); let new_render_target_id = self.palette.push_render_target(render_target);
render_target_mapping.insert(old_render_target_id, new_render_target_id); render_target_mapping.insert(old_render_target_id, new_render_target_id);
} }