mirror of
https://github.com/servo/servo.git
synced 2025-08-11 08:25:32 +01:00
Implement enough of 3d transforms spec to run the CSS FPS demo.
This commit is contained in:
parent
d86c587925
commit
39ddbbb0e1
19 changed files with 894 additions and 145 deletions
|
@ -32,7 +32,7 @@ use euclid::approxeq::ApproxEq;
|
|||
use euclid::num::Zero;
|
||||
use libc::uintptr_t;
|
||||
use paint_task::PaintLayer;
|
||||
use msg::compositor_msg::LayerId;
|
||||
use msg::compositor_msg::{LayerId, LayerKind};
|
||||
use net_traits::image::base::Image;
|
||||
use util::opts;
|
||||
use util::cursor::Cursor;
|
||||
|
@ -246,6 +246,12 @@ pub struct StackingContext {
|
|||
|
||||
/// A transform to be applied to this stacking context.
|
||||
pub transform: Matrix4,
|
||||
|
||||
/// The perspective matrix to be applied to children.
|
||||
pub perspective: Matrix4,
|
||||
|
||||
/// Whether this stacking context creates a new 3d rendering context.
|
||||
pub establishes_3d_context: bool,
|
||||
}
|
||||
|
||||
impl StackingContext {
|
||||
|
@ -255,30 +261,40 @@ impl StackingContext {
|
|||
bounds: &Rect<Au>,
|
||||
overflow: &Rect<Au>,
|
||||
z_index: i32,
|
||||
transform: &Matrix4,
|
||||
filters: filter::T,
|
||||
blend_mode: mix_blend_mode::T,
|
||||
layer: Option<Arc<PaintLayer>>)
|
||||
layer: Option<Arc<PaintLayer>>,
|
||||
transform: Matrix4,
|
||||
perspective: Matrix4,
|
||||
establishes_3d_context: bool)
|
||||
-> StackingContext {
|
||||
StackingContext {
|
||||
display_list: display_list,
|
||||
layer: layer,
|
||||
bounds: *bounds,
|
||||
overflow: *overflow,
|
||||
z_index: z_index,
|
||||
transform: *transform,
|
||||
filters: filters,
|
||||
blend_mode: blend_mode,
|
||||
layer: layer,
|
||||
transform: transform,
|
||||
perspective: perspective,
|
||||
establishes_3d_context: establishes_3d_context,
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws the stacking context in the proper order according to the steps in CSS 2.1 § E.2.
|
||||
pub fn optimize_and_draw_into_context(&self,
|
||||
paint_context: &mut PaintContext,
|
||||
tile_bounds: &Rect<AzFloat>,
|
||||
transform: &Matrix4,
|
||||
clip_rect: Option<&Rect<Au>>) {
|
||||
let transform = transform.mul(&self.transform);
|
||||
pub fn draw_into_context(&self,
|
||||
display_list: &DisplayList,
|
||||
paint_context: &mut PaintContext,
|
||||
tile_bounds: &Rect<AzFloat>,
|
||||
transform: &Matrix4,
|
||||
clip_rect: Option<&Rect<Au>>) {
|
||||
// If a layer is being used, the transform for this layer
|
||||
// will be handled by the compositor.
|
||||
let transform = match self.layer {
|
||||
Some(..) => *transform,
|
||||
None => transform.mul(&self.transform),
|
||||
};
|
||||
let temporary_draw_target =
|
||||
paint_context.get_or_create_temporary_draw_target(&self.filters, self.blend_mode);
|
||||
{
|
||||
|
@ -289,12 +305,9 @@ impl StackingContext {
|
|||
screen_rect: paint_context.screen_rect,
|
||||
clip_rect: clip_rect.map(|clip_rect| *clip_rect),
|
||||
transient_clip: None,
|
||||
layer_kind: paint_context.layer_kind,
|
||||
};
|
||||
|
||||
// Optimize the display list to throw out out-of-bounds display items and so forth.
|
||||
let display_list =
|
||||
DisplayListOptimizer::new(tile_bounds).optimize(&*self.display_list);
|
||||
|
||||
if opts::get().dump_display_list_optimized {
|
||||
println!("**** optimized display list. Tile bounds: {:?}", tile_bounds);
|
||||
display_list.print_items("*".to_owned());
|
||||
|
@ -409,6 +422,35 @@ impl StackingContext {
|
|||
paint_context.draw_temporary_draw_target_if_necessary(&temporary_draw_target,
|
||||
&self.filters,
|
||||
self.blend_mode)
|
||||
|
||||
}
|
||||
|
||||
/// Optionally optimize and then draws the stacking context.
|
||||
pub fn optimize_and_draw_into_context(&self,
|
||||
paint_context: &mut PaintContext,
|
||||
tile_bounds: &Rect<AzFloat>,
|
||||
transform: &Matrix4,
|
||||
clip_rect: Option<&Rect<Au>>) {
|
||||
// TODO(gw): This is a hack to avoid running the DL optimizer
|
||||
// on 3d transformed tiles. We should have a better solution
|
||||
// than just disabling the opts here.
|
||||
if paint_context.layer_kind == LayerKind::Layer3D {
|
||||
self.draw_into_context(&self.display_list,
|
||||
paint_context,
|
||||
tile_bounds,
|
||||
transform,
|
||||
clip_rect);
|
||||
|
||||
} else {
|
||||
// Optimize the display list to throw out out-of-bounds display items and so forth.
|
||||
let display_list = DisplayListOptimizer::new(tile_bounds).optimize(&*self.display_list);
|
||||
|
||||
self.draw_into_context(&display_list,
|
||||
paint_context,
|
||||
tile_bounds,
|
||||
transform,
|
||||
clip_rect);
|
||||
}
|
||||
}
|
||||
|
||||
/// Translate the given tile rect into the coordinate system of a child stacking context.
|
||||
|
@ -1005,7 +1047,7 @@ impl<'a> Iterator for DisplayItemIterator<'a> {
|
|||
impl DisplayItem {
|
||||
/// Paints this display item into the given painting context.
|
||||
fn draw_into_context(&self, paint_context: &mut PaintContext) {
|
||||
{
|
||||
if paint_context.layer_kind == LayerKind::Layer2D {
|
||||
let this_clip = &self.base().clip;
|
||||
match paint_context.transient_clip {
|
||||
Some(ref transient_clip) if transient_clip == this_clip => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue