Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progressive Rendering #557

Merged
merged 9 commits into from Jul 11, 2013

Clean up and annotations

  • Loading branch information
eschweic
eschweic committed Jul 11, 2013
commit 1948280aec04d6c0e2e73c3ddf3d18be8a3fe61b
@@ -11,7 +11,6 @@ use servo_msg::compositor_msg::{RenderListener, IdleRenderState, RenderingRender
use servo_msg::compositor_msg::{LayerBufferSet};
use font_context::FontContext;
use geom::matrix2d::Matrix2D;
use geom::point::Point2D;
use geom::size::Size2D;
use geom::rect::Rect;
use opts::Opts;
@@ -33,7 +32,7 @@ pub struct RenderLayer {

pub enum Msg {
RenderMsg(RenderLayer),
ReRenderMsg(~Rect<uint>], f32),
ReRenderMsg(~[(Rect<uint>, Rect<f32>)], f32),

This comment has been minimized.

@metajack

metajack Jul 3, 2013

Contributor

Please document this struct.

PaintPermissionGranted,
PaintPermissionRevoked,
ExitMsg(Chan<()>),
@@ -146,7 +145,7 @@ impl<C: RenderListener + Send> RenderTask<C> {
}
}

fn render(&mut self, tiles: ~[Rect<uint>], scale: f32) {
fn render(&mut self, tiles: ~[(Rect<uint>, Rect<f32>)], scale: f32) {

This comment has been minimized.

@metajack

metajack Jul 3, 2013

Contributor

I would prefer to use a named structure here instead of the anonymous tuple.

debug!("render_task: rendering");

let render_layer;
@@ -166,21 +165,18 @@ impl<C: RenderListener + Send> RenderTask<C> {

// Divide up the layer into tiles.
do time::profile(time::RenderingPrepBuffCategory, self.profiler_chan.clone()) {
for tiles.each |tile_rect| {
let x = tile_rect.origin.x;
let y = tile_rect.origin.y;
let width = tile_rect.size.width;
let height = tile_rect.size.height;

let rect = Rect(Point2D(x as f32 / scale, y as f32 / scale), Size2D(width as f32, height as f32));
for tiles.each |tile_rects| {
let (screen_rect, page_rect) = *tile_rects;
let width = screen_rect.size.width;
let height = screen_rect.size.height;

let buffer = LayerBuffer {
draw_target: DrawTarget::new_with_fbo(self.opts.render_backend,
self.share_gl_context,
Size2D(width as i32, height as i32),
B8G8R8A8),
rect: rect,
screen_pos: *tile_rect,
rect: page_rect,
screen_pos: screen_rect,
resolution: scale,
stride: (width * 4) as uint
};
@@ -28,7 +28,6 @@ use extra::timer;
use geom::matrix::identity;
use geom::point::Point2D;
use geom::size::Size2D;
use geom::rect::Rect; //eschweic
use layers::layers::{ARGB32Format, ContainerLayer, ContainerLayerKind, Format};
use layers::layers::{ImageData, WithDataFn};
use layers::layers::{TextureLayerKind, TextureLayer, TextureManager};
@@ -119,8 +118,7 @@ pub enum Msg {
/// Requests the compositors GL context.
GetGLContext(Chan<AzGLContext>),

//eschweic
// FIXME: Attach layer ids and epochs to these messages
// TODO: Attach layer ids and epochs to these messages
/// Alerts the compositor that there is a new layer to be rendered.
NewLayer(Size2D<uint>, uint),
/// Alerts the compositor that the current layer has changed size.
@@ -237,7 +235,9 @@ impl CompositorTask {
let ask_for_tiles: @fn() = || {
match *quadtree {
Some(ref quad) => {
let mut tile_size = quad.get_tile_size(); // temporary solution
// FIXME: find a better way to get the tile size
// currently tiles that need to be updated can be missed
let mut tile_size = quad.get_tile_size();
let mut tile_request = ~[]; //FIXME: try not to allocate if possible

let mut y = world_offset.y as uint;
@@ -253,15 +253,15 @@ impl CompositorTask {
}
None => {} // fall through
}
let (tile_pos, new_tile_size) = quad.get_tile_rect(x, y, *world_zoom);
tile_size = new_tile_size;
x = tile_pos.x;
y = tile_pos.y;
let (tile_screen_pos, tile_page_pos) = quad.get_tile_rect(x, y, *world_zoom);
tile_size = tile_screen_pos.size.width;
x = tile_screen_pos.origin.x;
y = tile_screen_pos.origin.y;

// TODO: clamp tiles to page bounds
// TODO: add null buffer/checkerboard tile to stop a flood of requests
println(fmt!("requesting tile: (%?, %?): %?", x, y, tile_size));
tile_request.push(Rect(Point2D(x, y), Size2D(tile_size, tile_size)));
debug!("requesting tile: (%?, %?): %?", x, y, tile_size);
tile_request.push((tile_screen_pos, tile_page_pos));

x += tile_size;
}
@@ -325,32 +325,14 @@ impl CompositorTask {
}
WindowMouseDownEvent(button, layer_mouse_point) => {
event = MouseDownEvent(button, world_mouse_point(layer_mouse_point));

//eschweic
match *quadtree {
Some(ref quad) => {

/* let wmp = world_mouse_point(layer_mouse_point);
println(fmt!("mouse: (%?, %?):", wmp.x as uint, wmp.y as uint));
let buffer = quad.get_tile(wmp.x as uint, wmp.y as uint, *world_zoom);
match *buffer {
None => println("None"),
Some(ref buffer) => println(fmt!("Some: (%?, %?), %?, %?", buffer.screen_pos.origin.x, buffer.screen_pos.origin.y, buffer.screen_pos.size.width, buffer.resolution)),
} */

println(quad.get_html());
}
None => {}
}

}
WindowMouseUpEvent(button, layer_mouse_point) => {

//FIXME: this should not be here eschweic
// FIXME: this should happen on a scroll/zoom event instead,
// but is here temporarily to prevent request floods to the renderer
ask_for_tiles();



event = MouseUpEvent(button, world_mouse_point(layer_mouse_point));
}
}
@@ -385,7 +367,6 @@ impl CompositorTask {

GetGLContext(chan) => chan.send(current_gl_context()),

//eschweic
NewLayer(new_size, tile_size) => {
*page_size = Size2D(new_size.width as f32, new_size.height as f32);
*quadtree = Some(Quadtree::new(0, 0, new_size.width, new_size.height, tile_size));
@@ -430,8 +411,8 @@ impl CompositorTask {
}

for quad.get_all_tiles().each |buffer| {
let width = buffer.rect.size.width as uint;
let height = buffer.rect.size.height as uint;
let width = buffer.screen_pos.size.width as uint;
let height = buffer.screen_pos.size.height as uint;

debug!("osmain: compositing buffer rect %?", &buffer.rect);

@@ -457,11 +438,11 @@ impl CompositorTask {
Some(_) => fail!(~"found unexpected layer kind"),
};

let origin = buffer.screen_pos.origin;
let origin = buffer.rect.origin;
let origin = Point2D(origin.x as f32, origin.y as f32);

// Set the layer's transform.
let transform = identity().translate(origin.x * *world_zoom / buffer.resolution, origin.y * *world_zoom / buffer.resolution, 0.0);
let transform = identity().translate(origin.x * *world_zoom, origin.y * *world_zoom, 0.0);
let transform = transform.scale(width as f32 * *world_zoom / buffer.resolution, height as f32 * *world_zoom / buffer.resolution, 1.0);
texture_layer.common.set_transform(transform);

@@ -6,6 +6,8 @@
// been rasterized and which have not.

use geom::point::Point2D;
use geom::size::Size2D;
use geom::rect::Rect;

/// Parent to all quadtree nodes. Stores variables needed at all levels. All method calls
/// at this level are in pixel coordinates.
@@ -65,8 +67,8 @@ impl<T> Quadtree<T> {
pub fn add_tile(&mut self, x: uint, y: uint, scale: f32, tile: T) {
self.root.add_tile(x as f32 / scale, y as f32 / scale, tile, self.max_tile_size as f32 / scale);
}
/// Get the tile size/offset for a given pixel position
pub fn get_tile_rect(&self, x: uint, y: uint, scale: f32) -> (Point2D<uint>, uint) {
/// Get the tile rect in screen and page coordinates for a given pixel position
pub fn get_tile_rect(&self, x: uint, y: uint, scale: f32) -> (Rect<uint>, Rect<f32>) {
self.root.get_tile_rect(x as f32 / scale, y as f32 / scale, scale, self.max_tile_size as f32 / scale)
}
/// Get all the tiles in the tree
@@ -191,8 +193,8 @@ impl<T> QuadtreeNode<T> {
}
}

/// Get an origin and a width/height for a future tile for a given position in page coords
fn get_tile_rect(&self, x: f32, y: f32, scale: f32, tile_size: f32) -> (Point2D<uint>, uint) {
/// Get a tile rect in screen and page coords for a given position in page coords
fn get_tile_rect(&self, x: f32, y: f32, scale: f32, tile_size: f32) -> (Rect<uint>, Rect<f32>) {
if x >= self.origin.x + self.size || x < self.origin.x
|| y >= self.origin.y + self.size || y < self.origin.y {
fail!("Quadtree: Tried to query a tile rect outside of range");
@@ -202,7 +204,8 @@ impl<T> QuadtreeNode<T> {
let self_x = (self.origin.x * scale).ceil() as uint;
let self_y = (self.origin.y * scale).ceil() as uint;
let self_size = (self.size * scale).ceil() as uint;
return (Point2D(self_x, self_y), self_size);
return (Rect(Point2D(self_x, self_y), Size2D(self_size, self_size)),
Rect(Point2D(self.origin.x, self.origin.y), Size2D(self.size, self.size)));
}

let index = self.get_quadrant(x,y) as int;
@@ -219,7 +222,8 @@ impl<T> QuadtreeNode<T> {
let new_x_pixel = (new_x_page * scale).ceil() as uint;
let new_y_pixel = (new_y_page * scale).ceil() as uint;

(Point2D(new_x_pixel, new_y_pixel), new_size_pixel)
(Rect(Point2D(new_x_pixel, new_y_pixel), Size2D(new_size_pixel, new_size_pixel)),
Rect(Point2D(new_x_page, new_y_page), Size2D(new_size_page, new_size_page)))
}
Some(ref child) => child.get_tile_rect(x, y, scale, tile_size),
}
@@ -20,7 +20,7 @@ pub struct LayerBuffer {
screen_pos: Rect<uint>,

// The scale at which this tile is rendered
resolution: f32, //eschweic
resolution: f32,

// NB: stride is in pixels, like OpenGL GL_UNPACK_ROW_LENGTH.
stride: uint,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.