diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/webgl2renderingcontext.rs | 30 | ||||
-rw-r--r-- | components/script/dom/webglframebuffer.rs | 55 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGL2RenderingContext.webidl | 4 |
3 files changed, 87 insertions, 2 deletions
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index f3c88cbb7c8..9f0bfcd89c3 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -3581,6 +3581,36 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { height, )) } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4 + fn FramebufferTextureLayer( + &self, + target: u32, + attachment: u32, + texture: Option<&WebGLTexture>, + level: i32, + layer: i32, + ) { + if let Some(tex) = texture { + handle_potential_webgl_error!(self.base, self.base.validate_ownership(tex), return); + } + + let fb_slot = match target { + constants::FRAMEBUFFER | constants::DRAW_FRAMEBUFFER => { + self.base.get_draw_framebuffer_slot() + }, + constants::READ_FRAMEBUFFER => self.base.get_read_framebuffer_slot(), + _ => return self.base.webgl_error(InvalidEnum), + }; + + match fb_slot.get() { + Some(fb) => handle_potential_webgl_error!( + self.base, + fb.texture_layer(attachment, texture, level, layer) + ), + None => self.base.webgl_error(InvalidOperation), + } + } } impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGL2RenderingContext> { diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 8f5f499072a..51604d3e415 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -727,6 +727,61 @@ impl WebGLFramebuffer { Ok(()) } + pub fn texture_layer( + &self, + attachment: u32, + texture: Option<&WebGLTexture>, + level: i32, + layer: i32, + ) -> WebGLResult<()> { + let binding = self + .attachment_binding(attachment) + .ok_or(WebGLError::InvalidEnum)?; + + let context = self.upcast::<WebGLObject>().context(); + + let tex_id = match texture { + Some(texture) => { + let (max_level, max_layer) = match texture.target() { + Some(constants::TEXTURE_3D) => ( + log2(context.limits().max_3d_texture_size), + context.limits().max_3d_texture_size - 1, + ), + Some(constants::TEXTURE_2D) => ( + log2(context.limits().max_tex_size), + context.limits().max_array_texture_layers - 1, + ), + _ => return Err(WebGLError::InvalidOperation), + }; + + if level < 0 || level as u32 >= max_level { + return Err(WebGLError::InvalidValue); + } + if layer < 0 || layer as u32 >= max_layer { + return Err(WebGLError::InvalidValue); + } + + *binding.borrow_mut() = Some(WebGLFramebufferAttachment::Texture { + texture: Dom::from_ref(texture), + level: level, + }); + texture.attach_to_framebuffer(self); + + Some(texture.id()) + }, + _ => None, + }; + + context.send_command(WebGLCommand::FramebufferTextureLayer( + self.target.get().unwrap(), + attachment, + tex_id, + level, + layer, + )); + Ok(()) + } + fn with_matching_renderbuffers<F>(&self, rb: &WebGLRenderbuffer, mut closure: F) where F: FnMut(&DomRefCell<Option<WebGLFramebufferAttachment>>, u32), diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index 6043c49cec3..21ddea415da 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -312,8 +312,8 @@ interface mixin WebGL2RenderingContextBase /* Framebuffer objects */ // void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, // GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - // void framebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, - // GLint layer); + void framebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, + GLint layer); void invalidateFramebuffer(GLenum target, sequence<GLenum> attachments); void invalidateSubFramebuffer(GLenum target, sequence<GLenum> attachments, GLint x, GLint y, GLsizei width, GLsizei height); |