Add support for WebGL2 TexImage2D

Adds initial support for one of the WebGL2 `TexImage2D` call.
This commit is contained in:
Istvan Miklos 2020-05-04 10:17:46 +02:00
parent 6c506ba260
commit 035cb6ebaa
4 changed files with 117 additions and 20 deletions

View file

@ -18,7 +18,9 @@ use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlcanvaselement::HTMLCanvasElement; use crate::dom::htmlcanvaselement::HTMLCanvasElement;
use crate::dom::webgl_validations::tex_image_2d::{TexStorageValidator, TexStorageValidatorResult}; use crate::dom::webgl_validations::tex_image_2d::{
TexImage2DValidator, TexImage2DValidatorResult, TexStorageValidator, TexStorageValidatorResult,
};
use crate::dom::webgl_validations::WebGLValidator; use crate::dom::webgl_validations::WebGLValidator;
use crate::dom::webglactiveinfo::WebGLActiveInfo; use crate::dom::webglactiveinfo::WebGLActiveInfo;
use crate::dom::webglbuffer::WebGLBuffer; use crate::dom::webglbuffer::WebGLBuffer;
@ -27,8 +29,8 @@ 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::{
uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, Operation, VertexAttrib, uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, Operation, TexPixels,
WebGLRenderingContext, VertexAttrib, WebGLRenderingContext,
}; };
use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue}; use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue};
use crate::dom::webglshader::WebGLShader; use crate::dom::webglshader::WebGLShader;
@ -48,7 +50,7 @@ use canvas_traits::webgl::{
}; };
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::default::{Point2D, Rect, Size2D}; use euclid::default::{Point2D, Rect, Size2D};
use ipc_channel::ipc; use ipc_channel::ipc::{self, IpcSharedMemory};
use js::jsapi::{JSObject, Type}; use js::jsapi::{JSObject, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, UInt32Value}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, UInt32Value};
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue}; use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
@ -2914,6 +2916,100 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
.TexImage2D_(target, level, internal_format, format, data_type, source) .TexImage2D_(target, level, internal_format, format, data_type, source)
} }
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.6
#[allow(unsafe_code)]
fn TexImage2D__(
&self,
target: u32,
level: i32,
internalformat: i32,
width: i32,
height: i32,
border: i32,
format: u32,
type_: u32,
src_data: CustomAutoRooterGuard<ArrayBufferView>,
src_offset: u32,
) -> Fallible<()> {
if self.bound_pixel_unpack_buffer.get().is_some() {
return Ok(self.base.webgl_error(InvalidOperation));
}
if type_ == constants::FLOAT_32_UNSIGNED_INT_24_8_REV {
return Ok(self.base.webgl_error(InvalidOperation));
}
let validator = TexImage2DValidator::new(
&self.base,
target,
level,
internalformat as u32,
width,
height,
border,
format,
type_,
);
let TexImage2DValidatorResult {
texture,
target,
width,
height,
level,
border,
internal_format,
format,
data_type,
} = match validator.validate() {
Ok(result) => result,
Err(_) => return Ok(()),
};
let unpacking_alignment = self.base.texture_unpacking_alignment();
let src_elem_size = typedarray_elem_size(src_data.get_array_type());
let src_byte_offset = src_offset as usize * src_elem_size;
if src_data.len() <= src_byte_offset {
return Ok(self.base.webgl_error(InvalidOperation));
}
let buff = IpcSharedMemory::from_bytes(unsafe { &src_data.as_slice()[src_byte_offset..] });
let expected_byte_length = match {
self.base.validate_tex_image_2d_data(
width,
height,
format,
data_type,
unpacking_alignment,
Some(&*src_data),
)
} {
Ok(byte_length) => byte_length,
Err(()) => return Ok(()),
};
if expected_byte_length as usize > buff.len() {
return Ok(self.base.webgl_error(InvalidOperation));
}
self.base.tex_image_2d(
&texture,
target,
data_type,
internal_format,
format,
level,
border,
unpacking_alignment,
TexPixels::from_array(buff, Size2D::new(width, height)),
);
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
fn TexSubImage2D( fn TexSubImage2D(
&self, &self,

View file

@ -306,6 +306,10 @@ impl WebGLRenderingContext {
&self.limits &self.limits
} }
pub fn texture_unpacking_alignment(&self) -> u32 {
self.texture_unpacking_alignment.get()
}
pub fn current_vao(&self) -> DomRoot<WebGLVertexArrayObjectOES> { pub fn current_vao(&self) -> DomRoot<WebGLVertexArrayObjectOES> {
self.current_vao.or_init(|| { self.current_vao.or_init(|| {
DomRoot::from_ref( DomRoot::from_ref(
@ -697,14 +701,14 @@ impl WebGLRenderingContext {
} }
// TODO(emilio): Move this logic to a validator. // TODO(emilio): Move this logic to a validator.
fn validate_tex_image_2d_data( pub fn validate_tex_image_2d_data(
&self, &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: &Option<ArrayBufferView>, data: Option<&ArrayBufferView>,
) -> 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();
@ -742,7 +746,7 @@ impl WebGLRenderingContext {
} }
} }
fn tex_image_2d( pub fn tex_image_2d(
&self, &self,
texture: &WebGLTexture, texture: &WebGLTexture,
target: TexImageTarget, target: TexImageTarget,
@ -4276,7 +4280,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
format, format,
data_type, data_type,
unpacking_alignment, unpacking_alignment,
&*pixels, pixels.as_ref(),
) )
} { } {
Ok(byte_length) => byte_length, Ok(byte_length) => byte_length,
@ -4503,7 +4507,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
format, format,
data_type, data_type,
unpacking_alignment, unpacking_alignment,
&*pixels, pixels.as_ref(),
) )
} { } {
Ok(byte_length) => byte_length, Ok(byte_length) => byte_length,
@ -4881,7 +4885,7 @@ impl TextureUnit {
} }
} }
struct TexPixels { pub struct TexPixels {
data: IpcSharedMemory, data: IpcSharedMemory,
size: Size2D<u32>, size: Size2D<u32>,
pixel_format: Option<PixelFormat>, pixel_format: Option<PixelFormat>,
@ -4903,7 +4907,7 @@ impl TexPixels {
} }
} }
fn from_array(data: IpcSharedMemory, size: Size2D<u32>) -> Self { pub fn from_array(data: IpcSharedMemory, size: Size2D<u32>) -> Self {
Self { Self {
data, data,
size, size,

View file

@ -512,10 +512,10 @@ interface mixin WebGL2RenderingContextOverloads
//void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, //void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
// GLint border, GLenum format, GLenum type, // GLint border, GLenum format, GLenum type,
// TexImageSource source); // May throw DOMException // TexImageSource source); // May throw DOMException
//[Throws] [Throws]
//void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
// GLint border, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView srcData, GLint border, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView srcData,
// GLuint srcOffset); GLuint srcOffset);
//[Throws] //[Throws]
//void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,

View file

@ -1,11 +1,8 @@
[views-with-offsets.html] [views-with-offsets.html]
expected: ERROR expected: ERROR
[WebGL test #0: Does not support texImage2D with offsets into views.] [WebGL test #47: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL
[WebGL test #1: Does not support texSubImage2D with offsets into views.] [WebGL test #46: Does not support texSubImage2D with offsets into views.]
expected: FAIL
[WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL expected: FAIL