aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2016-09-16 23:39:42 +0100
committerGlenn Watson <github@intuitionlibrary.com>2016-09-21 08:05:45 +1000
commit87c9333abddbf8fb16e2f79a09c59579d34dd49f (patch)
treef8b043cf9d023e6c637d49604c3e96d07e1492fb /components/script/dom
parentb2c169274ac88636ccbd9e67b10fc12faa612e4d (diff)
downloadservo-87c9333abddbf8fb16e2f79a09c59579d34dd49f.tar.gz
servo-87c9333abddbf8fb16e2f79a09c59579d34dd49f.zip
webgl: Do validation that the framebuffer is complete for FBO operations.
Given that we can't make a complete FBO yet, just return false from the status check.
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/webglframebuffer.rs7
-rw-r--r--components/script/dom/webglrenderingcontext.rs56
2 files changed, 63 insertions, 0 deletions
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index 6e426fa0969..cd212d644bf 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -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;
@@ -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()
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 71585c94def..f42eeab4dbf 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -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(),
@@ -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);
@@ -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,
@@ -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();
}
@@ -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();
@@ -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 |
@@ -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)