From 4d264a6bc0e47b48f1fe8db7741a59b9c0d8e4b2 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Thu, 17 Jul 2014 15:25:05 -0700 Subject: [PATCH 1/2] Reuse tile textures when appropriate Instead of constantly destroying, recreating, and binding buffers to textures, we should reuse tile textures when the buffer does not change. --- tiling.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tiling.rs b/tiling.rs index a71190a..5872644 100644 --- a/tiling.rs +++ b/tiling.rs @@ -52,6 +52,7 @@ impl Tile { fn replace_buffer(&mut self, buffer: Box) -> Option> { let old_buffer = self.buffer.take(); self.buffer = Some(buffer); + self.texture = Zero::zero(); // The old texture is bound to the old buffer. // TODO: If content_age_of_pending_buffer is None, that means that we were passed // a stale buffer at some point. We could handle this situation more gracefully if @@ -74,6 +75,11 @@ impl Tile { let size = Size2D(buffer.screen_pos.size.width as int, buffer.screen_pos.size.height as int); + // If we already have a texture it should still be valid. + if !self.texture.is_zero() { + return; + } + // Make a new texture and bind the LayerBuffer's surface to it. self.texture = Texture::new_with_buffer(buffer); debug!("Tile: binding to native surface {:d}", From 40b146da16db39e87cf344463ff6d1a6c0deb883 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Fri, 18 Jul 2014 14:10:44 -0700 Subject: [PATCH 2/2] Create textures immediately before compositing This step is fairly cheap and waiting until the last minute, prevents us from creating two textures when content changes twice between composite passes. --- rendergl.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/rendergl.rs b/rendergl.rs index dcf9c5a..48194b3 100755 --- a/rendergl.rs +++ b/rendergl.rs @@ -13,6 +13,7 @@ use scene::Scene; use texturegl::{Flip, NoFlip, VerticalFlip}; use texturegl::{Texture, TextureTarget2D, TextureTargetRectangle}; use tiling::Tile; +use platform::surface::NativeCompositingGraphicsContext; use geom::matrix::{Matrix4, ortho}; use geom::size::Size2D; @@ -142,10 +143,15 @@ pub struct RenderContext { program_2d: Option, program_rectangle: Option, buffers: Buffers, + + /// The platform-specific graphics context. + compositing_context: NativeCompositingGraphicsContext, } impl RenderContext { - fn new(program_2d: Option, program_rectangle: Option) -> RenderContext { + fn new(compositing_context: NativeCompositingGraphicsContext, + program_2d: Option, + program_rectangle: Option) -> RenderContext { let render_context = RenderContext { program_2d: match program_2d { Some(program) => { @@ -175,6 +181,7 @@ impl RenderContext { None => None, }, buffers: RenderContext::init_buffers(), + compositing_context: compositing_context, }; match render_context.program_2d { @@ -231,7 +238,7 @@ pub fn init_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint { #[cfg(target_os="linux")] #[cfg(target_os="macos")] -pub fn init_render_context() -> RenderContext { +pub fn init_render_context(compositing_context: NativeCompositingGraphicsContext) -> RenderContext { use opengles::gl2::TEXTURE_RECTANGLE_ARB; let vertex_2d_shader = load_shader(VERTEX_SHADER_SOURCE, VERTEX_SHADER); @@ -247,11 +254,11 @@ pub fn init_render_context() -> RenderContext { enable(BLEND); blend_func(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); - RenderContext::new(Some(program_2d), Some(program_rectangle)) + RenderContext::new(compositing_context, Some(program_2d), Some(program_rectangle)) } #[cfg(target_os="android")] -pub fn init_render_context() -> RenderContext { +pub fn init_render_context(compositing_context: NativeCompositingGraphicsContext) -> RenderContext { let vertex_2d_shader = load_shader(VERTEX_SHADER_SOURCE, VERTEX_SHADER); let fragment_2d_shader = load_shader(FRAGMENT_2D_SHADER_SOURCE, FRAGMENT_SHADER); let program_2d = init_program(vertex_2d_shader, fragment_2d_shader); @@ -260,7 +267,7 @@ pub fn init_render_context() -> RenderContext { enable(BLEND); blend_func(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); - RenderContext::new(Some(program_2d), None) + RenderContext::new(compositing_context, Some(program_2d), None) } fn bind_texture_coordinate_buffer(render_context: RenderContext, flip: Flip) { @@ -371,6 +378,7 @@ impl Render for layers::Layer { let origin = self.bounds.borrow().origin; let transform = transform.translate(origin.x, origin.y, 0.0).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) });