mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Add support for WebGL2 TexImage2D
Adds initial support for one of the WebGL2 `TexImage2D` call.
This commit is contained in:
parent
6c506ba260
commit
035cb6ebaa
4 changed files with 117 additions and 20 deletions
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue