mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Ensure that resized GL contexts do not destroy their resources while in use by WR.
This commit is contained in:
parent
85c1c5ad13
commit
878f020013
8 changed files with 43 additions and 23 deletions
|
@ -9,7 +9,9 @@ use euclid::Size2D;
|
|||
use fnv::FnvHashMap;
|
||||
use gleam::gl;
|
||||
use half::f16;
|
||||
use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods};
|
||||
use offscreen_gl_context::{
|
||||
DrawBuffer, GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods,
|
||||
};
|
||||
use pixels::{self, PixelFormat};
|
||||
use std::borrow::Cow;
|
||||
use std::thread;
|
||||
|
@ -228,6 +230,7 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
|
|||
Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id)
|
||||
.expect("WebGLContext not found in a WebGLMsg::Lock message");
|
||||
let info = self.cached_context_info.get_mut(&context_id).unwrap();
|
||||
info.render_state = ContextRenderState::Locked(None);
|
||||
// Insert a OpenGL Fence sync object that sends a signal when all the WebGL commands are finished.
|
||||
// The related gl().wait_sync call is performed in the WR thread. See WebGLExternalImageApi for mor details.
|
||||
let gl_sync = data.ctx.gl().fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
@ -247,6 +250,7 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
|
|||
Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id)
|
||||
.expect("WebGLContext not found in a WebGLMsg::Unlock message");
|
||||
let info = self.cached_context_info.get_mut(&context_id).unwrap();
|
||||
info.render_state = ContextRenderState::Unlocked;
|
||||
if let Some(gl_sync) = info.gl_sync.take() {
|
||||
// Release the GLSync object.
|
||||
data.ctx.gl().delete_sync(gl_sync);
|
||||
|
@ -299,6 +303,7 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
|
|||
image_key: None,
|
||||
share_mode,
|
||||
gl_sync: None,
|
||||
render_state: ContextRenderState::Unlocked,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -319,9 +324,19 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
|
|||
)
|
||||
.expect("Missing WebGL context!");
|
||||
match data.ctx.resize(size) {
|
||||
Ok(_) => {
|
||||
Ok(old_draw_buffer) => {
|
||||
let (real_size, texture_id, _) = data.ctx.get_info();
|
||||
let info = self.cached_context_info.get_mut(&context_id).unwrap();
|
||||
if let ContextRenderState::Locked(ref mut in_use) = info.render_state {
|
||||
// If there's already an outdated draw buffer present, we can ignore
|
||||
// the newly resized one since it's not in use by the renderer.
|
||||
if in_use.is_none() {
|
||||
// We're resizing the context while WR is actively rendering
|
||||
// it, so we need to retain the GL resources until WR is
|
||||
// finished with them.
|
||||
*in_use = Some(old_draw_buffer);
|
||||
}
|
||||
}
|
||||
// Update webgl texture size. Texture id may change too.
|
||||
info.texture_id = texture_id;
|
||||
info.size = real_size;
|
||||
|
@ -682,6 +697,14 @@ impl<VR: WebVRRenderHandler + 'static> Drop for WebGLThread<VR> {
|
|||
}
|
||||
}
|
||||
|
||||
enum ContextRenderState {
|
||||
/// The context is not being actively rendered.
|
||||
Unlocked,
|
||||
/// The context is actively being rendered. If a DrawBuffer value is present,
|
||||
/// it is outdated but in use as long as the context is locked.
|
||||
Locked(Option<DrawBuffer>),
|
||||
}
|
||||
|
||||
/// Helper struct to store cached WebGLContext information.
|
||||
struct WebGLContextInfo {
|
||||
/// Render to texture identifier used by the WebGLContext.
|
||||
|
@ -696,6 +719,8 @@ struct WebGLContextInfo {
|
|||
share_mode: WebGLContextShareMode,
|
||||
/// GLSync Object used for a correct synchronization with Webrender external image callbacks.
|
||||
gl_sync: Option<gl::GLsync>,
|
||||
/// The status of this context with respect to external consumers.
|
||||
render_state: ContextRenderState,
|
||||
}
|
||||
|
||||
/// This trait is used as a bridge between the `WebGLThreads` implementation and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue