mirror of
https://github.com/servo/servo.git
synced 2025-09-02 02:58:22 +01:00
Remove the DOMToTexture feature
This relies on WebRender's frame output API, `set_output_image_handler`, which has been removed from the latest upstream [1]. It's sad to remove this feature, which was probably a lot of work to implement, but it seems difficult to patch WebRender to restore this functionality. Fixes #29936. 1. https://hg.mozilla.org/mozilla-central/rev/361521e3c52324809553c555fb066d50f023d9bf
This commit is contained in:
parent
234d507234
commit
ec3b2826ae
10 changed files with 36 additions and 304 deletions
|
@ -7,12 +7,8 @@ use canvas_traits::webgl::webgl_channel;
|
|||
use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads};
|
||||
use euclid::default::Size2D;
|
||||
use fnv::FnvHashMap;
|
||||
use gleam;
|
||||
use servo_config::pref;
|
||||
use sparkle::gl;
|
||||
use sparkle::gl::GlType;
|
||||
use std::default::Default;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use surfman::Device;
|
||||
use surfman::SurfaceInfo;
|
||||
|
@ -30,7 +26,6 @@ use webxr_api::LayerGrandManager as WebXRLayerGrandManager;
|
|||
pub struct WebGLComm {
|
||||
pub webgl_threads: WebGLThreads,
|
||||
pub image_handler: Box<dyn WebrenderExternalImageApi>,
|
||||
pub output_handler: Option<Box<dyn webrender_api::OutputImageHandler>>,
|
||||
pub webxr_layer_grand_manager: WebXRLayerGrandManager<WebXRSurfman>,
|
||||
}
|
||||
|
||||
|
@ -38,7 +33,6 @@ impl WebGLComm {
|
|||
/// Creates a new `WebGLComm` object.
|
||||
pub fn new(
|
||||
surfman: WebrenderSurfman,
|
||||
webrender_gl: Rc<dyn gleam::gl::Gl>,
|
||||
webrender_api_sender: webrender_api::RenderApiSender,
|
||||
webrender_doc: webrender_api::DocumentId,
|
||||
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||
|
@ -64,12 +58,6 @@ impl WebGLComm {
|
|||
webxr_init,
|
||||
};
|
||||
|
||||
let output_handler = if pref!(dom.webgl.dom_to_texture.enabled) {
|
||||
Some(Box::new(OutputHandler::new(webrender_gl.clone())))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let external = WebGLExternalImages::new(surfman, webrender_swap_chains);
|
||||
|
||||
WebGLThread::run_on_own_thread(init);
|
||||
|
@ -77,7 +65,6 @@ impl WebGLComm {
|
|||
WebGLComm {
|
||||
webgl_threads: WebGLThreads(sender),
|
||||
image_handler: Box::new(external),
|
||||
output_handler: output_handler.map(|b| b as Box<_>),
|
||||
webxr_layer_grand_manager: webxr_layer_grand_manager,
|
||||
}
|
||||
}
|
||||
|
@ -144,43 +131,3 @@ impl WebrenderExternalImageApi for WebGLExternalImages {
|
|||
self.unlock_swap_chain(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// struct used to implement DOMToTexture feature and webrender::OutputImageHandler trait.
|
||||
struct OutputHandler {
|
||||
webrender_gl: Rc<dyn gleam::gl::Gl>,
|
||||
sync_objects: FnvHashMap<webrender_api::PipelineId, gleam::gl::GLsync>,
|
||||
}
|
||||
|
||||
impl OutputHandler {
|
||||
fn new(webrender_gl: Rc<dyn gleam::gl::Gl>) -> Self {
|
||||
OutputHandler {
|
||||
webrender_gl,
|
||||
sync_objects: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Bridge between the WR frame outputs and WebGL to implement DOMToTexture synchronization.
|
||||
impl webrender_api::OutputImageHandler for OutputHandler {
|
||||
fn lock(
|
||||
&mut self,
|
||||
id: webrender_api::PipelineId,
|
||||
) -> Option<(u32, webrender_api::units::FramebufferIntSize)> {
|
||||
// Insert a fence in the WR command queue
|
||||
let gl_sync = self
|
||||
.webrender_gl
|
||||
.fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
self.sync_objects.insert(id, gl_sync);
|
||||
// https://github.com/servo/servo/issues/24615
|
||||
None
|
||||
}
|
||||
|
||||
fn unlock(&mut self, id: webrender_api::PipelineId) {
|
||||
if let Some(gl_sync) = self.sync_objects.remove(&id) {
|
||||
// Flush the Sync object into the GPU's command queue to guarantee that it it's signaled.
|
||||
self.webrender_gl.flush();
|
||||
// Mark the sync object for deletion.
|
||||
self.webrender_gl.delete_sync(gl_sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use canvas_traits::webgl::ActiveAttribInfo;
|
|||
use canvas_traits::webgl::ActiveUniformBlockInfo;
|
||||
use canvas_traits::webgl::ActiveUniformInfo;
|
||||
use canvas_traits::webgl::AlphaTreatment;
|
||||
use canvas_traits::webgl::DOMToTextureCommand;
|
||||
use canvas_traits::webgl::GLContextAttributes;
|
||||
use canvas_traits::webgl::GLLimits;
|
||||
use canvas_traits::webgl::GlType;
|
||||
|
@ -239,8 +238,6 @@ pub(crate) struct WebGLThread {
|
|||
cached_context_info: FnvHashMap<WebGLContextId, WebGLContextInfo>,
|
||||
/// Current bound context.
|
||||
bound_context_id: Option<WebGLContextId>,
|
||||
/// Texture ids and sizes used in DOM to texture outputs.
|
||||
dom_outputs: FnvHashMap<webrender_api::PipelineId, DOMToTextureData>,
|
||||
/// List of registered webrender external images.
|
||||
/// We use it to get an unique ID for new WebGLContexts.
|
||||
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||
|
@ -298,7 +295,6 @@ impl WebGLThread {
|
|||
contexts: Default::default(),
|
||||
cached_context_info: Default::default(),
|
||||
bound_context_id: None,
|
||||
dom_outputs: Default::default(),
|
||||
external_images,
|
||||
sender,
|
||||
receiver: receiver.into_inner(),
|
||||
|
@ -410,9 +406,6 @@ impl WebGLThread {
|
|||
WebGLMsg::SwapBuffers(swap_ids, sender, sent_time) => {
|
||||
self.handle_swap_buffers(swap_ids, sender, sent_time);
|
||||
},
|
||||
WebGLMsg::DOMToTextureCommand(command) => {
|
||||
self.handle_dom_to_texture(command);
|
||||
},
|
||||
WebGLMsg::Exit => {
|
||||
return true;
|
||||
},
|
||||
|
@ -890,88 +883,6 @@ impl WebGLThread {
|
|||
SurfaceAccess::GPUOnly
|
||||
}
|
||||
|
||||
fn handle_dom_to_texture(&mut self, command: DOMToTextureCommand) {
|
||||
match command {
|
||||
DOMToTextureCommand::Attach(context_id, texture_id, document_id, pipeline_id, size) => {
|
||||
let data = Self::make_current_if_needed(
|
||||
&self.device,
|
||||
context_id,
|
||||
&self.contexts,
|
||||
&mut self.bound_context_id,
|
||||
)
|
||||
.expect("WebGLContext not found in a WebGL DOMToTextureCommand::Attach command");
|
||||
// Initialize the texture that WR will use for frame outputs.
|
||||
data.gl.tex_image_2d(
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RGBA as gl::GLint,
|
||||
size.width,
|
||||
size.height,
|
||||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
gl::TexImageSource::Pixels(None),
|
||||
);
|
||||
self.dom_outputs.insert(
|
||||
pipeline_id,
|
||||
DOMToTextureData {
|
||||
context_id,
|
||||
texture_id,
|
||||
document_id,
|
||||
size,
|
||||
},
|
||||
);
|
||||
let mut txn = webrender_api::Transaction::new();
|
||||
txn.enable_frame_output(pipeline_id, true);
|
||||
self.webrender_api.send_transaction(document_id, txn);
|
||||
},
|
||||
DOMToTextureCommand::Lock(pipeline_id, gl_sync, sender) => {
|
||||
let result = self.handle_dom_to_texture_lock(pipeline_id, gl_sync);
|
||||
// Send the texture id and size to WR.
|
||||
sender.send(result).unwrap();
|
||||
},
|
||||
DOMToTextureCommand::Detach(texture_id) => {
|
||||
if let Some((pipeline_id, document_id)) = self
|
||||
.dom_outputs
|
||||
.iter()
|
||||
.find(|&(_, v)| v.texture_id == texture_id)
|
||||
.map(|(k, v)| (*k, v.document_id))
|
||||
{
|
||||
let mut txn = webrender_api::Transaction::new();
|
||||
txn.enable_frame_output(pipeline_id, false);
|
||||
self.webrender_api.send_transaction(document_id, txn);
|
||||
self.dom_outputs.remove(&pipeline_id);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn handle_dom_to_texture_lock(
|
||||
&mut self,
|
||||
pipeline_id: webrender_api::PipelineId,
|
||||
gl_sync: usize,
|
||||
) -> Option<(u32, Size2D<i32>)> {
|
||||
let device = &self.device;
|
||||
let contexts = &self.contexts;
|
||||
let bound_context_id = &mut self.bound_context_id;
|
||||
self.dom_outputs.get(&pipeline_id).and_then(|dom_data| {
|
||||
let data = Self::make_current_if_needed(
|
||||
device,
|
||||
dom_data.context_id,
|
||||
contexts,
|
||||
bound_context_id,
|
||||
);
|
||||
data.and_then(|data| {
|
||||
// The next glWaitSync call is used to synchronize the two flows of
|
||||
// OpenGL commands (WR and WebGL) in order to avoid using semi-ready WR textures.
|
||||
// glWaitSync doesn't block WebGL CPU thread.
|
||||
data.gl
|
||||
.wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED);
|
||||
Some((dom_data.texture_id.get(), dom_data.size))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets a reference to a Context for a given WebGLContextId and makes it current if required.
|
||||
fn make_current_if_needed<'a>(
|
||||
device: &Device,
|
||||
|
@ -1106,14 +1017,6 @@ fn current_wr_texture_target(device: &Device) -> webrender_api::TextureTarget {
|
|||
}
|
||||
}
|
||||
|
||||
/// Data about the linked DOM<->WebGLTexture elements.
|
||||
struct DOMToTextureData {
|
||||
context_id: WebGLContextId,
|
||||
texture_id: WebGLTextureId,
|
||||
document_id: webrender_api::DocumentId,
|
||||
size: Size2D<i32>,
|
||||
}
|
||||
|
||||
/// WebGL Commands Implementation
|
||||
pub struct WebGLImpl;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::borrow::Cow;
|
|||
use std::fmt;
|
||||
use std::num::{NonZeroU32, NonZeroU64};
|
||||
use std::ops::Deref;
|
||||
use webrender_api::{DocumentId, ImageKey, PipelineId};
|
||||
use webrender_api::ImageKey;
|
||||
use webxr_api::ContextId as WebXRContextId;
|
||||
use webxr_api::Error as WebXRError;
|
||||
use webxr_api::LayerId as WebXRLayerId;
|
||||
|
@ -76,8 +76,6 @@ pub enum WebGLMsg {
|
|||
/// Runs a WebXRCommand (WebXR layers need to be created in the WebGL
|
||||
/// thread, as they may have thread affinity).
|
||||
WebXRCommand(WebXRCommand),
|
||||
/// Commands used for the DOMToTexture feature.
|
||||
DOMToTextureCommand(DOMToTextureCommand),
|
||||
/// Performs a buffer swap.
|
||||
///
|
||||
/// The third field contains the time (in ns) when the request
|
||||
|
@ -174,10 +172,6 @@ impl WebGLMsgSender {
|
|||
pub fn send_remove(&self) -> WebGLSendResult {
|
||||
self.sender.send(WebGLMsg::RemoveContext(self.ctx_id))
|
||||
}
|
||||
|
||||
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
|
||||
self.sender.send(WebGLMsg::DOMToTextureCommand(command))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
|
@ -662,23 +656,6 @@ pub enum WebGLFramebufferBindingRequest {
|
|||
|
||||
pub type WebGLResult<T> = Result<T, WebGLError>;
|
||||
|
||||
/// WebGL commands required to implement DOMToTexture feature.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub enum DOMToTextureCommand {
|
||||
/// Attaches a HTMLIFrameElement to a WebGLTexture.
|
||||
Attach(
|
||||
WebGLContextId,
|
||||
WebGLTextureId,
|
||||
DocumentId,
|
||||
PipelineId,
|
||||
Size2D<i32>,
|
||||
),
|
||||
/// Releases the HTMLIFrameElement to WebGLTexture attachment.
|
||||
Detach(WebGLTextureId),
|
||||
/// Lock message used for a correct synchronization with WebRender GL flow.
|
||||
Lock(PipelineId, usize, WebGLSender<Option<(u32, Size2D<i32>)>>),
|
||||
}
|
||||
|
||||
/// Information about a WebGL program linking operation.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct ProgramLinkInfo {
|
||||
|
|
|
@ -259,11 +259,6 @@ mod gen {
|
|||
#[serde(default)]
|
||||
enabled: bool,
|
||||
},
|
||||
webgl: {
|
||||
dom_to_texture: {
|
||||
enabled: bool,
|
||||
}
|
||||
},
|
||||
webgl2: {
|
||||
enabled: bool,
|
||||
},
|
||||
|
|
|
@ -24,7 +24,6 @@ use crate::dom::element::cors_setting_for_element;
|
|||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use crate::dom::htmlcanvaselement::utils as canvas_utils;
|
||||
use crate::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutCanvasRenderingContextHelpers};
|
||||
use crate::dom::htmliframeelement::HTMLIFrameElement;
|
||||
use crate::dom::node::{document_from_node, window_from_node, Node, NodeDamage};
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::dom::vertexarrayobject::VertexAttribData;
|
||||
|
@ -57,11 +56,11 @@ use crate::script_runtime::JSContext as SafeJSContext;
|
|||
use backtrace::Backtrace;
|
||||
use canvas_traits::webgl::WebGLError::*;
|
||||
use canvas_traits::webgl::{
|
||||
webgl_channel, AlphaTreatment, DOMToTextureCommand, GLContextAttributes, GLLimits, GlType,
|
||||
Parameter, SizedDataType, TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand,
|
||||
WebGLCommandBacktrace, WebGLContextId, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg,
|
||||
WebGLMsgSender, WebGLProgramId, WebGLResult, WebGLSLVersion, WebGLSendResult, WebGLSender,
|
||||
WebGLVersion, YAxisTreatment,
|
||||
webgl_channel, AlphaTreatment, GLContextAttributes, GLLimits, GlType, Parameter, SizedDataType,
|
||||
TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand, WebGLCommandBacktrace,
|
||||
WebGLContextId, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender,
|
||||
WebGLProgramId, WebGLResult, WebGLSLVersion, WebGLSendResult, WebGLSender, WebGLVersion,
|
||||
YAxisTreatment,
|
||||
};
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::EventLoopWaker;
|
||||
|
@ -379,10 +378,6 @@ impl WebGLRenderingContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn webgl_sender(&self) -> WebGLMessageSender {
|
||||
self.webgl_sender.clone()
|
||||
}
|
||||
|
||||
pub fn context_id(&self) -> WebGLContextId {
|
||||
self.webgl_sender.context_id()
|
||||
}
|
||||
|
@ -4434,60 +4429,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
||||
fn TexImageDOM(
|
||||
&self,
|
||||
target: u32,
|
||||
level: i32,
|
||||
internal_format: u32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
format: u32,
|
||||
data_type: u32,
|
||||
source: &HTMLIFrameElement,
|
||||
) -> ErrorResult {
|
||||
// Currently DOMToTexture only supports TEXTURE_2D, RGBA, UNSIGNED_BYTE and no levels.
|
||||
if target != constants::TEXTURE_2D ||
|
||||
level != 0 ||
|
||||
internal_format != constants::RGBA ||
|
||||
format != constants::RGBA ||
|
||||
data_type != constants::UNSIGNED_BYTE
|
||||
{
|
||||
return Ok(self.webgl_error(InvalidValue));
|
||||
}
|
||||
|
||||
// Get bound texture
|
||||
let texture = handle_potential_webgl_error!(
|
||||
self,
|
||||
self.textures
|
||||
.active_texture_slot(constants::TEXTURE_2D, self.webgl_version())
|
||||
.unwrap()
|
||||
.get()
|
||||
.ok_or(InvalidOperation),
|
||||
return Ok(())
|
||||
);
|
||||
|
||||
let pipeline_id = source.pipeline_id().ok_or(Error::InvalidState)?;
|
||||
let document_id = self
|
||||
.global()
|
||||
.downcast::<Window>()
|
||||
.ok_or(Error::InvalidState)?
|
||||
.webrender_document();
|
||||
|
||||
texture.set_attached_to_dom();
|
||||
|
||||
let command = DOMToTextureCommand::Attach(
|
||||
self.webgl_sender.context_id(),
|
||||
texture.id(),
|
||||
document_id,
|
||||
pipeline_id.to_webrender(),
|
||||
Size2D::new(width, height),
|
||||
);
|
||||
self.webgl_sender.send_dom_to_texture(command).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
||||
#[allow(unsafe_code)]
|
||||
fn TexSubImage2D(
|
||||
|
@ -5013,10 +4954,6 @@ impl WebGLMessageSender {
|
|||
pub fn send_remove(&self) -> WebGLSendResult {
|
||||
self.wake_after_send(|| self.sender.send_remove())
|
||||
}
|
||||
|
||||
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
|
||||
self.wake_after_send(|| self.sender.send_dom_to_texture(command))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Size2DExt {
|
||||
|
|
|
@ -20,7 +20,7 @@ use canvas_traits::webgl::{
|
|||
webgl_channel, TexDataType, TexFormat, TexParameter, TexParameterBool, TexParameterInt,
|
||||
WebGLResult, WebGLTextureId,
|
||||
};
|
||||
use canvas_traits::webgl::{DOMToTextureCommand, WebGLCommand, WebGLError};
|
||||
use canvas_traits::webgl::{WebGLCommand, WebGLError};
|
||||
use dom_struct::dom_struct;
|
||||
use std::cell::Cell;
|
||||
use std::cmp;
|
||||
|
@ -62,8 +62,6 @@ pub struct WebGLTexture {
|
|||
// Store information for min and mag filters
|
||||
min_filter: Cell<u32>,
|
||||
mag_filter: Cell<u32>,
|
||||
/// True if this texture is used for the DOMToTexture feature.
|
||||
attached_to_dom: Cell<bool>,
|
||||
/// Framebuffer that this texture is attached to.
|
||||
attached_framebuffer: MutNullableDom<WebGLFramebuffer>,
|
||||
/// Number of immutable levels.
|
||||
|
@ -90,7 +88,6 @@ impl WebGLTexture {
|
|||
min_filter: Cell::new(constants::NEAREST_MIPMAP_LINEAR),
|
||||
mag_filter: Cell::new(constants::LINEAR),
|
||||
image_info_array: DomRefCell::new([None; MAX_LEVEL_COUNT * MAX_FACE_COUNT]),
|
||||
attached_to_dom: Cell::new(false),
|
||||
attached_framebuffer: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -224,12 +221,6 @@ impl WebGLTexture {
|
|||
if !self.is_deleted.get() {
|
||||
self.is_deleted.set(true);
|
||||
let context = self.upcast::<WebGLObject>().context();
|
||||
// Notify WR to release the frame output when using DOMToTexture feature
|
||||
if self.attached_to_dom.get() {
|
||||
let _ = context
|
||||
.webgl_sender()
|
||||
.send_dom_to_texture(DOMToTextureCommand::Detach(self.id));
|
||||
}
|
||||
|
||||
/*
|
||||
If a texture object is deleted while its image is attached to one or more attachment
|
||||
|
@ -469,10 +460,6 @@ impl WebGLTexture {
|
|||
self.image_info_at_face(0, self.base_mipmap_level)
|
||||
}
|
||||
|
||||
pub fn set_attached_to_dom(&self) {
|
||||
self.attached_to_dom.set(true);
|
||||
}
|
||||
|
||||
pub fn attach_to_framebuffer(&self, fb: &WebGLFramebuffer) {
|
||||
self.attached_framebuffer.set(Some(fb));
|
||||
}
|
||||
|
|
|
@ -680,16 +680,9 @@ interface mixin WebGLRenderingContextOverloads
|
|||
undefined uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value);
|
||||
};
|
||||
|
||||
interface mixin WebGLRenderingContextExtensions {
|
||||
[Throws, Pref="dom.webgl.dom_to_texture.enabled"]
|
||||
undefined texImageDOM(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type, HTMLIFrameElement source); // May throw DOMException
|
||||
};
|
||||
|
||||
[Exposed=(Window)]
|
||||
interface WebGLRenderingContext
|
||||
{
|
||||
};
|
||||
WebGLRenderingContext includes WebGLRenderingContextBase;
|
||||
WebGLRenderingContext includes WebGLRenderingContextOverloads;
|
||||
WebGLRenderingContext includes WebGLRenderingContextExtensions;
|
||||
|
|
|
@ -440,10 +440,8 @@ where
|
|||
webgl_threads,
|
||||
webxr_layer_grand_manager,
|
||||
image_handler,
|
||||
output_handler,
|
||||
} = WebGLComm::new(
|
||||
webrender_surfman.clone(),
|
||||
webrender_gl.clone(),
|
||||
webrender_api.create_sender(),
|
||||
webrender_document,
|
||||
external_images.clone(),
|
||||
|
@ -453,11 +451,6 @@ where
|
|||
// Set webrender external image handler for WebGL textures
|
||||
external_image_handlers.set_handler(image_handler, WebrenderImageHandlerType::WebGL);
|
||||
|
||||
// Set DOM to texture handler, if enabled.
|
||||
if let Some(output_handler) = output_handler {
|
||||
webrender.set_output_image_handler(output_handler);
|
||||
}
|
||||
|
||||
// Create the WebXR main thread
|
||||
let mut webxr_main_thread =
|
||||
webxr::MainThreadRegistry::new(event_loop_waker, webxr_layer_grand_manager)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue