From 755f2b8c551dbe8f9c9ee2feb7b767e170588c35 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Thu, 11 Sep 2014 10:45:18 -0700 Subject: [PATCH] Store content offset in unscaled pixels This is necessary because the renderer pre-scales the scene when applying content offset. We also store a scene scale instead of a scene transformation, so that we know how to properly deal with device pixels. Also ensures that content offset is not accumulated when rendering layers. --- src/layers.rs | 8 ++++---- src/rendergl.rs | 17 +++++++++-------- src/scene.rs | 12 ++++++++---- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/layers.rs b/src/layers.rs index 1a7b479..4a55219 100644 --- a/src/layers.rs +++ b/src/layers.rs @@ -12,7 +12,7 @@ use tiling::{Tile, TileGrid}; use geom::matrix::{Matrix4, identity}; use geom::size::{Size2D, TypedSize2D}; -use geom::point::TypedPoint2D; +use geom::point::Point2D; use geom::rect::{Rect, TypedRect}; use platform::surface::{NativeSurfaceMethods, NativeSurface}; use platform::surface::{NativeCompositingGraphicsContext, NativePaintingGraphicsContext}; @@ -49,8 +49,8 @@ pub struct Layer { /// A monotonically increasing counter that keeps track of the current content age. pub content_age: RefCell, - /// The content offset for this layer in device pixels. - pub content_offset: RefCell>, + /// The content offset for this layer in unscaled layer pixels. + pub content_offset: RefCell>, } impl Layer { @@ -63,7 +63,7 @@ impl Layer { extra_data: RefCell::new(data), tile_grid: RefCell::new(TileGrid::new(tile_size)), content_age: RefCell::new(ContentAge::new()), - content_offset: RefCell::new(TypedPoint2D(0f32, 0f32)), + content_offset: RefCell::new(Point2D(0f32, 0f32)), } } diff --git a/src/rendergl.rs b/src/rendergl.rs index 5ed3200..13495cd 100755 --- a/src/rendergl.rs +++ b/src/rendergl.rs @@ -16,7 +16,7 @@ use texturegl::{Texture, TextureTarget2D, TextureTargetRectangle}; use tiling::Tile; use platform::surface::NativeCompositingGraphicsContext; -use geom::matrix::{Matrix4, ortho}; +use geom::matrix::{Matrix4, identity, ortho}; use geom::size::Size2D; use libc::c_int; use opengles::gl2::{ARRAY_BUFFER, BLEND, COLOR_BUFFER_BIT, COMPILE_STATUS, FRAGMENT_SHADER}; @@ -496,12 +496,12 @@ impl Render for layers::Layer { transform: Matrix4, scene_size: Size2D) { let bounds = self.bounds.borrow().to_untyped(); - let transform = transform.translate(bounds.origin.x, bounds.origin.y, 0.0) - .mul(&*self.transform.borrow()); + let cumulative_transform = transform.translate(bounds.origin.x, bounds.origin.y, 0.0); + let tile_transform = cumulative_transform.mul(&*self.transform.borrow()); self.create_textures(&render_context.compositing_context); self.do_for_all_tiles(|tile: &Tile| { - tile.render(render_context, transform, scene_size) + tile.render(render_context, tile_transform, scene_size) }); if render_context.show_debug_borders { @@ -514,7 +514,7 @@ impl Render for layers::Layer { } for child in self.children().iter() { - child.render(render_context, transform, scene_size) + child.render(render_context, cumulative_transform, scene_size) } } @@ -542,8 +542,9 @@ impl Render for Tile { } } -pub fn render_scene(root_layer: Rc>, render_context: RenderContext, - scene: &Scene) { +pub fn render_scene(root_layer: Rc>, + render_context: RenderContext, + scene: &Scene) { // Set the viewport. viewport(0 as GLint, 0 as GLint, scene.size.width as GLsizei, scene.size.height as GLsizei); @@ -555,7 +556,7 @@ pub fn render_scene(root_layer: Rc>, render_context: RenderContext, clear(COLOR_BUFFER_BIT); // Set up the initial modelview matrix. - let transform = scene.transform; + let transform = identity().scale(scene.scale, scene.scale, 1.0); // Render the root layer. root_layer.render(render_context, transform, scene.size); diff --git a/src/scene.rs b/src/scene.rs index 94989b5..5e6647d 100755 --- a/src/scene.rs +++ b/src/scene.rs @@ -20,17 +20,18 @@ use std::rc::Rc; pub struct Scene { pub root: Option>>, pub size: Size2D, - pub transform: Matrix4, pub background_color: Color, pub unused_buffers: Vec>, + + /// The scene scale, to allow for zooming and high-resolution painting. + pub scale: f32, } impl Scene { - pub fn new(size: Size2D, transform: Matrix4) -> Scene { + pub fn new(size: Size2D) -> Scene { Scene { root: None, size: size, - transform: transform, background_color: Color { r: 0.38f32, g: 0.36f32, @@ -38,6 +39,7 @@ impl Scene { a: 1.0f32 }, unused_buffers: Vec::new(), + scale: 1., } } @@ -46,9 +48,11 @@ impl Scene { layers_and_requests: &mut Vec<(Rc>, Vec)>, rect_in_window: TypedRect) { + let content_offset = *layer.content_offset.borrow() * self.scale; + let content_offset = Point2D::from_untyped(&content_offset); + // The rectangle passed in is in the coordinate system of our parent, so we // need to intersect with our boundaries and convert it to our coordinate system. - let content_offset = layer.content_offset.borrow(); let layer_bounds = layer.bounds.borrow().clone(); let layer_rect = Rect(Point2D(rect_in_window.origin.x - content_offset.x, rect_in_window.origin.y - content_offset.y),