diff options
author | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-01-04 13:56:37 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-01-04 13:58:49 +0100 |
commit | 4d32444bf731f75c29e6bad7777ae8eacb96bcdc (patch) | |
tree | 2d22c9ceec33a711826b0e093acfb1b1848c95b4 /components/script/dom | |
parent | 5ad9207a99295284f1525844b734f189d1a25255 (diff) | |
download | servo-4d32444bf731f75c29e6bad7777ae8eacb96bcdc.tar.gz servo-4d32444bf731f75c29e6bad7777ae8eacb96bcdc.zip |
webgl: Unify accessing ArrayBufferView objects
This fixes an invalid length being reported from
float32_array_to_slice (which used the byte length), and also to
generalize getting data from a JS array buffer view, to reduce code
duplication.
The pending type safety issues, like where we could send a UInt16Array
where we expect a Float32 one, should be solved by IDL bindings in
some cases, like uniform[n]fv or vertexAttrib[n]fv, and with extra
checks in others, like in the pending texImage2D(..., ArrayBufferView).
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 41 |
1 files changed, 13 insertions, 28 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 25ec30657ea..3938f97eb6b 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -29,7 +29,7 @@ use dom::webgluniformlocation::WebGLUniformLocation; 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::jsapi::{JS_GetObjectAsArrayBufferView}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_task::ImageResponse; @@ -37,7 +37,7 @@ use offscreen_gl_context::GLContextAttributes; use script_traits::ScriptMsg as ConstellationMsg; use std::cell::Cell; use std::sync::mpsc::channel; -use std::{ptr, slice}; +use std::{ptr, slice, mem}; use util::str::DOMString; use util::vec::byte_swap; @@ -167,31 +167,16 @@ impl WebGLRenderingContext { } #[allow(unsafe_code)] - fn float32_array_to_slice(&self, data: *mut JSObject) -> Option<Vec<f32>> { + fn array_buffer_view_to_vec<T: Clone>(&self, data: *mut JSObject) -> Option<Vec<T>> { unsafe { - let mut length = 0; + let mut byte_length = 0; let mut ptr = ptr::null_mut(); - let buffer_data = JS_GetObjectAsArrayBufferView(data, &mut length, &mut ptr); + let buffer_data = JS_GetObjectAsArrayBufferView(data, &mut byte_length, &mut ptr); if buffer_data.is_null() { self.webgl_error(InvalidValue); // https://github.com/servo/servo/issues/5014 return None; } - let data_f32 = JS_GetFloat32ArrayData(data, ptr::null()); - Some(slice::from_raw_parts(data_f32, length as usize).to_vec()) - } - } - - #[allow(unsafe_code)] - fn byte_array_to_slice(&self, data: *mut JSObject) -> Option<Vec<u8>> { - unsafe { - let mut length = 0; - let mut ptr = ptr::null_mut(); - let buffer_data = JS_GetObjectAsArrayBufferView(data, &mut length, &mut ptr); - if buffer_data.is_null() { - self.webgl_error(InvalidValue); // https://github.com/servo/servo/issues/5014 - return None; - } - Some(slice::from_raw_parts(ptr, length as usize).to_vec()) + Some(slice::from_raw_parts(ptr as *mut T, byte_length as usize / mem::size_of::<T>()).to_vec()) } } @@ -471,7 +456,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Some(data) => data, None => return self.webgl_error(InvalidValue), }; - if let Some(data_vec) = self.byte_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<u8>(data) { handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data_vec, usage)); } } @@ -495,7 +480,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { if offset < 0 { return self.webgl_error(InvalidValue); } - if let Some(data_vec) = self.byte_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<u8>(data) { if (offset as usize) + data_vec.len() > bound_buffer.capacity() { return self.webgl_error(InvalidValue); } @@ -973,7 +958,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { None => return, }; - if let Some(data_vec) = self.float32_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<f32>(data) { if data_vec.len() < 4 { return self.webgl_error(InvalidOperation); } @@ -999,7 +984,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = self.float32_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<f32>(data) { if data_vec.len() < 4 { return self.webgl_error(InvalidOperation); } @@ -1015,7 +1000,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = self.float32_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<f32>(data) { if data_vec.len() < 2 { return self.webgl_error(InvalidOperation); } @@ -1031,7 +1016,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib3fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = self.float32_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<f32>(data) { if data_vec.len() < 3 { return self.webgl_error(InvalidOperation); } @@ -1047,7 +1032,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib4fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { - if let Some(data_vec) = self.float32_array_to_slice(data) { + if let Some(data_vec) = self.array_buffer_view_to_vec::<f32>(data) { if data_vec.len() < 4 { return self.webgl_error(InvalidOperation); } |