gfx: Don't needlessly push and pop clip rects all the time.

15% painting improvement on CNN.
This commit is contained in:
Patrick Walton 2014-10-17 22:35:56 -07:00
parent 79f84a62fe
commit cd42c28f5b
2 changed files with 13 additions and 14 deletions

View file

@ -288,10 +288,10 @@ impl DisplayList {
pub fn draw_into_context(&self, pub fn draw_into_context(&self,
render_context: &mut RenderContext, render_context: &mut RenderContext,
current_transform: &Matrix2D<AzFloat>, current_transform: &Matrix2D<AzFloat>,
current_clip_rect: &Rect<Au>) { current_clip_stack: &mut Vec<Rect<Au>>) {
debug!("Beginning display list."); debug!("Beginning display list.");
for item in self.list.iter() { 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."); debug!("Ending display list.");
} }
@ -504,14 +504,19 @@ impl DisplayItem {
fn draw_into_context(&self, fn draw_into_context(&self,
render_context: &mut RenderContext, render_context: &mut RenderContext,
current_transform: &Matrix2D<AzFloat>, current_transform: &Matrix2D<AzFloat>,
current_clip_rect: &Rect<Au>) { current_clip_stack: &mut Vec<Rect<Au>>) {
// This should have been flattened to the content stacking level first. // This should have been flattened to the content stacking level first.
assert!(self.base().level == ContentStackingLevel); 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 clip_rect = &self.base().clip_rect;
let need_to_clip = current_clip_rect != clip_rect; if current_clip_stack.len() == 0 || current_clip_stack.last().unwrap() != clip_rect {
if need_to_clip { while current_clip_stack.len() != 0 {
render_context.draw_pop_clip();
drop(current_clip_stack.pop());
}
render_context.draw_push_clip(clip_rect); render_context.draw_push_clip(clip_rect);
current_clip_stack.push(*clip_rect);
} }
match *self { match *self {
@ -608,10 +613,6 @@ impl DisplayItem {
PseudoDisplayItemClass(_) => {} PseudoDisplayItemClass(_) => {}
} }
if need_to_clip {
render_context.draw_pop_clip();
}
} }
pub fn base<'a>(&'a self) -> &'a BaseDisplayItem { pub fn base<'a>(&'a self) -> &'a BaseDisplayItem {

View file

@ -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::{ConstellationChan, Failure, FailureMsg, PipelineId};
use servo_msg::constellation_msg::{RendererReadyMsg}; use servo_msg::constellation_msg::{RendererReadyMsg};
use servo_msg::platform::surface::NativeSurfaceAzureMethods; use servo_msg::platform::surface::NativeSurfaceAzureMethods;
use servo_util::geometry::{Au, mod}; use servo_util::geometry;
use servo_util::opts; use servo_util::opts;
use servo_util::smallvec::{SmallVec, SmallVec1}; use servo_util::smallvec::{SmallVec, SmallVec1};
use servo_util::task::spawn_named_with_send_on_failure; use servo_util::task::spawn_named_with_send_on_failure;
use servo_util::time::{TimeProfilerChan, profile}; use servo_util::time::{TimeProfilerChan, profile};
use servo_util::time; use servo_util::time;
use std::comm::{Receiver, Sender, channel}; use std::comm::{Receiver, Sender, channel};
use std::i32;
use sync::Arc; use sync::Arc;
use font_cache_task::FontCacheTask; use font_cache_task::FontCacheTask;
@ -359,9 +358,8 @@ impl<C:RenderListener + Send> RenderTask<C> {
None, None,
self.time_profiler_chan.clone(), self.time_profiler_chan.clone(),
|| { || {
let clip_rect = Rect(Point2D(Au(i32::MIN), Au(i32::MIN)), let mut clip_stack = Vec::new();
Size2D(Au(i32::MAX), Au(i32::MAX))); display_list.draw_into_context(&mut ctx, &matrix, &mut clip_stack);
display_list.draw_into_context(&mut ctx, &matrix, &clip_rect);
ctx.draw_target.flush(); ctx.draw_target.flush();
}); });
} }