Skip to content

Commit

Permalink
Add initial support for WebGL2 read framebuffer
Browse files Browse the repository at this point in the history
Adds support for binding to the read framebuffer slot and querying
its status.
  • Loading branch information
mmatyas committed Feb 14, 2020
1 parent 8334858 commit 796ee70
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 89 deletions.
49 changes: 47 additions & 2 deletions components/script/dom/webgl2renderingcontext.rs
Expand Up @@ -503,6 +503,13 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
self.current_transform_feedback.get()
);
},
// NOTE: DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING, handled on the WebGL1 side
constants::READ_FRAMEBUFFER_BINDING => unsafe {
return optional_root_object_to_js_or_null!(
*cx,
&self.base.get_read_framebuffer_slot().get()
);
},
_ => {},
}

Expand Down Expand Up @@ -650,7 +657,32 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn BindFramebuffer(&self, target: u32, framebuffer: Option<&WebGLFramebuffer>) {
self.base.BindFramebuffer(target, framebuffer)
handle_potential_webgl_error!(
self.base,
self.base.validate_new_framebuffer_binding(framebuffer),
return
);

let (bind_read, bind_draw) = match target {
constants::FRAMEBUFFER => (true, true),
constants::READ_FRAMEBUFFER => (true, false),
constants::DRAW_FRAMEBUFFER => (false, true),
_ => return self.base.webgl_error(InvalidEnum),
};
if bind_read {
self.base.bind_framebuffer_to(
target,
framebuffer,
&self.base.get_read_framebuffer_slot(),
);
}
if bind_draw {
self.base.bind_framebuffer_to(
target,
framebuffer,
&self.base.get_draw_framebuffer_slot(),
);
}
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
Expand Down Expand Up @@ -2221,7 +2253,20 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn CheckFramebufferStatus(&self, target: u32) -> u32 {
self.base.CheckFramebufferStatus(target)
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(),
_ => {
self.base.webgl_error(InvalidEnum);
return 0;
},
};
match fb_slot.get() {
Some(fb) => fb.check_status(),
None => constants::FRAMEBUFFER_COMPLETE,
}
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
Expand Down
24 changes: 14 additions & 10 deletions components/script/dom/webglrenderbuffer.rs
Expand Up @@ -96,20 +96,24 @@ impl WebGLRenderbuffer {
if !self.is_deleted.get() {
self.is_deleted.set(true);

let context = self.upcast::<WebGLObject>().context();

/*
If a renderbuffer object is deleted while its image is attached to the currently
bound framebuffer, then it is as if FramebufferRenderbuffer had been called, with
a renderbuffer of 0, for each attachment point to which this image was attached
in the currently bound framebuffer.
- GLES 2.0, 4.4.3, "Attaching Renderbuffer Images to a Framebuffer"
*/
let currently_bound_framebuffer =
self.upcast::<WebGLObject>().context().bound_framebuffer();
if let Some(fb) = currently_bound_framebuffer {
If a renderbuffer object is deleted while its image is attached to one or more
attachment points in a currently bound framebuffer object, then it is as if
FramebufferRenderbuffer had been called, with a renderbuffer of zero, for each
attachment point to which this image was attached in that framebuffer object.
In other words,the renderbuffer image is first detached from all attachment points
in that frame-buffer object.
- GLES 3.0, 4.4.2.3, "Attaching Renderbuffer Images to a Framebuffer"
*/
if let Some(fb) = context.get_draw_framebuffer_slot().get() {
let _ = fb.detach_renderbuffer(self);
}
if let Some(fb) = context.get_read_framebuffer_slot().get() {
let _ = fb.detach_renderbuffer(self);
}

let context = self.upcast::<WebGLObject>().context();
let cmd = WebGLCommand::DeleteRenderbuffer(self.id);
if fallible {
context.send_command_ignored(cmd);
Expand Down

0 comments on commit 796ee70

Please sign in to comment.