mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Adapt function bodies for usage with typed array args
This commit is contained in:
parent
36f39ce27a
commit
c1c74ed96c
1 changed files with 54 additions and 74 deletions
|
@ -825,15 +825,13 @@ impl WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(emilio): Move this logic to a validator.
|
// TODO(emilio): Move this logic to a validator.
|
||||||
#[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,
|
||||||
unpacking_alignment: u32,
|
unpacking_alignment: u32,
|
||||||
data: *mut JSObject,
|
data: &Option<ArrayBufferView>)
|
||||||
cx: *mut JSContext)
|
|
||||||
-> 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();
|
||||||
|
@ -846,21 +844,16 @@ impl WebGLRenderingContext {
|
||||||
// or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied.
|
// or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied.
|
||||||
// or FLOAT, a Float32Array must be supplied.
|
// or FLOAT, a Float32Array 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.
|
||||||
typedarray!(in(cx) let typedarray_u8: Uint8Array = data);
|
let received_size = match *data {
|
||||||
typedarray!(in(cx) let typedarray_u16: Uint16Array = data);
|
None => element_size,
|
||||||
typedarray!(in(cx) let typedarray_f32: Float32Array = data);
|
Some(ref buffer) => match buffer.get_array_type() {
|
||||||
let received_size = if data.is_null() {
|
Type::Uint8 => 1,
|
||||||
element_size
|
Type::Uint16 => 2,
|
||||||
} else {
|
Type::Float32 => 4,
|
||||||
if typedarray_u16.is_ok() {
|
_ => {
|
||||||
2
|
self.webgl_error(InvalidOperation);
|
||||||
} else if typedarray_u8.is_ok() {
|
return Err(());
|
||||||
1
|
}
|
||||||
} else if typedarray_f32.is_ok() {
|
|
||||||
4
|
|
||||||
} else {
|
|
||||||
self.webgl_error(InvalidOperation);
|
|
||||||
return Err(());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1709,38 +1702,35 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn BufferSubData(&self, target: u32, offset: i64, data: Option<ArrayBufferOrArrayBufferView>) {
|
fn BufferSubData(&self, target: u32, offset: i64, data: Option<ArrayBufferOrArrayBufferView>) {
|
||||||
if data.is_null() {
|
let data_vec = match data {
|
||||||
return Ok(self.webgl_error(InvalidValue));
|
// Typed array is rooted, so we can safely temporarily retrieve its slice
|
||||||
}
|
Some(ArrayBufferOrArrayBufferView::ArrayBuffer(mut inner)) => unsafe { inner.as_slice().to_vec() },
|
||||||
|
Some(ArrayBufferOrArrayBufferView::ArrayBufferView(mut inner)) => unsafe { inner.as_slice().to_vec() },
|
||||||
typedarray!(in(cx) let array_buffer: ArrayBuffer = data);
|
// Spec: If data is null then an INVALID_VALUE error is generated.
|
||||||
let data_vec = match array_buffer {
|
None => return self.webgl_error(InvalidValue),
|
||||||
Ok(mut data) => data.as_slice().to_vec(),
|
|
||||||
Err(_) => fallible_array_buffer_view_to_vec(cx, 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 Ok(self.webgl_error(InvalidEnum)),
|
_ => return 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 Ok(self.webgl_error(InvalidOperation)),
|
None => return self.webgl_error(InvalidOperation),
|
||||||
};
|
};
|
||||||
|
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return Ok(self.webgl_error(InvalidValue));
|
return self.webgl_error(InvalidValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
|
if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
|
||||||
return Ok(self.webgl_error(InvalidValue));
|
return self.webgl_error(InvalidValue);
|
||||||
}
|
}
|
||||||
self.send_command(WebGLCommand::BufferSubData(target, offset as isize, data_vec));
|
self.send_command(WebGLCommand::BufferSubData(target, offset as isize, data_vec));
|
||||||
|
|
||||||
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
|
||||||
|
@ -1750,7 +1740,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
// 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
|
||||||
|
@ -1760,8 +1749,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
// 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
|
||||||
|
@ -2608,25 +2595,24 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn ReadPixels(&self, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
|
fn ReadPixels(&self, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
|
||||||
pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>) {
|
mut pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>) {
|
||||||
if pixels.is_null() {
|
let (array_type, data) = match *pixels {
|
||||||
return Ok(self.webgl_error(InvalidValue));
|
// Spec: If data is null then an INVALID_VALUE error is generated.
|
||||||
}
|
None => return self.webgl_error(InvalidValue),
|
||||||
|
// The typed array is rooted and we should have a unique reference to it,
|
||||||
typedarray!(in(cx) let mut pixels_data: ArrayBufferView = pixels);
|
// so retrieving its mutable slice is safe here
|
||||||
let (array_type, data) = match { pixels_data.as_mut() } {
|
Some(ref mut data) => (data.get_array_type(), unsafe { data.as_mut_slice() }),
|
||||||
Ok(data) => (data.get_array_type(), data.as_mut_slice()),
|
|
||||||
Err(_) => return Err(Error::Type("Not an ArrayBufferView".to_owned())),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.validate_framebuffer_complete() {
|
if !self.validate_framebuffer_complete() {
|
||||||
return Ok(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match array_type {
|
match array_type {
|
||||||
Type::Uint8 => (),
|
Type::Uint8 => (),
|
||||||
_ => return Ok(self.webgl_error(InvalidOperation)),
|
_ => return self.webgl_error(InvalidOperation),
|
||||||
}
|
}
|
||||||
|
|
||||||
// From the WebGL specification, 5.14.12 Reading back pixels
|
// From the WebGL specification, 5.14.12 Reading back pixels
|
||||||
|
@ -2647,7 +2633,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
// always report RGBA/UNSIGNED_BYTE as our only supported
|
// always report RGBA/UNSIGNED_BYTE as our only supported
|
||||||
// format.
|
// format.
|
||||||
if format != constants::RGBA || pixel_type != constants::UNSIGNED_BYTE {
|
if format != constants::RGBA || pixel_type != constants::UNSIGNED_BYTE {
|
||||||
return Ok(self.webgl_error(InvalidOperation));
|
return self.webgl_error(InvalidOperation);
|
||||||
}
|
}
|
||||||
let cpp = 4;
|
let cpp = 4;
|
||||||
|
|
||||||
|
@ -2657,12 +2643,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
// INVALID_OPERATION error is generated."
|
// INVALID_OPERATION error is generated."
|
||||||
let stride = match width.checked_mul(cpp) {
|
let stride = match width.checked_mul(cpp) {
|
||||||
Some(stride) => stride,
|
Some(stride) => stride,
|
||||||
_ => return Ok(self.webgl_error(InvalidOperation)),
|
_ => return self.webgl_error(InvalidOperation),
|
||||||
};
|
};
|
||||||
|
|
||||||
match height.checked_mul(stride) {
|
match height.checked_mul(stride) {
|
||||||
Some(size) if size <= data.len() as i32 => {}
|
Some(size) if size <= data.len() as i32 => {}
|
||||||
_ => return Ok(self.webgl_error(InvalidOperation)),
|
_ => return self.webgl_error(InvalidOperation),
|
||||||
}
|
}
|
||||||
|
|
||||||
// "For any pixel lying outside the frame buffer, the
|
// "For any pixel lying outside the frame buffer, the
|
||||||
|
@ -2688,7 +2674,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
if width < 0 || height < 0 {
|
if width < 0 || height < 0 {
|
||||||
return Ok(self.webgl_error(InvalidValue));
|
return self.webgl_error(InvalidValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.get_current_framebuffer_size() {
|
match self.get_current_framebuffer_size() {
|
||||||
|
@ -2700,7 +2686,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
height = fb_height - y;
|
height = fb_height - y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Ok(self.webgl_error(InvalidOperation)),
|
_ => return self.webgl_error(InvalidOperation),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (sender, receiver) = webgl_channel().unwrap();
|
let (sender, receiver) = webgl_channel().unwrap();
|
||||||
|
@ -2714,8 +2700,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
result[(i * width * cpp + j) as usize];
|
result[(i * width * cpp + j) as usize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
@ -3235,6 +3219,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,
|
||||||
target: u32,
|
target: u32,
|
||||||
level: i32,
|
level: i32,
|
||||||
|
@ -3244,17 +3229,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
border: i32,
|
border: i32,
|
||||||
format: u32,
|
format: u32,
|
||||||
data_type: u32,
|
data_type: u32,
|
||||||
pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>) -> Fallible<()> {
|
mut pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>) -> Fallible<()> {
|
||||||
if !self.extension_manager.is_tex_type_enabled(data_type) {
|
if !self.extension_manager.is_tex_type_enabled(data_type) {
|
||||||
return Ok(self.webgl_error(InvalidEnum));
|
return Ok(self.webgl_error(InvalidEnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = if data_ptr.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(fallible_array_buffer_view_to_vec(cx, 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);
|
||||||
|
@ -3278,16 +3257,19 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
let expected_byte_length =
|
let expected_byte_length =
|
||||||
match { self.validate_tex_image_2d_data(width, height,
|
match { self.validate_tex_image_2d_data(width, height,
|
||||||
format, data_type,
|
format, data_type,
|
||||||
unpacking_alignment, data_ptr, cx) } {
|
unpacking_alignment, &*pixels) } {
|
||||||
Ok(byte_length) => byte_length,
|
Ok(byte_length) => byte_length,
|
||||||
Err(()) => return Ok(()),
|
Err(()) => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 = match data {
|
let buff = match *pixels {
|
||||||
None => vec![0u8; expected_byte_length as usize],
|
None => vec![0u8; expected_byte_length as usize],
|
||||||
Some(data) => data,
|
Some(ref mut data) => {
|
||||||
|
// Since the typed array is rooted, this is safe to perform
|
||||||
|
unsafe { data.as_slice().to_vec() }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// From the WebGL spec:
|
// From the WebGL spec:
|
||||||
|
@ -3405,6 +3387,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 TexSubImage2D(&self,
|
fn TexSubImage2D(&self,
|
||||||
target: u32,
|
target: u32,
|
||||||
level: i32,
|
level: i32,
|
||||||
|
@ -3414,13 +3397,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
height: i32,
|
height: i32,
|
||||||
format: u32,
|
format: u32,
|
||||||
data_type: u32,
|
data_type: u32,
|
||||||
pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>) -> Fallible<()> {
|
mut pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>) -> Fallible<()> {
|
||||||
let data = if data_ptr.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(fallible_array_buffer_view_to_vec(cx, 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);
|
||||||
|
@ -3443,16 +3420,19 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
let expected_byte_length =
|
let expected_byte_length =
|
||||||
match { self.validate_tex_image_2d_data(width, height,
|
match { self.validate_tex_image_2d_data(width, height,
|
||||||
format, data_type,
|
format, data_type,
|
||||||
unpacking_alignment, data_ptr, cx) } {
|
unpacking_alignment, &*pixels) } {
|
||||||
Ok(byte_length) => byte_length,
|
Ok(byte_length) => byte_length,
|
||||||
Err(()) => return Ok(()),
|
Err(()) => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 = match data {
|
let buff = match *pixels {
|
||||||
None => vec![0u8; expected_byte_length as usize],
|
None => vec![0u8; expected_byte_length as usize],
|
||||||
Some(data) => data,
|
Some(ref mut data) => {
|
||||||
|
// Since the typed array is rooted, this is safe to perform
|
||||||
|
unsafe { data.as_slice().to_vec() }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// From the WebGL spec:
|
// From the WebGL spec:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue