Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
webgl: Do validation that the framebuffer is complete for FBO operati…
…ons.

Given that we can't make a complete FBO yet, just return false from
the status check.
  • Loading branch information
anholt authored and gw3583 committed Sep 20, 2016
1 parent b2c1692 commit 87c9333
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
7 changes: 7 additions & 0 deletions components/script/dom/webglframebuffer.rs
Expand Up @@ -5,6 +5,7 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLFramebufferBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
Expand Down Expand Up @@ -79,6 +80,12 @@ impl WebGLFramebuffer {
self.is_deleted.get()
}

pub fn check_status(&self) -> u32 {
// Until we build support for attaching renderbuffers or
// textures, all user FBOs are incomplete.
return constants::FRAMEBUFFER_UNSUPPORTED;
}

pub fn target(&self) -> Option<u32> {
self.target.get()
}
Expand Down
56 changes: 56 additions & 0 deletions components/script/dom/webglrenderingcontext.rs
Expand Up @@ -212,6 +212,38 @@ impl WebGLRenderingContext {
}
}

// Helper function for validating framebuffer completeness in
// calls touching the framebuffer. From the GLES 2.0.25 spec,
// page 119:
//
// "Effects of Framebuffer Completeness on Framebuffer
// Operations
//
// If the currently bound framebuffer is not framebuffer
// complete, then it is an error to attempt to use the
// framebuffer for writing or reading. This means that
// rendering commands such as DrawArrays and DrawElements, as
// well as commands that read the framebuffer such as
// ReadPixels and CopyTexSubImage, will generate the error
// INVALID_FRAMEBUFFER_OPERATION if called while the
// framebuffer is not framebuffer complete."
//
// The WebGL spec mentions a couple more operations that trigger
// this: clear() and getParameter(IMPLEMENTATION_COLOR_READ_*).
fn validate_framebuffer_complete(&self) -> bool {
match self.bound_framebuffer.get() {
Some(fb) => match fb.check_status() {
constants::FRAMEBUFFER_COMPLETE => return true,
_ => {
self.webgl_error(InvalidFramebufferOperation);
return false;
}
},
// The default framebuffer is always complete.
None => return true,
}
}

fn tex_parameter(&self, target: u32, name: u32, value: TexParameterValue) {
let texture = match target {
constants::TEXTURE_2D => self.bound_texture_2d.get(),
Expand Down Expand Up @@ -886,6 +918,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CopyTexImage2D(&self, target: u32, level: i32, internal_format: u32,
x: i32, y: i32, width: i32, height: i32, border: i32) {
if !self.validate_framebuffer_complete() {
return;
}

let validator = CommonTexImage2DValidator::new(self, target, level,
internal_format, width,
height, border);
Expand Down Expand Up @@ -939,6 +975,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CopyTexSubImage2D(&self, target: u32, level: i32, xoffset: i32, yoffset: i32,
x: i32, y: i32, width: i32, height: i32) {
if !self.validate_framebuffer_complete() {
return;
}

// NB: We use a dummy (valid) format and border in order to reuse the
// common validations, but this should have its own validator.
let validator = CommonTexImage2DValidator::new(self, target, level,
Expand Down Expand Up @@ -978,6 +1018,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Clear(&self, mask: u32) {
if !self.validate_framebuffer_complete() {
return;
}

self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::Clear(mask))).unwrap();
self.mark_as_dirty();
}
Expand Down Expand Up @@ -1204,6 +1248,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue);
}

if !self.validate_framebuffer_complete() {
return;
}

self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count)))
.unwrap();
Expand Down Expand Up @@ -1240,6 +1288,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidOperation);
}

if !self.validate_framebuffer_complete() {
return;
}

match mode {
constants::POINTS | constants::LINE_STRIP |
constants::LINE_LOOP | constants::LINES |
Expand Down Expand Up @@ -1508,6 +1560,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
None => return self.webgl_error(InvalidValue),
};

if !self.validate_framebuffer_complete() {
return;
}

match unsafe { JS_GetArrayBufferViewType(pixels) } {
Type::Uint8 => (),
_ => return self.webgl_error(InvalidOperation)
Expand Down

0 comments on commit 87c9333

Please sign in to comment.