diff options
-rw-r--r-- | components/canvas/lib.rs | 1 | ||||
-rw-r--r-- | components/canvas/webgl_paint_task.rs | 155 | ||||
-rw-r--r-- | components/canvas_traits/lib.rs | 29 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 3 | ||||
-rw-r--r-- | components/script/dom/webglframebuffer.rs | 39 | ||||
-rw-r--r-- | components/script/dom/webglrenderbuffer.rs | 39 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 199 | ||||
-rw-r--r-- | components/script/dom/webgltexture.rs | 39 | ||||
-rw-r--r-- | components/script/dom/webgluniformlocation.rs | 17 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLFramebuffer.webidl | 7 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLRenderbuffer.webidl | 7 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLRenderingContext.webidl | 26 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLTexture.webidl | 7 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/interfaces.html | 3 |
14 files changed, 469 insertions, 102 deletions
diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index 962231581ef..4cf6691a786 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -6,6 +6,7 @@ #![feature(collections)] #![feature(rustc_private)] +extern crate core; extern crate canvas_traits; extern crate azure; extern crate cssparser; diff --git a/components/canvas/webgl_paint_task.rs b/components/canvas/webgl_paint_task.rs index 0237d62c830..758aa751b84 100644 --- a/components/canvas/webgl_paint_task.rs +++ b/components/canvas/webgl_paint_task.rs @@ -4,7 +4,7 @@ use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; use geom::size::Size2D; - +use core::nonzero::NonZero; use gleam::gl; use gleam::gl::types::{GLsizei}; @@ -49,11 +49,9 @@ impl WebGLPaintTask { match message { CanvasWebGLMsg::GetContextAttributes(sender) => self.get_context_attributes(sender), CanvasWebGLMsg::AttachShader(program_id, shader_id) => self.attach_shader(program_id, shader_id), - CanvasWebGLMsg::BindBuffer(buffer_type, buffer_id) => self.bind_buffer(buffer_type, buffer_id), CanvasWebGLMsg::BufferData(buffer_type, data, usage) => self.buffer_data(buffer_type, data, usage), CanvasWebGLMsg::Clear(mask) => self.clear(mask), CanvasWebGLMsg::ClearColor(r, g, b, a) => self.clear_color(r, g, b, a), - CanvasWebGLMsg::CreateBuffer(chan) => self.create_buffer(chan), CanvasWebGLMsg::DrawArrays(mode, first, count) => self.draw_arrays(mode, first, count), CanvasWebGLMsg::EnableVertexAttribArray(attrib_id) => self.enable_vertex_attrib_array(attrib_id), CanvasWebGLMsg::GetAttribLocation(program_id, name, chan) => @@ -64,8 +62,22 @@ impl WebGLPaintTask { CanvasWebGLMsg::GetUniformLocation(program_id, name, chan) => self.get_uniform_location(program_id, name, chan), CanvasWebGLMsg::CompileShader(shader_id) => self.compile_shader(shader_id), + CanvasWebGLMsg::CreateBuffer(chan) => self.create_buffer(chan), + CanvasWebGLMsg::CreateFramebuffer(chan) => self.create_framebuffer(chan), + CanvasWebGLMsg::CreateRenderbuffer(chan) => self.create_renderbuffer(chan), + CanvasWebGLMsg::CreateTexture(chan) => self.create_texture(chan), CanvasWebGLMsg::CreateProgram(chan) => self.create_program(chan), CanvasWebGLMsg::CreateShader(shader_type, chan) => self.create_shader(shader_type, chan), + CanvasWebGLMsg::DeleteBuffer(id) => self.delete_buffer(id), + CanvasWebGLMsg::DeleteFramebuffer(id) => self.delete_framebuffer(id), + CanvasWebGLMsg::DeleteRenderbuffer(id) => self.delete_renderbuffer(id), + CanvasWebGLMsg::DeleteTexture(id) => self.delete_texture(id), + CanvasWebGLMsg::DeleteProgram(id) => self.delete_program(id), + CanvasWebGLMsg::DeleteShader(id) => self.delete_shader(id), + CanvasWebGLMsg::BindBuffer(target, id) => self.bind_buffer(target, id), + CanvasWebGLMsg::BindFramebuffer(target, id) => self.bind_framebuffer(target, id), + CanvasWebGLMsg::BindRenderbuffer(target, id) => self.bind_renderbuffer(target, id), + CanvasWebGLMsg::BindTexture(target, id) => self.bind_texture(target, id), CanvasWebGLMsg::LinkProgram(program_id) => self.link_program(program_id), CanvasWebGLMsg::ShaderSource(shader_id, source) => self.shader_source(shader_id, source), CanvasWebGLMsg::Uniform4fv(uniform_id, data) => self.uniform_4fv(uniform_id, data), @@ -121,10 +133,6 @@ impl WebGLPaintTask { gl::attach_shader(program_id, shader_id); } - fn bind_buffer(&self, buffer_type: u32, buffer_id: u32) { - gl::bind_buffer(buffer_type, buffer_id); - } - fn buffer_data(&self, buffer_type: u32, data: Vec<f32>, usage: u32) { gl::buffer_data(buffer_type, &data, usage); } @@ -137,25 +145,123 @@ impl WebGLPaintTask { gl::clear_color(r, g, b, a); } - fn create_buffer(&self, chan: Sender<u32>) { - let buffers = gl::gen_buffers(1); - chan.send(buffers[0]).unwrap(); + fn create_buffer(&self, chan: Sender<Option<NonZero<u32>>>) { + let buffer = gl::gen_buffers(1)[0]; + let buffer = if buffer == 0 { + None + } else { + Some(unsafe { NonZero::new(buffer) }) + }; + chan.send(buffer).unwrap(); } - fn compile_shader(&self, shader_id: u32) { - gl::compile_shader(shader_id); + fn create_framebuffer(&self, chan: Sender<Option<NonZero<u32>>>) { + let framebuffer = gl::gen_framebuffers(1)[0]; + let framebuffer = if framebuffer == 0 { + None + } else { + Some(unsafe { NonZero::new(framebuffer) }) + }; + chan.send(framebuffer).unwrap(); + } + + fn create_renderbuffer(&self, chan: Sender<Option<NonZero<u32>>>) { + let renderbuffer = gl::gen_renderbuffers(1)[0]; + let renderbuffer = if renderbuffer == 0 { + None + } else { + Some(unsafe { NonZero::new(renderbuffer) }) + }; + chan.send(renderbuffer).unwrap(); + } + + fn create_texture(&self, chan: Sender<Option<NonZero<u32>>>) { + let texture = gl::gen_framebuffers(1)[0]; + let texture = if texture == 0 { + None + } else { + Some(unsafe { NonZero::new(texture) }) + }; + chan.send(texture).unwrap(); } - fn create_program(&self, chan: Sender<u32>) { + fn create_program(&self, chan: Sender<Option<NonZero<u32>>>) { let program = gl::create_program(); + let program = if program == 0 { + None + } else { + Some(unsafe { NonZero::new(program) }) + }; chan.send(program).unwrap(); } - fn create_shader(&self, shader_type: u32, chan: Sender<u32>) { + fn create_shader(&self, shader_type: u32, chan: Sender<Option<NonZero<u32>>>) { let shader = gl::create_shader(shader_type); + let shader = if shader == 0 { + None + } else { + Some(unsafe { NonZero::new(shader) }) + }; chan.send(shader).unwrap(); } + #[inline] + fn delete_buffer(&self, id: u32) { + gl::delete_buffers(&[id]); + } + + #[inline] + fn delete_renderbuffer(&self, id: u32) { + gl::delete_renderbuffers(&[id]); + } + + #[inline] + fn delete_framebuffer(&self, id: u32) { + gl::delete_framebuffers(&[id]); + } + + #[inline] + fn delete_texture(&self, id: u32) { + gl::delete_textures(&[id]); + } + + #[inline] + fn delete_program(&self, id: u32) { + gl::delete_program(id); + } + + #[inline] + fn delete_shader(&self, id: u32) { + gl::delete_shader(id); + } + + #[inline] + fn bind_buffer(&self, target: u32, id: u32) { + gl::bind_buffer(target, id); + } + + #[inline] + fn bind_framebuffer(&self, target: u32, id: u32) { + gl::bind_framebuffer(target, id); + } + + #[inline] + fn bind_renderbuffer(&self, target: u32, id: u32) { + gl::bind_renderbuffer(target, id); + } + + #[inline] + fn bind_texture(&self, target: u32, id: u32) { + gl::bind_texture(target, id); + } + + // TODO(ecoal95): This is not spec-compliant, we must check + // the version of GLSL used. This functionality should probably + // be in the WebGLShader object + fn compile_shader(&self, shader_id: u32) { + gl::compile_shader(shader_id); + } + fn draw_arrays(&self, mode: u32, first: i32, count: i32) { gl::draw_arrays(mode, first, count); } @@ -179,9 +285,15 @@ impl WebGLPaintTask { chan.send(parameter as i32).unwrap(); } - fn get_uniform_location(&self, program_id: u32, name: String, chan: Sender<u32>) { - let uniform_location = gl::get_uniform_location(program_id, &name); - chan.send(uniform_location as u32).unwrap(); + fn get_uniform_location(&self, program_id: u32, name: String, chan: Sender<Option<i32>>) { + let location = gl::get_uniform_location(program_id, &name); + let location = if location == -1 { + None + } else { + Some(location) + }; + + chan.send(location).unwrap(); } fn link_program(&self, program_id: u32) { @@ -218,13 +330,12 @@ impl WebGLPaintTask { unimplemented!() } - fn shader_source(&self, shader_id: u32, source_lines: Vec<String>) { - let mut lines: Vec<&[u8]> = source_lines.iter().map(|line| line.as_bytes()).collect(); - gl::shader_source(shader_id, &mut lines); + fn shader_source(&self, shader_id: u32, source: String) { + gl::shader_source(shader_id, &[source.as_bytes()]); } - fn uniform_4fv(&self, uniform_id: u32, data: Vec<f32>) { - gl::uniform_4f(uniform_id as i32, data[0], data[1], data[2], data[3]); + fn uniform_4fv(&self, uniform_id: i32, data: Vec<f32>) { + gl::uniform_4f(uniform_id, data[0], data[1], data[2], data[3]); } fn use_program(&self, program_id: u32) { diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 3b2d19bf755..d0ad89ce284 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -4,6 +4,8 @@ #![crate_name = "canvas_traits"] #![crate_type = "rlib"] +#![feature(core)] +extern crate core; extern crate azure; extern crate geom; extern crate cssparser; @@ -24,6 +26,7 @@ use gfx_traits::color; use std::sync::mpsc::{Sender}; use layers::platform::surface::NativeSurface; use offscreen_gl_context::GLContextAttributes; +use core::nonzero::NonZero; #[derive(Clone)] pub enum CanvasMsg { @@ -70,23 +73,35 @@ pub enum Canvas2dMsg { pub enum CanvasWebGLMsg { GetContextAttributes(Sender<GLContextAttributes>), AttachShader(u32, u32), - BindBuffer(u32, u32), BufferData(u32, Vec<f32>, u32), Clear(u32), ClearColor(f32, f32, f32, f32), CompileShader(u32), - CreateBuffer(Sender<u32>), - CreateProgram(Sender<u32>), - CreateShader(u32, Sender<u32>), + CreateBuffer(Sender<Option<NonZero<u32>>>), + CreateFramebuffer(Sender<Option<NonZero<u32>>>), + CreateRenderbuffer(Sender<Option<NonZero<u32>>>), + CreateTexture(Sender<Option<NonZero<u32>>>), + CreateProgram(Sender<Option<NonZero<u32>>>), + CreateShader(u32, Sender<Option<NonZero<u32>>>), + DeleteBuffer(u32), + DeleteFramebuffer(u32), + DeleteRenderbuffer(u32), + DeleteTexture(u32), + DeleteProgram(u32), + DeleteShader(u32), + BindBuffer(u32, u32), + BindFramebuffer(u32, u32), + 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>), - GetUniformLocation(u32, String, Sender<u32>), + GetUniformLocation(u32, String, Sender<Option<i32>>), LinkProgram(u32), - ShaderSource(u32, Vec<String>), - Uniform4fv(u32, Vec<f32>), + ShaderSource(u32, String), + Uniform4fv(i32, Vec<f32>), UseProgram(u32), VertexAttribPointer2f(u32, i32, bool, i32, i64), Viewport(i32, i32, i32, i32), diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index e693b1f70de..b0f1c5257b1 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -332,6 +332,9 @@ pub mod webglprogram; pub mod webglrenderingcontext; pub mod webglshader; pub mod webgluniformlocation; +pub mod webgltexture; +pub mod webglframebuffer; +pub mod webglrenderbuffer; pub mod websocket; pub mod window; pub mod worker; diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs new file mode 100644 index 00000000000..c1489c99e72 --- /dev/null +++ b/components/script/dom/webglframebuffer.rs @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl +use dom::bindings::codegen::Bindings::WebGLFramebufferBinding; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::utils::reflect_dom_object; +use dom::webglobject::WebGLObject; + +#[dom_struct] +pub struct WebGLFramebuffer { + webgl_object: WebGLObject, + id: u32, +} + +impl WebGLFramebuffer { + fn new_inherited(id: u32) -> WebGLFramebuffer { + WebGLFramebuffer { + webgl_object: WebGLObject::new_inherited(), + id: id, + } + } + + pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLFramebuffer> { + reflect_dom_object(box WebGLFramebuffer::new_inherited(id), global, WebGLFramebufferBinding::Wrap) + } +} + +pub trait WebGLFramebufferHelpers { + fn get_id(&self) -> u32; +} + +impl<'a> WebGLFramebufferHelpers for JSRef<'a, WebGLFramebuffer> { + fn get_id(&self) -> u32 { + self.id + } +} diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs new file mode 100644 index 00000000000..12cdd8240c6 --- /dev/null +++ b/components/script/dom/webglrenderbuffer.rs @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl +use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::utils::reflect_dom_object; +use dom::webglobject::WebGLObject; + +#[dom_struct] +pub struct WebGLRenderbuffer { + webgl_object: WebGLObject, + id: u32, +} + +impl WebGLRenderbuffer { + fn new_inherited(id: u32) -> WebGLRenderbuffer { + WebGLRenderbuffer { + webgl_object: WebGLObject::new_inherited(), + id: id, + } + } + + pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLRenderbuffer> { + reflect_dom_object(box WebGLRenderbuffer::new_inherited(id), global, WebGLRenderbufferBinding::Wrap) + } +} + +pub trait WebGLRenderbufferHelpers { + fn get_id(&self) -> u32; +} + +impl<'a> WebGLRenderbufferHelpers for JSRef<'a, WebGLRenderbuffer> { + fn get_id(&self) -> u32 { + self.id + } +} diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 4031c36f2c2..8e5e23cb3c6 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -13,6 +13,9 @@ use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::conversions::ToJSValConvertible; use dom::htmlcanvaselement::{HTMLCanvasElement}; use dom::webglbuffer::{WebGLBuffer, WebGLBufferHelpers}; +use dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferHelpers}; +use dom::webglrenderbuffer::{WebGLRenderbuffer, WebGLRenderbufferHelpers}; +use dom::webgltexture::{WebGLTexture, WebGLTextureHelpers}; use dom::webglshader::{WebGLShader, WebGLShaderHelpers}; use dom::webglprogram::{WebGLProgram, WebGLProgramHelpers}; use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelpers}; @@ -128,6 +131,13 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { }) } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.14 + fn GetExtension(self, _cx: *mut JSContext, _name: DOMString) -> *mut JSObject { + // TODO(ecoal95) we actually do not support extensions. + // `getSupportedExtensions` cannot be implemented as of right now (see #544) + 0 as *mut JSObject + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn AttachShader(self, program: Option<JSRef<WebGLProgram>>, shader: Option<JSRef<WebGLShader>>) { let program_id = match program { @@ -142,12 +152,31 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BindBuffer(self, buffer_type: u32, buffer: Option<JSRef<WebGLBuffer>>) { - let buffer_id = match buffer { - Some(buffer) => buffer.get_id(), - None => return, - }; - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(buffer_type, buffer_id))).unwrap() + fn BindBuffer(self, target: u32, buffer: Option<JSRef<WebGLBuffer>>) { + let id = buffer.map(|buf| buf.get_id()).unwrap_or(0); + self.renderer.send( + CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, id))).unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 + fn BindFramebuffer(self, target: u32, framebuffer: Option<JSRef<WebGLFramebuffer>>) { + let id = framebuffer.map(|fb| fb.get_id()).unwrap_or(0); + self.renderer.send( + CanvasMsg::WebGL(CanvasWebGLMsg::BindFramebuffer(target, id))).unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 + fn BindRenderbuffer(self, target: u32, renderbuffer: Option<JSRef<WebGLRenderbuffer>>) { + let id = renderbuffer.map(|rb| rb.get_id()).unwrap_or(0); + self.renderer.send( + CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, id))).unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + fn BindTexture(self, target: u32, texture: Option<JSRef<WebGLTexture>>) { + let id = texture.map(|tex| tex.get_id()).unwrap_or(0); + self.renderer.send( + CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(target, id))).unwrap() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 @@ -191,25 +220,98 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CompileShader(shader_id))).unwrap() } + // 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<Temporary<WebGLBuffer>> { - let (sender, receiver) = channel::<u32>(); + let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap(); - Some(WebGLBuffer::new(self.global.root().r(), receiver.recv().unwrap())) + receiver.recv().unwrap() + .map(|buffer_id| WebGLBuffer::new(self.global.root().r(), *buffer_id)) + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 + fn CreateFramebuffer(self) -> Option<Temporary<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)) + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 + fn CreateRenderbuffer(self) -> Option<Temporary<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)) + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + fn CreateTexture(self) -> Option<Temporary<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)) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn CreateProgram(self) -> Option<Temporary<WebGLProgram>> { - let (sender, receiver) = channel::<u32>(); + let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap(); - Some(WebGLProgram::new(self.global.root().r(), receiver.recv().unwrap())) + receiver.recv().unwrap() + .map(|program_id| WebGLProgram::new(self.global.root().r(), *program_id)) } // 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<Temporary<WebGLShader>> { - let (sender, receiver) = channel::<u32>(); + let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap(); - Some(WebGLShader::new(self.global.root().r(), receiver.recv().unwrap())) + receiver.recv().unwrap() + .map(|shader_id| WebGLShader::new(self.global.root().r(), *shader_id)) + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 + fn DeleteBuffer(self, buffer: Option<JSRef<WebGLBuffer>>) { + if let Some(buffer) = buffer { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteBuffer(buffer.get_id()))).unwrap(); + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 + fn DeleteFramebuffer(self, framebuffer: Option<JSRef<WebGLFramebuffer>>) { + if let Some(framebuffer) = framebuffer { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteFramebuffer(framebuffer.get_id()))).unwrap(); + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 + fn DeleteRenderbuffer(self, renderbuffer: Option<JSRef<WebGLRenderbuffer>>) { + if let Some(renderbuffer) = renderbuffer { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteRenderbuffer(renderbuffer.get_id()))).unwrap(); + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + fn DeleteTexture(self, texture: Option<JSRef<WebGLTexture>>) { + if let Some(texture) = texture { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(texture.get_id()))).unwrap(); + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 + fn DeleteProgram(self, program: Option<JSRef<WebGLProgram>>) { + if let Some(program) = program { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteProgram(program.get_id()))).unwrap(); + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 + fn DeleteShader(self, shader: Option<JSRef<WebGLShader>>) { + if let Some(shader) = shader { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteShader(shader.get_id()))).unwrap(); + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11 @@ -228,69 +330,62 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { Some(program) => program.get_id(), None => return -1, }; - let (sender, receiver) = channel::<i32>(); + let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetAttribLocation(program_id, name, sender))).unwrap(); receiver.recv().unwrap() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn GetShaderInfoLog(self, shader: Option<JSRef<WebGLShader>>) -> Option<DOMString> { - let shader_id = match shader { - Some(shader) => shader.get_id(), - None => return None, - }; - let (sender, receiver) = channel::<String>(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderInfoLog(shader_id, sender))).unwrap(); - let info = receiver.recv().unwrap(); - Some(info) + 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()) + } else { + None + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn GetShaderParameter(self, _: *mut JSContext, shader: Option<JSRef<WebGLShader>>, param_id: u32) -> JSVal { - let shader_id = match shader { - Some(shader) => shader.get_id(), - None => return NullValue(), - }; - let (sender, receiver) = channel::<i32>(); - let msg = CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderParameter(shader_id, param_id, sender)); - self.renderer.send(msg).unwrap(); - Int32Value(receiver.recv().unwrap()) + 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()) + } else { + NullValue() + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn GetUniformLocation(self, program: Option<JSRef<WebGLProgram>>, name: DOMString) -> Option<Temporary<WebGLUniformLocation>> { - let program_id = match program { - Some(program) => program.get_id(), - None => return None, - }; - let (sender, receiver) = channel::<u32>(); - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetUniformLocation(program_id, name, sender))).unwrap(); - Some(WebGLUniformLocation::new(self.global.root().r(), receiver.recv().unwrap())) + 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() + .map(|location| WebGLUniformLocation::new(self.global.root().r(), location)) + } else { + None + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn LinkProgram(self, program: Option<JSRef<WebGLProgram>>) { - let program_id = match program { - Some(program) => program.get_id(), - None => return, - }; - self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::LinkProgram(program_id))).unwrap() + if let Some(program) = program { + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::LinkProgram(program.get_id()))).unwrap() + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn ShaderSource(self, shader: Option<JSRef<WebGLShader>>, source: DOMString) { - let shader_id = match shader { - Some(shader) => shader.get_id(), - None => return, - }; - let source_lines: Vec<String> = source.trim() - .split(|c: char| c == '\n') - .map(|line: &str| String::from_str(line) + "\n") - .collect(); - let msg = CanvasMsg::WebGL(CanvasWebGLMsg::ShaderSource(shader_id, source_lines)); - self.renderer.send(msg).unwrap() + if let Some(shader) = shader { + self.renderer.send( + CanvasMsg::WebGL(CanvasWebGLMsg::ShaderSource(shader.get_id(), source))).unwrap(); + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -303,10 +398,12 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { Some(uniform) => uniform.get_id(), None => return, }; + let data = match data { Some(data) => data, None => return, }; + let data_vec: Vec<f32>; unsafe { let data_f32 = JS_GetFloat32ArrayData(data, cx); diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs new file mode 100644 index 00000000000..882f56ff52f --- /dev/null +++ b/components/script/dom/webgltexture.rs @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl +use dom::bindings::codegen::Bindings::WebGLTextureBinding; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::utils::reflect_dom_object; +use dom::webglobject::WebGLObject; + +#[dom_struct] +pub struct WebGLTexture { + webgl_object: WebGLObject, + id: u32, +} + +impl WebGLTexture { + fn new_inherited(id: u32) -> WebGLTexture { + WebGLTexture { + webgl_object: WebGLObject::new_inherited(), + id: id, + } + } + + pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLTexture> { + reflect_dom_object(box WebGLTexture::new_inherited(id), global, WebGLTextureBinding::Wrap) + } +} + +pub trait WebGLTextureHelpers { + fn get_id(&self) -> u32; +} + +impl<'a> WebGLTextureHelpers for JSRef<'a, WebGLTexture> { + fn get_id(&self) -> u32 { + self.id + } +} diff --git a/components/script/dom/webgluniformlocation.rs b/components/script/dom/webgluniformlocation.rs index 8d7beab3894..3f97000eedd 100644 --- a/components/script/dom/webgluniformlocation.rs +++ b/components/script/dom/webgluniformlocation.rs @@ -6,34 +6,33 @@ use dom::bindings::codegen::Bindings::WebGLUniformLocationBinding; use dom::bindings::global::GlobalRef; use dom::bindings::js::{Temporary, JSRef}; -use dom::bindings::utils::reflect_dom_object; -use dom::webglobject::WebGLObject; +use dom::bindings::utils::{Reflector,reflect_dom_object}; #[dom_struct] pub struct WebGLUniformLocation { - webgl_object: WebGLObject, - id: u32, + reflector_: Reflector, + id: i32, } impl WebGLUniformLocation { - fn new_inherited(id: u32) -> WebGLUniformLocation { + fn new_inherited(id: i32) -> WebGLUniformLocation { WebGLUniformLocation { - webgl_object: WebGLObject::new_inherited(), + reflector_: Reflector::new(), id: id, } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLUniformLocation> { + pub fn new(global: GlobalRef, id: i32) -> Temporary<WebGLUniformLocation> { reflect_dom_object(box WebGLUniformLocation::new_inherited(id), global, WebGLUniformLocationBinding::Wrap) } } pub trait WebGLUniformLocationHelpers { - fn get_id(&self) -> u32; + fn get_id(&self) -> i32; } impl<'a> WebGLUniformLocationHelpers for JSRef<'a, WebGLUniformLocation> { - fn get_id(&self) -> u32 { + fn get_id(&self) -> i32 { self.id } } diff --git a/components/script/dom/webidls/WebGLFramebuffer.webidl b/components/script/dom/webidls/WebGLFramebuffer.webidl new file mode 100644 index 00000000000..76454370410 --- /dev/null +++ b/components/script/dom/webidls/WebGLFramebuffer.webidl @@ -0,0 +1,7 @@ +// +// WebGL IDL definitions scraped from the Khronos specification: +// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.7 +// + +interface WebGLFramebuffer : WebGLObject { +}; diff --git a/components/script/dom/webidls/WebGLRenderbuffer.webidl b/components/script/dom/webidls/WebGLRenderbuffer.webidl new file mode 100644 index 00000000000..120c7272965 --- /dev/null +++ b/components/script/dom/webidls/WebGLRenderbuffer.webidl @@ -0,0 +1,7 @@ +// +// WebGL IDL definitions scraped from the Khronos specification: +// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.5 +// + +interface WebGLRenderbuffer : WebGLObject { +}; diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 4f33f4e3159..2dbd5f284a9 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -485,15 +485,15 @@ interface WebGLRenderingContextBase //[WebGLHandlesContextLoss] boolean isContextLost(); //sequence<DOMString>? getSupportedExtensions(); - //object? getExtension(DOMString name); + object? getExtension(DOMString name); //void activeTexture(GLenum texture); void attachShader(WebGLProgram? program, WebGLShader? shader); //void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name); void bindBuffer(GLenum target, WebGLBuffer? buffer); - //void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer); - //void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer); - //void bindTexture(GLenum target, WebGLTexture? texture); + void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer); + void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer); + void bindTexture(GLenum target, WebGLTexture? texture); //void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); //void blendEquation(GLenum mode); //void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); @@ -533,20 +533,20 @@ interface WebGLRenderingContextBase // GLint x, GLint y, GLsizei width, GLsizei height); WebGLBuffer? createBuffer(); - //WebGLFramebuffer? createFramebuffer(); + WebGLFramebuffer? createFramebuffer(); WebGLProgram? createProgram(); - //WebGLRenderbuffer? createRenderbuffer(); + WebGLRenderbuffer? createRenderbuffer(); WebGLShader? createShader(GLenum type); - //WebGLTexture? createTexture(); + WebGLTexture? createTexture(); //void cullFace(GLenum mode); - //void deleteBuffer(WebGLBuffer? buffer); - //void deleteFramebuffer(WebGLFramebuffer? framebuffer); - //void deleteProgram(WebGLProgram? program); - //void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer); - //void deleteShader(WebGLShader? shader); - //void deleteTexture(WebGLTexture? texture); + void deleteBuffer(WebGLBuffer? buffer); + void deleteFramebuffer(WebGLFramebuffer? framebuffer); + void deleteProgram(WebGLProgram? program); + void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer); + void deleteShader(WebGLShader? shader); + void deleteTexture(WebGLTexture? texture); //void depthFunc(GLenum func); //void depthMask(GLboolean flag); diff --git a/components/script/dom/webidls/WebGLTexture.webidl b/components/script/dom/webidls/WebGLTexture.webidl new file mode 100644 index 00000000000..ef9a4967db8 --- /dev/null +++ b/components/script/dom/webidls/WebGLTexture.webidl @@ -0,0 +1,7 @@ +// +// WebGL IDL definitions scraped from the Khronos specification: +// https://www.khronos.org/registry/webgl/specs/latest/#5.9 +// + +interface WebGLTexture : WebGLObject { +}; diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index 821f3715c97..06e04248be7 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -180,6 +180,9 @@ var interfaceNamesInGlobalScope = [ "WebGLRenderingContext", "WebGLUniformLocation", "WebGLBuffer", + "WebGLFramebuffer", + "WebGLRenderbuffer", + "WebGLTexture", "WebGLProgram", "WebGLShader", "WebGLObject", |