diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/canvas/webgl_paint_task.rs | 238 | ||||
-rw-r--r-- | components/canvas_traits/lib.rs | 19 | ||||
-rw-r--r-- | components/script/dom/canvasrenderingcontext2d.rs | 24 | ||||
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 16 | ||||
-rw-r--r-- | components/script/dom/webglbuffer.rs | 19 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 412 | ||||
-rw-r--r-- | components/script/dom/webgltexture.rs | 93 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLRenderingContext.webidl | 45 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 20 |
9 files changed, 650 insertions, 236 deletions
diff --git a/components/canvas/webgl_paint_task.rs b/components/canvas/webgl_paint_task.rs index ac367a83047..b434f468711 100644 --- a/components/canvas/webgl_paint_task.rs +++ b/components/canvas/webgl_paint_task.rs @@ -48,34 +48,68 @@ impl WebGLPaintTask { }) } + /// In this function the gl commands are called. + /// Those messages that just involve a gl call have the call inlined, + /// processing of messages that require extra work are moved to functions + /// + /// NB: Not gl-related validations (names, lengths, accepted parameters...) are + /// done in the corresponding DOM interfaces pub fn handle_webgl_message(&self, message: CanvasWebGLMsg) { match message { CanvasWebGLMsg::GetContextAttributes(sender) => self.get_context_attributes(sender), CanvasWebGLMsg::ActiveTexture(target) => - self.active_texture(target), + gl::active_texture(target), CanvasWebGLMsg::BlendColor(r, g, b, a) => - self.blend_color(r, g, b, a), + gl::blend_color(r, g, b, a), CanvasWebGLMsg::BlendEquation(mode) => - self.blend_equation(mode), + gl::blend_equation(mode), CanvasWebGLMsg::BlendEquationSeparate(mode_rgb, mode_alpha) => - self.blend_equation_separate(mode_rgb, mode_alpha), + gl::blend_equation_separate(mode_rgb, mode_alpha), CanvasWebGLMsg::BlendFunc(src, dest) => - self.blend_func(src, dest), + gl::blend_func(src, dest), CanvasWebGLMsg::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha) => - self.blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha), + gl::blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha), CanvasWebGLMsg::AttachShader(program_id, shader_id) => - self.attach_shader(program_id, shader_id), + gl::attach_shader(program_id, shader_id), CanvasWebGLMsg::BufferData(buffer_type, data, usage) => - self.buffer_data(buffer_type, data, usage), + gl::buffer_data(buffer_type, &data, usage), CanvasWebGLMsg::Clear(mask) => - self.clear(mask), + gl::clear(mask), CanvasWebGLMsg::ClearColor(r, g, b, a) => - self.clear_color(r, g, b, a), + gl::clear_color(r, g, b, a), + CanvasWebGLMsg::ClearDepth(depth) => + gl::clear_depth(depth), + CanvasWebGLMsg::ClearStencil(stencil) => + gl::clear_stencil(stencil), + CanvasWebGLMsg::ColorMask(r, g, b, a) => + gl::color_mask(r, g, b, a), + CanvasWebGLMsg::CullFace(mode) => + gl::cull_face(mode), + CanvasWebGLMsg::DepthFunc(func) => + gl::depth_func(func), + CanvasWebGLMsg::DepthMask(flag) => + gl::depth_mask(flag), + CanvasWebGLMsg::DepthRange(near, far) => + gl::depth_range(near, far), + CanvasWebGLMsg::Disable(cap) => + gl::disable(cap), + CanvasWebGLMsg::Enable(cap) => + gl::enable(cap), + CanvasWebGLMsg::FrontFace(mode) => + gl::front_face(mode), CanvasWebGLMsg::DrawArrays(mode, first, count) => - self.draw_arrays(mode, first, count), + gl::draw_arrays(mode, first, count), + CanvasWebGLMsg::Hint(name, val) => + gl::hint(name, val), + CanvasWebGLMsg::LineWidth(width) => + gl::line_width(width), + CanvasWebGLMsg::PixelStorei(name, val) => + gl::pixel_store_i(name, val), + CanvasWebGLMsg::PolygonOffset(factor, units) => + gl::polygon_offset(factor, units), CanvasWebGLMsg::EnableVertexAttribArray(attrib_id) => - self.enable_vertex_attrib_array(attrib_id), + gl::enable_vertex_attrib_array(attrib_id), CanvasWebGLMsg::GetAttribLocation(program_id, name, chan) => self.get_attrib_location(program_id, name, chan), CanvasWebGLMsg::GetShaderInfoLog(shader_id, chan) => @@ -99,37 +133,43 @@ impl WebGLPaintTask { CanvasWebGLMsg::CreateShader(shader_type, chan) => self.create_shader(shader_type, chan), CanvasWebGLMsg::DeleteBuffer(id) => - self.delete_buffer(id), + gl::delete_buffers(&[id]), CanvasWebGLMsg::DeleteFramebuffer(id) => - self.delete_framebuffer(id), + gl::delete_framebuffers(&[id]), CanvasWebGLMsg::DeleteRenderbuffer(id) => - self.delete_renderbuffer(id), + gl::delete_renderbuffers(&[id]), CanvasWebGLMsg::DeleteTexture(id) => - self.delete_texture(id), + gl::delete_textures(&[id]), CanvasWebGLMsg::DeleteProgram(id) => - self.delete_program(id), + gl::delete_program(id), CanvasWebGLMsg::DeleteShader(id) => - self.delete_shader(id), + gl::delete_shader(id), CanvasWebGLMsg::BindBuffer(target, id) => - self.bind_buffer(target, id), + gl::bind_buffer(target, id), CanvasWebGLMsg::BindFramebuffer(target, request) => self.bind_framebuffer(target, request), CanvasWebGLMsg::BindRenderbuffer(target, id) => - self.bind_renderbuffer(target, id), + gl::bind_renderbuffer(target, id), CanvasWebGLMsg::BindTexture(target, id) => - self.bind_texture(target, id), + gl::bind_texture(target, id), CanvasWebGLMsg::LinkProgram(program_id) => - self.link_program(program_id), + gl::link_program(program_id), CanvasWebGLMsg::ShaderSource(shader_id, source) => - self.shader_source(shader_id, source), + gl::shader_source(shader_id, &[source.as_bytes()]), CanvasWebGLMsg::Uniform4fv(uniform_id, data) => - self.uniform_4fv(uniform_id, data), + gl::uniform_4f(uniform_id, data[0], data[1], data[2], data[3]), CanvasWebGLMsg::UseProgram(program_id) => - self.use_program(program_id), + gl::use_program(program_id), CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset) => - self.vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset), + gl::vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset as u32), CanvasWebGLMsg::Viewport(x, y, width, height) => - self.viewport(x, y, width, height), + gl::viewport(x, y, width, height), + CanvasWebGLMsg::TexImage2D(target, level, internal, width, height, format, data_type, data) => + gl::tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)), + CanvasWebGLMsg::TexParameteri(target, name, value) => + gl::tex_parameter_i(target, name, value), + CanvasWebGLMsg::TexParameterf(target, name, value) => + gl::tex_parameter_f(target, name, value), CanvasWebGLMsg::DrawingBufferWidth(sender) => self.send_drawing_buffer_width(sender), CanvasWebGLMsg::DrawingBufferHeight(sender) => @@ -192,63 +232,6 @@ impl WebGLPaintTask { sender.send(self.size.height).unwrap() } - #[inline] - fn active_texture(&self, texture: u32) { - gl::active_texture(texture); - } - - #[inline] - fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) { - gl::blend_color(r, g, b, a); - } - - #[inline] - fn blend_equation(&self, mode: u32) { - gl::blend_equation(mode); - } - - #[inline] - fn blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32) { - gl::blend_equation_separate(mode_rgb, mode_alpha); - } - - #[inline] - fn blend_func(&self, src_factor: u32, dest_factor: u32) { - gl::blend_func(src_factor, dest_factor); - } - - #[inline] - fn blend_func_separate(&self, - src_rgb_factor: u32, - dest_rgb_factor: u32, - src_alpha_factor: u32, - dest_alpha_factor: u32) { - gl::blend_func_separate(src_rgb_factor, - dest_rgb_factor, - src_alpha_factor, - dest_alpha_factor); - } - - #[inline] - fn attach_shader(&self, program_id: u32, shader_id: u32) { - gl::attach_shader(program_id, shader_id); - } - - #[inline] - fn buffer_data(&self, buffer_type: u32, data: Vec<f32>, usage: u32) { - gl::buffer_data(buffer_type, &data, usage); - } - - #[inline] - fn clear(&self, mask: u32) { - gl::clear(mask); - } - - #[inline] - fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) { - gl::clear_color(r, g, b, a); - } - fn create_buffer(&self, chan: IpcSender<Option<NonZero<u32>>>) { let buffer = gl::gen_buffers(1)[0]; let buffer = if buffer == 0 { @@ -310,41 +293,6 @@ impl WebGLPaintTask { } #[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, request: WebGLFramebufferBindingRequest) { let id = match request { WebGLFramebufferBindingRequest::Explicit(id) => id, @@ -355,16 +303,6 @@ impl WebGLPaintTask { 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 @@ -373,16 +311,6 @@ impl WebGLPaintTask { gl::compile_shader(shader_id); } - #[inline] - fn draw_arrays(&self, mode: u32, first: i32, count: i32) { - gl::draw_arrays(mode, first, count); - } - - #[inline] - fn enable_vertex_attrib_array(&self, attrib_id: u32) { - gl::enable_vertex_attrib_array(attrib_id); - } - fn get_attrib_location(&self, program_id: u32, name: String, chan: IpcSender<Option<i32>> ) { let attrib_location = gl::get_attrib_location(program_id, &name); @@ -428,37 +356,6 @@ impl WebGLPaintTask { chan.send(location).unwrap(); } - #[inline] - fn link_program(&self, program_id: u32) { - gl::link_program(program_id); - } - - #[inline] - fn shader_source(&self, shader_id: u32, source: String) { - gl::shader_source(shader_id, &[source.as_bytes()]); - } - - #[inline] - fn uniform_4fv(&self, uniform_id: i32, data: Vec<f32>) { - gl::uniform_4f(uniform_id, data[0], data[1], data[2], data[3]); - } - - #[inline] - fn use_program(&self, program_id: u32) { - gl::use_program(program_id); - } - - #[inline] - fn vertex_attrib_pointer_f32(&self, attrib_id: u32, size: i32, - normalized: bool, stride: i32, offset: i64) { - gl::vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset as u32); - } - - #[inline] - fn viewport(&self, x: i32, y: i32, width: i32, height: i32) { - gl::viewport(x, y, width, height); - } - fn send_pixel_contents(&mut self, chan: IpcSender<IpcSharedMemory>) { // FIXME(#5652, dmarcos) Instead of a readback strategy we have // to layerize the canvas. @@ -466,6 +363,7 @@ impl WebGLPaintTask { // allowed you to mutate in-place before freezing the object for sending. let width = self.size.width as usize; let height = self.size.height as usize; + let mut pixels = gl::read_pixels(0, 0, self.size.width as gl::GLsizei, self.size.height as gl::GLsizei, diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 2ce53dfbb76..068eada3d9d 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -128,6 +128,16 @@ pub enum CanvasWebGLMsg { BufferData(u32, Vec<f32>, u32), Clear(u32), ClearColor(f32, f32, f32, f32), + ClearDepth(f64), + ClearStencil(i32), + ColorMask(bool, bool, bool, bool), + CullFace(u32), + FrontFace(u32), + DepthFunc(u32), + DepthMask(bool), + DepthRange(f64, f64), + Enable(u32), + Disable(u32), CompileShader(u32), CreateBuffer(IpcSender<Option<NonZero<u32>>>), CreateFramebuffer(IpcSender<Option<NonZero<u32>>>), @@ -151,12 +161,19 @@ pub enum CanvasWebGLMsg { GetShaderParameter(u32, u32, IpcSender<WebGLShaderParameter>), GetAttribLocation(u32, String, IpcSender<Option<i32>>), GetUniformLocation(u32, String, IpcSender<Option<i32>>), + PolygonOffset(f32, f32), + Hint(u32, u32), + LineWidth(f32), + PixelStorei(u32, i32), LinkProgram(u32), ShaderSource(u32, String), Uniform4fv(i32, Vec<f32>), UseProgram(u32), - VertexAttribPointer2f(u32, i32, bool, i32, i64), + VertexAttribPointer2f(u32, i32, bool, i32, u32), Viewport(i32, i32, i32, i32), + TexImage2D(u32, i32, i32, i32, i32, u32, u32, Vec<u8>), + TexParameteri(u32, u32, i32), + TexParameterf(u32, u32, f32), DrawingBufferWidth(IpcSender<i32>), DrawingBufferHeight(IpcSender<i32>), } diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 9e2ec6d1446..03f4014ee7a 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -17,11 +17,16 @@ use dom::bindings::num::Finite; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle}; use dom::canvaspattern::CanvasPattern; +use dom::htmlcanvaselement::utils as canvas_utils; use dom::htmlcanvaselement::{HTMLCanvasElement, HTMLCanvasElementHelpers}; use dom::htmlimageelement::{HTMLImageElement, HTMLImageElementHelpers}; use dom::imagedata::{ImageData, ImageDataHelpers}; use dom::node::{window_from_node, NodeHelpers, NodeDamage}; +use msg::constellation_msg::Msg as ConstellationMsg; +use net_traits::image::base::PixelFormat; +use net_traits::image_cache_task::ImageResponse; + use cssparser::Color as CSSColor; use cssparser::{Parser, RGBA}; use euclid::matrix2d::Matrix2D; @@ -34,10 +39,6 @@ use canvas_traits::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg}; use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle, RepetitionStyle}; use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; -use msg::constellation_msg::Msg as ConstellationMsg; -use net_traits::image::base::PixelFormat; -use net_traits::image_cache_task::{ImageCacheChan, ImageResponse}; - use ipc_channel::ipc::{self, IpcSender}; use num::{Float, ToPrimitive}; use std::borrow::ToOwned; @@ -201,7 +202,7 @@ impl CanvasRenderingContext2D { Size2D::new(source_rect_clipped.size.width, source_rect_clipped.size.height)); - return (source_rect, dest_rect) + (source_rect, dest_rect) } // @@ -364,9 +365,10 @@ impl CanvasRenderingContext2D { PixelFormat::KA8 => panic!("KA8 color type not supported"), }; - return Some((image_data, image_size)); + Some((image_data, image_size)) } + // TODO(ecoal95): Move this to `HTMLCanvasElement`, and support WebGL contexts fn fetch_canvas_data(&self, canvas_element: &HTMLCanvasElement, source_rect: Rect<f64>) @@ -385,18 +387,14 @@ impl CanvasRenderingContext2D { renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect.to_i32(), image_size, sender))).unwrap(); - return Some((receiver.recv().unwrap(), image_size)); + Some((receiver.recv().unwrap(), image_size)) } + #[inline] fn request_image_from_cache(&self, url: Url) -> ImageResponse { let canvas = self.canvas.root(); let window = window_from_node(canvas.r()); - let window = window.r(); - let image_cache = window.image_cache_task(); - let (response_chan, response_port) = ipc::channel().unwrap(); - image_cache.request_image(url, ImageCacheChan(response_chan), None); - let result = response_port.recv().unwrap(); - result.image_response + canvas_utils::request_image_from_cache(window.r(), url) } fn create_drawable_rect(&self, x: f64, y: f64, w: f64, h: f64) -> Option<Rect<f32>> { diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 4823f881be7..83e8397d859 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -159,6 +159,7 @@ pub trait HTMLCanvasElementHelpers { fn get_or_init_webgl_context(self, cx: *mut JSContext, attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>>; + fn is_valid(self) -> bool; } @@ -325,3 +326,18 @@ impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes { } } +pub mod utils { + use dom::window::Window; + use ipc_channel::ipc; + use net_traits::image_cache_task::{ImageCacheChan, ImageResponse}; + use url::Url; + + pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse { + let image_cache = window.image_cache_task(); + let (response_chan, response_port) = ipc::channel().unwrap(); + image_cache.request_image(url, ImageCacheChan(response_chan), None); + let result = response_port.recv().unwrap(); + result.image_response + } +} + diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index 5ad078a38e5..6f958d62597 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -9,7 +9,7 @@ use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; -use canvas_traits::{CanvasMsg, CanvasWebGLMsg}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult}; use ipc_channel::ipc::{self, IpcSender}; use std::cell::Cell; @@ -18,6 +18,8 @@ use std::cell::Cell; pub struct WebGLBuffer { webgl_object: WebGLObject, id: u32, + /// The target to which this buffer was bound the first time + target: Cell<Option<u32>>, is_deleted: Cell<bool>, #[ignore_heap_size_of = "Defined in ipc-channel"] renderer: IpcSender<CanvasMsg>, @@ -28,6 +30,7 @@ impl WebGLBuffer { WebGLBuffer { webgl_object: WebGLObject::new_inherited(), id: id, + target: Cell::new(None), is_deleted: Cell::new(false), renderer: renderer, } @@ -49,7 +52,7 @@ impl WebGLBuffer { pub trait WebGLBufferHelpers { fn id(self) -> u32; - fn bind(self, target: u32); + fn bind(self, target: u32) -> WebGLResult<()>; fn delete(self); } @@ -58,8 +61,18 @@ impl<'a> WebGLBufferHelpers for &'a WebGLBuffer { self.id } - fn bind(self, target: u32) { + // NB: Only valid buffer targets come here + fn bind(self, target: u32) -> WebGLResult<()> { + if let Some(previous_target) = self.target.get() { + if target != previous_target { + return Err(WebGLError::InvalidOperation); + } + } else { + self.target.set(Some(target)); + } self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, self.id))).unwrap(); + + Ok(()) } fn delete(self) { diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 356e556eaa6..2effacd8c59 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -5,35 +5,48 @@ use canvas_traits:: {CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLError, WebGLShaderParameter, WebGLFramebufferBindingRequest}; +use canvas_traits::WebGLError::*; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding:: {self, WebGLContextAttributes, WebGLRenderingContextMethods}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; +use dom::bindings::codegen::InheritTypes::NodeCast; +use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::global::{GlobalRef, GlobalField}; use dom::bindings::js::{JS, LayoutJS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; -use dom::htmlcanvaselement::{HTMLCanvasElement}; +use dom::htmlcanvaselement::HTMLCanvasElement; +use dom::htmlcanvaselement::utils as canvas_utils; +use dom::htmlimageelement::HTMLImageElementHelpers; +use dom::imagedata::ImageDataHelpers; +use dom::node::{window_from_node, NodeHelpers, NodeDamage}; use dom::webglbuffer::{WebGLBuffer, WebGLBufferHelpers}; use dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferHelpers}; use dom::webglprogram::{WebGLProgram, WebGLProgramHelpers}; use dom::webglrenderbuffer::{WebGLRenderbuffer, WebGLRenderbufferHelpers}; use dom::webglshader::{WebGLShader, WebGLShaderHelpers}; -use dom::webgltexture::{WebGLTexture, WebGLTextureHelpers}; +use dom::webgltexture::{TexParameterValue, WebGLTexture, WebGLTextureHelpers}; use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelpers}; use euclid::size::Size2D; use ipc_channel::ipc::{self, IpcSender}; use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView}; use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value, BooleanValue}; + use msg::constellation_msg::Msg as ConstellationMsg; -use offscreen_gl_context::GLContextAttributes; +use net_traits::image::base::PixelFormat; +use net_traits::image_cache_task::ImageResponse; + use std::cell::Cell; use std::mem; use std::ptr; use std::slice; use std::sync::mpsc::channel; use util::str::DOMString; +use util::vec::byte_swap; + +use offscreen_gl_context::GLContextAttributes; pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256; @@ -42,13 +55,23 @@ macro_rules! handle_potential_webgl_error { match $call { Ok(ret) => ret, Err(error) => { - $context.handle_webgl_error(error); + $context.webgl_error(error); $return_on_error } } } } +/// Set of bitflags for texture unpacking (texImage2d, etc...) +bitflags! { + #[derive(HeapSizeOf, JSTraceable)] + flags TextureUnpacking: u8 { + const FLIP_Y_AXIS = 0x01, + const PREMULTIPLY_ALPHA = 0x02, + const CONVERT_COLORSPACE = 0x04, + } +} + #[dom_struct] #[derive(HeapSizeOf)] pub struct WebGLRenderingContext { @@ -59,6 +82,9 @@ pub struct WebGLRenderingContext { ipc_renderer: IpcSender<CanvasMsg>, canvas: JS<HTMLCanvasElement>, last_error: Cell<Option<WebGLError>>, + texture_unpacking_settings: Cell<TextureUnpacking>, + bound_texture_2d: Cell<Option<JS<WebGLTexture>>>, + bound_texture_cube_map: Cell<Option<JS<WebGLTexture>>>, } impl WebGLRenderingContext { @@ -80,8 +106,11 @@ impl WebGLRenderingContext { global: GlobalField::from_rooted(&global), renderer_id: renderer_id, ipc_renderer: ipc_renderer, - last_error: Cell::new(None), canvas: JS::from_ref(canvas), + last_error: Cell::new(None), + texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE), + bound_texture_2d: Cell::new(None), + bound_texture_cube_map: Cell::new(None), } }) } @@ -101,6 +130,12 @@ impl WebGLRenderingContext { pub fn recreate(&self, size: Size2D<i32>) { self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap(); } + + fn mark_as_dirty(&self) { + let canvas = self.canvas.root(); + let node = NodeCast::from_ref(canvas.r()); + node.dirty(NodeDamage::OtherNodeDamage); + } } impl Drop for WebGLRenderingContext { @@ -241,8 +276,15 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn BindBuffer(self, target: u32, buffer: Option<&WebGLBuffer>) { + match target { + constants::ARRAY_BUFFER | + constants::ELEMENT_ARRAY_BUFFER => (), + + _ => return self.webgl_error(InvalidEnum), + } + if let Some(buffer) = buffer { - buffer.bind(target) + handle_potential_webgl_error!(self, buffer.bind(target), ()) } else { // Unbind the current buffer self.ipc_renderer @@ -253,6 +295,10 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 fn BindFramebuffer(self, target: u32, framebuffer: Option<&WebGLFramebuffer>) { + if target != constants::FRAMEBUFFER { + return self.webgl_error(InvalidOperation); + } + if let Some(framebuffer) = framebuffer { framebuffer.bind(target) } else { @@ -264,6 +310,10 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 fn BindRenderbuffer(self, target: u32, renderbuffer: Option<&WebGLRenderbuffer>) { + if target != constants::RENDERBUFFER { + return self.webgl_error(InvalidEnum); + } + if let Some(renderbuffer) = renderbuffer { renderbuffer.bind(target) } else { @@ -276,8 +326,23 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 fn BindTexture(self, target: u32, texture: Option<&WebGLTexture>) { + let slot = match target { + constants::TEXTURE_2D => &self.bound_texture_2d, + constants::TEXTURE_CUBE_MAP => &self.bound_texture_cube_map, + + _ => return self.webgl_error(InvalidEnum), + }; + if let Some(texture) = texture { - texture.bind(target) + match texture.bind(target) { + Ok(_) => slot.set(Some(JS::from_ref(texture))), + Err(err) => return self.webgl_error(err), + } + } else { + // Unbind the currently bound texture + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(target, 0))) + .unwrap() } } @@ -306,7 +371,8 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11 fn Clear(self, mask: u32) { - self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap() + self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap(); + self.mark_as_dirty(); } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 @@ -316,6 +382,102 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { .unwrap() } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn ClearDepth(self, depth: f32) { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearDepth(depth as f64))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn ClearStencil(self, stencil: i32) { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearStencil(stencil))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn ColorMask(self, r: bool, g: bool, b: bool, a: bool) { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::ColorMask(r, g, b, a))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn CullFace(self, mode: u32) { + match mode { + constants::FRONT | constants::BACK | constants::FRONT_AND_BACK => + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::CullFace(mode))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn FrontFace(self, mode: u32) { + match mode { + constants::CW | constants::CCW => + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::FrontFace(mode))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn DepthFunc(self, func: u32) { + match func { + constants::NEVER | constants::LESS | + constants::EQUAL | constants::LEQUAL | + constants::GREATER | constants::NOTEQUAL | + constants::GEQUAL | constants::ALWAYS => + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::DepthFunc(func))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn DepthMask(self, flag: bool) { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::DepthMask(flag))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn DepthRange(self, near: f32, far: f32) { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::DepthRange(near as f64, far as f64))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn Enable(self, cap: u32) { + match cap { + constants::BLEND | constants::CULL_FACE | constants::DEPTH_TEST | constants::DITHER | + constants::POLYGON_OFFSET_FILL | constants::SAMPLE_ALPHA_TO_COVERAGE | constants::SAMPLE_COVERAGE | + constants::SAMPLE_COVERAGE_INVERT | constants::SCISSOR_TEST => + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::Enable(cap))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn Disable(self, cap: u32) { + match cap { + constants::BLEND | constants::CULL_FACE | constants::DEPTH_TEST | constants::DITHER | + constants::POLYGON_OFFSET_FILL | constants::SAMPLE_ALPHA_TO_COVERAGE | constants::SAMPLE_COVERAGE | + constants::SAMPLE_COVERAGE_INVERT | constants::SCISSOR_TEST => + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::Disable(cap))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn CompileShader(self, shader: Option<&WebGLShader>) { if let Some(shader) = shader { @@ -401,9 +563,24 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11 fn DrawArrays(self, mode: u32, first: i32, count: i32) { - self.ipc_renderer - .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count))) - .unwrap() + match mode { + constants::POINTS | constants::LINE_STRIP | + constants::LINE_LOOP | constants::LINES | + constants::TRIANGLE_STRIP | constants::TRIANGLE_FAN | + constants::TRIANGLES => { + // TODO(ecoal95): Check the CURRENT_PROGRAM when we keep track of it, and if it's + // null generate an InvalidOperation error + if first < 0 || count < 0 { + self.webgl_error(InvalidValue); + } else { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count))) + .unwrap(); + self.mark_as_dirty(); + } + }, + _ => self.webgl_error(InvalidEnum), + } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -456,6 +633,96 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { } } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn Hint(self, target: u32, mode: u32) { + if target != constants::GENERATE_MIPMAP_HINT { + return self.webgl_error(InvalidEnum); + } + + match mode { + constants::FASTEST | + constants::NICEST | + constants::DONT_CARE => (), + + _ => return self.webgl_error(InvalidEnum), + } + + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::Hint(target, mode))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn LineWidth(self, width: f32) { + if width.is_nan() || width <= 0f32 { + return self.webgl_error(InvalidValue); + } + + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::LineWidth(width))) + .unwrap() + } + + // NOTE: Usage of this function could affect rendering while we keep using + // readback to render to the page. + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn PixelStorei(self, param_name: u32, param_value: i32) { + let mut texture_settings = self.texture_unpacking_settings.get(); + match param_name { + constants::UNPACK_FLIP_Y_WEBGL => { + if param_value != 0 { + texture_settings.insert(FLIP_Y_AXIS) + } else { + texture_settings.remove(FLIP_Y_AXIS) + } + + self.texture_unpacking_settings.set(texture_settings); + return; + }, + constants::UNPACK_PREMULTIPLY_ALPHA_WEBGL => { + if param_value != 0 { + texture_settings.insert(PREMULTIPLY_ALPHA) + } else { + texture_settings.remove(PREMULTIPLY_ALPHA) + } + + self.texture_unpacking_settings.set(texture_settings); + return; + }, + constants::UNPACK_COLORSPACE_CONVERSION_WEBGL => { + match param_value as u32 { + constants::BROWSER_DEFAULT_WEBGL + => texture_settings.insert(CONVERT_COLORSPACE), + constants::NONE + => texture_settings.remove(CONVERT_COLORSPACE), + _ => return self.webgl_error(InvalidEnum), + } + + self.texture_unpacking_settings.set(texture_settings); + return; + }, + constants::UNPACK_ALIGNMENT | + constants::PACK_ALIGNMENT => { + match param_value { + 1 | 2 | 4 | 8 => (), + _ => return self.webgl_error(InvalidValue), + } + }, + _ => return self.webgl_error(InvalidEnum), + } + + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::PixelStorei(param_name, param_value))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn PolygonOffset(self, factor: f32, units: f32) { + self.ipc_renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::PolygonOffset(factor, units))) + .unwrap() + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn LinkProgram(self, program: Option<&WebGLProgram>) { if let Some(program) = program { @@ -516,7 +783,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { normalized: bool, stride: i32, offset: i64) { if let constants::FLOAT = data_type { let msg = CanvasMsg::WebGL( - CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset)); + CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32)); self.ipc_renderer.send(msg).unwrap() } else { panic!("VertexAttribPointer: Data Type not supported") @@ -529,20 +796,137 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { .send(CanvasMsg::WebGL(CanvasWebGLMsg::Viewport(x, y, width, height))) .unwrap() } + + // 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 >) { + // TODO(ecoal95): Check for bound WebGLTexture, and validate more parameters + match target { + constants::TEXTURE_2D | + constants::TEXTURE_CUBE_MAP => (), + + _ => return self.webgl_error(InvalidEnum), + } + + let source = match source { + Some(s) => s, + None => return, + }; + + let (pixels, size) = match source { + ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::eImageData(image_data) => { + let global = self.global.root(); + (image_data.get_data_array(&global.r()), image_data.get_size()) + }, + ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::eHTMLImageElement(image) => { + let img_url = match image.r().get_url() { + Some(url) => url, + None => return, + }; + + let canvas = self.canvas.root(); + let window = window_from_node(canvas.r()); + + let img = match canvas_utils::request_image_from_cache(window.r(), img_url) { + ImageResponse::Loaded(img) => img, + ImageResponse::PlaceholderLoaded(_) | ImageResponse::None + => return, + }; + + let size = Size2D::new(img.width as i32, img.height as i32); + // TODO(ecoal95): Validate that the format argument is coherent with the image. + // RGB8 should be easy to support too + let mut data = match img.format { + PixelFormat::RGBA8 => img.bytes.to_vec(), + _ => unimplemented!(), + }; + + byte_swap(&mut data); + + (data, size) + }, + // TODO(ecoal95): Getting canvas data is implemented in CanvasRenderingContext2D, but + // we need to refactor it moving it to `HTMLCanvasElement` and supporting WebGLContext + ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::eHTMLCanvasElement(_rooted_canvas) + => unimplemented!(), + ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::eHTMLVideoElement(_rooted_video) + => unimplemented!(), + }; + + // TODO(ecoal95): Invert axis, convert colorspace, premultiply alpha if requested + let msg = CanvasWebGLMsg::TexImage2D(target, level, internal_format as i32, + size.width, size.height, + format, data_type, pixels); + + self.ipc_renderer + .send(CanvasMsg::WebGL(msg)) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + fn TexParameterf(self, target: u32, name: u32, value: f32) { + match target { + constants::TEXTURE_2D | + constants::TEXTURE_CUBE_MAP => { + if let Some(texture) = self.bound_texture_for(target) { + let texture = texture.root(); + let result = texture.r().tex_parameter(target, name, TexParameterValue::Float(value)); + handle_potential_webgl_error!(self, result, ()); + } else { + return self.webgl_error(InvalidOperation); + } + }, + + _ => return self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + fn TexParameteri(self, target: u32, name: u32, value: i32) { + match target { + constants::TEXTURE_2D | + constants::TEXTURE_CUBE_MAP => { + if let Some(texture) = self.bound_texture_for(target) { + let texture = texture.root(); + let result = texture.r().tex_parameter(target, name, TexParameterValue::Int(value)); + handle_potential_webgl_error!(self, result, ()); + } else { + return self.webgl_error(InvalidOperation); + } + }, + + _ => return self.webgl_error(InvalidEnum), + } + } } pub trait WebGLRenderingContextHelpers { - fn handle_webgl_error(&self, err: WebGLError); + fn webgl_error(&self, err: WebGLError); + fn bound_texture_for(&self, target: u32) -> Option<JS<WebGLTexture>>; } impl<'a> WebGLRenderingContextHelpers for &'a WebGLRenderingContext { - fn handle_webgl_error(&self, err: WebGLError) { + fn 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)); } } + + fn bound_texture_for(&self, target: u32) -> Option<JS<WebGLTexture>> { + match target { + constants::TEXTURE_2D => self.bound_texture_2d.get(), + constants::TEXTURE_CUBE_MAP => self.bound_texture_cube_map.get(), + + _ => unreachable!(), + } + } } pub trait LayoutCanvasWebGLRenderingContextHelpers { diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index 579c196e90a..7fa44178155 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -3,21 +3,29 @@ * 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::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLTextureBinding; use dom::bindings::global::GlobalRef; use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; -use canvas_traits::{CanvasMsg, CanvasWebGLMsg}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult}; use ipc_channel::ipc::{self, IpcSender}; use std::cell::Cell; +pub enum TexParameterValue { + Float(f32), + Int(i32), +} + #[dom_struct] #[derive(HeapSizeOf)] pub struct WebGLTexture { webgl_object: WebGLObject, id: u32, + /// The target to which this texture was bound the first time + target: Cell<Option<u32>>, is_deleted: Cell<bool>, #[ignore_heap_size_of = "Defined in ipc-channel"] renderer: IpcSender<CanvasMsg>, @@ -28,6 +36,7 @@ impl WebGLTexture { WebGLTexture { webgl_object: WebGLObject::new_inherited(), id: id, + target: Cell::new(None), is_deleted: Cell::new(false), renderer: renderer, } @@ -49,8 +58,12 @@ impl WebGLTexture { pub trait WebGLTextureHelpers { fn id(self) -> u32; - fn bind(self, target: u32); + fn bind(self, target: u32) -> WebGLResult<()>; fn delete(self); + fn tex_parameter(self, + target: u32, + name: u32, + value: TexParameterValue) -> WebGLResult<()>; } impl<'a> WebGLTextureHelpers for &'a WebGLTexture { @@ -58,8 +71,19 @@ impl<'a> WebGLTextureHelpers for &'a WebGLTexture { self.id } - fn bind(self, target: u32) { + // NB: Only valid texture targets come here + fn bind(self, target: u32) -> WebGLResult<()> { + if let Some(previous_target) = self.target.get() { + if target != previous_target { + return Err(WebGLError::InvalidOperation); + } + } else { + self.target.set(Some(target)); + } + self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(self.id, target))).unwrap(); + + Ok(()) } fn delete(self) { @@ -68,4 +92,67 @@ impl<'a> WebGLTextureHelpers for &'a WebGLTexture { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(self.id))).unwrap(); } } + + /// We have to follow the conversion rules for GLES 2.0. See: + /// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html + /// + fn tex_parameter(self, + target: u32, + name: u32, + value: TexParameterValue) -> WebGLResult<()> { + let (int_value, _float_value) = match value { + TexParameterValue::Int(int_value) => (int_value, int_value as f32), + TexParameterValue::Float(float_value) => (float_value as i32, float_value), + }; + + match name { + constants::TEXTURE_MIN_FILTER => { + match int_value as u32 { + constants::NEAREST | + constants::LINEAR | + constants::NEAREST_MIPMAP_NEAREST | + constants::LINEAR_MIPMAP_NEAREST | + constants::NEAREST_MIPMAP_LINEAR | + constants::LINEAR_MIPMAP_LINEAR => { + self.renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value))) + .unwrap(); + return Ok(()); + }, + + _ => return Err(WebGLError::InvalidEnum), + } + }, + constants::TEXTURE_MAG_FILTER => { + match int_value as u32 { + constants::NEAREST | + constants::LINEAR => { + self.renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value))) + .unwrap(); + return Ok(()); + }, + + _ => return Err(WebGLError::InvalidEnum), + } + }, + constants::TEXTURE_WRAP_S | + constants::TEXTURE_WRAP_T => { + match int_value as u32 { + constants::CLAMP_TO_EDGE | + constants::MIRRORED_REPEAT | + constants::REPEAT => { + self.renderer + .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value))) + .unwrap(); + return Ok(()); + }, + + _ => return Err(WebGLError::InvalidEnum), + } + }, + + _ => return Err(WebGLError::InvalidEnum), + } + } } diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index a888f97bac7..957220efa54 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -24,6 +24,11 @@ typedef unsigned long GLuint; typedef unrestricted float GLfloat; typedef unrestricted float GLclampf; +typedef (ImageData or + HTMLImageElement or + HTMLCanvasElement or + HTMLVideoElement) TexImageSource; + dictionary WebGLContextAttributes { GLboolean alpha = true; @@ -495,9 +500,9 @@ interface WebGLRenderingContextBase //[WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target); void clear(GLbitfield mask); void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - //void clearDepth(GLclampf depth); - //void clearStencil(GLint s); - //void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void clearDepth(GLclampf depth); + void clearStencil(GLint s); + void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void compileShader(WebGLShader? shader); //void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, @@ -521,7 +526,7 @@ interface WebGLRenderingContextBase WebGLShader? createShader(GLenum type); WebGLTexture? createTexture(); - //void cullFace(GLenum mode); + void cullFace(GLenum mode); void deleteBuffer(WebGLBuffer? buffer); void deleteFramebuffer(WebGLFramebuffer? framebuffer); @@ -530,16 +535,16 @@ interface WebGLRenderingContextBase void deleteShader(WebGLShader? shader); void deleteTexture(WebGLTexture? texture); - //void depthFunc(GLenum func); - //void depthMask(GLboolean flag); - //void depthRange(GLclampf zNear, GLclampf zFar); + void depthFunc(GLenum func); + void depthMask(GLboolean flag); + void depthRange(GLclampf zNear, GLclampf zFar); //void detachShader(WebGLProgram? program, WebGLShader? shader); - //void disable(GLenum cap); + void disable(GLenum cap); //void disableVertexAttribArray(GLuint index); void drawArrays(GLenum mode, GLint first, GLsizei count); //void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset); - //void enable(GLenum cap); + void enable(GLenum cap); void enableVertexAttribArray(GLuint index); //void finish(); //void flush(); @@ -548,7 +553,7 @@ interface WebGLRenderingContextBase // WebGLRenderbuffer? renderbuffer); //void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, // WebGLTexture? texture, GLint level); - //void frontFace(GLenum mode); + void frontFace(GLenum mode); //void generateMipmap(GLenum target); @@ -584,7 +589,7 @@ interface WebGLRenderingContextBase //[WebGLHandlesContextLoss] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname); - //void hint(GLenum target, GLenum mode); + void hint(GLenum target, GLenum mode); //[WebGLHandlesContextLoss] GLboolean isBuffer(WebGLBuffer? buffer); //[WebGLHandlesContextLoss] GLboolean isEnabled(GLenum cap); //[WebGLHandlesContextLoss] GLboolean isFramebuffer(WebGLFramebuffer? framebuffer); @@ -592,10 +597,10 @@ interface WebGLRenderingContextBase //[WebGLHandlesContextLoss] GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer); //[WebGLHandlesContextLoss] GLboolean isShader(WebGLShader? shader); //[WebGLHandlesContextLoss] GLboolean isTexture(WebGLTexture? texture); - //void lineWidth(GLfloat width); + void lineWidth(GLfloat width); void linkProgram(WebGLProgram? program); - //void pixelStorei(GLenum pname, GLint param); - //void polygonOffset(GLfloat factor, GLfloat units); + void pixelStorei(GLenum pname, GLint param); + void polygonOffset(GLfloat factor, GLfloat units); //void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, // GLenum format, GLenum type, ArrayBufferView? pixels); @@ -614,18 +619,14 @@ interface WebGLRenderingContextBase //void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); //void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); - //typedef (ImageData or - // HTMLImageElement or - // HTMLCanvasElement or - // HTMLVideoElement) TexImageSource; //void texImage2D(GLenum target, GLint level, GLenum internalformat, // GLsizei width, GLsizei height, GLint border, GLenum format, // GLenum type, ArrayBufferView? pixels); - //void texImage2D(GLenum target, GLint level, GLenum internalformat, - // GLenum format, GLenum type, TexImageSource? source); // May throw DOMException + void texImage2D(GLenum target, GLint level, GLenum internalformat, + GLenum format, GLenum type, TexImageSource? source); // May throw DOMException - //void texParameterf(GLenum target, GLenum pname, GLfloat param); - //void texParameteri(GLenum target, GLenum pname, GLint param); + void texParameterf(GLenum target, GLenum pname, GLfloat param); + void texParameteri(GLenum target, GLenum pname, GLint param); //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, // GLsizei width, GLsizei height, diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 350f69e5308..facd2a902da 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -115,7 +115,7 @@ dependencies = [ "cssparser 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -146,7 +146,7 @@ name = "cgl" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -204,7 +204,7 @@ dependencies = [ "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", "gfx_traits 0.0.1", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "layout_traits 0.0.1", @@ -597,11 +597,11 @@ dependencies = [ [[package]] name = "gleam" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -646,7 +646,7 @@ dependencies = [ "compositing 0.0.1", "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.3.5 (git+https://github.com/servo/glutin?branch=servo)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -782,7 +782,7 @@ dependencies = [ "cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -841,7 +841,7 @@ dependencies = [ "core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "glx 0.0.1 (git+https://github.com/servo/rust-glx)", "io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1106,7 +1106,7 @@ dependencies = [ "core-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "gl_generator 0.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1460,7 +1460,7 @@ dependencies = [ "euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "expat-sys 2.1.0 (git+https://github.com/servo/libexpat)", "freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)", - "gleam 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "glx 0.0.1 (git+https://github.com/servo/rust-glx)", "io-surface 0.1.0 (git+https://github.com/servo/io-surface-rs)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", |