diff options
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 920fd91bbad..4c6996cbb90 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -31,7 +31,7 @@ use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::ImageResponse; -use offscreen_gl_context::GLContextAttributes; +use offscreen_gl_context::{GLContextAttributes, GLLimits}; use script_traits::ScriptMsg as ConstellationMsg; use std::cell::Cell; use util::str::DOMString; @@ -71,6 +71,8 @@ pub struct WebGLRenderingContext { reflector_: Reflector, #[ignore_heap_size_of = "Defined in ipc-channel"] ipc_renderer: IpcSender<CanvasMsg>, + #[ignore_heap_size_of = "Defined in offscreen_gl_context"] + limits: GLLimits, canvas: JS<HTMLCanvasElement>, #[ignore_heap_size_of = "Defined in webrender_traits"] last_error: Cell<Option<WebGLError>>, @@ -95,10 +97,11 @@ impl WebGLRenderingContext { .unwrap(); let result = receiver.recv().unwrap(); - result.map(|ipc_renderer| { + result.map(|(ipc_renderer, context_limits)| { WebGLRenderingContext { reflector_: Reflector::new(), ipc_renderer: ipc_renderer, + limits: context_limits, canvas: JS::from_ref(canvas), last_error: Cell::new(None), texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE), @@ -139,6 +142,9 @@ impl WebGLRenderingContext { } pub fn webgl_error(&self, err: WebGLError) { + // TODO(emilio): Add useful debug messages to this + warn!("WebGL error: {:?}, previous error was {:?}", err, self.last_error.get()); + // If an error has been detected no further errors must be // recorded until `getError` has been called if self.last_error.get().is_none() { @@ -155,7 +161,7 @@ impl WebGLRenderingContext { if let Some(texture) = texture { handle_potential_webgl_error!(self, texture.tex_parameter(target, name, value)); } else { - return self.webgl_error(InvalidOperation); + self.webgl_error(InvalidOperation) } } @@ -164,6 +170,10 @@ impl WebGLRenderingContext { } fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) { + if indx > self.limits.max_vertex_attribs { + return self.webgl_error(InvalidValue); + } + self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w))) .unwrap(); @@ -680,6 +690,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn CreateShader(&self, shader_type: u32) -> Option<Root<WebGLShader>> { + match shader_type { + constants::VERTEX_SHADER | constants::FRAGMENT_SHADER => {}, + _ => { + self.webgl_error(InvalidEnum); + return None; + } + } WebGLShader::maybe_new(self.global().r(), self.ipc_renderer.clone(), shader_type) } @@ -737,13 +754,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } if first < 0 || count < 0 { - self.webgl_error(InvalidValue); - } else { - self.ipc_renderer - .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count))) - .unwrap(); - self.mark_as_dirty(); + return self.webgl_error(InvalidValue); } + + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count))) + .unwrap(); + self.mark_as_dirty(); }, _ => self.webgl_error(InvalidEnum), } @@ -790,6 +807,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn EnableVertexAttribArray(&self, attrib_id: u32) { + if attrib_id > self.limits.max_vertex_attribs { + return self.webgl_error(InvalidValue); + } + self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::EnableVertexAttribArray(attrib_id))) .unwrap() @@ -807,6 +828,17 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + fn GetActiveAttrib(&self, program: Option<&WebGLProgram>, index: u32) -> Option<Root<WebGLActiveInfo>> { + program.and_then(|p| match p.get_active_attrib(index) { + Ok(ret) => Some(ret), + Err(error) => { + self.webgl_error(error); + None + }, + }) + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn GetAttribLocation(&self, program: Option<&WebGLProgram>, name: DOMString) -> i32 { if let Some(program) = program { handle_potential_webgl_error!(self, program.get_attrib_location(name), None).unwrap_or(-1) @@ -1188,7 +1220,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.vertex_attrib(indx, x, 0f32, 0f32, 1f32) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { @@ -1206,7 +1237,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.vertex_attrib(indx, x, y, 0f32, 1f32) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { @@ -1257,6 +1287,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttribPointer(&self, attrib_id: u32, size: i32, data_type: u32, normalized: bool, stride: i32, offset: i64) { + if attrib_id > self.limits.max_vertex_attribs { + return self.webgl_error(InvalidValue); + } + if let constants::FLOAT = data_type { let msg = CanvasMsg::WebGL( WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32)); |