Auto merge of #13305 - emilio:webgl-idl, r=nox,KiChjang

WebGL IDL and correctness.

<!-- Please describe your changes on the following line: -->
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [x] There are tests for these changes

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

This is a change set 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.

I expect having it to run on try a few times, but... r? @nox or @KiChjang

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13305)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-09 06:26:06 -05:00 committed by GitHub
commit ddff5ce2eb
25 changed files with 2833 additions and 262 deletions

View file

@ -48,7 +48,7 @@ use js::glue::{RUST_JSID_IS_INT, RUST_JSID_TO_INT};
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject}; use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
use js::jsapi::{HandleId, HandleObject, HandleValue, JSClass, JSContext}; use js::jsapi::{HandleId, HandleObject, HandleValue, JSClass, JSContext};
use js::jsapi::{JSObject, JSString, JS_GetArrayBufferViewType, JS_GetClass}; use js::jsapi::{JSObject, JSString, JS_GetArrayBufferViewType, JS_GetClass};
use js::jsapi::{JS_GetLatin1StringCharsAndLength, JS_GetObjectAsArrayBufferView}; use js::jsapi::{JS_GetLatin1StringCharsAndLength, JS_GetObjectAsArrayBuffer, JS_GetObjectAsArrayBufferView};
use js::jsapi::{JS_GetReservedSlot, JS_GetTwoByteStringCharsAndLength, ToWindowProxyIfWindow}; use js::jsapi::{JS_GetReservedSlot, JS_GetTwoByteStringCharsAndLength, ToWindowProxyIfWindow};
use js::jsapi::{JS_IsArrayObject, JS_NewStringCopyN, JS_StringHasLatin1Chars}; use js::jsapi::{JS_IsArrayObject, JS_NewStringCopyN, JS_StringHasLatin1Chars};
use js::jsapi::{JS_WrapValue, MutableHandleValue, Type, IsObjectInContextCompartment}; use js::jsapi::{JS_WrapValue, MutableHandleValue, Type, IsObjectInContextCompartment};
@ -532,9 +532,13 @@ unsafe impl ArrayBufferViewContents for f64 {
} }
} }
/// Returns a mutable slice of the Array Buffer View data, viewed as T, without checking the real /// Returns a mutable slice of the Array Buffer View data, viewed as T, without
/// type of it. /// checking the real type of it.
pub unsafe fn array_buffer_view_data<'a, T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<&'a mut [T]> { pub unsafe fn array_buffer_view_data<'a, T>(abv: *mut JSObject) -> Option<&'a mut [T]>
where T: ArrayBufferViewContents
{
assert!(!abv.is_null());
let mut byte_length = 0; let mut byte_length = 0;
let mut ptr = ptr::null_mut(); let mut ptr = ptr::null_mut();
let mut is_shared = false; let mut is_shared = false;
@ -546,17 +550,19 @@ 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>())) 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, viewed as T, without checking the real type of it. /// Returns a copy of the ArrayBufferView data, viewed as T, without checking
pub fn array_buffer_view_to_vec<T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<Vec<T>> { /// the real type of it.
unsafe { pub unsafe fn array_buffer_view_to_vec<T>(abv: *mut JSObject) -> Option<Vec<T>>
array_buffer_view_data(abv).map(|data| data.to_vec()) where T: ArrayBufferViewContents
} {
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 /// Returns a mutable slice of the Array Buffer View data, viewed as T, checking
/// of it is ty. /// that the real type of it is ty.
pub unsafe fn array_buffer_view_data_checked<'a, T: ArrayBufferViewContents>(abv: *mut JSObject) pub unsafe fn array_buffer_view_data_checked<'a, T>(abv: *mut JSObject) -> Option<&'a mut [T]>
-> Option<&'a mut [T]> { where T: ArrayBufferViewContents
{
array_buffer_view_data::<T>(abv).and_then(|data| { array_buffer_view_data::<T>(abv).and_then(|data| {
if T::is_type_compatible(JS_GetArrayBufferViewType(abv)) { if T::is_type_compatible(JS_GetArrayBufferViewType(abv)) {
Some(data) Some(data)
@ -566,12 +572,35 @@ 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 /// Returns a copy of the ArrayBufferView data, viewed as T, checking that the
/// of it is ty. /// real type of it is ty.
pub fn array_buffer_view_to_vec_checked<T: ArrayBufferViewContents>(abv: *mut JSObject) -> Option<Vec<T>> { pub unsafe fn array_buffer_view_to_vec_checked<T>(abv: *mut JSObject) -> Option<Vec<T>>
unsafe { where T: ArrayBufferViewContents
array_buffer_view_data_checked(abv).map(|data| data.to_vec()) {
array_buffer_view_data_checked(abv).map(|data| data.to_vec())
}
/// Similar API as the array_buffer_view_xxx functions, but for ArrayBuffer
/// objects.
pub unsafe fn array_buffer_data<'a, T>(ab: *mut JSObject) -> Option<&'a mut [T]>
where T: ArrayBufferViewContents
{
assert!(!ab.is_null());
let mut byte_length = 0;
let mut ptr = ptr::null_mut();
let ret = JS_GetObjectAsArrayBuffer(ab, &mut byte_length, &mut ptr);
if ret.is_null() {
return None;
} }
Some(slice::from_raw_parts_mut(ptr as *mut T, byte_length as usize / mem::size_of::<T>()))
}
/// Similar API to array_buffer_view_to_vec, but for ArrayBuffer objects.
pub unsafe fn array_buffer_to_vec<T>(ab: *mut JSObject) -> Option<Vec<T>>
where T: ArrayBufferViewContents
{
array_buffer_data(ab).map(|data| data.to_vec())
} }
/// Returns whether `value` is an array-like object. /// Returns whether `value` is an array-like object.

View file

@ -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::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
use dom::bindings::conversions::{ToJSValConvertible, array_buffer_view_data, array_buffer_view_data_checked}; use dom::bindings::conversions::{ArrayBufferViewContents, ConversionResult, FromJSValConvertible, ToJSValConvertible};
use dom::bindings::conversions::{array_buffer_to_vec, 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::{array_buffer_view_to_vec, array_buffer_view_to_vec_checked};
use dom::bindings::error::{Error, Fallible};
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
@ -34,6 +36,7 @@ use dom::webgltexture::{TexParameterValue, WebGLTexture};
use dom::webgluniformlocation::WebGLUniformLocation; use dom::webgluniformlocation::WebGLUniformLocation;
use euclid::size::Size2D; use euclid::size::Size2D;
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::{self, IpcSender};
use js::conversions::ConversionBehavior;
use js::jsapi::{JSContext, JSObject, JS_GetArrayBufferViewType, Type}; use js::jsapi::{JSContext, JSObject, JS_GetArrayBufferViewType, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue};
use net_traits::image::base::PixelFormat; use net_traits::image::base::PixelFormat;
@ -288,7 +291,7 @@ impl WebGLRenderingContext {
fn validate_uniform_parameters<T>(&self, fn validate_uniform_parameters<T>(&self,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
uniform_type: UniformSetterType, uniform_type: UniformSetterType,
data: Option<&[T]>) -> bool { data: &[T]) -> bool {
let uniform = match uniform { let uniform = match uniform {
Some(uniform) => uniform, Some(uniform) => uniform,
None => return false, 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 // TODO(emilio): Get more complex uniform info from ANGLE, and use it to
// properly validate that the uniform setter type is compatible with the // properly validate that the uniform setter type is compatible with the
// uniform type, and that the uniform size matches. // uniform type, and that the uniform size matches.
@ -390,13 +385,13 @@ impl WebGLRenderingContext {
// TODO(emilio): Move this logic to a validator. // TODO(emilio): Move this logic to a validator.
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn validate_tex_image_2d_data(&self, unsafe fn validate_tex_image_2d_data(&self,
width: u32, width: u32,
height: u32, height: u32,
format: TexFormat, format: TexFormat,
data_type: TexDataType, data_type: TexDataType,
data: Option<*mut JSObject>) data: *mut JSObject)
-> Result<u32, ()> { -> Result<u32, ()> {
let element_size = data_type.element_size(); let element_size = data_type.element_size();
let components_per_element = data_type.components_per_element(); let components_per_element = data_type.components_per_element();
let components = format.components(); let components = format.components();
@ -407,17 +402,17 @@ impl WebGLRenderingContext {
// if it is UNSIGNED_SHORT_5_6_5, UNSIGNED_SHORT_4_4_4_4, // if it is UNSIGNED_SHORT_5_6_5, UNSIGNED_SHORT_4_4_4_4,
// or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied. // or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied.
// If the types do not match, an INVALID_OPERATION error is generated. // If the types do not match, an INVALID_OPERATION error is generated.
let received_size = if let Some(data) = data { let received_size = if data.is_null() {
if unsafe { array_buffer_view_data_checked::<u16>(data).is_some() } { element_size
} else {
if array_buffer_view_data_checked::<u16>(data).is_some() {
2 2
} else if unsafe { array_buffer_view_data_checked::<u8>(data).is_some() } { } else if array_buffer_view_data_checked::<u8>(data).is_some() {
1 1
} else { } else {
self.webgl_error(InvalidOperation); self.webgl_error(InvalidOperation);
return Err(()); return Err(());
} }
} else {
element_size
}; };
if received_size != element_size { if received_size != element_size {
@ -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 { impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn Canvas(&self) -> Root<HTMLCanvasElement> { fn Canvas(&self) -> Root<HTMLCanvasElement> {
@ -571,7 +605,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
receiver.recv().unwrap() receiver.recv().unwrap()
} }
#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal { fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal {
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap();
@ -845,86 +878,104 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
#[allow(unsafe_code)] #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn BufferData(&self, _cx: *mut JSContext, target: u32, data: Option<*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 = unsafe {
match array_buffer_to_vec::<u8>(data) {
Some(data) => data,
// Not an ArrayBuffer object, maybe an ArrayBufferView?
None => try!(fallible_array_buffer_view_to_vec::<u8>(data)),
}
};
let bound_buffer = match target { let bound_buffer = match target {
constants::ARRAY_BUFFER => self.bound_buffer_array.get(), constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_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 { let bound_buffer = match bound_buffer {
Some(bound_buffer) => bound_buffer, Some(bound_buffer) => bound_buffer,
None => return self.webgl_error(InvalidValue), None => return Ok(self.webgl_error(InvalidValue)),
}; };
match usage { match usage {
constants::STREAM_DRAW | constants::STREAM_DRAW |
constants::STATIC_DRAW | constants::STATIC_DRAW |
constants::DYNAMIC_DRAW => (), constants::DYNAMIC_DRAW => (),
_ => return self.webgl_error(InvalidEnum), _ => return Ok(self.webgl_error(InvalidEnum)),
} }
let data = match data { handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data_vec, usage));
Some(data) => data,
None => return self.webgl_error(InvalidValue),
};
if let Some(data_vec) = array_buffer_view_to_vec::<u8>(data) { Ok(())
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);
}
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: Option<*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 = unsafe {
match array_buffer_to_vec::<u8>(data) {
Some(data) => data,
// Not an ArrayBuffer object, maybe an ArrayBufferView?
None => try!(fallible_array_buffer_view_to_vec::<u8>(data)),
}
};
let bound_buffer = match target { let bound_buffer = match target {
constants::ARRAY_BUFFER => self.bound_buffer_array.get(), constants::ARRAY_BUFFER => self.bound_buffer_array.get(),
constants::ELEMENT_ARRAY_BUFFER => self.bound_buffer_element_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 { let bound_buffer = match bound_buffer {
Some(bound_buffer) => bound_buffer, Some(bound_buffer) => bound_buffer,
None => return self.webgl_error(InvalidOperation), None => return Ok(self.webgl_error(InvalidOperation)),
};
let data = match data {
Some(data) => data,
None => return self.webgl_error(InvalidValue),
}; };
if offset < 0 { if offset < 0 {
return self.webgl_error(InvalidValue); return Ok(self.webgl_error(InvalidValue));
} }
if let Some(data_vec) = array_buffer_view_to_vec::<u8>(data) {
if (offset as usize) + data_vec.len() > bound_buffer.capacity() { if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
return self.webgl_error(InvalidValue); return Ok(self.webgl_error(InvalidValue));
}
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::BufferSubData(target, offset as isize, data_vec)))
.unwrap()
} else {
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 // 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, 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 // 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 // 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 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CompressedTexSubImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32, fn CompressedTexSubImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32,
_xoffset: i32, _yoffset: i32, _width: i32, _height: 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 // 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 // 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 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@ -1652,19 +1703,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
#[allow(unsafe_code)] #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 // 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, 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 Ok(self.webgl_error(InvalidValue));
}
let mut data = match unsafe { array_buffer_view_data::<u8>(pixels) } { let mut data = match unsafe { array_buffer_view_data::<u8>(pixels) } {
Some(data) => data, Some(data) => data,
None => return self.webgl_error(InvalidValue), None => return Err(Error::Type("Not an ArrayBufferView".to_owned())),
}; };
if !self.validate_framebuffer_complete() { if !self.validate_framebuffer_complete() {
return; return Ok(());
} }
match unsafe { JS_GetArrayBufferViewType(pixels) } { match unsafe { JS_GetArrayBufferViewType(pixels) } {
Type::Uint8 => (), Type::Uint8 => (),
_ => return self.webgl_error(InvalidOperation) _ => return Ok(self.webgl_error(InvalidOperation)),
} }
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap();
@ -1675,12 +1730,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
let result = receiver.recv().unwrap(); let result = receiver.recv().unwrap();
if result.len() > data.len() { if result.len() > data.len() {
return self.webgl_error(InvalidOperation) return Ok(self.webgl_error(InvalidOperation));
} }
for i in 0..result.len() { for i in 0..result.len() {
data[i] = result[i] data[i] = result[i]
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@ -1800,7 +1857,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn Uniform1f(&self, fn Uniform1f(&self,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
val: f32) { val: f32) {
if self.validate_uniform_parameters(uniform, UniformSetterType::Float, Some(&[val])) { if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &[val]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.unwrap().id(), val))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.unwrap().id(), val)))
.unwrap() .unwrap()
@ -1811,7 +1868,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn Uniform1i(&self, fn Uniform1i(&self,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
val: i32) { val: i32) {
if self.validate_uniform_parameters(uniform, UniformSetterType::Int, Some(&[val])) { if self.validate_uniform_parameters(uniform, UniformSetterType::Int, &[val]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform1i(uniform.unwrap().id(), val))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform1i(uniform.unwrap().id(), val)))
.unwrap() .unwrap()
@ -1819,36 +1876,46 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform1iv(&self, fn Uniform1iv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); assert!(!data.is_null());
if self.validate_uniform_parameters(uniform, UniformSetterType::Int, data_vec.as_ref().map(Vec::as_slice)) { 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) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform1fv(&self, fn Uniform1fv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); assert!(!data.is_null());
if self.validate_uniform_parameters(uniform, UniformSetterType::Float, data_vec.as_ref().map(Vec::as_slice)) { let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn Uniform2f(&self, fn Uniform2f(&self,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
x: f32, y: f32) { 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 self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2f(uniform.unwrap().id(), x, y))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform2f(uniform.unwrap().id(), x, y)))
.unwrap() .unwrap()
@ -1856,18 +1923,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform2fv(&self, fn Uniform2fv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); assert!(!data.is_null());
let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec2, UniformSetterType::FloatVec2,
data_vec.as_ref().map(Vec::as_slice)) { &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -1876,7 +1948,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: i32, y: i32) { x: i32, y: i32) {
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec2, UniformSetterType::IntVec2,
Some(&[x, y])) { &[x, y]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform2i(uniform.unwrap().id(), x, y))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform2i(uniform.unwrap().id(), x, y)))
.unwrap() .unwrap()
@ -1884,18 +1956,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform2iv(&self, fn Uniform2iv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); assert!(!data.is_null());
let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec2, UniformSetterType::IntVec2,
data_vec.as_ref().map(Vec::as_slice)) { &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -1904,7 +1981,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: f32, y: f32, z: f32) { x: f32, y: f32, z: f32) {
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec3, UniformSetterType::FloatVec3,
Some(&[x, y, z])) { &[x, y, z]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3f(uniform.unwrap().id(), x, y, z))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform3f(uniform.unwrap().id(), x, y, z)))
.unwrap() .unwrap()
@ -1912,18 +1989,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform3fv(&self, fn Uniform3fv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); assert!(!data.is_null());
let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec3, UniformSetterType::FloatVec3,
data_vec.as_ref().map(Vec::as_slice)) { &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -1932,7 +2014,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: i32, y: i32, z: i32) { x: i32, y: i32, z: i32) {
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec3, UniformSetterType::IntVec3,
Some(&[x, y, z])) { &[x, y, z]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform3i(uniform.unwrap().id(), x, y, z))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform3i(uniform.unwrap().id(), x, y, z)))
.unwrap() .unwrap()
@ -1940,18 +2022,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform3iv(&self, fn Uniform3iv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); assert!(!data.is_null());
let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec3, UniformSetterType::IntVec3,
data_vec.as_ref().map(Vec::as_slice)) { &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -1960,7 +2047,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: i32, y: i32, z: i32, w: i32) { x: i32, y: i32, z: i32, w: i32) {
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec4, UniformSetterType::IntVec4,
Some(&[x, y, z, w])) { &[x, y, z, w]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4i(uniform.unwrap().id(), x, y, z, w))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform4i(uniform.unwrap().id(), x, y, z, w)))
.unwrap() .unwrap()
@ -1969,18 +2056,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform4iv(&self, fn Uniform4iv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<i32>(d)); assert!(!data.is_null());
let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) });
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec4, UniformSetterType::IntVec4,
data_vec.as_ref().map(Vec::as_slice)) { &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -1989,7 +2081,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x: f32, y: f32, z: f32, w: f32) { x: f32, y: f32, z: f32, w: f32) {
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec4, UniformSetterType::FloatVec4,
Some(&[x, y, z, w])) { &[x, y, z, w]) {
self.ipc_renderer self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.unwrap().id(), x, y, z, w))) .send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.unwrap().id(), x, y, z, w)))
.unwrap() .unwrap()
@ -1997,18 +2089,23 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
#[allow(unsafe_code)]
fn Uniform4fv(&self, fn Uniform4fv(&self,
_cx: *mut JSContext, cx: *mut JSContext,
uniform: Option<&WebGLUniformLocation>, uniform: Option<&WebGLUniformLocation>,
data: Option<*mut JSObject>) { data: *mut JSObject) -> Fallible<()> {
let data_vec = data.and_then(|d| array_buffer_view_to_vec::<f32>(d)); assert!(!data.is_null());
let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
if self.validate_uniform_parameters(uniform, if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec4, UniformSetterType::FloatVec4,
data_vec.as_ref().map(Vec::as_slice)) { &data_vec) {
self.ipc_renderer 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() .unwrap()
} }
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@ -2036,15 +2133,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { #[allow(unsafe_code)]
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { fn VertexAttrib1fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
if data_vec.len() < 1 { assert!(!data.is_null());
return self.webgl_error(InvalidOperation); let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
} if data_vec.len() < 1 {
self.vertex_attrib(indx, data_vec[0], 0f32, 0f32, 1f32) return Ok(self.webgl_error(InvalidOperation));
} else {
self.webgl_error(InvalidValue);
} }
self.vertex_attrib(indx, data_vec[0], 0f32, 0f32, 1f32);
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -2053,15 +2150,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { #[allow(unsafe_code)]
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { fn VertexAttrib2fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
if data_vec.len() < 2 { assert!(!data.is_null());
return self.webgl_error(InvalidOperation); let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
} if data_vec.len() < 2 {
self.vertex_attrib(indx, data_vec[0], data_vec[1], 0f32, 1f32) return Ok(self.webgl_error(InvalidOperation));
} else {
self.webgl_error(InvalidValue);
} }
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 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -2069,17 +2166,16 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
self.vertex_attrib(indx, x, y, z, 1f32) self.vertex_attrib(indx, x, y, z, 1f32)
} }
#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib3fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { #[allow(unsafe_code)]
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { fn VertexAttrib3fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
if data_vec.len() < 3 { assert!(!data.is_null());
return self.webgl_error(InvalidOperation); let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
} if data_vec.len() < 3 {
self.vertex_attrib(indx, data_vec[0], data_vec[1], data_vec[2], 1f32) return Ok(self.webgl_error(InvalidOperation));
} else {
self.webgl_error(InvalidValue);
} }
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 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -2088,15 +2184,16 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib4fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { #[allow(unsafe_code)]
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { fn VertexAttrib4fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> {
if data_vec.len() < 4 { assert!(!data.is_null());
return self.webgl_error(InvalidOperation); let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) });
} if data_vec.len() < 4 {
self.vertex_attrib(indx, data_vec[0], data_vec[1], data_vec[2], data_vec[3]) return Ok(self.webgl_error(InvalidOperation));
} else {
self.webgl_error(InvalidValue);
} }
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 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -2152,6 +2249,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
#[allow(unsafe_code)]
fn TexImage2D(&self, fn TexImage2D(&self,
_cx: *mut JSContext, _cx: *mut JSContext,
target: u32, target: u32,
@ -2162,7 +2260,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
border: i32, border: i32,
format: u32, format: u32,
data_type: u32, data_type: u32,
data: Option<*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, let validator = TexImage2DValidator::new(self, target, level,
internal_format, width, height, internal_format, width, height,
border, format, data_type); border, format, data_type);
@ -2178,33 +2282,32 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
data_type, data_type,
} = match validator.validate() { } = match validator.validate() {
Ok(result) => result, 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 self.validate_tex_image_2d_data(width, let expected_byte_length =
height, match unsafe { self.validate_tex_image_2d_data(width, height,
format, format, data_type,
data_type, data_ptr) } {
data) { Ok(byte_length) => byte_length,
Ok(byte_length) => byte_length, Err(()) => return Ok(()),
Err(_) => return, };
};
// If data is null, a buffer of sufficient size // If data is null, a buffer of sufficient size
// initialized to 0 is passed. // initialized to 0 is passed.
let buff = if let Some(data) = data { let buff = match data {
array_buffer_view_to_vec::<u8>(data) None => vec![0u8; expected_byte_length as usize],
.expect("Can't reach here without being an ArrayBufferView!") Some(data) => data,
} else {
vec![0u8; expected_byte_length as usize]
}; };
if buff.len() != expected_byte_length as usize { 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, 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 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@ -2214,14 +2317,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
internal_format: u32, internal_format: u32,
format: u32, format: u32,
data_type: u32, data_type: u32,
source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) { source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) -> Fallible<()> {
// Get pixels from image source // Get pixels from image source
let (pixels, size) = match self.get_image_pixels(source) { let (pixels, size) = match self.get_image_pixels(source) {
Ok((pixels, size)) => (pixels, size), Ok((pixels, size)) => (pixels, size),
Err(_) => return, Err(_) => return Ok(()),
}; };
let validator = TexImage2DValidator::new(self, let validator = TexImage2DValidator::new(self,
target, level, internal_format, target, level, internal_format,
size.width, size.height, size.width, size.height,
@ -2238,14 +2340,16 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
data_type, data_type,
} = match validator.validate() { } = match validator.validate() {
Ok(result) => result, 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, self.tex_image_2d(texture, target, data_type, format,
level, width, height, border, pixels); level, width, height, border, pixels);
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
#[allow(unsafe_code)]
fn TexSubImage2D(&self, fn TexSubImage2D(&self,
_cx: *mut JSContext, _cx: *mut JSContext,
target: u32, target: u32,
@ -2256,7 +2360,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
height: i32, height: i32,
format: u32, format: u32,
data_type: u32, data_type: u32,
data: Option<*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, let validator = TexImage2DValidator::new(self, target, level,
format, width, height, format, width, height,
0, format, data_type); 0, format, data_type);
@ -2271,34 +2382,32 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
.. ..
} = match validator.validate() { } = match validator.validate() {
Ok(result) => result, 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 self.validate_tex_image_2d_data(width, let expected_byte_length =
height, match unsafe { self.validate_tex_image_2d_data(width, height,
format, format, data_type,
data_type, data_ptr) } {
data) { Ok(byte_length) => byte_length,
Ok(byte_length) => byte_length, Err(()) => return Ok(()),
Err(()) => return, };
};
// If data is null, a buffer of sufficient size // If data is null, a buffer of sufficient size
// initialized to 0 is passed. // initialized to 0 is passed.
let buff = if let Some(data) = data { let buff = match data {
array_buffer_view_to_vec::<u8>(data) None => vec![0u8; expected_byte_length as usize],
.expect("Can't reach here without being an ArrayBufferView!") Some(data) => data,
} else {
vec![0u8; expected_byte_length as usize]
}; };
if expected_byte_length != 0 && if expected_byte_length != 0 &&
buff.len() != expected_byte_length as usize { 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, self.tex_sub_image_2d(texture, target, level, xoffset, yoffset,
width, height, format, data_type, buff); width, height, format, data_type, buff);
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@ -2309,10 +2418,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
yoffset: i32, yoffset: i32,
format: u32, format: u32,
data_type: u32, data_type: u32,
source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>) { source: Option<ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement>)
-> Fallible<()> {
let (pixels, size) = match self.get_image_pixels(source) { let (pixels, size) = match self.get_image_pixels(source) {
Ok((pixels, size)) => (pixels, size), Ok((pixels, size)) => (pixels, size),
Err(_) => return, Err(_) => return Ok(()),
}; };
let validator = TexImage2DValidator::new(self, target, level, format, let validator = TexImage2DValidator::new(self, target, level, format,
@ -2329,11 +2439,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
.. ..
} = match validator.validate() { } = match validator.validate() {
Ok(result) => result, 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, self.tex_sub_image_2d(texture, target, level, xoffset, yoffset,
width, height, format, data_type, pixels); width, height, format, data_type, pixels);
Ok(())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8

View file

@ -492,11 +492,14 @@ interface WebGLRenderingContextBase
//void bufferData(GLenum target, GLsizeiptr size, GLenum usage); //void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
// FIXME(dmarcos) The function below is the original function in the webIdl: // FIXME(dmarcos) The function below is the original function in the webIdl:
// void bufferData(GLenum target, BufferDataSource? data, GLenum usage); // void bufferData(GLenum target, BufferDataSource? data, GLenum usage);
// The Code generator doesn't handle BufferDataSource so we're using 'optional object' // The Code generator doesn't handle BufferDataSource so we're using 'object?'
// in the meantime // in the meantime, and marking the function as [Throws], so we can handle
void bufferData(GLenum target, optional object data, GLenum usage); // the type error from inside.
[Throws]
void bufferData(GLenum target, object? data, GLenum usage);
//void bufferSubData(GLenum target, GLintptr offset, BufferDataSource? data); //void bufferSubData(GLenum target, GLintptr offset, BufferDataSource? data);
void bufferSubData(GLenum target, GLintptr offset, optional object data); [Throws]
void bufferSubData(GLenum target, GLintptr offset, object? data);
//[WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target); //[WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target);
void clear(GLbitfield mask); void clear(GLbitfield mask);
@ -507,10 +510,12 @@ interface WebGLRenderingContextBase
void compileShader(WebGLShader? shader); void compileShader(WebGLShader? shader);
// FIXME(simartin) The Code generator doesn't handle ArrayBufferView so we're // FIXME(simartin) The Code generator doesn't handle ArrayBufferView so we're
// using 'object' in the meantime // using 'object' in the meantime, and marking the function as Throws to
// handle the type error from inside.
// void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, // void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
// GLsizei width, GLsizei height, GLint border, // GLsizei width, GLsizei height, GLint border,
// ArrayBufferView data); // ArrayBufferView data);
[Throws]
void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
object data); object data);
@ -518,6 +523,7 @@ interface WebGLRenderingContextBase
// GLint xoffset, GLint yoffset, // GLint xoffset, GLint yoffset,
// GLsizei width, GLsizei height, GLenum format, // GLsizei width, GLsizei height, GLenum format,
// ArrayBufferView data); // ArrayBufferView data);
[Throws]
void compressedTexSubImage2D(GLenum target, GLint level, void compressedTexSubImage2D(GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLsizei width, GLsizei height, GLenum format,
@ -616,6 +622,7 @@ interface WebGLRenderingContextBase
//void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, //void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
// GLenum format, GLenum type, ArrayBufferView? pixels); // GLenum format, GLenum type, ArrayBufferView? pixels);
[Throws]
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, object? pixels); GLenum format, GLenum type, object? pixels);
@ -637,58 +644,70 @@ interface WebGLRenderingContextBase
// GLsizei width, GLsizei height, GLint border, GLenum format, // GLsizei width, GLsizei height, GLint border, GLenum format,
// GLenum type, ArrayBufferView? pixels); // GLenum type, ArrayBufferView? pixels);
// FIXME: SM interface arguments // FIXME: SM interface arguments
[Throws]
void texImage2D(GLenum target, GLint level, GLenum internalformat, void texImage2D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLint border, GLenum format, GLsizei width, GLsizei height, GLint border, GLenum format,
GLenum type, optional object data); GLenum type, object? data);
[Throws]
void texImage2D(GLenum target, GLint level, GLenum internalformat, void texImage2D(GLenum target, GLint level, GLenum internalformat,
GLenum format, GLenum type, TexImageSource? source); // May throw DOMException GLenum format, GLenum type, TexImageSource? source); // May throw DOMException
void texParameterf(GLenum target, GLenum pname, GLfloat param); void texParameterf(GLenum target, GLenum pname, GLfloat param);
void texParameteri(GLenum target, GLenum pname, GLint param); void texParameteri(GLenum target, GLenum pname, GLint param);
[Throws]
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei width, GLsizei height,
GLenum format, GLenum type, optional object data); GLenum format, GLenum type, object? data);
[Throws]
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, TexImageSource? source); // May throw DOMException GLenum format, GLenum type, TexImageSource? source); // May throw DOMException
void uniform1f(WebGLUniformLocation? location, GLfloat x); void uniform1f(WebGLUniformLocation? location, GLfloat x);
//void uniform1fv(WebGLUniformLocation? location, Float32Array v); //void uniform1fv(WebGLUniformLocation? location, Float32Array v);
//void uniform1fv(WebGLUniformLocation? location, sequence<GLfloat> v); //void uniform1fv(WebGLUniformLocation? location, sequence<GLfloat> v);
void uniform1fv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform1fv(WebGLUniformLocation? location, object v);
void uniform1i(WebGLUniformLocation? location, GLint x); void uniform1i(WebGLUniformLocation? location, GLint x);
//void uniform1iv(WebGLUniformLocation? location, Int32Array v); //void uniform1iv(WebGLUniformLocation? location, Int32Array v);
//void uniform1iv(WebGLUniformLocation? location, sequence<long> v); //void uniform1iv(WebGLUniformLocation? location, sequence<long> v);
void uniform1iv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform1iv(WebGLUniformLocation? location, object v);
void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
//void uniform2fv(WebGLUniformLocation? location, Float32Array v); //void uniform2fv(WebGLUniformLocation? location, Float32Array v);
//void uniform2fv(WebGLUniformLocation? location, sequence<GLfloat> v); //void uniform2fv(WebGLUniformLocation? location, sequence<GLfloat> v);
void uniform2fv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform2fv(WebGLUniformLocation? location, object v);
//void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); //void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
//void uniform2iv(WebGLUniformLocation? location, Int32Array v); //void uniform2iv(WebGLUniformLocation? location, Int32Array v);
//void uniform2iv(WebGLUniformLocation? location, sequence<long> v); //void uniform2iv(WebGLUniformLocation? location, sequence<long> v);
void uniform2iv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform2iv(WebGLUniformLocation? location, object v);
void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
void uniform3fv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform3fv(WebGLUniformLocation? location, object v);
//void uniform3fv(WebGLUniformLocation? location, Float32Array v); //void uniform3fv(WebGLUniformLocation? location, Float32Array v);
//void uniform3fv(WebGLUniformLocation? location, sequence<GLfloat> v); //void uniform3fv(WebGLUniformLocation? location, sequence<GLfloat> v);
void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
//void uniform3iv(WebGLUniformLocation? location, Int32Array v); //void uniform3iv(WebGLUniformLocation? location, Int32Array v);
//void uniform3iv(WebGLUniformLocation? location, sequence<long> v); //void uniform3iv(WebGLUniformLocation? location, sequence<long> v);
void uniform3iv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform3iv(WebGLUniformLocation? location, object v);
void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
// FIXME(dmarcos) The function below is the original function in the webIdl: // FIXME(dmarcos) The function below is the original function in the webIdl:
//void uniform4fv(WebGLUniformLocation? location, Float32Array v); //void uniform4fv(WebGLUniformLocation? location, Float32Array v);
// The Code genearator doesn't handle BufferDataSource so we're using 'optional object' // The Code genearator doesn't handle typed arrays, so we use object
// in the meantime // instead, and handle the type error ourselves.
void uniform4fv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform4fv(WebGLUniformLocation? location, object v);
//void uniform4fv(WebGLUniformLocation? location, sequence<GLfloat> v); //void uniform4fv(WebGLUniformLocation? location, sequence<GLfloat> v);
void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
//void uniform4iv(WebGLUniformLocation? location, Int32Array v); //void uniform4iv(WebGLUniformLocation? location, Int32Array v);
//void uniform4iv(WebGLUniformLocation? location, sequence<long> v); //void uniform4iv(WebGLUniformLocation? location, sequence<long> v);
// See FIXME above // See FIXME above
void uniform4iv(WebGLUniformLocation? location, optional object v); [Throws]
void uniform4iv(WebGLUniformLocation? location, object v);
//void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, //void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose,
// Float32Array value); // Float32Array value);
@ -710,18 +729,22 @@ interface WebGLRenderingContextBase
// The code generator doesn't handle Float32Array so we're using 'object' // The code generator doesn't handle Float32Array so we're using 'object'
void vertexAttrib1f(GLuint indx, GLfloat x); void vertexAttrib1f(GLuint indx, GLfloat x);
//void vertexAttrib1fv(GLuint indx, Float32Array values); //void vertexAttrib1fv(GLuint indx, Float32Array values);
[Throws]
void vertexAttrib1fv(GLuint indx, object values); void vertexAttrib1fv(GLuint indx, object values);
//void vertexAttrib1fv(GLuint indx, sequence<GLfloat> values); //void vertexAttrib1fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y); void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
//void vertexAttrib2fv(GLuint indx, Float32Array values); //void vertexAttrib2fv(GLuint indx, Float32Array values);
[Throws]
void vertexAttrib2fv(GLuint indx, object values); void vertexAttrib2fv(GLuint indx, object values);
//void vertexAttrib2fv(GLuint indx, sequence<GLfloat> values); //void vertexAttrib2fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z); void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
//void vertexAttrib3fv(GLuint indx, Float32Array values); //void vertexAttrib3fv(GLuint indx, Float32Array values);
[Throws]
void vertexAttrib3fv(GLuint indx, object values); void vertexAttrib3fv(GLuint indx, object values);
//void vertexAttrib3fv(GLuint indx, sequence<GLfloat> values); //void vertexAttrib3fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
//void vertexAttrib4fv(GLuint indx, Float32Array values); //void vertexAttrib4fv(GLuint indx, Float32Array values);
[Throws]
void vertexAttrib4fv(GLuint indx, object values); void vertexAttrib4fv(GLuint indx, object values);
//void vertexAttrib4fv(GLuint indx, sequence<GLfloat> values); //void vertexAttrib4fv(GLuint indx, sequence<GLfloat> values);
void vertexAttribPointer(GLuint indx, GLint size, GLenum type, void vertexAttribPointer(GLuint indx, GLint size, GLenum type,

View file

@ -7,3 +7,6 @@
[WebGL test #5: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #5: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL
[WebGL test #3: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

View file

@ -1,5 +0,0 @@
[texImage2DBadArgs.html]
type: testharness
[WebGL test #0: testTexImage2D]
expected: FAIL

View file

@ -1,5 +0,0 @@
[uniformf.html]
type: testharness
[WebGL test #0: testUniformf]
expected: FAIL

View file

@ -1,5 +0,0 @@
[uniformfArrayLen1.html]
type: testharness
[WebGL test #0: testUniformArray]
expected: FAIL

View file

@ -1,5 +1,6 @@
[uniformfBadArgs.html] [uniformfBadArgs.html]
type: testharness type: testharness
expected: CRASH
[WebGL test #0: testUniformf] [WebGL test #0: testUniformf]
expected: FAIL expected: FAIL

View file

@ -1,5 +0,0 @@
[uniformi.html]
type: testharness
[WebGL test #0: testUniformf]
expected: FAIL

View file

@ -1,5 +1,6 @@
[uniformiBadArgs.html] [uniformiBadArgs.html]
type: testharness type: testharness
expected: CRASH
[WebGL test #0: testUniformf] [WebGL test #0: testUniformf]
expected: FAIL expected: FAIL

View file

@ -1,5 +0,0 @@
[vertexAttrib.html]
type: testharness
[WebGL test #0: testVertexAttrib]
expected: FAIL

View file

@ -1,5 +0,0 @@
[vertexAttribBadArgs.html]
type: testharness
[WebGL test #0: testVertexAttrib]
expected: FAIL

View file

@ -1,6 +1,5 @@
[gl-geterror.html] [gl-geterror.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[tex-image-with-invalid-data.html] [tex-image-with-invalid-data.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #1: getError expected: INVALID_OPERATION. Was NO_ERROR : ] [WebGL test #1: getError expected: INVALID_OPERATION. Was NO_ERROR : ]
expected: FAIL expected: FAIL

View file

@ -4,3 +4,6 @@
[WebGL test #3: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #3: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL
[WebGL test #20: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

View file

@ -1,6 +1,5 @@
[tex-sub-image-2d.html] [tex-sub-image-2d.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #0: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #0: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[texture-clear.html] [texture-clear.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[texture-draw-with-2d-and-cube.html] [texture-draw-with-2d-and-cube.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[texture-formats-test.html] [texture-formats-test.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL
@ -10,3 +9,18 @@
[WebGL test #1: context does not exist] [WebGL test #1: context does not exist]
expected: FAIL expected: FAIL
[WebGL test #77: getError expected: NO_ERROR. Was INVALID_OPERATION : gl.texImage2D with format: RGBA, type: UNSIGNED_SHORT_4_4_4_4 should generate NO_ERROR]
expected: FAIL
[WebGL test #78: at (0, 0) expected: 0,0,255,255 was 0,255,0,255]
expected: FAIL
[WebGL test #79: getError expected: NO_ERROR. Was INVALID_OPERATION : gl.texImage2D with format: RGB, type: UNSIGNED_SHORT_5_6_5 should generate NO_ERROR]
expected: FAIL
[WebGL test #81: getError expected: NO_ERROR. Was INVALID_OPERATION : gl.texImage2D with format: RGBA, type: UNSIGNED_SHORT_5_5_5_1 should generate NO_ERROR]
expected: FAIL
[WebGL test #82: at (0, 0) expected: 0,0,255,255 was 0,255,0,255]
expected: FAIL

View file

@ -1,6 +1,5 @@
[texture-mips.html] [texture-mips.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,183 @@
[texture-size-limit.html] [texture-size-limit.html]
type: testharness type: testharness
expected: ERROR expected: CRASH
[WebGL test #0: Unable to fetch WebGL rendering context for Canvas] [WebGL test #0: Unable to fetch WebGL rendering context for Canvas]
expected: FAIL expected: FAIL
[WebGL test #2: getError expected: INVALID_VALUE. Was NO_ERROR : width or height out of bounds for specified level: should generate INVALID_VALUE: level is 14, size is 4x4.]
expected: FAIL
[WebGL test #3: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 14 1x1]
expected: FAIL
[WebGL test #4: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 14 1x1]
expected: FAIL
[WebGL test #5: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 14 2x1]
expected: FAIL
[WebGL test #6: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 14 1x2]
expected: FAIL
[WebGL test #7: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 13 2x1]
expected: FAIL
[WebGL test #8: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 13 1x2]
expected: FAIL
[WebGL test #9: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 13 4x1]
expected: FAIL
[WebGL test #10: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 13 1x4]
expected: FAIL
[WebGL test #11: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 12 4x1]
expected: FAIL
[WebGL test #12: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 12 1x4]
expected: FAIL
[WebGL test #13: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 12 8x1]
expected: FAIL
[WebGL test #14: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 12 1x8]
expected: FAIL
[WebGL test #15: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 11 8x1]
expected: FAIL
[WebGL test #16: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 11 1x8]
expected: FAIL
[WebGL test #17: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 11 16x1]
expected: FAIL
[WebGL test #18: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 11 1x16]
expected: FAIL
[WebGL test #19: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 10 16x1]
expected: FAIL
[WebGL test #20: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 10 1x16]
expected: FAIL
[WebGL test #21: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 10 32x1]
expected: FAIL
[WebGL test #22: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 10 1x32]
expected: FAIL
[WebGL test #23: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 9 32x1]
expected: FAIL
[WebGL test #24: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 9 1x32]
expected: FAIL
[WebGL test #25: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 9 64x1]
expected: FAIL
[WebGL test #26: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 9 1x64]
expected: FAIL
[WebGL test #27: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 8 64x1]
expected: FAIL
[WebGL test #28: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 8 1x64]
expected: FAIL
[WebGL test #29: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 8 128x1]
expected: FAIL
[WebGL test #30: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 8 1x128]
expected: FAIL
[WebGL test #31: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 7 128x1]
expected: FAIL
[WebGL test #32: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 7 1x128]
expected: FAIL
[WebGL test #33: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 7 256x1]
expected: FAIL
[WebGL test #34: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 7 1x256]
expected: FAIL
[WebGL test #35: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 6 256x1]
expected: FAIL
[WebGL test #36: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 6 1x256]
expected: FAIL
[WebGL test #37: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 6 512x1]
expected: FAIL
[WebGL test #38: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 6 1x512]
expected: FAIL
[WebGL test #39: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 5 512x1]
expected: FAIL
[WebGL test #40: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 5 1x512]
expected: FAIL
[WebGL test #41: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 5 1024x1]
expected: FAIL
[WebGL test #42: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 5 1x1024]
expected: FAIL
[WebGL test #43: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 4 1024x1]
expected: FAIL
[WebGL test #44: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 4 1x1024]
expected: FAIL
[WebGL test #45: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 4 2048x1]
expected: FAIL
[WebGL test #46: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 4 1x2048]
expected: FAIL
[WebGL test #47: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 3 2048x1]
expected: FAIL
[WebGL test #48: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 3 1x2048]
expected: FAIL
[WebGL test #49: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 3 4096x1]
expected: FAIL
[WebGL test #50: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 3 1x4096]
expected: FAIL
[WebGL test #51: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 2 4096x1]
expected: FAIL
[WebGL test #52: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 2 1x4096]
expected: FAIL
[WebGL test #53: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 2 8192x1]
expected: FAIL
[WebGL test #54: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 2 1x8192]
expected: FAIL
[WebGL test #55: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 1 8192x1]
expected: FAIL
[WebGL test #56: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 1 1x8192]
expected: FAIL
[WebGL test #57: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 1 16384x1]
expected: FAIL
[WebGL test #58: getError expected: INVALID_VALUE. Was NO_ERROR : should generate INVALID_VALUE for level: 1 1x16384]
expected: FAIL
[WebGL test #59: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 0 16384x1]
expected: FAIL
[WebGL test #60: getError expected: NO_ERROR. Was INVALID_OPERATION : there should be no error for level: 0 1x16384]
expected: FAIL

View file

@ -4,3 +4,9 @@
[WebGL test #0: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #0: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL
[WebGL test #0: unexpected gl error: INVALID_VALUE]
expected: FAIL
[WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

View file

@ -1,6 +1,5 @@
[texture-upload-cube-maps.html] [texture-upload-cube-maps.html]
type: testharness type: testharness
expected: ERROR
[WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL

View file

@ -1,3 +1,3 @@
[svg.html] [svg.html]
type: reftest type: reftest
prefs: [dom.svg.enabled:true] prefs: [dom.svg.enabled:true]