From b201e19cc7a3536c184014456e79b14af307d4c3 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Thu, 20 Jul 2023 01:23:31 +0200 Subject: [PATCH] wgpu: Don't create an extra fresh texture for applying filters to a CAB --- core/src/display_object.rs | 1 + render/src/filters.rs | 11 +++++++++++ render/wgpu/src/backend.rs | 19 +++++++++++++------ swf/src/types/blur_filter.rs | 4 ++++ swf/src/types/color_matrix_filter.rs | 6 ++++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/core/src/display_object.rs b/core/src/display_object.rs index cb3173a1c..a23fd0310 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -747,6 +747,7 @@ pub fn render_base<'gc>(this: DisplayObject<'gc>, context: &mut RenderContext<'_ let bounds: Rectangle = this.bounds_with_transform(&base_transform.matrix); let name = this.name(); let mut filters: Vec = this.filters(); + filters.retain(|f| !f.impotent()); if let Some(cache) = this.base_mut(context.gc_context).bitmap_cache_mut() { let width = bounds.width().to_pixels().ceil().max(0.0); diff --git a/render/src/filters.rs b/render/src/filters.rs index 352a6c807..bee7c4fc8 100644 --- a/render/src/filters.rs +++ b/render/src/filters.rs @@ -59,6 +59,17 @@ impl Filter { _ => {} } } + + /// Checks if this filter is impotent. + /// Impotent filters will have no effect if applied, and can safely be skipped. + pub fn impotent(&self) -> bool { + // TODO: There's more cases here, find them! + match self { + Filter::BlurFilter(filter) => filter.impotent(), + Filter::ColorMatrixFilter(filter) => filter.impotent(), + _ => false, + } + } } impl From<&swf::Filter> for Filter { diff --git a/render/wgpu/src/backend.rs b/render/wgpu/src/backend.rs index f11b1d4c1..ff0d1e755 100644 --- a/render/wgpu/src/backend.rs +++ b/render/wgpu/src/backend.rs @@ -548,13 +548,20 @@ impl RenderBackend for WgpuRenderBackend { &mut self.offscreen_texture_pool, ); } else { + // We're relying on there being no impotent filters here, + // so that we can safely start by using the actual CAB texture. + // It's guaranteed that at least one filter would have used it and moved the target to something else, + // letting us safely copy back to it later. let mut target = surface.draw_commands( - RenderTargetMode::FreshWithColor(wgpu::Color { - r: f64::from(entry.clear.r) / 255.0, - g: f64::from(entry.clear.g) / 255.0, - b: f64::from(entry.clear.b) / 255.0, - a: f64::from(entry.clear.a) / 255.0, - }), + RenderTargetMode::ExistingWithColor( + texture.texture.clone(), + wgpu::Color { + r: f64::from(entry.clear.r) / 255.0, + g: f64::from(entry.clear.g) / 255.0, + b: f64::from(entry.clear.b) / 255.0, + a: f64::from(entry.clear.a) / 255.0, + }, + ), &self.descriptors, &self.meshes, entry.commands, diff --git a/swf/src/types/blur_filter.rs b/swf/src/types/blur_filter.rs index 3a1e2ed30..e5392c877 100644 --- a/swf/src/types/blur_filter.rs +++ b/swf/src/types/blur_filter.rs @@ -18,6 +18,10 @@ impl BlurFilter { self.blur_x *= Fixed16::from_f32(x); self.blur_y *= Fixed16::from_f32(y); } + + pub fn impotent(&self) -> bool { + self.blur_x == Fixed16::ZERO && self.blur_y == Fixed16::ZERO + } } bitflags! { diff --git a/swf/src/types/color_matrix_filter.rs b/swf/src/types/color_matrix_filter.rs index b0345fbd1..4a543596f 100644 --- a/swf/src/types/color_matrix_filter.rs +++ b/swf/src/types/color_matrix_filter.rs @@ -15,3 +15,9 @@ impl Default for ColorMatrixFilter { } } } + +impl ColorMatrixFilter { + pub fn impotent(&self) -> bool { + self == &Default::default() + } +}