aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas/webgl_thread.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2019-10-07 11:44:42 -0400
committerJosh Matthews <josh@joshmatthews.net>2019-10-09 10:27:47 -0400
commit4d7110aca53f54c5a9ee2bbbfbe800627c9af249 (patch)
tree0ded5b13477905cf957f2f101ab987d9b1062e73 /components/canvas/webgl_thread.rs
parentbb174275264e48ea91ce85f28829d465e61084bd (diff)
downloadservo-4d7110aca53f54c5a9ee2bbbfbe800627c9af249.tar.gz
servo-4d7110aca53f54c5a9ee2bbbfbe800627c9af249.zip
webgl: Clear the drawing buffer when preserveDrawingBuffer is false.
Diffstat (limited to 'components/canvas/webgl_thread.rs')
-rw-r--r--components/canvas/webgl_thread.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
index f8e63cd1fa3..0e930b1f947 100644
--- a/components/canvas/webgl_thread.rs
+++ b/components/canvas/webgl_thread.rs
@@ -388,6 +388,7 @@ impl WebGLThread {
pub(crate) fn handle_unlock(&mut self, context_id: WebGLContextId) {
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() {
let data = Self::make_current_if_needed(
context_id,
@@ -399,6 +400,32 @@ impl WebGLThread {
data.ctx.gl().delete_sync(gl_sync);
debug_assert!(data.ctx.gl().get_error() == gl::NO_ERROR);
}
+
+ self.clear_drawing_buffer(context_id);
+ }
+
+ fn clear_drawing_buffer(&mut self, context_id: WebGLContextId) {
+ let info = self.cached_context_info.get_mut(&context_id).unwrap();
+ if info.preserve_drawing_buffer {
+ return;
+ }
+
+ let data = Self::make_current_if_needed(
+ context_id,
+ &self.contexts,
+ &mut self.bound_context_id,
+ )
+ .expect("WebGLContext not found when clearing drawing buffer");
+ trace!("clearing GL framebuffer");
+ data.ctx.gl().clear_color(0., 0., 0., 0.);
+ data.ctx.gl().clear_depth(1.0);
+ data.ctx.gl().clear_stencil(0);
+ data.ctx.gl().clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
+
+ let (r, g, b, a) = data.state.clear_color;
+ data.ctx.gl().clear_color(r, g, b, a);
+ data.ctx.gl().clear_depth(data.state.depth_clear_value);
+ data.ctx.gl().clear_stencil(data.state.stencil_clear_value);
}
/// Creates a new WebGLContext
@@ -412,6 +439,8 @@ impl WebGLThread {
// Clear it to ensure that make_current() is called in subsequent commands.
self.bound_context_id = None;
+ let preserve_drawing_buffer = attributes.preserve_drawing_buffer;
+
// First try to create a shared context for the best performance.
// Fallback to readback mode if the shared context creation fails.
let (ctx, share_mode) = self
@@ -456,6 +485,7 @@ impl WebGLThread {
share_mode,
gl_sync: None,
render_state: ContextRenderState::Unlocked,
+ preserve_drawing_buffer,
},
);
@@ -597,6 +627,12 @@ impl WebGLThread {
// Send the ImageKey to the Layout thread.
sender.send(image_key).unwrap();
+
+ if let WebGLContextShareMode::Readback = info.share_mode {
+ // Ensure that the drawing buffer is cleared when webrender isn't involved
+ // in drawing the GL texture.
+ self.clear_drawing_buffer(context_id);
+ }
}
fn handle_dom_to_texture(&mut self, command: DOMToTextureCommand) {
@@ -882,6 +918,8 @@ struct WebGLContextInfo {
gl_sync: Option<gl::GLsync>,
/// The status of this context with respect to external consumers.
render_state: ContextRenderState,
+ /// Should the drawing buffer be preserved between frames?
+ preserve_drawing_buffer: bool,
}
/// Data about the linked DOM<->WebGLTexture elements.