aboutsummaryrefslogtreecommitdiffstats
path: root/components/gfx/render_task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/gfx/render_task.rs')
-rw-r--r--components/gfx/render_task.rs144
1 files changed, 82 insertions, 62 deletions
diff --git a/components/gfx/render_task.rs b/components/gfx/render_task.rs
index e1d190ac5fa..6dc3335faff 100644
--- a/components/gfx/render_task.rs
+++ b/components/gfx/render_task.rs
@@ -5,8 +5,7 @@
//! The task that handles all rendering/painting.
use buffer_map::BufferMap;
-use display_list::optimizer::DisplayListOptimizer;
-use display_list::DisplayList;
+use display_list::{mod, StackingContext};
use font_cache_task::FontCacheTask;
use font_context::FontContext;
use render_context::RenderContext;
@@ -27,9 +26,9 @@ 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;
+use servo_util::geometry::{Au, ZERO_POINT};
use servo_util::opts;
-use servo_util::smallvec::{SmallVec, SmallVec1};
+use servo_util::smallvec::SmallVec;
use servo_util::task::spawn_named_with_send_on_failure;
use servo_util::task_state;
use servo_util::time::{TimeProfilerChan, profile};
@@ -39,21 +38,28 @@ use std::mem;
use std::task::TaskBuilder;
use sync::Arc;
-/// Information about a layer that layout sends to the painting task.
+/// Information about a hardware graphics layer that layout sends to the painting task.
#[deriving(Clone)]
pub struct RenderLayer {
/// A per-pipeline ID describing this layer that should be stable across reflows.
pub id: LayerId,
- /// The display list describing the contents of this layer.
- pub display_list: Arc<DisplayList>,
- /// The position of the layer in pixels.
- pub position: Rect<uint>,
/// The color of the background in this layer. Used for unrendered content.
pub background_color: Color,
/// The scrolling policy of this layer.
pub scroll_policy: ScrollPolicy,
}
+impl RenderLayer {
+ /// Creates a new `RenderLayer`.
+ pub fn new(id: LayerId, background_color: Color, scroll_policy: ScrollPolicy) -> RenderLayer {
+ RenderLayer {
+ id: id,
+ background_color: background_color,
+ scroll_policy: scroll_policy,
+ }
+ }
+}
+
pub struct RenderRequest {
pub buffer_requests: Vec<BufferRequest>,
pub scale: f32,
@@ -62,7 +68,7 @@ pub struct RenderRequest {
}
pub enum Msg {
- RenderInitMsg(SmallVec1<RenderLayer>),
+ RenderInitMsg(Arc<StackingContext>),
RenderMsg(Vec<RenderRequest>),
UnusedBufferMsg(Vec<Box<LayerBuffer>>),
PaintPermissionGranted,
@@ -102,8 +108,8 @@ pub struct RenderTask<C> {
/// The native graphics context.
native_graphics_context: Option<NativePaintingGraphicsContext>,
- /// The layers to be rendered.
- render_layers: SmallVec1<RenderLayer>,
+ /// The root stacking context sent to us by the layout thread.
+ root_stacking_context: Option<Arc<StackingContext>>,
/// Permission to send paint messages to the compositor
paint_permission: bool,
@@ -129,17 +135,36 @@ macro_rules! native_graphics_context(
fn initialize_layers<C>(compositor: &mut C,
pipeline_id: PipelineId,
epoch: Epoch,
- render_layers: &[RenderLayer])
+ root_stacking_context: &StackingContext)
where C: RenderListener {
- let metadata = render_layers.iter().map(|render_layer| {
- LayerMetadata {
- id: render_layer.id,
- position: render_layer.position,
- background_color: render_layer.background_color,
- scroll_policy: render_layer.scroll_policy,
- }
- }).collect();
+ let mut metadata = Vec::new();
+ build(&mut metadata, root_stacking_context, &ZERO_POINT);
compositor.initialize_layers_for_pipeline(pipeline_id, metadata, epoch);
+
+ fn build(metadata: &mut Vec<LayerMetadata>,
+ stacking_context: &StackingContext,
+ page_position: &Point2D<Au>) {
+ let page_position = stacking_context.bounds.origin + *page_position;
+ match stacking_context.layer {
+ None => {}
+ Some(ref render_layer) => {
+ metadata.push(LayerMetadata {
+ id: render_layer.id,
+ position:
+ Rect(Point2D(page_position.x.to_nearest_px() as uint,
+ page_position.y.to_nearest_px() as uint),
+ Size2D(stacking_context.bounds.size.width.to_nearest_px() as uint,
+ stacking_context.bounds.size.height.to_nearest_px() as uint)),
+ background_color: render_layer.background_color,
+ scroll_policy: render_layer.scroll_policy,
+ })
+ }
+ }
+
+ for kid in stacking_context.display_list.children.iter() {
+ build(metadata, &**kid, &page_position)
+ }
+ }
}
impl<C> RenderTask<C> where C: RenderListener + Send {
@@ -170,11 +195,8 @@ impl<C> RenderTask<C> where C: RenderListener + Send {
compositor: compositor,
constellation_chan: constellation_chan,
time_profiler_chan: time_profiler_chan,
-
native_graphics_context: native_graphics_context,
-
- render_layers: SmallVec1::new(),
-
+ root_stacking_context: None,
paint_permission: false,
epoch: Epoch(0),
buffer_map: BufferMap::new(10000000),
@@ -205,9 +227,9 @@ impl<C> RenderTask<C> where C: RenderListener + Send {
loop {
match self.port.recv() {
- RenderInitMsg(render_layers) => {
+ RenderInitMsg(stacking_context) => {
self.epoch.next();
- self.render_layers = render_layers;
+ self.root_stacking_context = Some(stacking_context.clone());
if !self.paint_permission {
debug!("render_task: render ready msg");
@@ -219,7 +241,7 @@ impl<C> RenderTask<C> where C: RenderListener + Send {
initialize_layers(&mut self.compositor,
self.id,
self.epoch,
- self.render_layers.as_slice());
+ &*stacking_context);
}
RenderMsg(requests) => {
if !self.paint_permission {
@@ -254,15 +276,15 @@ impl<C> RenderTask<C> where C: RenderListener + Send {
PaintPermissionGranted => {
self.paint_permission = true;
- // Here we assume that the main layer—the layer responsible for the page size—
- // is the first layer. This is a pretty fragile assumption. It will be fixed
- // once we use the layers-based scrolling infrastructure for all scrolling.
- if self.render_layers.len() > 1 {
- self.epoch.next();
- initialize_layers(&mut self.compositor,
- self.id,
- self.epoch,
- self.render_layers.as_slice());
+ match self.root_stacking_context {
+ None => {}
+ Some(ref stacking_context) => {
+ self.epoch.next();
+ initialize_layers(&mut self.compositor,
+ self.id,
+ self.epoch,
+ &**stacking_context);
+ }
}
}
PaintPermissionRevoked => {
@@ -327,9 +349,15 @@ impl<C> RenderTask<C> where C: RenderListener + Send {
scale: f32,
layer_id: LayerId) {
time::profile(time::PaintingCategory, None, self.time_profiler_chan.clone(), || {
- // Bail out if there is no appropriate render layer.
- let render_layer = match self.render_layers.iter().find(|layer| layer.id == layer_id) {
- Some(render_layer) => (*render_layer).clone(),
+ // Bail out if there is no appropriate stacking context.
+ let stacking_context = match self.root_stacking_context {
+ Some(ref stacking_context) => {
+ match display_list::find_stacking_context_with_layer_id(stacking_context,
+ layer_id) {
+ Some(stacking_context) => stacking_context,
+ None => return,
+ }
+ }
None => return,
};
@@ -342,7 +370,7 @@ impl<C> RenderTask<C> where C: RenderListener + Send {
let layer_buffer = self.find_or_create_layer_buffer_for_tile(&tile, scale);
self.worker_threads[thread_id].paint_tile(tile,
layer_buffer,
- render_layer.clone(),
+ stacking_context.clone(),
scale);
}
let new_buffers = Vec::from_fn(tile_count, |i| {
@@ -397,9 +425,9 @@ impl WorkerThreadProxy {
fn paint_tile(&mut self,
tile: BufferRequest,
layer_buffer: Option<Box<LayerBuffer>>,
- render_layer: RenderLayer,
+ stacking_context: Arc<StackingContext>,
scale: f32) {
- self.sender.send(PaintTileMsgToWorkerThread(tile, layer_buffer, render_layer, scale))
+ self.sender.send(PaintTileMsgToWorkerThread(tile, layer_buffer, stacking_context, scale))
}
fn get_painted_tile_buffer(&mut self) -> Box<LayerBuffer> {
@@ -443,8 +471,8 @@ impl WorkerThread {
loop {
match self.receiver.recv() {
ExitMsgToWorkerThread => break,
- PaintTileMsgToWorkerThread(tile, layer_buffer, render_layer, scale) => {
- let draw_target = self.optimize_and_paint_tile(&tile, render_layer, scale);
+ PaintTileMsgToWorkerThread(tile, layer_buffer, stacking_context, scale) => {
+ let draw_target = self.optimize_and_paint_tile(&tile, stacking_context, scale);
let buffer = self.create_layer_buffer_for_painted_tile(&tile,
layer_buffer,
draw_target,
@@ -457,21 +485,9 @@ impl WorkerThread {
fn optimize_and_paint_tile(&mut self,
tile: &BufferRequest,
- render_layer: RenderLayer,
+ stacking_context: Arc<StackingContext>,
scale: f32)
-> DrawTarget {
- // page_rect is in coordinates relative to the layer origin, but all display list
- // components are relative to the page origin. We make page_rect relative to
- // the page origin before passing it to the optimizer.
- let page_rect = tile.page_rect.translate(&Point2D(render_layer.position.origin.x as f32,
- render_layer.position.origin.y as f32));
- let page_rect_au = geometry::f32_rect_to_au_rect(page_rect);
-
- // Optimize the display list for this tile.
- let optimizer = DisplayListOptimizer::new(render_layer.display_list.clone(),
- page_rect_au);
- let display_list = optimizer.optimize();
-
let size = Size2D(tile.screen_rect.size.width as i32, tile.screen_rect.size.height as i32);
let draw_target = if !opts::get().gpu_painting {
DrawTarget::new(SkiaBackend, size, B8G8R8A8)
@@ -496,10 +512,11 @@ impl WorkerThread {
};
// Apply the translation to render the tile we want.
+ let tile_bounds = tile.page_rect;
let matrix: Matrix2D<AzFloat> = Matrix2D::identity();
let matrix = matrix.scale(scale as AzFloat, scale as AzFloat);
- let matrix = matrix.translate(-page_rect.origin.x as AzFloat,
- -page_rect.origin.y as AzFloat);
+ let matrix = matrix.translate(-tile_bounds.origin.x as AzFloat,
+ -tile_bounds.origin.y as AzFloat);
render_context.draw_target.set_transform(&matrix);
@@ -509,7 +526,10 @@ impl WorkerThread {
// Draw the display list.
profile(time::PaintingPerTileCategory, None, self.time_profiler_sender.clone(), || {
let mut clip_stack = Vec::new();
- display_list.draw_into_context(&mut render_context, &matrix, &mut clip_stack);
+ stacking_context.optimize_and_draw_into_context(&mut render_context,
+ &tile.page_rect,
+ &matrix,
+ &mut clip_stack);
render_context.draw_target.flush();
});
}
@@ -564,7 +584,7 @@ impl WorkerThread {
enum MsgToWorkerThread {
ExitMsgToWorkerThread,
- PaintTileMsgToWorkerThread(BufferRequest, Option<Box<LayerBuffer>>, RenderLayer, f32),
+ PaintTileMsgToWorkerThread(BufferRequest, Option<Box<LayerBuffer>>, Arc<StackingContext>, f32),
}
enum MsgFromWorkerThread {