Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for WebGL2 TexImage2D #26520

Merged
merged 1 commit into from May 21, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -18,7 +18,9 @@ use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
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::webglactiveinfo::WebGLActiveInfo;
use crate::dom::webglbuffer::WebGLBuffer;
@@ -27,8 +29,8 @@ use crate::dom::webglprogram::WebGLProgram;
use crate::dom::webglquery::WebGLQuery;
use crate::dom::webglrenderbuffer::WebGLRenderbuffer;
use crate::dom::webglrenderingcontext::{
uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, Operation, VertexAttrib,
WebGLRenderingContext,
uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, Operation, TexPixels,
VertexAttrib, WebGLRenderingContext,
};
use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue};
use crate::dom::webglshader::WebGLShader;
@@ -48,7 +50,7 @@ use canvas_traits::webgl::{
};
use dom_struct::dom_struct;
use euclid::default::{Point2D, Rect, Size2D};
use ipc_channel::ipc;
use ipc_channel::ipc::{self, IpcSharedMemory};
use js::jsapi::{JSObject, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, UInt32Value};
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
@@ -2914,6 +2916,100 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
.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
fn TexSubImage2D(
&self,
@@ -306,6 +306,10 @@ impl WebGLRenderingContext {
&self.limits
}

pub fn texture_unpacking_alignment(&self) -> u32 {
self.texture_unpacking_alignment.get()
}

pub fn current_vao(&self) -> DomRoot<WebGLVertexArrayObjectOES> {
self.current_vao.or_init(|| {
DomRoot::from_ref(
@@ -697,14 +701,14 @@ impl WebGLRenderingContext {
}

// TODO(emilio): Move this logic to a validator.
fn validate_tex_image_2d_data(
pub fn validate_tex_image_2d_data(
&self,
width: u32,
height: u32,
format: TexFormat,
data_type: TexDataType,
unpacking_alignment: u32,
data: &Option<ArrayBufferView>,
data: Option<&ArrayBufferView>,
) -> Result<u32, ()> {
let element_size = data_type.element_size();
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,
texture: &WebGLTexture,
target: TexImageTarget,
@@ -4276,7 +4280,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
format,
data_type,
unpacking_alignment,
&*pixels,
pixels.as_ref(),
)
} {
Ok(byte_length) => byte_length,
@@ -4503,7 +4507,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
format,
data_type,
unpacking_alignment,
&*pixels,
pixels.as_ref(),
)
} {
Ok(byte_length) => byte_length,
@@ -4881,7 +4885,7 @@ impl TextureUnit {
}
}

struct TexPixels {
pub struct TexPixels {
data: IpcSharedMemory,
size: Size2D<u32>,
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 {
data,
size,
@@ -512,10 +512,10 @@ interface mixin WebGL2RenderingContextOverloads
//void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
// GLint border, GLenum format, GLenum type,
// TexImageSource source); // May throw DOMException
//[Throws]
//void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
// GLint border, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView srcData,
// GLuint srcOffset);
[Throws]
void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView srcData,
GLuint srcOffset);

//[Throws]
//void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
@@ -1,11 +1,8 @@
[views-with-offsets.html]
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

[WebGL test #1: 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).]
[WebGL test #46: Does not support texSubImage2D with offsets into views.]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.