11/* This Source Code Form is subject to the terms of the Mozilla Public
22 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4-
54use crate :: gl_context:: GLContextFactory ;
65use crate :: webgl_thread:: { WebGLMainThread , WebGLThread , WebGLThreadInit } ;
76use canvas_traits:: webgl:: webgl_channel;
@@ -17,6 +16,7 @@ use std::default::Default;
1716use std:: rc:: Rc ;
1817use std:: sync:: { Arc , Mutex } ;
1918use webrender_traits:: { WebrenderExternalImageApi , WebrenderExternalImageRegistry } ;
19+ use webxr_api:: WebGLExternalImageApi ;
2020
2121/// WebGL Threading API entry point that lives in the constellation.
2222pub struct WebGLThreads ( WebGLSender < WebGLMsg > ) ;
@@ -38,6 +38,7 @@ impl WebGLThreads {
3838 ) -> (
3939 WebGLThreads ,
4040 Option < Rc < WebGLMainThread > > ,
41+ Box < dyn webxr_api:: WebGLExternalImageApi > ,
4142 Box < dyn WebrenderExternalImageApi > ,
4243 Option < Box < dyn webrender:: OutputImageHandler > > ,
4344 ) {
@@ -77,6 +78,7 @@ impl WebGLThreads {
7778 (
7879 WebGLThreads ( sender) ,
7980 webgl_thread,
81+ external. sendable . clone_box ( ) ,
8082 Box :: new ( external) ,
8183 output_handler. map ( |b| b as Box < _ > ) ,
8284 )
@@ -96,9 +98,8 @@ impl WebGLThreads {
9698 }
9799}
98100
99- /// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
100- struct WebGLExternalImages {
101- webrender_gl : Rc < dyn gl:: Gl > ,
101+ /// Bridge between the webxr_api::ExternalImage callbacks and the WebGLThreads.
102+ struct SendableWebGLExternalImages {
102103 webgl_channel : WebGLSender < WebGLMsg > ,
103104 // Used to avoid creating a new channel on each received WebRender request.
104105 lock_channel : (
@@ -107,24 +108,26 @@ struct WebGLExternalImages {
107108 ) ,
108109}
109110
110- impl WebGLExternalImages {
111- fn new ( webrender_gl : Rc < dyn gl:: Gl > , channel : WebGLSender < WebGLMsg > ) -> Self {
112- WebGLExternalImages {
113- webrender_gl,
111+ impl SendableWebGLExternalImages {
112+ fn new ( channel : WebGLSender < WebGLMsg > ) -> Self {
113+ Self {
114114 webgl_channel : channel,
115115 lock_channel : webgl_channel ( ) . unwrap ( ) ,
116116 }
117117 }
118118}
119119
120- impl WebrenderExternalImageApi for WebGLExternalImages {
121- fn lock ( & mut self , id : u64 ) -> ( u32 , Size2D < i32 > ) {
120+ impl webxr_api :: WebGLExternalImageApi for SendableWebGLExternalImages {
121+ fn lock ( & self , id : usize ) -> ( u32 , Size2D < i32 > , Option < gl :: GLsync > ) {
122122 if let Some ( main_thread) = WebGLMainThread :: on_current_thread ( ) {
123123 // If we're on the same thread as WebGL, we can get the data directly
124- main_thread
124+ let ( image_id , size ) = main_thread
125125 . thread_data
126126 . borrow_mut ( )
127- . handle_lock_unsync ( WebGLContextId ( id as usize ) )
127+ . handle_lock_unsync ( WebGLContextId ( id as usize ) ) ;
128+ // We don't need a GLsync object if we're running on the main thread
129+ // Might be better to return an option?
130+ ( image_id, size, None )
128131 } else {
129132 // WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue.
130133 // The WebGLMsg::Lock message inserts a fence in the WebGL command queue.
@@ -135,16 +138,11 @@ impl WebrenderExternalImageApi for WebGLExternalImages {
135138 ) )
136139 . unwrap ( ) ;
137140 let ( image_id, size, gl_sync) = self . lock_channel . 1 . recv ( ) . unwrap ( ) ;
138- // The next glWaitSync call is run on the WR thread and it's used to synchronize the two
139- // flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture.
140- // glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem.
141- self . webrender_gl
142- . wait_sync ( gl_sync as gl:: GLsync , 0 , gl:: TIMEOUT_IGNORED ) ;
143- ( image_id, size)
141+ ( image_id, size, Some ( gl_sync as gl:: GLsync ) )
144142 }
145143 }
146144
147- fn unlock ( & mut self , id : u64 ) {
145+ fn unlock ( & self , id : usize ) {
148146 if let Some ( main_thread) = WebGLMainThread :: on_current_thread ( ) {
149147 // If we're on the same thread as WebGL, we can unlock directly
150148 main_thread
@@ -157,6 +155,42 @@ impl WebrenderExternalImageApi for WebGLExternalImages {
157155 . unwrap ( )
158156 }
159157 }
158+
159+ fn clone_box ( & self ) -> Box < dyn webxr_api:: WebGLExternalImageApi > {
160+ Box :: new ( Self :: new ( self . webgl_channel . clone ( ) ) )
161+ }
162+ }
163+
164+ /// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
165+ struct WebGLExternalImages {
166+ webrender_gl : Rc < dyn gl:: Gl > ,
167+ sendable : SendableWebGLExternalImages ,
168+ }
169+
170+ impl WebGLExternalImages {
171+ fn new ( webrender_gl : Rc < dyn gl:: Gl > , channel : WebGLSender < WebGLMsg > ) -> Self {
172+ Self {
173+ webrender_gl,
174+ sendable : SendableWebGLExternalImages :: new ( channel) ,
175+ }
176+ }
177+ }
178+
179+ impl WebrenderExternalImageApi for WebGLExternalImages {
180+ fn lock ( & mut self , id : u64 ) -> ( u32 , Size2D < i32 > ) {
181+ let ( image_id, size, gl_sync) = self . sendable . lock ( id as usize ) ;
182+ // The next glWaitSync call is run on the WR thread and it's used to synchronize the two
183+ // flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture.
184+ // glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem.
185+ if let Some ( gl_sync) = gl_sync {
186+ self . webrender_gl . wait_sync ( gl_sync, 0 , gl:: TIMEOUT_IGNORED ) ;
187+ }
188+ ( image_id, size)
189+ }
190+
191+ fn unlock ( & mut self , id : u64 ) {
192+ self . sendable . unlock ( id as usize ) ;
193+ }
160194}
161195
162196/// struct used to implement DOMToTexture feature and webrender::OutputImageHandler trait.
0 commit comments