aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/trace.rs5
-rw-r--r--components/script/dom/document.rs22
-rw-r--r--components/script/dom/webglrenderingcontext.rs46
-rw-r--r--components/script/dom/window.rs7
4 files changed, 46 insertions, 34 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 5fbc9629f68..e86c96e0a9e 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -48,7 +48,9 @@ use canvas_traits::canvas::{CompositionOrBlending, LineCapStyle, LineJoinStyle,
use canvas_traits::webgl::WebGLVertexArrayId;
use canvas_traits::webgl::{ActiveAttribInfo, ActiveUniformInfo, GlType, TexDataType, TexFormat};
use canvas_traits::webgl::{GLFormats, GLLimits, WebGLQueryId, WebGLSamplerId};
-use canvas_traits::webgl::{WebGLBufferId, WebGLChan, WebGLContextShareMode, WebGLError};
+use canvas_traits::webgl::{
+ WebGLBufferId, WebGLChan, WebGLContextId, WebGLContextShareMode, WebGLError,
+};
use canvas_traits::webgl::{WebGLFramebufferId, WebGLMsgSender, WebGLPipeline, WebGLProgramId};
use canvas_traits::webgl::{WebGLReceiver, WebGLRenderbufferId, WebGLSLVersion, WebGLSender};
use canvas_traits::webgl::{WebGLShaderId, WebGLSyncId, WebGLTextureId, WebGLVersion};
@@ -519,6 +521,7 @@ unsafe_no_jsmanaged_fields!(Rect<f32>);
unsafe_no_jsmanaged_fields!(CascadeData);
unsafe_no_jsmanaged_fields!(WindowGLContext);
unsafe_no_jsmanaged_fields!(Frame);
+unsafe_no_jsmanaged_fields!(WebGLContextId);
unsafe impl<'a> JSTraceable for &'a str {
#[inline]
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index da44169ce59..452212a2b3c 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -109,6 +109,7 @@ use crate::stylesheet_set::StylesheetSetRef;
use crate::task::TaskBox;
use crate::task_source::{TaskSource, TaskSourceName};
use crate::timers::OneshotTimerCallback;
+use canvas_traits::webgl::{self, WebGLContextId, WebGLMsg};
use cookie::Cookie;
use devtools_traits::ScriptToDevtoolsControlMsg;
use dom_struct::dom_struct;
@@ -395,6 +396,8 @@ pub struct Document {
/// where `id` needs to match any of the registered ShadowRoots
/// hosting the media controls UI.
media_controls: DomRefCell<HashMap<String, Dom<ShadowRoot>>>,
+ /// List of all WebGL context IDs that need flushing.
+ dirty_webgl_contexts: DomRefCell<HashSet<WebGLContextId>>,
}
#[derive(JSTraceable, MallocSizeOf)]
@@ -2490,6 +2493,24 @@ impl Document {
debug_assert!(false, "Trying to unregister unknown media controls");
}
}
+
+ pub fn add_dirty_canvas(&self, context_id: WebGLContextId) {
+ self.dirty_webgl_contexts.borrow_mut().insert(context_id);
+ }
+
+ pub fn flush_dirty_canvases(&self) {
+ let dirty_context_ids: Vec<_> = self.dirty_webgl_contexts.borrow_mut().drain().collect();
+ if dirty_context_ids.is_empty() {
+ return;
+ }
+ let (sender, receiver) = webgl::webgl_channel().unwrap();
+ self.window
+ .webgl_chan()
+ .expect("Where's the WebGL channel?")
+ .send(WebGLMsg::SwapBuffers(dirty_context_ids, sender))
+ .unwrap();
+ receiver.recv().unwrap();
+ }
}
#[derive(MallocSizeOf, PartialEq)]
@@ -2784,6 +2805,7 @@ impl Document {
shadow_roots: DomRefCell::new(HashSet::new()),
shadow_roots_styles_changed: Cell::new(false),
media_controls: DomRefCell::new(HashMap::new()),
+ dirty_webgl_contexts: DomRefCell::new(HashSet::new()),
}
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 06141d5b5e7..f19664ad0ad 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -81,7 +81,6 @@ use std::cell::Cell;
use std::cmp;
use std::ptr::{self, NonNull};
use std::rc::Rc;
-use webrender_api::ImageKey;
// From the GLES 2.0.25 spec, page 85:
//
@@ -130,7 +129,7 @@ pub struct WebGLRenderingContext {
#[ignore_malloc_size_of = "Channels are hard"]
webgl_sender: WebGLMessageSender,
#[ignore_malloc_size_of = "Defined in webrender"]
- webrender_image: Cell<Option<webrender_api::ImageKey>>,
+ webrender_image: webrender_api::ImageKey,
share_mode: WebGLContextShareMode,
webgl_version: WebGLVersion,
glsl_version: WebGLSLVersion,
@@ -195,7 +194,7 @@ impl WebGLRenderingContext {
ctx_data.sender,
window.get_event_loop_waker(),
),
- webrender_image: Cell::new(None),
+ webrender_image: ctx_data.image_key,
share_mode: ctx_data.share_mode,
webgl_version,
glsl_version: ctx_data.glsl_version,
@@ -453,13 +452,17 @@ impl WebGLRenderingContext {
}
fn mark_as_dirty(&self) {
- // If we don't have a bound framebuffer, then don't mark the canvas
- // as dirty.
- if self.bound_framebuffer.get().is_none() {
- self.canvas
- .upcast::<Node>()
- .dirty(NodeDamage::OtherNodeDamage);
+ // If we have a bound framebuffer, then don't mark the canvas as dirty.
+ if self.bound_framebuffer.get().is_some() {
+ return;
}
+
+ self.canvas
+ .upcast::<Node>()
+ .dirty(NodeDamage::OtherNodeDamage);
+
+ let document = document_from_node(&*self.canvas);
+ document.add_dirty_canvas(self.context_id());
}
fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) {
@@ -808,26 +811,7 @@ impl WebGLRenderingContext {
}
pub fn layout_handle(&self) -> webrender_api::ImageKey {
- match self.share_mode {
- WebGLContextShareMode::SharedTexture => {
- // WR using ExternalTexture requires a single update message.
- self.webrender_image.get().unwrap_or_else(|| {
- let (sender, receiver) = webgl_channel().unwrap();
- self.webgl_sender.send_update_wr_image(sender).unwrap();
- let image_key = receiver.recv().unwrap();
- self.webrender_image.set(Some(image_key));
-
- image_key
- })
- },
- WebGLContextShareMode::Readback => {
- // WR using Readback requires to update WR image every frame
- // in order to send the new raw pixels.
- let (sender, receiver) = webgl_channel().unwrap();
- self.webgl_sender.send_update_wr_image(sender).unwrap();
- receiver.recv().unwrap()
- },
- }
+ self.webrender_image
}
// https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/
@@ -4438,10 +4422,6 @@ impl WebGLMessageSender {
self.wake_after_send(|| self.sender.send_remove())
}
- pub fn send_update_wr_image(&self, sender: WebGLSender<ImageKey>) -> WebGLSendResult {
- self.wake_after_send(|| self.sender.send_update_wr_image(sender))
- }
-
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
self.wake_after_send(|| self.sender.send_dom_to_texture(command))
}
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 8e139158427..565308ff36f 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -1520,6 +1520,13 @@ impl Window {
let stylesheets_changed = document.flush_stylesheets_for_reflow();
+ // If this reflow is for display, ensure webgl canvases are composited with
+ // up-to-date contents.
+ match reflow_goal {
+ ReflowGoal::Full => document.flush_dirty_canvases(),
+ ReflowGoal::TickAnimations | ReflowGoal::LayoutQuery(..) => {},
+ }
+
// Send new document and relevant styles to layout.
let needs_display = reflow_goal.needs_display();
let reflow = ScriptReflow {