diff options
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 254 |
1 files changed, 107 insertions, 147 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index ad572751607..30c60feea35 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -16,7 +16,7 @@ use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderi use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, ToJSValConvertible}; -use dom::bindings::error::{Error, Fallible}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom}; @@ -471,7 +471,7 @@ impl WebGLRenderingContext { } fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) { - if indx > self.limits.max_vertex_attribs { + if indx >= self.limits.max_vertex_attribs { return self.webgl_error(InvalidValue); } @@ -763,14 +763,10 @@ impl WebGLRenderingContext { } } - fn get_image_pixels(&self, - source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) - -> ImagePixelResult { - let source = match source { - Some(s) => s, - None => return Err(()), - }; - + fn get_image_pixels( + &self, + source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, + ) -> ImagePixelResult { // NOTE: Getting the pixels probably can be short-circuited if some // parameter is invalid. // @@ -1273,6 +1269,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { match parameter { constants::ARRAY_BUFFER_BINDING => return object_binding_to_js_or_null!(cx, &self.bound_buffer_array), + constants::CURRENT_PROGRAM => { + return object_binding_to_js_or_null!(cx, &self.current_program); + } constants::ELEMENT_ARRAY_BUFFER_BINDING => return object_binding_to_js_or_null!(cx, &self.bound_buffer_element_array), constants::FRAMEBUFFER_BINDING => @@ -1306,6 +1305,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return Int32Value(constants::UNSIGNED_BYTE as i32); } } + constants::VIEWPORT => { + let (sender, receiver) = webgl_channel().unwrap(); + self.send_command(WebGLCommand::GetViewport(sender)); + let (x, y, width, height) = receiver.recv().unwrap(); + rooted!(in(cx) let mut rval = UndefinedValue()); + [x, y, width, height].to_jsval(cx, rval.handle_mut()); + return rval.get(); + } _ => { if !self.extension_manager.is_get_parameter_name_enabled(parameter) { self.webgl_error(WebGLError::InvalidEnum); @@ -1965,10 +1972,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn CompileShader(&self, shader: Option<&WebGLShader>) { - if let Some(shader) = shader { - shader.compile(self.webgl_version, self.glsl_version, &self.extension_manager) - } + fn CompileShader(&self, shader: &WebGLShader) { + shader.compile(self.webgl_version, self.glsl_version, &self.extension_manager) } // TODO(emilio): Probably in the future we should keep track of the @@ -2137,24 +2142,28 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { constants::POINTS | constants::LINE_STRIP | constants::LINE_LOOP | constants::LINES | constants::TRIANGLE_STRIP | constants::TRIANGLE_FAN | - constants::TRIANGLES => { - if self.current_program.get().is_none() { - return self.webgl_error(InvalidOperation); - } - - if first < 0 || count < 0 { - return self.webgl_error(InvalidValue); - } - - if !self.validate_framebuffer_complete() { - return; - } - - self.send_command(WebGLCommand::DrawArrays(mode, first, count)); - self.mark_as_dirty(); - }, - _ => self.webgl_error(InvalidEnum), + constants::TRIANGLES => {}, + _ => { + return self.webgl_error(InvalidEnum); + } } + if first < 0 || count < 0 { + return self.webgl_error(InvalidValue); + } + if self.current_program.get().is_none() { + return self.webgl_error(InvalidOperation); + } + if let Some(array_buffer) = self.bound_buffer_array.get() { + if count > 0 && (first as u64 + count as u64 > array_buffer.capacity() as u64) { + return self.webgl_error(InvalidOperation); + } + } + if !self.validate_framebuffer_complete() { + return; + } + + self.send_command(WebGLCommand::DrawArrays(mode, first, count)); + self.mark_as_dirty(); } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11 @@ -2223,7 +2232,7 @@ 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 { + if attrib_id >= self.limits.max_vertex_attribs { return self.webgl_error(InvalidValue); } @@ -2232,7 +2241,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn DisableVertexAttribArray(&self, attrib_id: u32) { - if attrib_id > self.limits.max_vertex_attribs { + if attrib_id >= self.limits.max_vertex_attribs { return self.webgl_error(InvalidValue); } @@ -2240,23 +2249,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn GetActiveUniform(&self, program: Option<&WebGLProgram>, index: u32) -> Option<DomRoot<WebGLActiveInfo>> { - let program = match program { - Some(program) => program, - None => { - // Reasons to generate InvalidValue error - // From the GLES 2.0 spec - // - // "INVALID_VALUE is generated if index is greater than or equal - // to the number of active uniform variables in program" - // - // A null program has no uniforms so any index is always greater than the active uniforms - // WebGl conformance expects error with null programs. Check tests in get-active-test.html - self.webgl_error(InvalidValue); - return None; - } - }; - + fn GetActiveUniform(&self, program: &WebGLProgram, index: u32) -> Option<DomRoot<WebGLActiveInfo>> { match program.get_active_uniform(index) { Ok(ret) => Some(ret), Err(e) => { @@ -2267,23 +2260,7 @@ 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<DomRoot<WebGLActiveInfo>> { - let program = match program { - Some(program) => program, - None => { - // Reasons to generate InvalidValue error - // From the GLES 2.0 spec - // - // "INVALID_VALUE is generated if index is greater than or equal - // to the number of active attribute variables in program" - // - // A null program has no attributes so any index is always greater than the active uniforms - // WebGl conformance expects error with null programs. Check tests in get-active-test.html - self.webgl_error(InvalidValue); - return None; - } - }; - + fn GetActiveAttrib(&self, program: &WebGLProgram, index: u32) -> Option<DomRoot<WebGLActiveInfo>> { match program.get_active_attrib(index) { Ok(ret) => Some(ret), Err(e) => { @@ -2294,12 +2271,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // 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) - } else { - -1 - } + fn GetAttribLocation(&self, program: &WebGLProgram, name: DOMString) -> i32 { + handle_potential_webgl_error!(self, program.get_attrib_location(name), None).unwrap_or(-1) } #[allow(unsafe_code)] @@ -2390,61 +2363,48 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetProgramInfoLog(&self, program: Option<&WebGLProgram>) -> Option<DOMString> { - if let Some(program) = program { - match program.get_info_log() { - Ok(value) => Some(DOMString::from(value)), - Err(e) => { - self.webgl_error(e); - None - } + fn GetProgramInfoLog(&self, program: &WebGLProgram) -> Option<DOMString> { + match program.get_info_log() { + Ok(value) => Some(DOMString::from(value)), + Err(e) => { + self.webgl_error(e); + None } - } else { - self.webgl_error(WebGLError::InvalidValue); - None } } #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetProgramParameter(&self, _: *mut JSContext, program: Option<&WebGLProgram>, param_id: u32) -> JSVal { - if let Some(program) = program { - match handle_potential_webgl_error!(self, program.parameter(param_id), WebGLParameter::Invalid) { - WebGLParameter::Int(val) => Int32Value(val), - WebGLParameter::Bool(val) => BooleanValue(val), - WebGLParameter::String(_) => panic!("Program parameter should not be string"), - WebGLParameter::Float(_) => panic!("Program parameter should not be float"), - WebGLParameter::FloatArray(_) => { - panic!("Program paramenter should not be float array") - } - WebGLParameter::Invalid => NullValue(), + unsafe fn GetProgramParameter(&self, _: *mut JSContext, program: &WebGLProgram, param_id: u32) -> JSVal { + match handle_potential_webgl_error!(self, program.parameter(param_id), WebGLParameter::Invalid) { + WebGLParameter::Int(val) => Int32Value(val), + WebGLParameter::Bool(val) => BooleanValue(val), + WebGLParameter::String(_) => panic!("Program parameter should not be string"), + WebGLParameter::Float(_) => panic!("Program parameter should not be float"), + WebGLParameter::FloatArray(_) => { + panic!("Program paramenter should not be float array") } - } else { - NullValue() + WebGLParameter::Invalid => NullValue(), } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetShaderInfoLog(&self, shader: Option<&WebGLShader>) -> Option<DOMString> { - shader.and_then(|s| s.info_log()).map(DOMString::from) + fn GetShaderInfoLog(&self, shader: &WebGLShader) -> Option<DOMString> { + shader.info_log().map(DOMString::from) } #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetShaderParameter(&self, _: *mut JSContext, shader: Option<&WebGLShader>, param_id: u32) -> JSVal { - if let Some(shader) = shader { - match handle_potential_webgl_error!(self, shader.parameter(param_id), WebGLParameter::Invalid) { - WebGLParameter::Int(val) => Int32Value(val), - WebGLParameter::Bool(val) => BooleanValue(val), - WebGLParameter::String(_) => panic!("Shader parameter should not be string"), - WebGLParameter::Float(_) => panic!("Shader parameter should not be float"), - WebGLParameter::FloatArray(_) => { - panic!("Shader paramenter should not be float array") - } - WebGLParameter::Invalid => NullValue(), + unsafe fn GetShaderParameter(&self, _: *mut JSContext, shader: &WebGLShader, param_id: u32) -> JSVal { + match handle_potential_webgl_error!(self, shader.parameter(param_id), WebGLParameter::Invalid) { + WebGLParameter::Int(val) => Int32Value(val), + WebGLParameter::Bool(val) => BooleanValue(val), + WebGLParameter::String(_) => panic!("Shader parameter should not be string"), + WebGLParameter::Float(_) => panic!("Shader parameter should not be float"), + WebGLParameter::FloatArray(_) => { + panic!("Shader paramenter should not be float array") } - } else { - NullValue() + WebGLParameter::Invalid => NullValue(), } } @@ -2477,12 +2437,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn GetUniformLocation(&self, - program: Option<&WebGLProgram>, - name: DOMString) -> Option<DomRoot<WebGLUniformLocation>> { - program.and_then(|p| { - handle_potential_webgl_error!(self, p.get_uniform_location(name), None) - .map(|location| WebGLUniformLocation::new(self.global().as_window(), location, p.id())) + fn GetUniformLocation( + &self, + program: &WebGLProgram, + name: DOMString, + ) -> Option<DomRoot<WebGLUniformLocation>> { + handle_potential_webgl_error!(self, program.get_uniform_location(name), None).map(|location| { + WebGLUniformLocation::new(self.global().as_window(), location, program.id()) }) } @@ -2859,15 +2820,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn ShaderSource(&self, shader: Option<&WebGLShader>, source: DOMString) { - if let Some(shader) = shader { - shader.set_source(source) - } + fn ShaderSource(&self, shader: &WebGLShader, source: DOMString) { + shader.set_source(source) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetShaderSource(&self, shader: Option<&WebGLShader>) -> Option<DOMString> { - shader.and_then(|s| s.source()) + fn GetShaderSource(&self, shader: &WebGLShader) -> Option<DOMString> { + shader.source() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3158,11 +3117,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn ValidateProgram(&self, program: Option<&WebGLProgram>) { - if let Some(program) = program { - if let Err(e) = program.validate() { - self.webgl_error(e); - } + fn ValidateProgram(&self, program: &WebGLProgram) { + if let Err(e) = program.validate() { + self.webgl_error(e); } } @@ -3238,7 +3195,7 @@ 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 { + if attrib_id >= self.limits.max_vertex_attribs { return self.webgl_error(InvalidValue); } @@ -3287,7 +3244,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return self.webgl_error(InvalidValue) } - self.send_command(WebGLCommand::Viewport(x, y, width, height)) + self.send_command(WebGLCommand::SetViewport(x, y, width, height)) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 @@ -3372,13 +3329,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn TexImage2D_(&self, - target: u32, - level: i32, - internal_format: u32, - format: u32, - data_type: u32, - source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) -> Fallible<()> { + fn TexImage2D_( + &self, + target: u32, + level: i32, + internal_format: u32, + format: u32, + data_type: u32, + source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, + ) -> ErrorResult { if !self.extension_manager.is_tex_type_enabled(data_type) { return Ok(self.webgl_error(InvalidEnum)); } @@ -3533,15 +3492,16 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn TexSubImage2D_(&self, - target: u32, - level: i32, - xoffset: i32, - yoffset: i32, - format: u32, - data_type: u32, - source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) - -> Fallible<()> { + fn TexSubImage2D_( + &self, + target: u32, + level: i32, + xoffset: i32, + yoffset: i32, + format: u32, + data_type: u32, + source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, + ) -> ErrorResult { let (pixels, size, premultiplied) = match self.get_image_pixels(source) { Ok((pixels, size, premultiplied)) => (pixels, size, premultiplied), Err(_) => return Ok(()), |