aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webgl2renderingcontext.rs
diff options
context:
space:
mode:
authorIstvan Miklos <istvan.miklos@h-lab.eu>2020-05-04 10:17:46 +0200
committerIstvan Miklos <istvan.miklos@h-lab.eu>2020-05-21 10:49:51 +0200
commit035cb6ebaa66562be3db002e29a5526819fb5f5b (patch)
tree20b8eb709999a8fe8a3947e16f4973be17a1696a /components/script/dom/webgl2renderingcontext.rs
parent6c506ba2608c082a6c3c908b5e72f1cb5ea8a082 (diff)
downloadservo-035cb6ebaa66562be3db002e29a5526819fb5f5b.tar.gz
servo-035cb6ebaa66562be3db002e29a5526819fb5f5b.zip
Add support for WebGL2 TexImage2D
Adds initial support for one of the WebGL2 `TexImage2D` call.
Diffstat (limited to 'components/script/dom/webgl2renderingcontext.rs')
-rw-r--r--components/script/dom/webgl2renderingcontext.rs104
1 files changed, 100 insertions, 4 deletions
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs
index 9bc4b8fe0a8..7dd7ddd0279 100644
--- a/components/script/dom/webgl2renderingcontext.rs
+++ b/components/script/dom/webgl2renderingcontext.rs
@@ -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,