Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webgl: Make a general way to get data from a JS array buffer view #8970

Merged
merged 4 commits into from Jan 5, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

conversions: Add a checked version to array_buffer_view_data

  • Loading branch information
emilio committed Jan 4, 2016
commit 43d395a682c1b03497e4869744b4b25e92906cc6
@@ -46,9 +46,10 @@ use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
use js::jsapi::{HandleId, HandleObject, HandleValue, JS_GetClass};
use js::jsapi::{JSClass, JSContext, JSObject, MutableHandleValue};
use js::jsapi::{JS_GetLatin1StringCharsAndLength, JS_GetReservedSlot};
use js::jsapi::{JS_GetObjectAsArrayBufferView, JS_GetArrayBufferViewType};
use js::jsapi::{JS_GetTwoByteStringCharsAndLength, JS_NewStringCopyN};
use js::jsapi::{JS_StringHasLatin1Chars, JS_WrapValue};
use js::jsapi::{JS_GetObjectAsArrayBufferView};
use js::jsapi::{Type};
use js::jsval::{ObjectValue, StringValue};
use js::rust::ToString;
use libc;
@@ -348,7 +349,8 @@ unsafe impl ArrayBufferViewContents for i32 {}
unsafe impl ArrayBufferViewContents for f32 {}
unsafe impl ArrayBufferViewContents for f64 {}

/// Returns a mutable slice of the Array Buffer View data, viewed as T
/// Returns a mutable slice of the Array Buffer View data, viewed as T, without checking the real
/// type of it.
pub unsafe fn array_buffer_view_data<'a, T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<&'a mut [T]> {
let mut byte_length = 0;
let mut ptr = ptr::null_mut();
@@ -359,9 +361,31 @@ pub unsafe fn array_buffer_view_data<'a, T: ArrayBufferViewContents>(abv: *mut J
Some(slice::from_raw_parts_mut(ptr as *mut T, byte_length as usize / mem::size_of::<T>()))
}

/// Returns a copy of the ArrayBufferView data
/// Returns a copy of the ArrayBufferView data, viewed as T, without checking the real type of it.
pub fn array_buffer_view_to_vec<T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<Vec<T>> {
unsafe {
array_buffer_view_data(abv).map(|data| data.to_vec())
}
}

/// Returns a mutable slice of the Array Buffer View data, viewed as T, checking that the real type
/// of it is ty.
pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv: *mut JSObject,
ty: Type) -> Option<&'a mut [T]> {
array_buffer_view_data::<T>(abv).and_then(|data| {
let real_ty = JS_GetArrayBufferViewType(abv);
if real_ty as i32 == ty as i32 {
Some(data)
} else {
None
}
})
}

/// Returns a copy of the ArrayBufferView data, viewed as T, checking that the real type
/// of it is ty.
pub fn array_buffer_view_to_vec_checked<T: ArrayBufferViewContents>(abv: *mut JSObject, ty: Type) -> Option<Vec<T>> {
unsafe {
array_buffer_view_data_checked(abv, ty).map(|data| data.to_vec())
}
}
@@ -3,9 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::conversions::array_buffer_view_data;
use dom::bindings::codegen::Bindings::CryptoBinding;
use dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods;
use dom::bindings::conversions::array_buffer_view_data;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -9,7 +9,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_to_vec};
use dom::bindings::conversions::{ToJSValConvertible, array_buffer_view_to_vec_checked, array_buffer_view_to_vec};
use dom::bindings::global::{GlobalField, GlobalRef};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
@@ -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, JSObject, RootedValue, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue};
use net_traits::image::base::PixelFormat;
use net_traits::image_cache_task::ImageResponse;
@@ -948,7 +948,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
None => return,
};

if let Some(data_vec) = array_buffer_view_to_vec::<f32>(data) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data, Type::Float32) {
if data_vec.len() < 4 {
return self.webgl_error(InvalidOperation);
}
@@ -976,7 +976,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) = array_buffer_view_to_vec::<f32>(data) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data, Type::Float32) {
if data_vec.len() < 4 {
return self.webgl_error(InvalidOperation);
}
@@ -994,7 +994,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) = array_buffer_view_to_vec::<f32>(data) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data, Type::Float32) {
if data_vec.len() < 2 {
return self.webgl_error(InvalidOperation);
}
@@ -1012,7 +1012,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) = array_buffer_view_to_vec::<f32>(data) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data, Type::Float32) {
if data_vec.len() < 3 {
return self.webgl_error(InvalidOperation);
}
@@ -1027,10 +1027,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
self.vertex_attrib(indx, x, y, z, w)
}

#[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) = array_buffer_view_to_vec::<f32>(data) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data, Type::Float32) {
if data_vec.len() < 4 {
return self.webgl_error(InvalidOperation);
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.