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

Prev

conversions: Make a `is_type_compatible` method for ArrayBufferViews.

  • Loading branch information
emilio committed Jan 4, 2016
commit d30f05554b981ae564293234c55ad43bc2df8134
@@ -339,15 +339,62 @@ impl<T: Reflectable> ToJSValConvertible for Root<T> {
}

/// A JS ArrayBufferView contents can only be viewed as the types marked with this trait
pub unsafe trait ArrayBufferViewContents: Clone {}
unsafe impl ArrayBufferViewContents for u8 {}
unsafe impl ArrayBufferViewContents for i8 {}
unsafe impl ArrayBufferViewContents for u16 {}
unsafe impl ArrayBufferViewContents for i16 {}
unsafe impl ArrayBufferViewContents for u32 {}
unsafe impl ArrayBufferViewContents for i32 {}
unsafe impl ArrayBufferViewContents for f32 {}
unsafe impl ArrayBufferViewContents for f64 {}
pub unsafe trait ArrayBufferViewContents: Clone {
/// Check if the JS ArrayBufferView type is compatible with the implementor of the
/// trait
fn is_type_compatible(ty: Type) -> bool;
}

unsafe impl ArrayBufferViewContents for u8 {
fn is_type_compatible(ty: Type) -> bool {
match ty {
Type::Uint8 |
Type::Uint8Clamped => true,
_ => false,
}
}
}

unsafe impl ArrayBufferViewContents for i8 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Int8 as i32
}
}

unsafe impl ArrayBufferViewContents for u16 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Uint16 as i32
}
}

unsafe impl ArrayBufferViewContents for i16 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Int16 as i32
}
}

unsafe impl ArrayBufferViewContents for u32 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Uint32 as i32
}
}

unsafe impl ArrayBufferViewContents for i32 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Int32 as i32
}
}

unsafe impl ArrayBufferViewContents for f32 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Float32 as i32
}
}
unsafe impl ArrayBufferViewContents for f64 {
fn is_type_compatible(ty: Type) -> bool {
ty as i32 == Type::Float64 as i32
}
}

/// Returns a mutable slice of the Array Buffer View data, viewed as T, without checking the real
/// type of it.
@@ -370,11 +417,10 @@ pub fn array_buffer_view_to_vec<T: ArrayBufferViewContents>(abv: *mut JSObject)

/// 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]> {
pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv: *mut JSObject)
-> 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 {
if T::is_type_compatible(JS_GetArrayBufferViewType(abv)) {
Some(data)
} else {
None
@@ -384,8 +430,8 @@ pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv

/// 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>> {
pub fn array_buffer_view_to_vec_checked<T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<Vec<T>> {
unsafe {
array_buffer_view_data_checked(abv, ty).map(|data| data.to_vec())
array_buffer_view_data_checked(abv).map(|data| data.to_vec())
}
}
@@ -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, Type};
use js::jsapi::{JSContext, JSObject, RootedValue};
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_checked::<f32>(data, Type::Float32) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
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_checked::<f32>(data, Type::Float32) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
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_checked::<f32>(data, Type::Float32) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
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_checked::<f32>(data, Type::Float32) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
if data_vec.len() < 3 {
return self.webgl_error(InvalidOperation);
}
@@ -1029,7 +1029,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {

// 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_checked::<f32>(data, Type::Float32) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
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.