From cd42c28f5b819357d037c67f33e993fbe9bbb75d Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 17 Oct 2014 22:35:56 -0700 Subject: [PATCH] gfx: Don't needlessly push and pop clip rects all the time. 15% painting improvement on CNN. --- components/gfx/display_list/mod.rs | 19 ++++++++++--------- components/gfx/render_task.rs | 8 +++----- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index a72f0b44d08..7f8975a2ca6 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -288,10 +288,10 @@ impl DisplayList { pub fn draw_into_context(&self, render_context: &mut RenderContext, current_transform: &Matrix2D, - current_clip_rect: &Rect) { + current_clip_stack: &mut Vec>) { debug!("Beginning display list."); for item in self.list.iter() { - item.draw_into_context(render_context, current_transform, current_clip_rect) + item.draw_into_context(render_context, current_transform, current_clip_stack) } debug!("Ending display list."); } @@ -504,14 +504,19 @@ impl DisplayItem { fn draw_into_context(&self, render_context: &mut RenderContext, current_transform: &Matrix2D, - current_clip_rect: &Rect) { + current_clip_stack: &mut Vec>) { // This should have been flattened to the content stacking level first. assert!(self.base().level == ContentStackingLevel); + // TODO(pcwalton): This will need some tweaking to deal with more complex clipping regions. let clip_rect = &self.base().clip_rect; - let need_to_clip = current_clip_rect != clip_rect; - if need_to_clip { + if current_clip_stack.len() == 0 || current_clip_stack.last().unwrap() != clip_rect { + while current_clip_stack.len() != 0 { + render_context.draw_pop_clip(); + drop(current_clip_stack.pop()); + } render_context.draw_push_clip(clip_rect); + current_clip_stack.push(*clip_rect); } match *self { @@ -608,10 +613,6 @@ impl DisplayItem { PseudoDisplayItemClass(_) => {} } - - if need_to_clip { - render_context.draw_pop_clip(); - } } pub fn base<'a>(&'a self) -> &'a BaseDisplayItem { diff --git a/components/gfx/render_task.rs b/components/gfx/render_task.rs index 53f50f95102..32c5d97c2b1 100644 --- a/components/gfx/render_task.rs +++ b/components/gfx/render_task.rs @@ -25,14 +25,13 @@ use servo_msg::compositor_msg::{LayerMetadata, RenderListener, RenderingRenderSt use servo_msg::constellation_msg::{ConstellationChan, Failure, FailureMsg, PipelineId}; use servo_msg::constellation_msg::{RendererReadyMsg}; use servo_msg::platform::surface::NativeSurfaceAzureMethods; -use servo_util::geometry::{Au, mod}; +use servo_util::geometry; use servo_util::opts; use servo_util::smallvec::{SmallVec, SmallVec1}; use servo_util::task::spawn_named_with_send_on_failure; use servo_util::time::{TimeProfilerChan, profile}; use servo_util::time; use std::comm::{Receiver, Sender, channel}; -use std::i32; use sync::Arc; use font_cache_task::FontCacheTask; @@ -359,9 +358,8 @@ impl RenderTask { None, self.time_profiler_chan.clone(), || { - let clip_rect = Rect(Point2D(Au(i32::MIN), Au(i32::MIN)), - Size2D(Au(i32::MAX), Au(i32::MAX))); - display_list.draw_into_context(&mut ctx, &matrix, &clip_rect); + let mut clip_stack = Vec::new(); + display_list.draw_into_context(&mut ctx, &matrix, &mut clip_stack); ctx.draw_target.flush(); }); }