aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-01-04 13:56:37 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-01-04 13:58:49 +0100
commit4d32444bf731f75c29e6bad7777ae8eacb96bcdc (patch)
tree2d22c9ceec33a711826b0e093acfb1b1848c95b4 /components/script/dom
parent5ad9207a99295284f1525844b734f189d1a25255 (diff)
downloadservo-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.rs41
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);
}