aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/webgl2renderingcontext.rs30
-rw-r--r--components/script/dom/webglframebuffer.rs55
-rw-r--r--components/script/dom/webidls/WebGL2RenderingContext.webidl4
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);