aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglrenderingcontext.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r--components/script/dom/webglrenderingcontext.rs84
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