mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add support for WebGL2 ReadPixels functions
Adds support for the new ReadPixels functions introduced with WebGL2 and the relevant PixelStorei parameters. Reference: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.10
This commit is contained in:
parent
ea32495504
commit
8fefa23019
9 changed files with 385 additions and 404 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -5154,9 +5154,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sparkle"
|
name = "sparkle"
|
||||||
version = "0.1.10"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84b935631ddcc08b257a331ac645cc6831e52a4ff55d4c430142575c6757a094"
|
checksum = "ef7f82a5133e57fe21cb3465f0e609045e53f2627f5e210d1d60be7d764c7dd4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gl_generator 0.13.1",
|
"gl_generator 0.13.1",
|
||||||
]
|
]
|
||||||
|
|
|
@ -33,7 +33,7 @@ num-traits = "0.2"
|
||||||
raqote = {git = "https://github.com/jrmuizel/raqote", optional = true}
|
raqote = {git = "https://github.com/jrmuizel/raqote", optional = true}
|
||||||
pixels = {path = "../pixels"}
|
pixels = {path = "../pixels"}
|
||||||
servo_config = {path = "../config"}
|
servo_config = {path = "../config"}
|
||||||
sparkle = "0.1.8"
|
sparkle = "0.1.12"
|
||||||
webrender = {git = "https://github.com/servo/webrender"}
|
webrender = {git = "https://github.com/servo/webrender"}
|
||||||
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||||
webrender_traits = {path = "../webrender_traits"}
|
webrender_traits = {path = "../webrender_traits"}
|
||||||
|
|
|
@ -1166,6 +1166,17 @@ impl WebGLImpl {
|
||||||
);
|
);
|
||||||
sender.send(&pixels).unwrap();
|
sender.send(&pixels).unwrap();
|
||||||
},
|
},
|
||||||
|
WebGLCommand::ReadPixelsPP(rect, format, pixel_type, offset) => unsafe {
|
||||||
|
gl.read_pixels_into_pixel_pack_buffer(
|
||||||
|
rect.origin.x,
|
||||||
|
rect.origin.y,
|
||||||
|
rect.size.width,
|
||||||
|
rect.size.height,
|
||||||
|
format,
|
||||||
|
pixel_type,
|
||||||
|
offset,
|
||||||
|
);
|
||||||
|
},
|
||||||
WebGLCommand::RenderbufferStorage(target, format, width, height) => {
|
WebGLCommand::RenderbufferStorage(target, format, width, height) => {
|
||||||
gl.renderbuffer_storage(target, format, width, height)
|
gl.renderbuffer_storage(target, format, width, height)
|
||||||
},
|
},
|
||||||
|
|
|
@ -305,6 +305,7 @@ pub enum WebGLCommand {
|
||||||
PolygonOffset(f32, f32),
|
PolygonOffset(f32, f32),
|
||||||
RenderbufferStorage(u32, u32, i32, i32),
|
RenderbufferStorage(u32, u32, i32, i32),
|
||||||
ReadPixels(Rect<u32>, u32, u32, IpcBytesSender),
|
ReadPixels(Rect<u32>, u32, u32, IpcBytesSender),
|
||||||
|
ReadPixelsPP(Rect<i32>, u32, u32, usize),
|
||||||
SampleCoverage(f32, bool),
|
SampleCoverage(f32, bool),
|
||||||
Scissor(i32, i32, u32, u32),
|
Scissor(i32, i32, u32, u32),
|
||||||
StencilFunc(u32, i32, u32),
|
StencilFunc(u32, i32, u32),
|
||||||
|
|
|
@ -25,7 +25,7 @@ use crate::dom::webglprogram::WebGLProgram;
|
||||||
use crate::dom::webglquery::WebGLQuery;
|
use crate::dom::webglquery::WebGLQuery;
|
||||||
use crate::dom::webglrenderbuffer::WebGLRenderbuffer;
|
use crate::dom::webglrenderbuffer::WebGLRenderbuffer;
|
||||||
use crate::dom::webglrenderingcontext::{
|
use crate::dom::webglrenderingcontext::{
|
||||||
LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext,
|
LayoutCanvasWebGLRenderingContextHelpers, Size2DExt, WebGLRenderingContext,
|
||||||
};
|
};
|
||||||
use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue};
|
use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue};
|
||||||
use crate::dom::webglshader::WebGLShader;
|
use crate::dom::webglshader::WebGLShader;
|
||||||
|
@ -42,13 +42,15 @@ use canvas_traits::webgl::{
|
||||||
webgl_channel, GLContextAttributes, WebGLCommand, WebGLResult, WebGLVersion,
|
webgl_channel, GLContextAttributes, WebGLCommand, WebGLResult, WebGLVersion,
|
||||||
};
|
};
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use euclid::default::Size2D;
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use js::jsapi::{JSObject, Type};
|
use js::jsapi::{JSObject, Type};
|
||||||
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
|
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
|
||||||
use js::rust::CustomAutoRooterGuard;
|
use js::rust::CustomAutoRooterGuard;
|
||||||
use js::typedarray::ArrayBufferView;
|
use js::typedarray::ArrayBufferView;
|
||||||
use script_layout_interface::HTMLCanvasDataSource;
|
use script_layout_interface::HTMLCanvasDataSource;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::cmp;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -65,6 +67,9 @@ pub struct WebGL2RenderingContext {
|
||||||
bound_transform_feedback_buffer: MutNullableDom<WebGLBuffer>,
|
bound_transform_feedback_buffer: MutNullableDom<WebGLBuffer>,
|
||||||
bound_uniform_buffer: MutNullableDom<WebGLBuffer>,
|
bound_uniform_buffer: MutNullableDom<WebGLBuffer>,
|
||||||
current_transform_feedback: MutNullableDom<WebGLTransformFeedback>,
|
current_transform_feedback: MutNullableDom<WebGLTransformFeedback>,
|
||||||
|
texture_pack_row_length: Cell<usize>,
|
||||||
|
texture_pack_skip_pixels: Cell<usize>,
|
||||||
|
texture_pack_skip_rows: Cell<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typedarray_elem_size(typeid: Type) -> usize {
|
fn typedarray_elem_size(typeid: Type) -> usize {
|
||||||
|
@ -77,6 +82,17 @@ fn typedarray_elem_size(typeid: Type) -> usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ReadPixelsAllowedFormats<'a> {
|
||||||
|
array_types: &'a [Type],
|
||||||
|
channels: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReadPixelsSizes {
|
||||||
|
row_stride: usize,
|
||||||
|
skipped_bytes: usize,
|
||||||
|
size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl WebGL2RenderingContext {
|
impl WebGL2RenderingContext {
|
||||||
fn new_inherited(
|
fn new_inherited(
|
||||||
window: &Window,
|
window: &Window,
|
||||||
|
@ -104,6 +120,9 @@ impl WebGL2RenderingContext {
|
||||||
bound_transform_feedback_buffer: MutNullableDom::new(None),
|
bound_transform_feedback_buffer: MutNullableDom::new(None),
|
||||||
bound_uniform_buffer: MutNullableDom::new(None),
|
bound_uniform_buffer: MutNullableDom::new(None),
|
||||||
current_transform_feedback: MutNullableDom::new(None),
|
current_transform_feedback: MutNullableDom::new(None),
|
||||||
|
texture_pack_row_length: Cell::new(0),
|
||||||
|
texture_pack_skip_pixels: Cell::new(0),
|
||||||
|
texture_pack_skip_rows: Cell::new(0),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +166,213 @@ impl WebGL2RenderingContext {
|
||||||
slot.set(None);
|
slot.set(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calc_read_pixel_formats(
|
||||||
|
&self,
|
||||||
|
pixel_type: u32,
|
||||||
|
format: u32,
|
||||||
|
) -> WebGLResult<ReadPixelsAllowedFormats> {
|
||||||
|
let array_types = match pixel_type {
|
||||||
|
constants::BYTE => &[Type::Int8][..],
|
||||||
|
constants::SHORT => &[Type::Int16][..],
|
||||||
|
constants::INT => &[Type::Int32][..],
|
||||||
|
constants::UNSIGNED_BYTE => &[Type::Uint8, Type::Uint8Clamped][..],
|
||||||
|
constants::UNSIGNED_SHORT |
|
||||||
|
constants::UNSIGNED_SHORT_4_4_4_4 |
|
||||||
|
constants::UNSIGNED_SHORT_5_5_5_1 |
|
||||||
|
constants::UNSIGNED_SHORT_5_6_5 => &[Type::Uint16][..],
|
||||||
|
constants::UNSIGNED_INT |
|
||||||
|
constants::UNSIGNED_INT_2_10_10_10_REV |
|
||||||
|
constants::UNSIGNED_INT_10F_11F_11F_REV |
|
||||||
|
constants::UNSIGNED_INT_5_9_9_9_REV => &[Type::Uint32][..],
|
||||||
|
constants::FLOAT => &[Type::Float32][..],
|
||||||
|
constants::HALF_FLOAT => &[Type::Uint16][..],
|
||||||
|
_ => return Err(InvalidEnum),
|
||||||
|
};
|
||||||
|
let channels = match format {
|
||||||
|
constants::ALPHA | constants::RED | constants::RED_INTEGER => 1,
|
||||||
|
constants::RG | constants::RG_INTEGER => 2,
|
||||||
|
constants::RGB | constants::RGB_INTEGER => 3,
|
||||||
|
constants::RGBA | constants::RGBA_INTEGER => 4,
|
||||||
|
_ => return Err(InvalidEnum),
|
||||||
|
};
|
||||||
|
Ok(ReadPixelsAllowedFormats {
|
||||||
|
array_types,
|
||||||
|
channels,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_read_pixel_sizes(
|
||||||
|
&self,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
bytes_per_pixel: usize,
|
||||||
|
) -> WebGLResult<ReadPixelsSizes> {
|
||||||
|
if width < 0 || height < 0 {
|
||||||
|
return Err(InvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See also https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.36
|
||||||
|
let pixels_per_row = if self.texture_pack_row_length.get() > 0 {
|
||||||
|
self.texture_pack_row_length.get()
|
||||||
|
} else {
|
||||||
|
width as usize
|
||||||
|
};
|
||||||
|
if self.texture_pack_skip_pixels.get() + width as usize > pixels_per_row {
|
||||||
|
return Err(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes_per_row = pixels_per_row
|
||||||
|
.checked_mul(bytes_per_pixel)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
let row_padding_bytes = {
|
||||||
|
let pack_alignment = self.base.get_texture_packing_alignment() as usize;
|
||||||
|
match bytes_per_row % pack_alignment {
|
||||||
|
0 => 0,
|
||||||
|
remainder => pack_alignment - remainder,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let row_stride = bytes_per_row + row_padding_bytes;
|
||||||
|
let size = if width == 0 || height == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
let full_row_bytes = row_stride
|
||||||
|
.checked_mul(height as usize - 1)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
let last_row_bytes = bytes_per_pixel
|
||||||
|
.checked_mul(width as usize)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
let result = full_row_bytes
|
||||||
|
.checked_add(last_row_bytes)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
result
|
||||||
|
};
|
||||||
|
let skipped_bytes = {
|
||||||
|
let skipped_row_bytes = self
|
||||||
|
.texture_pack_skip_rows
|
||||||
|
.get()
|
||||||
|
.checked_mul(row_stride)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
let skipped_pixel_bytes = self
|
||||||
|
.texture_pack_skip_pixels
|
||||||
|
.get()
|
||||||
|
.checked_mul(bytes_per_pixel)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
let result = skipped_row_bytes
|
||||||
|
.checked_add(skipped_pixel_bytes)
|
||||||
|
.ok_or(InvalidOperation)?;
|
||||||
|
result
|
||||||
|
};
|
||||||
|
Ok(ReadPixelsSizes {
|
||||||
|
row_stride,
|
||||||
|
skipped_bytes,
|
||||||
|
size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn read_pixels_into(
|
||||||
|
&self,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
format: u32,
|
||||||
|
pixel_type: u32,
|
||||||
|
dst: &mut ArrayBufferView,
|
||||||
|
dst_elem_offset: u32,
|
||||||
|
) {
|
||||||
|
handle_potential_webgl_error!(self.base, self.base.validate_framebuffer(), return);
|
||||||
|
|
||||||
|
if self.bound_pixel_pack_buffer.get().is_some() {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
let dst_byte_offset = {
|
||||||
|
let dst_elem_size = typedarray_elem_size(dst.get_array_type());
|
||||||
|
dst_elem_offset as usize * dst_elem_size
|
||||||
|
};
|
||||||
|
if dst_byte_offset > dst.len() {
|
||||||
|
return self.base.webgl_error(InvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
let dst_array_type = dst.get_array_type();
|
||||||
|
let ReadPixelsAllowedFormats {
|
||||||
|
array_types: allowed_array_types,
|
||||||
|
channels,
|
||||||
|
} = match self.calc_read_pixel_formats(pixel_type, format) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => return self.base.webgl_error(error),
|
||||||
|
};
|
||||||
|
if !allowed_array_types.contains(&dst_array_type) {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
if format != constants::RGBA || pixel_type != constants::UNSIGNED_BYTE {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes_per_pixel = typedarray_elem_size(dst_array_type) * channels;
|
||||||
|
let ReadPixelsSizes {
|
||||||
|
row_stride,
|
||||||
|
skipped_bytes,
|
||||||
|
size,
|
||||||
|
} = match self.calc_read_pixel_sizes(width, height, bytes_per_pixel) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => return self.base.webgl_error(error),
|
||||||
|
};
|
||||||
|
let dst_end = dst_byte_offset + skipped_bytes + size;
|
||||||
|
let dst_pixels = unsafe { dst.as_mut_slice() };
|
||||||
|
if dst_pixels.len() < dst_end {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
let dst_byte_offset = {
|
||||||
|
let margin_left = cmp::max(0, -x) as usize;
|
||||||
|
let margin_top = cmp::max(0, -y) as usize;
|
||||||
|
dst_byte_offset +
|
||||||
|
skipped_bytes +
|
||||||
|
margin_left * bytes_per_pixel +
|
||||||
|
margin_top * row_stride
|
||||||
|
};
|
||||||
|
let src_rect = {
|
||||||
|
let (fb_width, fb_height) = handle_potential_webgl_error!(
|
||||||
|
self.base,
|
||||||
|
self.base
|
||||||
|
.get_current_framebuffer_size()
|
||||||
|
.ok_or(InvalidOperation),
|
||||||
|
return
|
||||||
|
);
|
||||||
|
let src_origin = Point2D::new(x, y);
|
||||||
|
let src_size = Size2D::new(width as u32, height as u32);
|
||||||
|
let fb_size = Size2D::new(fb_width as u32, fb_height as u32);
|
||||||
|
match pixels::clip(src_origin, src_size.to_u64(), fb_size.to_u64()) {
|
||||||
|
Some(rect) => rect.to_u32(),
|
||||||
|
None => return,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let src_row_bytes = handle_potential_webgl_error!(
|
||||||
|
self.base,
|
||||||
|
src_rect
|
||||||
|
.size
|
||||||
|
.width
|
||||||
|
.checked_mul(bytes_per_pixel as u32)
|
||||||
|
.ok_or(InvalidOperation),
|
||||||
|
return
|
||||||
|
);
|
||||||
|
|
||||||
|
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||||
|
self.base.send_command(WebGLCommand::ReadPixels(
|
||||||
|
src_rect, format, pixel_type, sender,
|
||||||
|
));
|
||||||
|
let src = receiver.recv().unwrap();
|
||||||
|
|
||||||
|
for i in 0..src_rect.size.height as usize {
|
||||||
|
let src_start = i * src_row_bytes as usize;
|
||||||
|
let dst_start = dst_byte_offset + i * row_stride;
|
||||||
|
dst_pixels[dst_start..dst_start + src_row_bytes as usize]
|
||||||
|
.copy_from_slice(&src[src_start..src_start + src_row_bytes as usize]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
||||||
|
@ -936,9 +1162,18 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
||||||
self.base.LineWidth(width)
|
self.base.LineWidth(width)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2
|
||||||
fn PixelStorei(&self, param_name: u32, param_value: i32) {
|
fn PixelStorei(&self, param_name: u32, param_value: i32) {
|
||||||
self.base.PixelStorei(param_name, param_value)
|
if param_value < 0 {
|
||||||
|
return self.base.webgl_error(InvalidValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
match param_name {
|
||||||
|
constants::PACK_ROW_LENGTH => self.texture_pack_row_length.set(param_value as _),
|
||||||
|
constants::PACK_SKIP_PIXELS => self.texture_pack_skip_pixels.set(param_value as _),
|
||||||
|
constants::PACK_SKIP_ROWS => self.texture_pack_skip_rows.set(param_value as _),
|
||||||
|
_ => self.base.PixelStorei(param_name, param_value),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
|
@ -955,10 +1190,128 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
||||||
height: i32,
|
height: i32,
|
||||||
format: u32,
|
format: u32,
|
||||||
pixel_type: u32,
|
pixel_type: u32,
|
||||||
pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>,
|
mut pixels: CustomAutoRooterGuard<Option<ArrayBufferView>>,
|
||||||
) {
|
) {
|
||||||
self.base
|
let pixels =
|
||||||
.ReadPixels(x, y, width, height, format, pixel_type, pixels)
|
handle_potential_webgl_error!(self.base, pixels.as_mut().ok_or(InvalidValue), return);
|
||||||
|
|
||||||
|
self.read_pixels_into(x, y, width, height, format, pixel_type, pixels, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.10
|
||||||
|
fn ReadPixels_(
|
||||||
|
&self,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
format: u32,
|
||||||
|
pixel_type: u32,
|
||||||
|
dst_byte_offset: i64,
|
||||||
|
) {
|
||||||
|
handle_potential_webgl_error!(self.base, self.base.validate_framebuffer(), return);
|
||||||
|
|
||||||
|
let dst = match self.bound_pixel_pack_buffer.get() {
|
||||||
|
Some(buffer) => buffer,
|
||||||
|
None => return self.base.webgl_error(InvalidOperation),
|
||||||
|
};
|
||||||
|
|
||||||
|
if dst_byte_offset < 0 {
|
||||||
|
return self.base.webgl_error(InvalidValue);
|
||||||
|
}
|
||||||
|
let dst_byte_offset = dst_byte_offset as usize;
|
||||||
|
if dst_byte_offset > dst.capacity() {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ReadPixelsAllowedFormats {
|
||||||
|
array_types: _,
|
||||||
|
channels: bytes_per_pixel,
|
||||||
|
} = match self.calc_read_pixel_formats(pixel_type, format) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => return self.base.webgl_error(error),
|
||||||
|
};
|
||||||
|
if format != constants::RGBA || pixel_type != constants::UNSIGNED_BYTE {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ReadPixelsSizes {
|
||||||
|
row_stride: _,
|
||||||
|
skipped_bytes,
|
||||||
|
size,
|
||||||
|
} = match self.calc_read_pixel_sizes(width, height, bytes_per_pixel) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => return self.base.webgl_error(error),
|
||||||
|
};
|
||||||
|
let dst_end = dst_byte_offset + skipped_bytes + size;
|
||||||
|
if dst.capacity() < dst_end {
|
||||||
|
return self.base.webgl_error(InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let (fb_width, fb_height) = handle_potential_webgl_error!(
|
||||||
|
self.base,
|
||||||
|
self.base
|
||||||
|
.get_current_framebuffer_size()
|
||||||
|
.ok_or(InvalidOperation),
|
||||||
|
return
|
||||||
|
);
|
||||||
|
let src_origin = Point2D::new(x, y);
|
||||||
|
let src_size = Size2D::new(width as u32, height as u32);
|
||||||
|
let fb_size = Size2D::new(fb_width as u32, fb_height as u32);
|
||||||
|
if pixels::clip(src_origin, src_size.to_u64(), fb_size.to_u64()).is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let src_rect = Rect::new(Point2D::new(x, y), Size2D::new(width, height));
|
||||||
|
|
||||||
|
self.base.send_command(WebGLCommand::PixelStorei(
|
||||||
|
constants::PACK_ALIGNMENT,
|
||||||
|
self.base.get_texture_packing_alignment() as _,
|
||||||
|
));
|
||||||
|
self.base.send_command(WebGLCommand::PixelStorei(
|
||||||
|
constants::PACK_ROW_LENGTH,
|
||||||
|
self.texture_pack_row_length.get() as _,
|
||||||
|
));
|
||||||
|
self.base.send_command(WebGLCommand::PixelStorei(
|
||||||
|
constants::PACK_SKIP_ROWS,
|
||||||
|
self.texture_pack_skip_rows.get() as _,
|
||||||
|
));
|
||||||
|
self.base.send_command(WebGLCommand::PixelStorei(
|
||||||
|
constants::PACK_SKIP_PIXELS,
|
||||||
|
self.texture_pack_skip_pixels.get() as _,
|
||||||
|
));
|
||||||
|
self.base.send_command(WebGLCommand::ReadPixelsPP(
|
||||||
|
src_rect,
|
||||||
|
format,
|
||||||
|
pixel_type,
|
||||||
|
dst_byte_offset,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.10
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn ReadPixels__(
|
||||||
|
&self,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
format: u32,
|
||||||
|
pixel_type: u32,
|
||||||
|
mut dst: CustomAutoRooterGuard<ArrayBufferView>,
|
||||||
|
dst_elem_offset: u32,
|
||||||
|
) {
|
||||||
|
self.read_pixels_into(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
format,
|
||||||
|
pixel_type,
|
||||||
|
&mut dst,
|
||||||
|
dst_elem_offset,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
|
@ -380,7 +380,7 @@ impl WebGLRenderingContext {
|
||||||
//
|
//
|
||||||
// The WebGL spec mentions a couple more operations that trigger
|
// The WebGL spec mentions a couple more operations that trigger
|
||||||
// this: clear() and getParameter(IMPLEMENTATION_COLOR_READ_*).
|
// this: clear() and getParameter(IMPLEMENTATION_COLOR_READ_*).
|
||||||
fn validate_framebuffer(&self) -> WebGLResult<()> {
|
pub fn validate_framebuffer(&self) -> WebGLResult<()> {
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_framebuffer.get() {
|
||||||
Some(fb) => match fb.check_status_for_rendering() {
|
Some(fb) => match fb.check_status_for_rendering() {
|
||||||
CompleteForRendering::Complete => Ok(()),
|
CompleteForRendering::Complete => Ok(()),
|
||||||
|
@ -481,7 +481,7 @@ impl WebGLRenderingContext {
|
||||||
self.send_command(WebGLCommand::VertexAttrib(indx, x, y, z, w));
|
self.send_command(WebGLCommand::VertexAttrib(indx, x, y, z, w));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_current_framebuffer_size(&self) -> Option<(i32, i32)> {
|
pub fn get_current_framebuffer_size(&self) -> Option<(i32, i32)> {
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_framebuffer.get() {
|
||||||
Some(fb) => return fb.size(),
|
Some(fb) => return fb.size(),
|
||||||
|
|
||||||
|
@ -490,6 +490,10 @@ impl WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_texture_packing_alignment(&self) -> u8 {
|
||||||
|
self.texture_packing_alignment.get()
|
||||||
|
}
|
||||||
|
|
||||||
// LINEAR filtering may be forbidden when using WebGL extensions.
|
// LINEAR filtering may be forbidden when using WebGL extensions.
|
||||||
// https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/
|
// https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/
|
||||||
fn validate_filterable_texture(
|
fn validate_filterable_texture(
|
||||||
|
|
|
@ -497,10 +497,10 @@ interface mixin WebGL2RenderingContextBase
|
||||||
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||||
/*[AllowShared]*/ ArrayBufferView? dstData);
|
/*[AllowShared]*/ ArrayBufferView? dstData);
|
||||||
// WebGL2:
|
// WebGL2:
|
||||||
// void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||||
// GLintptr offset);
|
GLintptr offset);
|
||||||
// void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||||
// [AllowShared] ArrayBufferView dstData, GLuint dstOffset);
|
/*[AllowShared]*/ ArrayBufferView dstData, GLuint dstOffset);
|
||||||
|
|
||||||
/* Multiple Render Targets */
|
/* Multiple Render Targets */
|
||||||
// void drawBuffers(sequence<GLenum> buffers);
|
// void drawBuffers(sequence<GLenum> buffers);
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[read-pixels-into-pixel-pack-buffer.html]
|
|
||||||
expected: CRASH
|
|
||||||
[WebGL test #1: getError expected: INVALID_OPERATION. Was INVALID_ENUM : should generate INVALID_OPERATION if pixel pack buffer is bound]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,380 +0,0 @@
|
||||||
[read-pixels-pack-parameters.html]
|
|
||||||
expected: ERROR
|
|
||||||
[WebGL test #15: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #125: Padding byte 0 of row 1 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #52: Padding byte 0 of row 0 changed: expected 1, got 249]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #54: Padding byte 0 of row 1 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #44: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #177: first pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #55: last pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #147: Padding byte 4 of row 0 changed: expected 1, got 99]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #141: first pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #163: skipped bytes changed at index 0: expected 1 got 249]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #148: last pixel of row 1: expected [99,5,76,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #85: last pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #88: first pixel of row 1: expected [1,2,3,4\], got [249,102,0,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #131: last pixel of row 1: expected [249,102,0,255\], got [2,200,102,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #115: Padding byte 8 of row 0 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #120: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #22: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #92: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #83: last pixel of row 1: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #171: getError expected: INVALID_OPERATION. Was NO_ERROR : Invalid pack params combination]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #132: Padding byte 0 of row 1 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #172: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #124: last pixel of row 1: expected [249,102,0,255\], got [2,200,102,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #170: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #17: getError expected: NO_ERROR. Was INVALID_ENUM : readPixels should succeed]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #80: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #180: last pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #110: Padding byte 0 of row 1 changed: expected 1, got 134]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #56: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #74: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #58: first pixel of row 1: expected [1,2,3,4\], got [249,102,0,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #89: last pixel of row 1: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #152: first pixel of row 1: expected [99,5,76,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #108: Padding byte 4 of row 0 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #62: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #7: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #158: getError expected: INVALID_OPERATION. Was NO_ERROR : Invalid pack params combination]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #166: first pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #144: first pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #106: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #53: last pixel of row 1: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #9: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #59: last pixel of row 1: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #164: first pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #76: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #34: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #142: last pixel of row 1: expected [1,2,3,4\], got [134,87,234,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #143: Padding byte 0 of row 1 changed: expected 1, got 134]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #134: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #91: last pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #40: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #169: last pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #182: last pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #18: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #140: Padding byte 4 of row 0 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #174: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #20: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #42: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #136: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #155: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #78: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #104: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #145: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #118: Padding byte 0 of row 1 changed: expected 1, got 134]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #165: last pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #11: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #3: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #176: skipped bytes changed at index 0: expected 1 got 249]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #94: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #102: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #5: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #126: first pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #24: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #157: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #117: last pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #98: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #161: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #178: last pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #66: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #36: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #32: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #111: first pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #151: Padding byte 4 of row 0 changed: expected 1, got 99]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #28: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #179: first pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #112: last pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #82: Padding byte 0 of row 0 changed: expected 1, got 249]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #84: Padding byte 0 of row 1 changed: expected 1, got 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #61: last pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #38: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #64: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #173: getError expected: INVALID_OPERATION. Was NO_ERROR : Invalid pack params combination]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #109: last pixel of row 1: expected [2,200,102,255\], got [134,87,234,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #119: last pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #86: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #153: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #90: first pixel of row 2: expected [1,2,3,4\], got [2,200,102,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #68: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #122: Padding byte 0 of row 0 changed: expected 1, got 249]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #116: first pixel of row 1: expected [1,2,3,4\], got [2,200,102,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #113: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #26: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #96: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #46: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #123: first pixel of row 1: expected [249,102,0,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #183: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #168: first pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #60: first pixel of row 2: expected [1,2,3,4\], got [2,200,102,255\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #128: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #72: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #13: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #130: Padding byte 4 of row 0 changed: expected 1, got 249]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #167: last pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #160: getError expected: INVALID_OPERATION. Was NO_ERROR : Invalid pack params combination]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #100: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #70: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #181: first pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #50: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #48: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #1: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #149: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #133: last pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #159: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #30: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #127: last pixel of row 2: expected [2,200,102,255\], got [1,2,3,4\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #138: getError expected: INVALID_OPERATION. Was INVALID_ENUM : buffer too small]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue