aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglrenderingcontext.rs
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-09-17 15:59:16 -0700
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-10-09 12:41:13 +0200
commitf985a73caeef534c3eacf1cbc8c7337064b6f005 (patch)
tree9ec24c9fd9747f1e0b500012e63541373b650d35 /components/script/dom/webglrenderingcontext.rs
parent602246a14ccf3027232d642eaa30ed97dab48c2d (diff)
downloadservo-f985a73caeef534c3eacf1cbc8c7337064b6f005.tar.gz
servo-f985a73caeef534c3eacf1cbc8c7337064b6f005.zip
webgl: Handle both sequences and typed arrays, managing the type error ourselves.
This is a step with multiple intentions: * Be correct. * Unlock tests that are blocking @anholt. * Ease the transition to typed arrays once the changes by @Ms2ger start rolling in, since I expect the amount of test expectations to update to be non-trivial.
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r--components/script/dom/webglrenderingcontext.rs401
1 files changed, 232 insertions, 169 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 644066b6710..ae971503864 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -8,8 +8,10 @@ use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGL
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
-use dom::bindings::conversions::{ToJSValConvertible, array_buffer_view_data, array_buffer_view_data_checked};
-use dom::bindings::conversions::{array_buffer_view_to_vec, array_buffer_view_to_vec_checked};
+use dom::bindings::conversions::{ArrayBufferViewContents, ConversionResult, FromJSValConvertible, ToJSValConvertible};
+use dom::bindings::conversions::{array_buffer_view_data, array_buffer_view_data_checked, array_buffer_view_to_vec};
+use dom::bindings::conversions::array_buffer_view_to_vec_checked;
+use dom::bindings::error::{Error, Fallible};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
@@ -34,6 +36,7 @@ use dom::webgltexture::{TexParameterValue, WebGLTexture};
use dom::webgluniformlocation::WebGLUniformLocation;
use euclid::size::Size2D;
use ipc_channel::ipc::{self, IpcSender};
+use js::conversions::ConversionBehavior;
use js::jsapi::{JSContext, JSObject, JS_GetArrayBufferViewType, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue};
use net_traits::image::base::PixelFormat;
@@ -288,7 +291,7 @@ impl WebGLRenderingContext {
fn validate_uniform_parameters<T>(&self,
uniform: Option<&WebGLUniformLocation>,
uniform_type: UniformSetterType,
- data: Option<&[T]>) -> bool {
+ data: &[T]) -> bool {
let uniform = match uniform {
Some(uniform) => uniform,
None => return false,
@@ -303,14 +306,6 @@ impl WebGLRenderingContext {
},
};
- let data = match data {
- Some(data) => data,
- None => {
- self.webgl_error(InvalidOperation);
- return false;
- },
- };
-
// TODO(emilio): Get more complex uniform info from ANGLE, and use it to
// properly validate that the uniform setter type is compatible with the
// uniform type, and that the uniform size matches.
@@ -391,12 +386,12 @@ impl WebGLRenderingContext {
// TODO(emilio): Move this logic to a validator.
#[allow(unsafe_code)]
unsafe fn validate_tex_image_2d_data(&self,
- width: u32,
- height: u32,
- format: TexFormat,
- data_type: TexDataType,
- data: *mut JSObject)
- -> Result<u32, ()> {
+ width: u32,
+ height: u32,
+ format: TexFormat,
+ data_type: TexDataType,
+ data: *mut JSObject)
+ -> Result<u32, ()> {
let element_size = data_type.element_size();
let components_per_element = data_type.components_per_element();
let components = format.components();
@@ -531,6 +526,45 @@ impl Drop for WebGLRenderingContext {
}
}
+// FIXME: After [1] lands and the relevant Servo and codegen PR too, we should
+// convert all our raw JSObject pointers to proper types.
+//
+// [1]: https://github.com/servo/rust-mozjs/pull/304
+#[allow(unsafe_code)]
+unsafe fn typed_array_or_sequence_to_vec<T>(cx: *mut JSContext,
+ sequence_or_abv: *mut JSObject,
+ config: <T as FromJSValConvertible>::Config) -> Result<Vec<T>, Error>
+ where T: ArrayBufferViewContents + FromJSValConvertible,
+ <T as FromJSValConvertible>::Config: Clone,
+{
+ assert!(!sequence_or_abv.is_null());
+ if let Some(v) = array_buffer_view_to_vec_checked::<T>(sequence_or_abv) {
+ return Ok(v);
+ }
+
+ rooted!(in(cx) let mut val = UndefinedValue());
+ sequence_or_abv.to_jsval(cx, val.handle_mut());
+
+ match Vec::<T>::from_jsval(cx, val.handle(), config) {
+ Ok(ConversionResult::Success(v)) => Ok(v),
+ Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
+ // FIXME: What to do here? Generated code only aborts the execution of
+ // the script.
+ Err(err) => panic!("unexpected conversion error: {:?}", err),
+ }
+}
+
+#[allow(unsafe_code)]
+unsafe fn fallible_array_buffer_view_to_vec<T>(abv: *mut JSObject) -> Result<Vec<T>, Error>
+ where T: ArrayBufferViewContents
+{
+ assert!(!abv.is_null());
+ match array_buffer_view_to_vec::<T>(abv) {
+ Some(v) => Ok(v),
+ None => Err(Error::Type("Not an ArrayBufferView".to_owned())),
+ }
+}
+
impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn Canvas(&self) -> Root<HTMLCanvasElement> {
@@ -844,85 +878,92 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
- fn BufferData(&self, _cx: *mut JSContext, target: u32, data: *mut JSObject, usage: u32) {
+ fn BufferData(&self, _cx: *mut JSContext, target: u32, data: *mut JSObject, usage: u32) -> Fallible<()> {
+ if data.is_null() {
+ return Ok(self.webgl_error(InvalidValue));
+ }
+
+ let data_vec = try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(data) });
+
let bound_buffer = match target {
constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(),
- _ => return self.webgl_error(InvalidEnum),
+ _ => return Ok(self.webgl_error(InvalidEnum)),
};
let bound_buffer = match bound_buffer {
Some(bound_buffer) => bound_buffer,
- None => return self.webgl_error(InvalidValue),
+ None => return Ok(self.webgl_error(InvalidValue)),
};
match usage {
constants::STREAM_DRAW |
constants::STATIC_DRAW |
constants::DYNAMIC_DRAW => (),
- _ => return self.webgl_error(InvalidEnum),
+ _ => return Ok(self.webgl_error(InvalidEnum)),
}
- if let Some(data_vec) = unsafe { array_buffer_view_to_vec::<u8>(data) } {
- handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data_vec, usage));
- } else {
- // NB: array_buffer_view_to_vec should never fail when we have
- // WebIDL support for Float32Array etc.
- self.webgl_error(InvalidValue);
- }
+ handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data_vec, usage));
+
+ Ok(())
}
#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
- fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: *mut JSObject) {
+ fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: *mut JSObject) -> Fallible<()> {
+ if data.is_null() {
+ return Ok(self.webgl_error(InvalidValue));
+ }
+
+ let data_vec = try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(data) });
+
let bound_buffer = match target {
constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_array.get(),
- _ => return self.webgl_error(InvalidEnum),
+ _ => return Ok(self.webgl_error(InvalidEnum)),
};
let bound_buffer = match bound_buffer {
Some(bound_buffer) => bound_buffer,
- None => return self.webgl_error(InvalidOperation),
+ None => return Ok(self.webgl_error(InvalidOperation)),
};
- if data.is_null() {
- return self.webgl_error(InvalidValue);
- }
-
if offset < 0 {
- return self.webgl_error(InvalidValue);
+ return Ok(self.webgl_error(InvalidValue));
}
- if let Some(data_vec) = unsafe { array_buffer_view_to_vec::<u8>(data) } {
- if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
- return self.webgl_error(InvalidValue);
- }
- self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::BufferSubData(target, offset as isize, data_vec)))
- .unwrap()
- } else {
- // NB: array_buffer_view_to_vec should never fail when we have
- // WebIDL support for Float32Array etc.
- self.webgl_error(InvalidValue);
+ if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
+ return Ok(self.webgl_error(InvalidValue));
}
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BufferSubData(target, offset as isize, data_vec)))
+ .unwrap();
+
+ Ok(())
}
+ #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CompressedTexImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32, _internal_format: u32,
- _width: i32, _height: i32, _border: i32, _pixels: *mut JSObject) {
+ _width: i32, _height: i32, _border: i32, pixels: *mut JSObject) -> Fallible<()> {
+ let _data = try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(pixels) });
// FIXME: No compressed texture format is currently supported, so error out as per
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#COMPRESSED_TEXTURE_SUPPORT
- self.webgl_error(InvalidEnum)
+ self.webgl_error(InvalidEnum);
+ Ok(())
}
+ #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CompressedTexSubImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32,
_xoffset: i32, _yoffset: i32, _width: i32, _height: i32,
- _format: u32, _pixels: *mut JSObject) {
+ _format: u32, pixels: *mut JSObject) -> Fallible<()> {
+ let _data = try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(pixels) });
// FIXME: No compressed texture format is currently supported, so error out as per
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#COMPRESSED_TEXTURE_SUPPORT
- self.webgl_error(InvalidEnum)
+ self.webgl_error(InvalidEnum);
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@@ -1650,23 +1691,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
#[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) {
+ format: u32, pixel_type: u32, pixels: *mut JSObject) -> Fallible<()> {
if pixels.is_null() {
- return self.webgl_error(InvalidValue);
+ return Ok(self.webgl_error(InvalidValue));
}
let mut data = match unsafe { array_buffer_view_data::<u8>(pixels) } {
Some(data) => data,
- None => return self.webgl_error(InvalidValue),
+ None => return Err(Error::Type("Not an ArrayBufferView".to_owned())),
};
if !self.validate_framebuffer_complete() {
- return;
+ return Ok(());
}
match unsafe { JS_GetArrayBufferViewType(pixels) } {
Type::Uint8 => (),
- _ => return self.webgl_error(InvalidOperation)
+ _ => return Ok(self.webgl_error(InvalidOperation)),
}
let (sender, receiver) = ipc::channel().unwrap();
@@ -1677,12 +1718,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
let result = receiver.recv().unwrap();
if result.len() > data.len() {
- return self.webgl_error(InvalidOperation)
+ return Ok(self.webgl_error(InvalidOperation));
}
for i in 0..result.len() {
data[i] = result[i]
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -1802,7 +1845,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn Uniform1f(&self,
uniform: Option<&WebGLUniformLocation>,
val: f32) {
- if self.validate_uniform_parameters(uniform, UniformSetterType::Float, Some(&[val])) {
+ if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &[val]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.unwrap().id(), val)))
.unwrap()
@@ -1813,7 +1856,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn Uniform1i(&self,
uniform: Option<&WebGLUniformLocation>,
val: i32) {
- if self.validate_uniform_parameters(uniform, UniformSetterType::Int, Some(&[val])) {
+ if self.validate_uniform_parameters(uniform, UniformSetterType::Int, &[val]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1i(uniform.unwrap().id(), val)))
.unwrap()
@@ -1823,40 +1866,44 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform1iv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
- if self.validate_uniform_parameters(uniform, UniformSetterType::Int, data_vec.as_ref().map(Vec::as_slice)) {
+ if self.validate_uniform_parameters(uniform, UniformSetterType::Int, &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform1iv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1iv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform1fv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
- if self.validate_uniform_parameters(uniform, UniformSetterType::Float, data_vec.as_ref().map(Vec::as_slice)) {
+ if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform1fv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1fv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn Uniform2f(&self,
uniform: Option<&WebGLUniformLocation>,
x: f32, y: f32) {
- if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec2, Some(&[x, y])) {
+ if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec2, &[x, y]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2f(uniform.unwrap().id(), x, y)))
.unwrap()
@@ -1866,18 +1913,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform2fv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
+
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec2,
- data_vec.as_ref().map(Vec::as_slice)) {
+ &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform2fv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform2fv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -1886,7 +1936,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: i32, y: i32) {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec2,
- Some(&[x, y])) {
+ &[x, y]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2i(uniform.unwrap().id(), x, y)))
.unwrap()
@@ -1896,19 +1946,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform2iv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec2,
- data_vec.as_ref().map(Vec::as_slice)) {
+ &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform2iv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform2iv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -1917,7 +1969,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: f32, y: f32, z: f32) {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec3,
- Some(&[x, y, z])) {
+ &[x, y, z]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3f(uniform.unwrap().id(), x, y, z)))
.unwrap()
@@ -1927,19 +1979,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform3fv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec3,
- data_vec.as_ref().map(Vec::as_slice)) {
+ &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform3fv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform3fv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -1948,7 +2002,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: i32, y: i32, z: i32) {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec3,
- Some(&[x, y, z])) {
+ &[x, y, z]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3i(uniform.unwrap().id(), x, y, z)))
.unwrap()
@@ -1958,19 +2012,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform3iv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec3,
- data_vec.as_ref().map(Vec::as_slice)) {
+ &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform3iv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform3iv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -1979,7 +2035,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: i32, y: i32, z: i32, w: i32) {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec4,
- Some(&[x, y, z, w])) {
+ &[x, y, z, w]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4i(uniform.unwrap().id(), x, y, z, w)))
.unwrap()
@@ -1990,19 +2046,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform4iv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<i32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec4,
- data_vec.as_ref().map(Vec::as_slice)) {
+ &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform4iv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4iv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2011,7 +2069,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: f32, y: f32, z: f32, w: f32) {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec4,
- Some(&[x, y, z, w])) {
+ &[x, y, z, w]) {
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.unwrap().id(), x, y, z, w)))
.unwrap()
@@ -2021,19 +2079,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform4fv(&self,
- _cx: *mut JSContext,
+ cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>,
- data: *mut JSObject) {
+ data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- let data_vec = unsafe { array_buffer_view_to_vec::<f32>(data) };
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec4,
- data_vec.as_ref().map(Vec::as_slice)) {
+ &data_vec) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::Uniform4fv(uniform.unwrap().id(), data_vec.unwrap())))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4fv(uniform.unwrap().id(), data_vec)))
.unwrap()
}
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@@ -2062,16 +2122,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
- fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) {
+ fn VertexAttrib1fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- if let Some(data_vec) = unsafe { array_buffer_view_to_vec_checked::<f32>(data) } {
- if data_vec.len() < 1 {
- return self.webgl_error(InvalidOperation);
- }
- self.vertex_attrib(indx, data_vec[0], 0f32, 0f32, 1f32)
- } else {
- self.webgl_error(InvalidValue);
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
+ if data_vec.len() < 1 {
+ return Ok(self.webgl_error(InvalidOperation));
}
+ self.vertex_attrib(indx, data_vec[0], 0f32, 0f32, 1f32);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2081,16 +2139,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
- fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) {
+ fn VertexAttrib2fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- if let Some(data_vec) = unsafe { array_buffer_view_to_vec_checked::<f32>(data) } {
- if data_vec.len() < 2 {
- return self.webgl_error(InvalidOperation);
- }
- self.vertex_attrib(indx, data_vec[0], data_vec[1], 0f32, 1f32)
- } else {
- self.webgl_error(InvalidValue);
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
+ if data_vec.len() < 2 {
+ return Ok(self.webgl_error(InvalidOperation));
}
+ self.vertex_attrib(indx, data_vec[0], data_vec[1], 0f32, 1f32);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2100,16 +2156,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
- fn VertexAttrib3fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) {
+ fn VertexAttrib3fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- if let Some(data_vec) = unsafe { array_buffer_view_to_vec_checked::<f32>(data) } {
- if data_vec.len() < 3 {
- return self.webgl_error(InvalidOperation);
- }
- self.vertex_attrib(indx, data_vec[0], data_vec[1], data_vec[2], 1f32)
- } else {
- self.webgl_error(InvalidValue);
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
+ if data_vec.len() < 3 {
+ return Ok(self.webgl_error(InvalidOperation));
}
+ self.vertex_attrib(indx, data_vec[0], data_vec[1], data_vec[2], 1f32);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2119,16 +2173,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
- fn VertexAttrib4fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) {
+ fn VertexAttrib4fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
assert!(!data.is_null());
- if let Some(data_vec) = unsafe { array_buffer_view_to_vec_checked::<f32>(data) } {
- if data_vec.len() < 4 {
- return self.webgl_error(InvalidOperation);
- }
- self.vertex_attrib(indx, data_vec[0], data_vec[1], data_vec[2], data_vec[3])
- } else {
- self.webgl_error(InvalidValue);
+ let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
+ if data_vec.len() < 4 {
+ return Ok(self.webgl_error(InvalidOperation));
}
+
+ self.vertex_attrib(indx, data_vec[0], data_vec[1], data_vec[2], data_vec[3]);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2195,7 +2248,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
border: i32,
format: u32,
data_type: u32,
- data: *mut JSObject) {
+ data_ptr: *mut JSObject) -> Fallible<()> {
+ let data = if data_ptr.is_null() {
+ None
+ } else {
+ Some(try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(data_ptr) }))
+ };
+
let validator = TexImage2DValidator::new(self, target, level,
internal_format, width, height,
border, format, data_type);
@@ -2211,34 +2270,32 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
data_type,
} = match validator.validate() {
Ok(result) => result,
- Err(_) => return, // NB: The validator sets the correct error for us.
+ Err(_) => return Ok(()), // NB: The validator sets the correct error for us.
};
let expected_byte_length =
match unsafe { self.validate_tex_image_2d_data(width, height,
format, data_type,
- data) } {
+ data_ptr) } {
Ok(byte_length) => byte_length,
- Err(_) => return,
+ Err(()) => return Ok(()),
};
// If data is null, a buffer of sufficient size
// initialized to 0 is passed.
- let buff = if data.is_null() {
- vec![0u8; expected_byte_length as usize]
- } else {
- unsafe {
- array_buffer_view_to_vec::<u8>(data)
- .expect("Can't reach here without being an ArrayBufferView!")
- }
+ let buff = match data {
+ None => vec![0u8; expected_byte_length as usize],
+ Some(data) => data,
};
if buff.len() != expected_byte_length as usize {
- return self.webgl_error(InvalidOperation);
+ return Ok(self.webgl_error(InvalidOperation));
}
self.tex_image_2d(texture, target, data_type, format,
- level, width, height, border, buff)
+ level, width, height, border, buff);
+
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@@ -2248,14 +2305,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
internal_format: u32,
format: u32,
data_type: u32,
- source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) {
+ source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) -> Fallible<()> {
// Get pixels from image source
let (pixels, size) = match self.get_image_pixels(source) {
Ok((pixels, size)) => (pixels, size),
- Err(_) => return,
+ Err(_) => return Ok(()),
};
-
let validator = TexImage2DValidator::new(self,
target, level, internal_format,
size.width, size.height,
@@ -2272,11 +2328,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
data_type,
} = match validator.validate() {
Ok(result) => result,
- Err(_) => return, // NB: The validator sets the correct error for us.
+ Err(_) => return Ok(()), // NB: The validator sets the correct error for us.
};
self.tex_image_2d(texture, target, data_type, format,
level, width, height, border, pixels);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@@ -2291,7 +2348,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
height: i32,
format: u32,
data_type: u32,
- data: *mut JSObject) {
+ data_ptr: *mut JSObject) -> Fallible<()> {
+ let data = if data_ptr.is_null() {
+ None
+ } else {
+ Some(try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(data_ptr) }))
+ };
+
+
let validator = TexImage2DValidator::new(self, target, level,
format, width, height,
0, format, data_type);
@@ -2306,35 +2370,32 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
..
} = match validator.validate() {
Ok(result) => result,
- Err(_) => return, // NB: The validator sets the correct error for us.
+ Err(_) => return Ok(()), // NB: The validator sets the correct error for us.
};
let expected_byte_length =
match unsafe { self.validate_tex_image_2d_data(width, height,
format, data_type,
- data) } {
+ data_ptr) } {
Ok(byte_length) => byte_length,
- Err(()) => return,
+ Err(()) => return Ok(()),
};
// If data is null, a buffer of sufficient size
// initialized to 0 is passed.
- let buff = if data.is_null() {
- vec![0u8; expected_byte_length as usize]
- } else {
- unsafe {
- array_buffer_view_to_vec::<u8>(data)
- .expect("Can't reach here without being an ArrayBufferView!")
- }
+ let buff = match data {
+ None => vec![0u8; expected_byte_length as usize],
+ Some(data) => data,
};
if expected_byte_length != 0 &&
buff.len() != expected_byte_length as usize {
- return self.webgl_error(InvalidOperation);
+ return Ok(self.webgl_error(InvalidOperation));
}
self.tex_sub_image_2d(texture, target, level, xoffset, yoffset,
width, height, format, data_type, buff);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@@ -2345,10 +2406,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
yoffset: i32,
format: u32,
data_type: u32,
- source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) {
+ source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>)
+ -> Fallible<()> {
let (pixels, size) = match self.get_image_pixels(source) {
Ok((pixels, size)) => (pixels, size),
- Err(_) => return,
+ Err(_) => return Ok(()),
};
let validator = TexImage2DValidator::new(self, target, level, format,
@@ -2365,11 +2427,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
..
} = match validator.validate() {
Ok(result) => result,
- Err(_) => return, // NB: The validator sets the correct error for us.
+ Err(_) => return Ok(()), // NB: The validator sets the correct error for us.
};
self.tex_sub_image_2d(texture, target, level, xoffset, yoffset,
width, height, format, data_type, pixels);
+ Ok(())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8