diff options
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 70b98ce06cd..241aa0aa60e 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderi use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{WebGLRenderingContextMethods}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; -use dom::bindings::conversions::{ToJSValConvertible, array_buffer_view_data_checked}; +use dom::bindings::conversions::{ToJSValConvertible, array_buffer_view_data, array_buffer_view_data_checked}; use dom::bindings::conversions::{array_buffer_view_to_vec_checked, array_buffer_view_to_vec}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; @@ -28,7 +28,7 @@ use dom::webgltexture::{TexParameterValue, WebGLTexture}; use dom::webgluniformlocation::WebGLUniformLocation; use euclid::size::Size2D; use ipc_channel::ipc::{self, IpcSender}; -use js::jsapi::{JSContext, JSObject, RootedValue}; +use js::jsapi::{JSContext, JS_GetArrayBufferViewType, JSObject, RootedValue, Type}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::ImageResponse; @@ -83,6 +83,8 @@ pub struct WebGLRenderingContext { bound_buffer_array: MutNullableHeap<JS<WebGLBuffer>>, bound_buffer_element_array: MutNullableHeap<JS<WebGLBuffer>>, current_program: MutNullableHeap<JS<WebGLProgram>>, + #[ignore_heap_size_of = "Because it's small"] + current_vertex_attrib_0: Cell<(f32, f32, f32, f32)>, } impl WebGLRenderingContext { @@ -93,8 +95,7 @@ impl WebGLRenderingContext { -> Result<WebGLRenderingContext, String> { let (sender, receiver) = ipc::channel().unwrap(); let constellation_chan = global.constellation_chan(); - constellation_chan.0 - .send(ConstellationMsg::CreateWebGLPaintThread(size, attrs, sender)) + constellation_chan.send(ConstellationMsg::CreateWebGLPaintThread(size, attrs, sender)) .unwrap(); let result = receiver.recv().unwrap(); @@ -111,6 +112,7 @@ impl WebGLRenderingContext { bound_buffer_array: MutNullableHeap::new(None), bound_buffer_element_array: MutNullableHeap::new(None), current_program: MutNullableHeap::new(None), + current_vertex_attrib_0: Cell::new((0f32, 0f32, 0f32, 1f32)), } }) } @@ -175,6 +177,10 @@ impl WebGLRenderingContext { return self.webgl_error(InvalidValue); } + if indx == 0 { + self.current_vertex_attrib_0.set((x, y, z, w)) + } + self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w))) .unwrap(); @@ -471,8 +477,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { WebGLParameter::Int(val) => Int32Value(val), WebGLParameter::Bool(_) => panic!("Buffer parameter should not be bool"), WebGLParameter::Float(_) => panic!("Buffer parameter should not be float"), - WebGLParameter::String(_) => panic!("Buffer parameter should not be string"), WebGLParameter::FloatArray(_) => panic!("Buffer parameter should not be float array"), + WebGLParameter::String(_) => panic!("Buffer parameter should not be string"), WebGLParameter::Invalid => NullValue(), } } @@ -1138,6 +1144,38 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { }) } + #[allow(unsafe_code)] + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 + fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, pname: u32) -> JSVal { + if index == 0 && pname == constants::CURRENT_VERTEX_ATTRIB { + let mut result = RootedValue::new(cx, UndefinedValue()); + let (x, y, z, w) = self.current_vertex_attrib_0.get(); + let attrib = vec![x, y, z, w]; + unsafe { + attrib.to_jsval(cx, result.handle_mut()); + } + return result.ptr + } + + let (sender, receiver) = ipc::channel().unwrap(); + self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::GetVertexAttrib(index, pname, sender))).unwrap(); + + match handle_potential_webgl_error!(self, receiver.recv().unwrap(), WebGLParameter::Invalid) { + WebGLParameter::Int(val) => Int32Value(val), + WebGLParameter::Bool(val) => BooleanValue(val), + WebGLParameter::String(_) => panic!("Vertex attrib should not be string"), + WebGLParameter::Float(_) => panic!("Vertex attrib should not be float"), + WebGLParameter::FloatArray(val) => { + let mut result = RootedValue::new(cx, UndefinedValue()); + unsafe { + val.to_jsval(cx, result.handle_mut()); + } + result.ptr + } + WebGLParameter::Invalid => NullValue(), + } + } + // 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 { @@ -1238,6 +1276,36 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { .unwrap() } + #[allow(unsafe_code)] + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 + fn ReadPixels(&self, _cx: *mut JSContext, x: i32, y: i32, width: i32, height: i32, + format: u32, pixel_type: u32, pixels: *mut JSObject) { + let mut data = match unsafe { array_buffer_view_data::<u8>(pixels) } { + Some(data) => data, + None => return self.webgl_error(InvalidValue), + }; + + match unsafe { JS_GetArrayBufferViewType(pixels) } { + Type::Uint8 => (), + _ => return self.webgl_error(InvalidOperation) + } + + let (sender, receiver) = ipc::channel().unwrap(); + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, sender))) + .unwrap(); + + let result = receiver.recv().unwrap(); + + if result.len() > data.len() { + return self.webgl_error(InvalidOperation) + } + + for i in 0..result.len() { + data[i] = result[i] + } + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4 fn Scissor(&self, x: i32, y: i32, width: i32, height: i32) { self.ipc_renderer @@ -1337,11 +1405,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // 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 - } + shader.and_then(|s| s.source()) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 |