diff --git a/webrender/src/device.rs b/webrender/src/device.rs index b1d97e3b4e..b478d5fba3 100644 --- a/webrender/src/device.rs +++ b/webrender/src/device.rs @@ -1042,6 +1042,10 @@ impl Device { self.raw_textures.insert(texture_id, (x0, y0, width, height)); } + pub fn remove_raw_texture(&mut self, texture_id: TextureId) { + self.raw_textures.remove(&texture_id); + } + fn set_texture_parameters(&mut self, target: gl::GLuint, filter: TextureFilter) { let filter = match filter { TextureFilter::Nearest => { diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs index 92a0895386..16c4b40766 100644 --- a/webrender/src/internal_types.rs +++ b/webrender/src/internal_types.rs @@ -134,6 +134,17 @@ impl GLContextWrapper { } } } + + pub fn resize(&mut self, size: &Size2D) -> Result<(), &'static str> { + match *self { + GLContextWrapper::Native(ref mut ctx) => { + ctx.resize(*size) + } + GLContextWrapper::OSMesa(ref mut ctx) => { + ctx.resize(*size) + } + } + } } pub type DeviceRect = TypedRect; @@ -338,6 +349,7 @@ pub enum TextureUpdateOp { Create(u32, u32, ImageFormat, TextureFilter, RenderTargetMode, Option>), Update(u32, u32, u32, u32, TextureUpdateDetails), Grow(u32, u32, ImageFormat, TextureFilter, RenderTargetMode), + Remove } pub struct TextureUpdate { diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index 06f061dbe1..dca700a447 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -303,6 +303,21 @@ impl RenderBackend { tx.send(Err("Not implemented yet".to_owned())).unwrap(); } } + ApiMsg::ResizeWebGLContext(context_id, size) => { + let ctx = self.webgl_contexts.get_mut(&context_id).unwrap(); + ctx.make_current(); + match ctx.resize(&size) { + Ok(_) => { + // Update webgl texture size. Texture id may change too. + let (real_size, texture_id, _) = ctx.get_info(); + self.resource_cache + .update_webgl_texture(context_id, TextureId::new(texture_id), real_size); + }, + Err(msg) => { + error!("Error resizing WebGLContext: {}", msg); + } + } + } ApiMsg::WebGLCommand(context_id, command) => { // TODO: Buffer the commands and only apply them here if they need to // be synchronous. diff --git a/webrender/src/renderer.rs b/webrender/src/renderer.rs index 3412040547..4c25cb9245 100644 --- a/webrender/src/renderer.rs +++ b/webrender/src/renderer.rs @@ -1033,6 +1033,9 @@ impl Renderer { } } } + TextureUpdateOp::Remove => { + self.device.remove_raw_texture(update.id); + } } } } diff --git a/webrender/src/resource_cache.rs b/webrender/src/resource_cache.rs index 800a3681a4..2f44bc142d 100644 --- a/webrender/src/resource_cache.rs +++ b/webrender/src/resource_cache.rs @@ -216,6 +216,18 @@ impl ResourceCache { self.texture_cache.add_raw_update(texture_id, size); } + pub fn update_webgl_texture(&mut self, id: WebGLContextId, texture_id: TextureId, size: Size2D) { + let prev_texture_id = *self.webgl_textures.get(&id).unwrap(); + + // Remove existing cache if texture id has changed + if prev_texture_id != texture_id { + self.texture_cache.add_raw_remove(prev_texture_id); + } + // Update new texture id and size + self.webgl_textures.insert(id, texture_id); + self.texture_cache.add_raw_update(texture_id, size); + } + pub fn add_resource_list(&mut self, resource_list: &ResourceList, frame_id: FrameId) { // Update texture cache with any images that aren't yet uploaded to GPU. resource_list.for_each_image(|image_key, image_rendering| { diff --git a/webrender/src/texture_cache.rs b/webrender/src/texture_cache.rs index 5f6f906c0b..c4db3138f9 100644 --- a/webrender/src/texture_cache.rs +++ b/webrender/src/texture_cache.rs @@ -779,6 +779,13 @@ impl TextureCache { }) } + pub fn add_raw_remove(&mut self, id: TextureId) { + self.pending_updates.push(TextureUpdate { + id: id, + op: TextureUpdateOp::Remove + }); + } + pub fn update(&mut self, image_id: TextureCacheItemId, width: u32, diff --git a/webrender_traits/src/api.rs b/webrender_traits/src/api.rs index 2e949faadd..287516054b 100644 --- a/webrender_traits/src/api.rs +++ b/webrender_traits/src/api.rs @@ -229,6 +229,11 @@ impl RenderApi { rx.recv().unwrap() } + pub fn resize_webgl_context(&self, context_id: WebGLContextId, size: &Size2D) { + let msg = ApiMsg::ResizeWebGLContext(context_id, *size); + self.api_sender.send(msg).unwrap(); + } + pub fn send_webgl_command(&self, context_id: WebGLContextId, command: WebGLCommand) { let msg = ApiMsg::WebGLCommand(context_id, command); self.api_sender.send(msg).unwrap(); diff --git a/webrender_traits/src/types.rs b/webrender_traits/src/types.rs index e425ca929c..d84ae39c02 100644 --- a/webrender_traits/src/types.rs +++ b/webrender_traits/src/types.rs @@ -55,6 +55,7 @@ pub enum ApiMsg { TranslatePointToLayerSpace(Point2D, IpcSender<(Point2D, PipelineId)>), GetScrollLayerState(IpcSender>), RequestWebGLContext(Size2D, GLContextAttributes, IpcSender>), + ResizeWebGLContext(WebGLContextId, Size2D), WebGLCommand(WebGLContextId, WebGLCommand), }