mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Reuse WebGL ImageKeys after a resize.
This commit is contained in:
parent
174c37fddd
commit
21f8b519c3
2 changed files with 43 additions and 41 deletions
|
@ -8,7 +8,6 @@ use euclid::Size2D;
|
|||
use fnv::FnvHashMap;
|
||||
use gleam::gl;
|
||||
use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods};
|
||||
use std::mem;
|
||||
use std::thread;
|
||||
use super::gl_context::{GLContextFactory, GLContextWrapper};
|
||||
use webrender;
|
||||
|
@ -202,8 +201,6 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
image_key: None,
|
||||
share_mode,
|
||||
gl_sync: None,
|
||||
old_image_key: None,
|
||||
very_old_image_key: None,
|
||||
});
|
||||
|
||||
self.observer.on_context_create(id, texture_id, size);
|
||||
|
@ -231,13 +228,18 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
// Update webgl texture size. Texture id may change too.
|
||||
info.texture_id = texture_id;
|
||||
info.size = real_size;
|
||||
// WR doesn't support resizing and requires to create a new `ImageKey`.
|
||||
// Mark the current image_key to be deleted later in the next epoch.
|
||||
if let Some(image_key) = info.image_key.take() {
|
||||
// If this executes, then we are in a new epoch since we last recreated the canvas,
|
||||
// so `old_image_key` must be `None`.
|
||||
debug_assert!(info.old_image_key.is_none());
|
||||
info.old_image_key = Some(image_key);
|
||||
// Update WR image if needed. Resize image updates are only required for SharedTexture mode.
|
||||
// Readback mode already updates the image every frame to send the raw pixels.
|
||||
// See `handle_update_wr_image`.
|
||||
match (info.image_key, info.share_mode) {
|
||||
(Some(image_key), WebGLContextShareMode::SharedTexture) => {
|
||||
Self::update_wr_external_image(&self.webrender_api,
|
||||
info.size,
|
||||
info.alpha,
|
||||
context_id,
|
||||
image_key);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
sender.send(Ok(())).unwrap();
|
||||
|
@ -257,12 +259,6 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
if let Some(image_key) = info.image_key {
|
||||
updates.delete_image(image_key);
|
||||
}
|
||||
if let Some(image_key) = info.old_image_key {
|
||||
updates.delete_image(image_key);
|
||||
}
|
||||
if let Some(image_key) = info.very_old_image_key {
|
||||
updates.delete_image(image_key);
|
||||
}
|
||||
|
||||
self.webrender_api.update_resources(updates)
|
||||
}
|
||||
|
@ -276,9 +272,9 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
self.bound_context_id = None;
|
||||
}
|
||||
|
||||
/// Handles the creation/update of webrender_api::ImageKeys fpr a specific WebGLContext.
|
||||
/// Handles the creation/update of webrender_api::ImageKeys for a specific WebGLContext.
|
||||
/// This method is invoked from a UpdateWebRenderImage message sent by the layout thread.
|
||||
/// If SharedTexture is used the UpdateWebRenderImage message is sent only after a WebGLContext creation or resize.
|
||||
/// If SharedTexture is used the UpdateWebRenderImage message is sent only after a WebGLContext creation.
|
||||
/// If Readback is used UpdateWebRenderImage message is sent always on each layout iteration in order to
|
||||
/// submit the updated raw pixels.
|
||||
fn handle_update_wr_image(&mut self, context_id: WebGLContextId, sender: WebGLSender<webrender_api::ImageKey>) {
|
||||
|
@ -290,7 +286,7 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
let size = info.size;
|
||||
let alpha = info.alpha;
|
||||
// Reuse existing ImageKey or generate a new one.
|
||||
// When using a shared texture ImageKeys are only generated after a WebGLContext creation or resize.
|
||||
// When using a shared texture ImageKeys are only generated after a WebGLContext creation.
|
||||
*info.image_key.get_or_insert_with(|| {
|
||||
Self::create_wr_external_image(webrender_api, size, alpha, context_id)
|
||||
})
|
||||
|
@ -322,13 +318,6 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
}
|
||||
};
|
||||
|
||||
// Delete old image
|
||||
if let Some(image_key) = mem::replace(&mut info.very_old_image_key, info.old_image_key.take()) {
|
||||
let mut updates = webrender_api::ResourceUpdates::new();
|
||||
updates.delete_image(image_key);
|
||||
self.webrender_api.update_resources(updates);
|
||||
}
|
||||
|
||||
// Send the ImageKey to the Layout thread.
|
||||
sender.send(image_key).unwrap();
|
||||
}
|
||||
|
@ -365,13 +354,7 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
alpha: bool,
|
||||
context_id: WebGLContextId) -> webrender_api::ImageKey {
|
||||
let descriptor = Self::image_descriptor(size, alpha);
|
||||
|
||||
let data = webrender_api::ExternalImageData {
|
||||
id: webrender_api::ExternalImageId(context_id.0 as u64),
|
||||
channel_index: 0,
|
||||
image_type: webrender_api::ExternalImageType::Texture2DHandle,
|
||||
};
|
||||
let data = webrender_api::ImageData::External(data);
|
||||
let data = Self::external_image_data(context_id);
|
||||
|
||||
let image_key = webrender_api.generate_image_key();
|
||||
let mut updates = webrender_api::ResourceUpdates::new();
|
||||
|
@ -384,6 +367,23 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
image_key
|
||||
}
|
||||
|
||||
/// Updates a `webrender_api::ImageKey` that uses shared textures.
|
||||
fn update_wr_external_image(webrender_api: &webrender_api::RenderApi,
|
||||
size: Size2D<i32>,
|
||||
alpha: bool,
|
||||
context_id: WebGLContextId,
|
||||
image_key: webrender_api::ImageKey) {
|
||||
let descriptor = Self::image_descriptor(size, alpha);
|
||||
let data = Self::external_image_data(context_id);
|
||||
|
||||
let mut updates = webrender_api::ResourceUpdates::new();
|
||||
updates.update_image(image_key,
|
||||
descriptor,
|
||||
data,
|
||||
None);
|
||||
webrender_api.update_resources(updates);
|
||||
}
|
||||
|
||||
/// Creates a `webrender_api::ImageKey` that uses raw pixels.
|
||||
fn create_wr_readback_image(webrender_api: &webrender_api::RenderApi,
|
||||
size: Size2D<i32>,
|
||||
|
@ -432,6 +432,16 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper function to create a `webrender_api::ImageData::External` instance.
|
||||
fn external_image_data(context_id: WebGLContextId) -> webrender_api::ImageData {
|
||||
let data = webrender_api::ExternalImageData {
|
||||
id: webrender_api::ExternalImageId(context_id.0 as u64),
|
||||
channel_index: 0,
|
||||
image_type: webrender_api::ExternalImageType::Texture2DHandle,
|
||||
};
|
||||
webrender_api::ImageData::External(data)
|
||||
}
|
||||
|
||||
/// Helper function to fetch the raw pixels used in readback mode.
|
||||
fn raw_pixels(context: &GLContextWrapper, size: Size2D<i32>) -> Vec<u8> {
|
||||
let width = size.width as usize;
|
||||
|
@ -479,10 +489,6 @@ struct WebGLContextInfo {
|
|||
share_mode: WebGLContextShareMode,
|
||||
/// GLSync Object used for a correct synchronization with Webrender external image callbacks.
|
||||
gl_sync: Option<gl::GLsync>,
|
||||
/// An old WebRender image key that can be deleted when the next epoch ends.
|
||||
old_image_key: Option<webrender_api::ImageKey>,
|
||||
/// An old WebRender image key that can be deleted when the current epoch ends.
|
||||
very_old_image_key: Option<webrender_api::ImageKey>,
|
||||
}
|
||||
|
||||
/// Trait used to observe events in a WebGL Thread.
|
||||
|
|
|
@ -264,10 +264,6 @@ impl WebGLRenderingContext {
|
|||
return;
|
||||
};
|
||||
|
||||
// Reset webrender_image because resize creates a new image_key.
|
||||
// The new image key is set in the next handle_layout() method.
|
||||
self.webrender_image.set(None);
|
||||
|
||||
// ClearColor needs to be restored because after a resize the GLContext is recreated
|
||||
// and the framebuffer is cleared using the default black transparent color.
|
||||
let color = self.current_clear_color.get();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue