aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglrenderingcontext.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r--components/script/dom/webglrenderingcontext.rs98
1 files changed, 61 insertions, 37 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index f19664ad0ad..b5faecc7371 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -54,11 +54,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, GLFormats, GLLimits,
- GlType, Parameter, TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand,
- WebGLCommandBacktrace, WebGLContextId, WebGLContextShareMode, WebGLError,
- WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender, WebGLProgramId, WebGLResult,
- WebGLSLVersion, WebGLSendResult, WebGLSender, WebGLVersion, WebVRCommand, YAxisTreatment,
+ webgl_channel, AlphaTreatment, DOMToTextureCommand, GLContextAttributes, GLLimits, GlType,
+ Parameter, TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand,
+ WebGLCommandBacktrace, WebGLContextId, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg,
+ WebGLMsgSender, WebGLOpaqueFramebufferId, WebGLProgramId, WebGLResult, WebGLSLVersion,
+ WebGLSendResult, WebGLSender, WebGLVersion, WebVRCommand, YAxisTreatment,
};
use dom_struct::dom_struct;
use embedder_traits::EventLoopWaker;
@@ -81,6 +81,7 @@ use std::cell::Cell;
use std::cmp;
use std::ptr::{self, NonNull};
use std::rc::Rc;
+use webxr_api::SwapChainId as WebXRSwapChainId;
// From the GLES 2.0.25 spec, page 85:
//
@@ -130,10 +131,9 @@ pub struct WebGLRenderingContext {
webgl_sender: WebGLMessageSender,
#[ignore_malloc_size_of = "Defined in webrender"]
webrender_image: webrender_api::ImageKey,
- share_mode: WebGLContextShareMode,
webgl_version: WebGLVersion,
glsl_version: WebGLSLVersion,
- #[ignore_malloc_size_of = "Defined in offscreen_gl_context"]
+ #[ignore_malloc_size_of = "Defined in surfman"]
limits: GLLimits,
canvas: Dom<HTMLCanvasElement>,
#[ignore_malloc_size_of = "Defined in canvas_traits"]
@@ -160,7 +160,6 @@ pub struct WebGLRenderingContext {
current_vao: MutNullableDom<WebGLVertexArrayObjectOES>,
textures: Textures,
api_type: GlType,
- framebuffer_format: GLFormats,
}
impl WebGLRenderingContext {
@@ -195,7 +194,6 @@ impl WebGLRenderingContext {
window.get_event_loop_waker(),
),
webrender_image: ctx_data.image_key,
- share_mode: ctx_data.share_mode,
webgl_version,
glsl_version: ctx_data.glsl_version,
limits: ctx_data.limits,
@@ -220,7 +218,6 @@ impl WebGLRenderingContext {
current_vao: Default::default(),
textures: Textures::new(max_combined_texture_image_units),
api_type: ctx_data.api_type,
- framebuffer_format: ctx_data.framebuffer_format,
}
})
}
@@ -292,7 +289,7 @@ impl WebGLRenderingContext {
self.send_command(WebGLCommand::Scissor(rect.0, rect.1, rect.2, rect.3));
// Bound texture must not change when the canvas is resized.
- // Right now offscreen_gl_context generates a new FBO and the bound texture is changed
+ // Right now surfman generates a new FBO and the bound texture is changed
// in order to create a new render to texture attachment.
// Send a command to re-bind the TEXTURE_2D, if any.
if let Some(texture) = self
@@ -308,7 +305,7 @@ impl WebGLRenderingContext {
}
// Bound framebuffer must not change when the canvas is resized.
- // Right now offscreen_gl_context generates a new FBO on resize.
+ // Right now surfman generates a new FBO on resize.
// Send a command to re-bind the framebuffer, if any.
if let Some(fbo) = self.bound_framebuffer.get() {
let id = WebGLFramebufferBindingRequest::Explicit(fbo.id());
@@ -324,6 +321,10 @@ impl WebGLRenderingContext {
self.webgl_sender.context_id()
}
+ pub fn onscreen(&self) -> bool {
+ self.canvas.upcast::<Node>().is_connected()
+ }
+
#[inline]
pub fn send_command(&self, command: WebGLCommand) {
self.webgl_sender
@@ -337,6 +338,10 @@ impl WebGLRenderingContext {
.send(command, capture_webgl_backtrace(self));
}
+ pub fn swap_buffers(&self, id: Option<WebGLOpaqueFramebufferId>) {
+ let _ = self.webgl_sender.send_swap_buffers(id);
+ }
+
#[inline]
pub fn send_vr_command(&self, command: WebVRCommand) {
self.webgl_sender.send_vr(command).unwrap();
@@ -438,13 +443,12 @@ impl WebGLRenderingContext {
}
let target = TexImageTarget::Texture2D;
- let info = texture.image_info_for_target(&target, 0);
- if info.is_initialized() {
+ if let Some(info) = texture.image_info_for_target(&target, 0) {
self.validate_filterable_texture(
&texture,
target,
0,
- info.internal_format().unwrap_or(TexFormat::RGBA),
+ info.internal_format(),
Size2D::new(info.width(), info.height()),
info.data_type().unwrap_or(TexDataType::UnsignedByte),
);
@@ -462,7 +466,7 @@ impl WebGLRenderingContext {
.dirty(NodeDamage::OtherNodeDamage);
let document = document_from_node(&*self.canvas);
- document.add_dirty_canvas(self.context_id());
+ document.add_dirty_canvas(self);
}
fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) {
@@ -746,7 +750,10 @@ impl WebGLRenderingContext {
pixels: TexPixels,
) {
// We have already validated level
- let image_info = texture.image_info_for_target(&target, level);
+ let image_info = match texture.image_info_for_target(&target, level) {
+ Some(info) => info,
+ None => return self.webgl_error(InvalidOperation),
+ };
// GL_INVALID_VALUE is generated if:
// - xoffset or yoffset is less than 0
@@ -761,9 +768,7 @@ impl WebGLRenderingContext {
}
// NB: format and internal_format must match.
- if format != image_info.internal_format().unwrap() ||
- data_type != image_info.data_type().unwrap()
- {
+ if format != image_info.internal_format() || data_type != image_info.data_type().unwrap() {
return self.webgl_error(InvalidOperation);
}
@@ -810,8 +815,9 @@ impl WebGLRenderingContext {
receiver.recv().unwrap()
}
- pub fn layout_handle(&self) -> webrender_api::ImageKey {
- self.webrender_image
+ pub(crate) fn layout_handle(&self) -> HTMLCanvasDataSource {
+ let image_key = self.webrender_image;
+ HTMLCanvasDataSource::WebGL(image_key)
}
// https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/
@@ -1086,17 +1092,9 @@ impl WebGLRenderingContext {
self.bound_framebuffer.get()
}
- pub fn bound_renderbuffer(&self) -> Option<DomRoot<WebGLRenderbuffer>> {
- self.bound_renderbuffer.get()
- }
-
pub fn extension_manager(&self) -> &WebGLExtensions {
&self.extension_manager
}
-
- pub fn formats(&self) -> &GLFormats {
- &self.framebuffer_format
- }
}
#[cfg(not(feature = "webgl_backtrace"))]
@@ -1921,9 +1919,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
Some(WebGLFramebufferAttachmentRoot::Renderbuffer(rb)) => {
TexFormat::from_gl_constant(rb.internal_format())
},
- Some(WebGLFramebufferAttachmentRoot::Texture(texture)) => {
- texture.image_info_for_target(&target, 0).internal_format()
- },
+ Some(WebGLFramebufferAttachmentRoot::Texture(texture)) => texture
+ .image_info_for_target(&target, 0)
+ .map(|info| info.internal_format()),
None => None,
},
None => {
@@ -2022,7 +2020,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
Err(_) => return,
};
- let image_info = texture.image_info_for_target(&target, level);
+ let image_info = match texture.image_info_for_target(&target, level) {
+ Some(info) => info,
+ None => return self.webgl_error(InvalidOperation),
+ };
// GL_INVALID_VALUE is generated if:
// - xoffset or yoffset is less than 0
@@ -2225,6 +2226,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn DeleteFramebuffer(&self, framebuffer: Option<&WebGLFramebuffer>) {
if let Some(framebuffer) = framebuffer {
+ // https://immersive-web.github.io/webxr/#opaque-framebuffer
+ // Can opaque framebuffers be deleted?
+ // https://github.com/immersive-web/webxr/issues/855
+ handle_potential_webgl_error!(self, framebuffer.validate_transparent(), return);
handle_potential_webgl_error!(self, self.validate_ownership(framebuffer), return);
handle_object_deletion!(
self,
@@ -2384,7 +2389,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
pname: u32,
) -> JSVal {
// Check if currently bound framebuffer is non-zero as per spec.
- if self.bound_framebuffer.get().is_none() {
+ if let Some(fb) = self.bound_framebuffer.get() {
+ // Opaque framebuffers cannot have their attachments inspected
+ // https://immersive-web.github.io/webxr/#opaque-framebuffer
+ handle_potential_webgl_error!(self, fb.validate_transparent(), return NullValue());
+ } else {
self.webgl_error(InvalidOperation);
return NullValue();
}
@@ -2487,6 +2496,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
fn GetRenderbufferParameter(&self, _cx: SafeJSContext, target: u32, pname: u32) -> JSVal {
+ // We do not check to see if the renderbuffer came from an opaque framebuffer
+ // https://github.com/immersive-web/webxr/issues/862
let target_matches = target == constants::RENDERBUFFER;
let pname_matches = match pname {
@@ -3477,6 +3488,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if program.is_deleted() ||
!program.is_linked() ||
+ self.context_id() != location.context_id() ||
program.id() != location.program_id() ||
program.link_generation() != location.link_generation()
{
@@ -4153,7 +4165,7 @@ pub trait LayoutCanvasWebGLRenderingContextHelpers {
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGLRenderingContext> {
#[allow(unsafe_code)]
unsafe fn canvas_data_source(&self) -> HTMLCanvasDataSource {
- HTMLCanvasDataSource::WebGL((*self.unsafe_get()).layout_handle())
+ (*self.unsafe_get()).layout_handle()
}
}
@@ -4347,7 +4359,7 @@ impl TexPixels {
}
#[derive(JSTraceable)]
-pub(crate) struct WebGLCommandSender {
+pub struct WebGLCommandSender {
sender: WebGLChan,
waker: Option<Box<dyn EventLoopWaker>>,
}
@@ -4410,6 +4422,18 @@ impl WebGLMessageSender {
self.wake_after_send(|| self.sender.send_vr(command))
}
+ pub fn send_swap_buffers(&self, id: Option<WebGLOpaqueFramebufferId>) -> WebGLSendResult {
+ self.wake_after_send(|| self.sender.send_swap_buffers(id))
+ }
+
+ pub fn send_create_webxr_swap_chain(
+ &self,
+ size: Size2D<i32>,
+ sender: WebGLSender<Option<WebXRSwapChainId>>,
+ ) -> WebGLSendResult {
+ self.wake_after_send(|| self.sender.send_create_webxr_swap_chain(size, sender))
+ }
+
pub fn send_resize(
&self,
size: Size2D<u32>,