From d146303f1d7e2247cfa768a6caf2b4deb5e5bf11 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 9 Apr 2020 20:27:24 -0700 Subject: [PATCH 1/2] Dirty canvas when exiting immersive sessions --- components/script/dom/webglrenderingcontext.rs | 2 +- components/script/dom/xrsystem.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index f23ca9f1415..53dff84c6ec 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -503,7 +503,7 @@ impl WebGLRenderingContext { } } - fn mark_as_dirty(&self) { + pub fn mark_as_dirty(&self) { // If we have a bound framebuffer, then don't mark the canvas as dirty. if self.bound_draw_framebuffer.get().is_some() { return; diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 0e2a44f09cb..7bd7f72e8fe 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -3,8 +3,13 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateMethods; +use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionInit; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::{XRSessionMode, XRSystemMethods}; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::{ + XRWebGLLayerMethods, XRWebGLRenderingContext, +}; use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible}; use crate::dom::bindings::error::Error; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; @@ -81,6 +86,17 @@ impl XRSystem { if let Some(active) = self.active_immersive_session.get() { if Dom::from_ref(&*active) == Dom::from_ref(session) { self.active_immersive_session.set(None); + + // Dirty the canvas, since it has been skipping this step whilst in immersive + // mode + if let Some(layer) = session.RenderState().GetBaseLayer() { + match layer.Context() { + XRWebGLRenderingContext::WebGLRenderingContext(c) => c.mark_as_dirty(), + XRWebGLRenderingContext::WebGL2RenderingContext(c) => { + c.base_context().mark_as_dirty() + }, + } + } } } self.active_inline_sessions From 453be48c94ca93ad092300a7e26d7756aed73c0a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 9 Apr 2020 22:48:19 -0700 Subject: [PATCH 2/2] Dirty layers when changing visibility state --- components/script/dom/xrsession.rs | 17 +++++++++++++++++ components/script/dom/xrsystem.rs | 15 +-------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 3396ca669c1..9b05ae1e933 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -14,6 +14,9 @@ use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCal use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRVisibilityState; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionMode; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::{ + XRWebGLLayerMethods, XRWebGLRenderingContext, +}; use crate::dom::bindings::error::{Error, ErrorResult}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::Trusted; @@ -322,6 +325,9 @@ impl XRSession { self, ); event.upcast::().fire(self.upcast()); + // The page may be visible again, dirty the layers + // This also wakes up the event loop if necessary + self.dirty_layers(); }, XREvent::AddInput(info) => { self.input_sources.add_input_sources(self, &[info]); @@ -452,6 +458,17 @@ impl XRSession { pub fn session_id(&self) -> SessionId { self.session.borrow().id() } + + pub fn dirty_layers(&self) { + if let Some(layer) = self.RenderState().GetBaseLayer() { + match layer.Context() { + XRWebGLRenderingContext::WebGLRenderingContext(c) => c.mark_as_dirty(), + XRWebGLRenderingContext::WebGL2RenderingContext(c) => { + c.base_context().mark_as_dirty() + }, + } + } + } } impl XRSessionMethods for XRSession { diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 7bd7f72e8fe..0fc4ab108e2 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -3,13 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateMethods; -use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionInit; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::{XRSessionMode, XRSystemMethods}; -use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::{ - XRWebGLLayerMethods, XRWebGLRenderingContext, -}; use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible}; use crate::dom::bindings::error::Error; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; @@ -86,17 +81,9 @@ impl XRSystem { if let Some(active) = self.active_immersive_session.get() { if Dom::from_ref(&*active) == Dom::from_ref(session) { self.active_immersive_session.set(None); - // Dirty the canvas, since it has been skipping this step whilst in immersive // mode - if let Some(layer) = session.RenderState().GetBaseLayer() { - match layer.Context() { - XRWebGLRenderingContext::WebGLRenderingContext(c) => c.mark_as_dirty(), - XRWebGLRenderingContext::WebGL2RenderingContext(c) => { - c.base_context().mark_as_dirty() - }, - } - } + session.dirty_layers(); } } self.active_inline_sessions