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,
render_context: &mut RenderContext,
current_transform: &Matrix2D<AzFloat>,
current_clip_rect: &Rect<Au>) {
current_clip_stack: &mut Vec<Rect<Au>>) {
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<AzFloat>,
current_clip_rect: &Rect<Au>) {
current_clip_stack: &mut Vec<Rect<Au>>) {
// 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 {

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::{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<C:RenderListener + Send> RenderTask<C> {
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();
});
}