diff options
-rw-r--r-- | components/canvas/webgl_paint_task.rs | 42 | ||||
-rw-r--r-- | components/canvas_traits/lib.rs | 41 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 2 | ||||
-rw-r--r-- | components/script/dom/webglbuffer.rs | 39 | ||||
-rw-r--r-- | components/script/dom/webglframebuffer.rs | 40 | ||||
-rw-r--r-- | components/script/dom/webglprogram.rs | 110 | ||||
-rw-r--r-- | components/script/dom/webglrenderbuffer.rs | 39 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 221 | ||||
-rw-r--r-- | components/script/dom/webglshader.rs | 96 | ||||
-rw-r--r-- | components/script/dom/webgltexture.rs | 39 | ||||
-rw-r--r-- | components/script/dom/webgluniformlocation.rs | 4 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLRenderingContext.webidl | 4 |
12 files changed, 530 insertions, 147 deletions
diff --git a/components/canvas/webgl_paint_task.rs b/components/canvas/webgl_paint_task.rs index 24258954c1e..6aecf0eba33 100644 --- a/components/canvas/webgl_paint_task.rs +++ b/components/canvas/webgl_paint_task.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLShaderParameter, WebGLFramebufferBindingRequest}; use euclid::size::Size2D; use core::nonzero::NonZero; use gleam::gl; @@ -109,8 +109,8 @@ impl WebGLPaintTask { self.delete_shader(id), CanvasWebGLMsg::BindBuffer(target, id) => self.bind_buffer(target, id), - CanvasWebGLMsg::BindFramebuffer(target, id) => - self.bind_framebuffer(target, id), + CanvasWebGLMsg::BindFramebuffer(target, request) => + self.bind_framebuffer(target, request), CanvasWebGLMsg::BindRenderbuffer(target, id) => self.bind_renderbuffer(target, id), CanvasWebGLMsg::BindTexture(target, id) => @@ -329,7 +329,13 @@ impl WebGLPaintTask { } #[inline] - fn bind_framebuffer(&self, target: u32, id: u32) { + fn bind_framebuffer(&self, target: u32, request: WebGLFramebufferBindingRequest) { + let id = match request { + WebGLFramebufferBindingRequest::Explicit(id) => id, + WebGLFramebufferBindingRequest::Default => + self.gl_context.borrow_draw_buffer().unwrap().get_framebuffer(), + }; + gl::bind_framebuffer(target, id); } @@ -361,19 +367,35 @@ impl WebGLPaintTask { gl::enable_vertex_attrib_array(attrib_id); } - fn get_attrib_location(&self, program_id: u32, name: String, chan: Sender<i32> ) { + fn get_attrib_location(&self, program_id: u32, name: String, chan: Sender<Option<i32>> ) { let attrib_location = gl::get_attrib_location(program_id, &name); + + let attrib_location = if attrib_location == -1 { + None + } else { + Some(attrib_location) + }; + chan.send(attrib_location).unwrap(); } - fn get_shader_info_log(&self, shader_id: u32, chan: Sender<String>) { + fn get_shader_info_log(&self, shader_id: u32, chan: Sender<Option<String>>) { + // TODO(ecoal95): Right now we always return a value, we should + // check for gl errors and return None there let info = gl::get_shader_info_log(shader_id); - chan.send(info).unwrap(); + chan.send(Some(info)).unwrap(); } - fn get_shader_parameter(&self, shader_id: u32, param_id: u32, chan: Sender<i32>) { - let parameter = gl::get_shader_iv(shader_id, param_id); - chan.send(parameter as i32).unwrap(); + fn get_shader_parameter(&self, shader_id: u32, param_id: u32, chan: Sender<WebGLShaderParameter>) { + let result = match param_id { + gl::SHADER_TYPE => + WebGLShaderParameter::Int(gl::get_shader_iv(shader_id, param_id)), + gl::DELETE_STATUS | gl::COMPILE_STATUS => + WebGLShaderParameter::Bool(gl::get_shader_iv(shader_id, param_id) != 0), + _ => panic!("Unexpected shader parameter type"), + }; + + chan.send(result).unwrap(); } fn get_uniform_location(&self, program_id: u32, name: String, chan: Sender<Option<i32>>) { diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 0fee050d78d..6f5e73bb2c1 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -38,6 +38,14 @@ pub enum CanvasMsg { } #[derive(Clone)] +pub enum CanvasCommonMsg { + Close, + Recreate(Size2D<i32>), + SendPixelContents(Sender<Vec<u8>>), + SendNativeSurface(Sender<NativeSurface>), +} + +#[derive(Clone)] pub enum Canvas2dMsg { Arc(Point2D<f32>, f32, f32, f32, bool), ArcTo(Point2D<f32>, Point2D<f32>, f32), @@ -102,14 +110,14 @@ pub enum CanvasWebGLMsg { DeleteProgram(u32), DeleteShader(u32), BindBuffer(u32, u32), - BindFramebuffer(u32, u32), + BindFramebuffer(u32, WebGLFramebufferBindingRequest), BindRenderbuffer(u32, u32), BindTexture(u32, u32), DrawArrays(u32, i32, i32), EnableVertexAttribArray(u32), - GetAttribLocation(u32, String, Sender<i32>), - GetShaderInfoLog(u32, Sender<String>), - GetShaderParameter(u32, u32, Sender<i32>), + GetShaderInfoLog(u32, Sender<Option<String>>), + GetShaderParameter(u32, u32, Sender<WebGLShaderParameter>), + GetAttribLocation(u32, String, Sender<Option<i32>>), GetUniformLocation(u32, String, Sender<Option<i32>>), LinkProgram(u32), ShaderSource(u32, String), @@ -121,14 +129,29 @@ pub enum CanvasWebGLMsg { DrawingBufferHeight(Sender<i32>), } +#[derive(Clone, Copy, PartialEq)] +pub enum WebGLError { + InvalidEnum, + InvalidOperation, + InvalidValue, + OutOfMemory, + ContextLost, +} + +pub type WebGLResult<T> = Result<T, WebGLError>; + #[derive(Clone)] -pub enum CanvasCommonMsg { - Close, - Recreate(Size2D<i32>), - SendPixelContents(Sender<Vec<u8>>), - SendNativeSurface(Sender<NativeSurface>), +pub enum WebGLFramebufferBindingRequest { + Explicit(u32), + Default, } +#[derive(Clone)] +pub enum WebGLShaderParameter { + Int(i32), + Bool(bool), + Invalid, +} #[derive(Clone)] pub struct CanvasGradientStop { 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<ScriptChan+Send> { #[inline] diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index f7c17cb8f04..4970b577bb7 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -9,31 +9,60 @@ use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg}; +use std::sync::mpsc::{channel, Sender}; +use std::cell::Cell; + #[dom_struct] pub struct WebGLBuffer { webgl_object: WebGLObject, id: u32, + is_deleted: Cell<bool>, + renderer: Sender<CanvasMsg>, } impl WebGLBuffer { - fn new_inherited(id: u32) -> WebGLBuffer { + fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLBuffer { WebGLBuffer { webgl_object: WebGLObject::new_inherited(), id: id, + is_deleted: Cell::new(false), + renderer: renderer, } } - pub fn new(global: GlobalRef, id: u32) -> Root<WebGLBuffer> { - reflect_dom_object(box WebGLBuffer::new_inherited(id), global, WebGLBufferBinding::Wrap) + pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLBuffer>> { + let (sender, receiver) = channel(); + renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap(); + + let result = receiver.recv().unwrap(); + result.map(|buffer_id| WebGLBuffer::new(global, renderer, *buffer_id)) + } + + pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLBuffer> { + reflect_dom_object(box WebGLBuffer::new_inherited(renderer, id), global, WebGLBufferBinding::Wrap) } } pub trait WebGLBufferHelpers { - fn get_id(self) -> u32; + fn id(self) -> u32; + fn bind(self, target: u32); + fn delete(self); } impl<'a> WebGLBufferHelpers for &'a WebGLBuffer { - fn get_id(self) -> u32 { + fn id(self) -> u32 { self.id } + + fn bind(self, target: u32) { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, self.id))).unwrap(); + } + + fn delete(self) { + if !self.is_deleted.get() { + self.is_deleted.set(true); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteBuffer(self.id))).unwrap(); + } + } } diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index f4bb4b2b043..26773ca4b17 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -9,31 +9,61 @@ use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLFramebufferBindingRequest}; +use std::sync::mpsc::{channel, Sender}; +use std::cell::Cell; + #[dom_struct] pub struct WebGLFramebuffer { webgl_object: WebGLObject, id: u32, + is_deleted: Cell<bool>, + renderer: Sender<CanvasMsg>, } impl WebGLFramebuffer { - fn new_inherited(id: u32) -> WebGLFramebuffer { + fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLFramebuffer { WebGLFramebuffer { webgl_object: WebGLObject::new_inherited(), id: id, + is_deleted: Cell::new(false), + renderer: renderer, } } - pub fn new(global: GlobalRef, id: u32) -> Root<WebGLFramebuffer> { - reflect_dom_object(box WebGLFramebuffer::new_inherited(id), global, WebGLFramebufferBinding::Wrap) + pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLFramebuffer>> { + let (sender, receiver) = channel(); + renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateFramebuffer(sender))).unwrap(); + + let result = receiver.recv().unwrap(); + result.map(|fb_id| WebGLFramebuffer::new(global, renderer, *fb_id)) + } + + pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLFramebuffer> { + reflect_dom_object(box WebGLFramebuffer::new_inherited(renderer, id), global, WebGLFramebufferBinding::Wrap) } } pub trait WebGLFramebufferHelpers { - fn get_id(self) -> u32; + fn id(self) -> u32; + fn bind(self, target: u32); + fn delete(self); } impl<'a> WebGLFramebufferHelpers for &'a WebGLFramebuffer { - fn get_id(self) -> u32 { + fn id(self) -> u32 { self.id } + + fn bind(self, target: u32) { + let cmd = CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Explicit(self.id)); + self.renderer.send(CanvasMsg::WebGL(cmd)).unwrap(); + } + + fn delete(self) { + if !self.is_deleted.get() { + self.is_deleted.set(true); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteFramebuffer(self.id))).unwrap(); + } + } } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 3e6191d764c..71e0d2e6616 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -5,35 +5,131 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLProgramBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::Root; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; +use dom::webglshader::{WebGLShader, WebGLShaderHelpers}; +use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN; + +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; + +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError}; +use std::sync::mpsc::{channel, Sender}; +use std::cell::Cell; #[dom_struct] pub struct WebGLProgram { webgl_object: WebGLObject, id: u32, + is_deleted: Cell<bool>, + fragment_shader: MutNullableHeap<JS<WebGLShader>>, + vertex_shader: MutNullableHeap<JS<WebGLShader>>, + renderer: Sender<CanvasMsg>, } impl WebGLProgram { - fn new_inherited(id: u32) -> WebGLProgram { + fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLProgram { WebGLProgram { webgl_object: WebGLObject::new_inherited(), id: id, + is_deleted: Cell::new(false), + fragment_shader: Default::default(), + vertex_shader: Default::default(), + renderer: renderer, } } - pub fn new(global: GlobalRef, id: u32) -> Root<WebGLProgram> { - reflect_dom_object(box WebGLProgram::new_inherited(id), global, WebGLProgramBinding::Wrap) + pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLProgram>> { + let (sender, receiver) = channel(); + renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap(); + + let result = receiver.recv().unwrap(); + result.map(|program_id| WebGLProgram::new(global, renderer, *program_id)) + } + + pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLProgram> { + reflect_dom_object(box WebGLProgram::new_inherited(renderer, id), global, WebGLProgramBinding::Wrap) } } pub trait WebGLProgramHelpers { - fn get_id(self) -> u32; + fn delete(self); + fn link(self); + fn use_program(self); + fn attach_shader(self, shader: &WebGLShader) -> WebGLResult<()>; + fn get_attrib_location(self, name: String) -> WebGLResult<Option<i32>>; + fn get_uniform_location(self, name: String) -> WebGLResult<Option<i32>>; } impl<'a> WebGLProgramHelpers for &'a WebGLProgram { - fn get_id(self) -> u32 { - self.id + /// glDeleteProgram + fn delete(self) { + if !self.is_deleted.get() { + self.is_deleted.set(true); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteProgram(self.id))).unwrap(); + } + } + + /// glLinkProgram + fn link(self) { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::LinkProgram(self.id))).unwrap(); + } + + /// glUseProgram + fn use_program(self) { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::UseProgram(self.id))).unwrap(); + } + + /// glAttachShader + fn attach_shader(self, shader: &WebGLShader) -> WebGLResult<()> { + let shader_slot = match shader.gl_type() { + constants::FRAGMENT_SHADER => &self.fragment_shader, + constants::VERTEX_SHADER => &self.vertex_shader, + _ => return Err(WebGLError::InvalidOperation), + }; + + // TODO(ecoal95): Differentiate between same shader already assigned and other previous + // shader. + if shader_slot.get().is_some() { + return Err(WebGLError::InvalidOperation); + } + + shader_slot.set(Some(JS::from_ref(shader))); + + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(self.id, shader.id()))).unwrap(); + + Ok(()) + } + + /// glGetAttribLocation + fn get_attrib_location(self, name: String) -> WebGLResult<Option<i32>> { + if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN { + return Err(WebGLError::InvalidValue); + } + + // Check if the name is reserved + if name.starts_with("webgl") || name.starts_with("_webgl_") { + return Ok(None); + } + + let (sender, receiver) = channel(); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetAttribLocation(self.id, name, sender))).unwrap(); + Ok(receiver.recv().unwrap()) + } + + /// glGetUniformLocation + fn get_uniform_location(self, name: String) -> WebGLResult<Option<i32>> { + if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN { + return Err(WebGLError::InvalidValue); + } + + // Check if the name is reserved + if name.starts_with("webgl") || name.starts_with("_webgl_") { + return Ok(None); + } + + let (sender, receiver) = channel(); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetUniformLocation(self.id, name, sender))).unwrap(); + Ok(receiver.recv().unwrap()) } } diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index 5165235acfb..d7084564ec3 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -9,31 +9,60 @@ use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg}; +use std::sync::mpsc::{channel, Sender}; +use std::cell::Cell; + #[dom_struct] pub struct WebGLRenderbuffer { webgl_object: WebGLObject, id: u32, + is_deleted: Cell<bool>, + renderer: Sender<CanvasMsg>, } impl WebGLRenderbuffer { - fn new_inherited(id: u32) -> WebGLRenderbuffer { + fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLRenderbuffer { WebGLRenderbuffer { webgl_object: WebGLObject::new_inherited(), id: id, + is_deleted: Cell::new(false), + renderer: renderer, } } - pub fn new(global: GlobalRef, id: u32) -> Root<WebGLRenderbuffer> { - reflect_dom_object(box WebGLRenderbuffer::new_inherited(id), global, WebGLRenderbufferBinding::Wrap) + pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLRenderbuffer>> { + let (sender, receiver) = channel(); + renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateRenderbuffer(sender))).unwrap(); + + let result = receiver.recv().unwrap(); + result.map(|renderbuffer_id| WebGLRenderbuffer::new(global, renderer, *renderbuffer_id)) + } + + pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLRenderbuffer> { + reflect_dom_object(box WebGLRenderbuffer::new_inherited(renderer, id), global, WebGLRenderbufferBinding::Wrap) } } pub trait WebGLRenderbufferHelpers { - fn get_id(self) -> u32; + fn id(self) -> u32; + fn bind(self, target: u32); + fn delete(self); } impl<'a> WebGLRenderbufferHelpers for &'a WebGLRenderbuffer { - fn get_id(self) -> u32 { + fn id(self) -> u32 { self.id } + + fn bind(self, target: u32) { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, self.id))).unwrap(); + } + + fn delete(self) { + if !self.is_deleted.get() { + self.is_deleted.set(true); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteRenderbuffer(self.id))).unwrap(); + } + } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 766c61fa57c..123c1e200c3 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -3,10 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use canvas::webgl_paint_task::WebGLPaintTask; -use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; -use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding; -use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{ - WebGLContextAttributes, WebGLRenderingContextMethods, WebGLRenderingContextConstants}; +use canvas_traits:: + {CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLError, + WebGLShaderParameter, WebGLFramebufferBindingRequest}; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding:: + {self, WebGLContextAttributes, WebGLRenderingContextMethods}; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; + use dom::bindings::global::{GlobalRef, GlobalField}; use dom::bindings::js::{JS, LayoutJS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; @@ -22,7 +25,8 @@ use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelper use euclid::size::Size2D; use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView}; -use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value}; +use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value, BooleanValue}; +use std::cell::Cell; use std::mem; use std::ptr; use std::slice; @@ -30,12 +34,27 @@ use std::sync::mpsc::{channel, Sender}; use util::str::DOMString; use offscreen_gl_context::GLContextAttributes; +pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256; + +macro_rules! handle_potential_webgl_error { + ($context:ident, $call:expr, $return_on_error:expr) => { + match $call { + Ok(ret) => ret, + Err(error) => { + $context.handle_webgl_error(error); + $return_on_error + } + } + } +} + #[dom_struct] pub struct WebGLRenderingContext { reflector_: Reflector, global: GlobalField, renderer: Sender<CanvasMsg>, canvas: JS<HTMLCanvasElement>, + last_error: Cell<Option<WebGLError>>, } impl WebGLRenderingContext { @@ -50,6 +69,7 @@ impl WebGLRenderingContext { reflector_: Reflector::new(), global: GlobalField::from_rooted(&global), renderer: chan, + last_error: Cell::new(None), canvas: JS::from_ref(canvas), }) } @@ -102,16 +122,33 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // TODO(ecoal95): Implement the missing parameters from the spec let mut rval = RootedValue::new(cx, UndefinedValue()); match parameter { - WebGLRenderingContextConstants::VERSION => + constants::VERSION => "WebGL 1.0".to_jsval(cx, rval.handle_mut()), - WebGLRenderingContextConstants::RENDERER | - WebGLRenderingContextConstants::VENDOR => + constants::RENDERER | + constants::VENDOR => "Mozilla/Servo".to_jsval(cx, rval.handle_mut()), _ => rval.ptr = NullValue(), } rval.ptr } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn GetError(self) -> u32 { + let error_code = if let Some(error) = self.last_error.get() { + match 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, + } + } else { + constants::NO_ERROR + }; + self.last_error.set(None); + error_code + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.2 fn GetContextAttributes(self) -> Option<WebGLContextAttributes> { let (sender, receiver) = channel(); @@ -174,43 +211,49 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn AttachShader(self, program: Option<&WebGLProgram>, shader: Option<&WebGLShader>) { - let program_id = match program { - Some(program) => program.get_id(), - None => return, - }; - let shader_id = match shader { - Some(shader) => shader.get_id(), - None => return, - }; - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(program_id, shader_id))).unwrap() + if let Some(program) = program { + if let Some(shader) = shader { + handle_potential_webgl_error!(self, program.attach_shader(shader), ()); + } + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn BindBuffer(self, target: u32, buffer: Option<&WebGLBuffer>) { - let id = buffer.map(|buf| buf.get_id()).unwrap_or(0); - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, id))).unwrap() + if let Some(buffer) = buffer { + buffer.bind(target) + } else { + // Unbind the current buffer + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0))).unwrap() + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 fn BindFramebuffer(self, target: u32, framebuffer: Option<&WebGLFramebuffer>) { - let id = framebuffer.map(|fb| fb.get_id()).unwrap_or(0); - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::BindFramebuffer(target, id))).unwrap() + if let Some(framebuffer) = framebuffer { + framebuffer.bind(target) + } else { + // Bind the default framebuffer + let cmd = CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default); + self.renderer.send(CanvasMsg::WebGL(cmd)).unwrap(); + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 fn BindRenderbuffer(self, target: u32, renderbuffer: Option<&WebGLRenderbuffer>) { - let id = renderbuffer.map(|rb| rb.get_id()).unwrap_or(0); - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, id))).unwrap() + if let Some(renderbuffer) = renderbuffer { + renderbuffer.bind(target) + } else { + // Unbind the currently bound renderbuffer + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0))).unwrap() + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 fn BindTexture(self, target: u32, texture: Option<&WebGLTexture>) { - let id = texture.map(|tex| tex.get_id()).unwrap_or(0); - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(target, id))).unwrap() + if let Some(texture) = texture { + texture.bind(target) + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 @@ -246,104 +289,84 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn CompileShader(self, shader: Option<&WebGLShader>) { - let shader_id = match shader { - Some(shader) => shader.get_id(), - None => return, - }; - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CompileShader(shader_id))).unwrap() + if let Some(shader) = shader { + shader.compile() + } } // TODO(ecoal95): Probably in the future we should keep track of the // generated objects, either here or in the webgl task // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn CreateBuffer(self) -> Option<Root<WebGLBuffer>> { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap(); - receiver.recv().unwrap() - .map(|buffer_id| WebGLBuffer::new(self.global.root().r(), *buffer_id)) + WebGLBuffer::maybe_new(self.global.root().r(), self.renderer.clone()) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 fn CreateFramebuffer(self) -> Option<Root<WebGLFramebuffer>> { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateFramebuffer(sender))).unwrap(); - receiver.recv().unwrap() - .map(|fb_id| WebGLFramebuffer::new(self.global.root().r(), *fb_id)) + WebGLFramebuffer::maybe_new(self.global.root().r(), self.renderer.clone()) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 fn CreateRenderbuffer(self) -> Option<Root<WebGLRenderbuffer>> { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateRenderbuffer(sender))).unwrap(); - receiver.recv().unwrap() - .map(|program_id| WebGLRenderbuffer::new(self.global.root().r(), *program_id)) + WebGLRenderbuffer::maybe_new(self.global.root().r(), self.renderer.clone()) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 fn CreateTexture(self) -> Option<Root<WebGLTexture>> { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap(); - receiver.recv().unwrap() - .map(|texture_id| WebGLTexture::new(self.global.root().r(), *texture_id)) + WebGLTexture::maybe_new(self.global.root().r(), self.renderer.clone()) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn CreateProgram(self) -> Option<Root<WebGLProgram>> { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap(); - receiver.recv().unwrap() - .map(|program_id| WebGLProgram::new(self.global.root().r(), *program_id)) + WebGLProgram::maybe_new(self.global.root().r(), self.renderer.clone()) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 // TODO(ecoal95): Check if constants are cross-platform or if we must make a translation // between WebGL constants and native ones. fn CreateShader(self, shader_type: u32) -> Option<Root<WebGLShader>> { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap(); - receiver.recv().unwrap() - .map(|shader_id| WebGLShader::new(self.global.root().r(), *shader_id)) + WebGLShader::maybe_new(self.global.root().r(), self.renderer.clone(), shader_type) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn DeleteBuffer(self, buffer: Option<&WebGLBuffer>) { if let Some(buffer) = buffer { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteBuffer(buffer.get_id()))).unwrap(); + buffer.delete() } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 fn DeleteFramebuffer(self, framebuffer: Option<&WebGLFramebuffer>) { if let Some(framebuffer) = framebuffer { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteFramebuffer(framebuffer.get_id()))).unwrap(); + framebuffer.delete() } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 fn DeleteRenderbuffer(self, renderbuffer: Option<&WebGLRenderbuffer>) { if let Some(renderbuffer) = renderbuffer { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteRenderbuffer(renderbuffer.get_id()))).unwrap(); + renderbuffer.delete() } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 fn DeleteTexture(self, texture: Option<&WebGLTexture>) { if let Some(texture) = texture { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(texture.get_id()))).unwrap(); + texture.delete() } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn DeleteProgram(self, program: Option<&WebGLProgram>) { if let Some(program) = program { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteProgram(program.get_id()))).unwrap(); + program.delete() } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn DeleteShader(self, shader: Option<&WebGLShader>) { if let Some(shader) = shader { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteShader(shader.get_id()))).unwrap(); + shader.delete() } } @@ -359,21 +382,17 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn GetAttribLocation(self, program: Option<&WebGLProgram>, name: DOMString) -> i32 { - let program_id = match program { - Some(program) => program.get_id(), - None => return -1, - }; - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetAttribLocation(program_id, name, sender))).unwrap(); - receiver.recv().unwrap() + if let Some(program) = program { + handle_potential_webgl_error!(self, program.get_attrib_location(name), None).unwrap_or(-1) + } else { + -1 + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn GetShaderInfoLog(self, shader: Option<&WebGLShader>) -> Option<DOMString> { if let Some(shader) = shader { - let (sender, receiver) = channel(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderInfoLog(shader.get_id(), sender))).unwrap(); - Some(receiver.recv().unwrap()) + shader.info_log() } else { None } @@ -382,10 +401,11 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn GetShaderParameter(self, _: *mut JSContext, shader: Option<&WebGLShader>, param_id: u32) -> JSVal { if let Some(shader) = shader { - let (sender, receiver) = channel(); - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderParameter(shader.get_id(), param_id, sender))).unwrap(); - Int32Value(receiver.recv().unwrap()) + match handle_potential_webgl_error!(self, shader.parameter(param_id), WebGLShaderParameter::Invalid) { + WebGLShaderParameter::Int(val) => Int32Value(val), + WebGLShaderParameter::Bool(val) => BooleanValue(val), + WebGLShaderParameter::Invalid => NullValue(), + } } else { NullValue() } @@ -396,10 +416,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { program: Option<&WebGLProgram>, name: DOMString) -> Option<Root<WebGLUniformLocation>> { if let Some(program) = program { - let (sender, receiver) = channel(); - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::GetUniformLocation(program.get_id(), name, sender))).unwrap(); - receiver.recv().unwrap() + handle_potential_webgl_error!(self, program.get_uniform_location(name), None) .map(|location| WebGLUniformLocation::new(self.global.root().r(), location)) } else { None @@ -409,15 +426,23 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn LinkProgram(self, program: Option<&WebGLProgram>) { if let Some(program) = program { - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::LinkProgram(program.get_id()))).unwrap() + program.link() } } // 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 { - self.renderer.send( - CanvasMsg::WebGL(CanvasWebGLMsg::ShaderSource(shader.get_id(), source))).unwrap(); + 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> { + if let Some(shader) = shader { + shader.source() + } else { + None } } @@ -428,7 +453,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { uniform: Option<&WebGLUniformLocation>, data: Option<*mut JSObject>) { let uniform_id = match uniform { - Some(uniform) => uniform.get_id(), + Some(uniform) => uniform.id(), None => return, }; @@ -446,18 +471,16 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn UseProgram(self, program: Option<&WebGLProgram>) { - let program_id = match program { - Some(program) => program.get_id(), - None => return, - }; - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::UseProgram(program_id as u32))).unwrap() + if let Some(program) = program { + program.use_program() + } } // 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) { match data_type { - WebGLRenderingContextConstants::FLOAT => { + constants::FLOAT => { let msg = CanvasMsg::WebGL( CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset)); self.renderer.send(msg).unwrap() @@ -473,6 +496,20 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { } } +pub trait WebGLRenderingContextHelpers { + fn handle_webgl_error(&self, err: WebGLError); +} + +impl<'a> WebGLRenderingContextHelpers for &'a WebGLRenderingContext { + 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().is_none() { + self.last_error.set(Some(err)); + } + } +} + pub trait LayoutCanvasWebGLRenderingContextHelpers { #[allow(unsafe_code)] unsafe fn get_renderer(&self) -> Sender<CanvasMsg>; diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index 7030b1fda99..f5d40b16699 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -9,32 +9,118 @@ use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; + +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError, WebGLShaderParameter}; +use std::sync::mpsc::{channel, Sender}; +use std::cell::Cell; +use std::cell::RefCell; + #[dom_struct] pub struct WebGLShader { webgl_object: WebGLObject, id: u32, + gl_type: u32, + source: RefCell<Option<String>>, + is_deleted: Cell<bool>, + // TODO(ecoal95): Evaluate moving this to `WebGLObject` + renderer: Sender<CanvasMsg>, } impl WebGLShader { - fn new_inherited(id: u32) -> WebGLShader { + fn new_inherited(renderer: Sender<CanvasMsg>, id: u32, shader_type: u32) -> WebGLShader { WebGLShader { webgl_object: WebGLObject::new_inherited(), id: id, + gl_type: shader_type, + source: RefCell::new(None), + is_deleted: Cell::new(false), + renderer: renderer, } } - pub fn new(global: GlobalRef, id: u32) -> Root<WebGLShader> { - reflect_dom_object(box WebGLShader::new_inherited(id), global, WebGLShaderBinding::Wrap) + pub fn maybe_new(global: GlobalRef, + renderer: Sender<CanvasMsg>, + shader_type: u32) -> Option<Root<WebGLShader>> { + let (sender, receiver) = channel(); + renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap(); + + let result = receiver.recv().unwrap(); + result.map(|shader_id| WebGLShader::new(global, renderer, *shader_id, shader_type)) + } + + pub fn new(global: GlobalRef, + renderer: Sender<CanvasMsg>, + id: u32, + shader_type: u32) -> Root<WebGLShader> { + reflect_dom_object( + box WebGLShader::new_inherited(renderer, id, shader_type), global, WebGLShaderBinding::Wrap) } } pub trait WebGLShaderHelpers { - fn get_id(self) -> u32; + fn id(self) -> u32; + fn gl_type(self) -> u32; + fn compile(self); + fn delete(self); + fn info_log(self) -> Option<String>; + fn parameter(self, param_id: u32) -> WebGLResult<WebGLShaderParameter>; + fn source(self) -> Option<String>; + fn set_source(self, src: String); } impl<'a> WebGLShaderHelpers for &'a WebGLShader { - fn get_id(self) -> u32 { + fn id(self) -> u32 { self.id } + + fn gl_type(self) -> u32 { + self.gl_type + } + + // TODO(ecoal95): Validate shaders to be conforming to the WebGL spec + /// glCompileShader + fn compile(self) { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CompileShader(self.id))).unwrap() + } + + /// Mark this shader as deleted (if it wasn't previously) + /// and delete it as if calling glDeleteShader. + fn delete(self) { + if !self.is_deleted.get() { + self.is_deleted.set(true); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteShader(self.id))).unwrap() + } + } + + /// glGetShaderInfoLog + fn info_log(self) -> Option<String> { + let (sender, receiver) = channel(); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderInfoLog(self.id, sender))).unwrap(); + receiver.recv().unwrap() + } + + /// glGetShaderParameter + fn parameter(self, param_id: u32) -> WebGLResult<WebGLShaderParameter> { + match param_id { + constants::SHADER_TYPE | constants::DELETE_STATUS | constants::COMPILE_STATUS => {}, + _ => return Err(WebGLError::InvalidEnum), + } + + let (sender, receiver) = channel(); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderParameter(self.id, param_id, sender))).unwrap(); + Ok(receiver.recv().unwrap()) + } + + /// Get the shader source + fn source(self) -> Option<String> { + self.source.borrow().clone() + } + + /// glShaderSource + fn set_source(self, source: String) { + *self.source.borrow_mut() = Some(source.clone()); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ShaderSource(self.id, source))).unwrap() + } } diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index d871bc598da..ab934a5f47d 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -9,31 +9,60 @@ use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg}; +use std::sync::mpsc::{channel, Sender}; +use std::cell::Cell; + #[dom_struct] pub struct WebGLTexture { webgl_object: WebGLObject, id: u32, + is_deleted: Cell<bool>, + renderer: Sender<CanvasMsg>, } impl WebGLTexture { - fn new_inherited(id: u32) -> WebGLTexture { + fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLTexture { WebGLTexture { webgl_object: WebGLObject::new_inherited(), id: id, + is_deleted: Cell::new(false), + renderer: renderer, } } - pub fn new(global: GlobalRef, id: u32) -> Root<WebGLTexture> { - reflect_dom_object(box WebGLTexture::new_inherited(id), global, WebGLTextureBinding::Wrap) + pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLTexture>> { + let (sender, receiver) = channel(); + renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap(); + + let result = receiver.recv().unwrap(); + result.map(|texture_id| WebGLTexture::new(global, renderer, *texture_id)) + } + + pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLTexture> { + reflect_dom_object(box WebGLTexture::new_inherited(renderer, id), global, WebGLTextureBinding::Wrap) } } pub trait WebGLTextureHelpers { - fn get_id(self) -> u32; + fn id(self) -> u32; + fn bind(self, target: u32); + fn delete(self); } impl<'a> WebGLTextureHelpers for &'a WebGLTexture { - fn get_id(self) -> u32 { + fn id(self) -> u32 { self.id } + + fn bind(self, target: u32) { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(self.id, target))).unwrap(); + } + + fn delete(self) { + if !self.is_deleted.get() { + self.is_deleted.set(true); + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(self.id))).unwrap(); + } + } } diff --git a/components/script/dom/webgluniformlocation.rs b/components/script/dom/webgluniformlocation.rs index 675ddf42ca0..56a97555ce6 100644 --- a/components/script/dom/webgluniformlocation.rs +++ b/components/script/dom/webgluniformlocation.rs @@ -28,11 +28,11 @@ impl WebGLUniformLocation { } pub trait WebGLUniformLocationHelpers { - fn get_id(self) -> i32; + fn id(self) -> i32; } impl<'a> WebGLUniformLocationHelpers for &'a WebGLUniformLocation { - fn get_id(self) -> i32 { + fn id(self) -> i32 { self.id } } diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index d3865c91c4a..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); @@ -569,7 +569,7 @@ interface WebGLRenderingContextBase //WebGLShaderPrecisionFormat? getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype); DOMString? getShaderInfoLog(WebGLShader? shader); - //DOMString? getShaderSource(WebGLShader? shader); + DOMString? getShaderSource(WebGLShader? shader); //any getTexParameter(GLenum target, GLenum pname); |