diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 01925408b5e..ff68685ca60 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -129,8 +129,9 @@ pub enum CanvasWebGLMsg { DrawingBufferHeight(Sender), } -#[derive(Clone)] +#[derive(Clone, Copy, PartialEq)] pub enum WebGLError { + NoError, InvalidEnum, InvalidOperation, InvalidValue, diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 5c854953f8f..b64d46a212e 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -36,6 +36,7 @@ use script_task::ScriptChan; use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle}; use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending, RepetitionStyle}; +use canvas_traits::WebGLError; use cssparser::RGBA; use encoding::types::EncodingRef; use euclid::matrix2d::Matrix2D; @@ -297,6 +298,7 @@ no_jsmanaged_fields!(StorageType); no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle); no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending); no_jsmanaged_fields!(RepetitionStyle); +no_jsmanaged_fields!(WebGLError); impl JSTraceable for Box { #[inline] diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 23090a73cfb..c87b901d391 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -26,6 +26,7 @@ use euclid::size::Size2D; use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView}; use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value, BooleanValue}; +use std::cell::Cell; use std::mem; use std::ptr; use std::slice; @@ -53,6 +54,7 @@ pub struct WebGLRenderingContext { global: GlobalField, renderer: Sender, canvas: JS, + last_error: Cell, } impl WebGLRenderingContext { @@ -67,6 +69,7 @@ impl WebGLRenderingContext { reflector_: Reflector::new(), global: GlobalField::from_rooted(&global), renderer: chan, + last_error: Cell::new(WebGLError::NoError), canvas: JS::from_ref(canvas), }) } @@ -129,6 +132,20 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { rval.ptr } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn GetError(self) -> u32 { + let error_code = match self.last_error.get() { + WebGLError::NoError => constants::NO_ERROR, + WebGLError::InvalidEnum => constants::INVALID_ENUM, + WebGLError::InvalidValue => constants::INVALID_VALUE, + WebGLError::InvalidOperation => constants::INVALID_OPERATION, + WebGLError::OutOfMemory => constants::OUT_OF_MEMORY, + WebGLError::ContextLost => constants::CONTEXT_LOST_WEBGL, + }; + self.last_error.set(WebGLError::NoError); + error_code + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.2 fn GetContextAttributes(self) -> Option { let (sender, receiver) = channel(); @@ -482,9 +499,12 @@ pub trait WebGLRenderingContextHelpers { } impl<'a> WebGLRenderingContextHelpers for &'a WebGLRenderingContext { - fn handle_webgl_error(&self, _: WebGLError) { - debug!("WebGL error received"); - // ignore for now + fn handle_webgl_error(&self, err: WebGLError) { + // If an error has been detected no further errors must be + // recorded until `getError` has been called + if self.last_error.get() == WebGLError::NoError { + self.last_error.set(err); + } } } diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 5177dd22cb1..8f4b6f95f02 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -558,7 +558,7 @@ interface WebGLRenderingContextBase //any getBufferParameter(GLenum target, GLenum pname); any getParameter(GLenum pname); - //[WebGLHandlesContextLoss] GLenum getError(); + [WebGLHandlesContextLoss] GLenum getError(); //any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, // GLenum pname);