Skip to content

Commit

Permalink
webgl: Add support for renderbufferStorage().
Browse files Browse the repository at this point in the history
This is not a complete implementation yet: It doesn't clear the
contents of the renderbuffer on creation.  However, Gecko's plan to
only clear renderbuffers when the first FBO using them is the
simplest.
  • Loading branch information
anholt committed Oct 26, 2016
1 parent 8a0ca2e commit 989c936
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 30 deletions.
29 changes: 28 additions & 1 deletion components/script/dom/webglrenderbuffer.rs
Expand Up @@ -5,20 +5,22 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::globalscope::GlobalScope;
use dom::webglobject::WebGLObject;
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
use webrender_traits::{WebGLCommand, WebGLRenderbufferId};
use webrender_traits::{WebGLCommand, WebGLRenderbufferId, WebGLResult, WebGLError};

#[dom_struct]
pub struct WebGLRenderbuffer {
webgl_object: WebGLObject,
id: WebGLRenderbufferId,
ever_bound: Cell<bool>,
is_deleted: Cell<bool>,
internal_format: Cell<Option<u32>>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
renderer: IpcSender<CanvasMsg>,
}
Expand All @@ -33,6 +35,7 @@ impl WebGLRenderbuffer {
ever_bound: Cell::new(false),
is_deleted: Cell::new(false),
renderer: renderer,
internal_format: Cell::new(None),
}
}

Expand Down Expand Up @@ -81,4 +84,28 @@ impl WebGLRenderbuffer {
pub fn ever_bound(&self) -> bool {
self.ever_bound.get()
}

pub fn storage(&self, internal_format: u32, width: i32, height: i32) -> WebGLResult<()> {
// Validate the internal_format, and save it for completeness
// validation.
match internal_format {
constants::RGBA4 |
constants::DEPTH_STENCIL |
constants::DEPTH_COMPONENT16 |
constants::STENCIL_INDEX8 =>
self.internal_format.set(Some(internal_format)),

_ => return Err(WebGLError::InvalidEnum),
};

// FIXME: Check that w/h are < MAX_RENDERBUFFER_SIZE

// FIXME: Invalidate completeness after the call

let msg = CanvasMsg::WebGL(WebGLCommand::RenderbufferStorage(constants::RENDERBUFFER,
internal_format, width, height));
self.renderer.send(msg).unwrap();

Ok(())
}
}
33 changes: 33 additions & 0 deletions components/script/dom/webglrenderingcontext.rs
Expand Up @@ -2569,6 +2569,39 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
None => return constants::FRAMEBUFFER_COMPLETE,
}
}

fn RenderbufferStorage(&self, target: u32, internal_format: u32,
width: i32, height: i32) {
// From the GLES 2.0.25 spec:
//
// "target must be RENDERBUFFER."
if target != constants::RENDERBUFFER {
return self.webgl_error(InvalidOperation)
}

// From the GLES 2.0.25 spec:
//
// "If either width or height is greater than the value of
// MAX_RENDERBUFFER_SIZE , the error INVALID_VALUE is
// generated."
//
// and we have to throw out negative-size values as well just
// like for TexImage.
//
// FIXME: Handle max_renderbuffer_size, which doesn't seem to
// be in limits.
if width < 0 || height < 0 {
return self.webgl_error(InvalidValue);
}

match self.bound_renderbuffer.get() {
Some(rb) => handle_potential_webgl_error!(self, rb.storage(internal_format, width, height)),
None => self.webgl_error(InvalidOperation),
};

// FIXME: We need to clear the renderbuffer before it can be
// accessed. See https://github.com/servo/servo/issues/13710
}
}

pub trait LayoutCanvasWebGLRenderingContextHelpers {
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/webidls/WebGLRenderingContext.webidl
Expand Up @@ -626,8 +626,8 @@ interface WebGLRenderingContextBase
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, object? pixels);

//void renderbufferStorage(GLenum target, GLenum internalformat,
// GLsizei width, GLsizei height);
void renderbufferStorage(GLenum target, GLenum internalformat,
GLsizei width, GLsizei height);
void sampleCoverage(GLclampf value, GLboolean invert);
void scissor(GLint x, GLint y, GLsizei width, GLsizei height);

Expand Down
Expand Up @@ -86,9 +86,6 @@
[WebGL test #29: Property either does not exist or is not a function: readPixels]
expected: FAIL

[WebGL test #30: Property either does not exist or is not a function: renderbufferStorage]
expected: FAIL

[WebGL test #31: Property either does not exist or is not a function: sampleCoverage]
expected: FAIL

Expand Down Expand Up @@ -227,9 +224,6 @@
[WebGL test #25: Property either does not exist or is not a function: readPixels]
expected: FAIL

[WebGL test #26: Property either does not exist or is not a function: renderbufferStorage]
expected: FAIL

[WebGL test #27: Property either does not exist or is not a function: sampleCoverage]
expected: FAIL

Expand Down
Expand Up @@ -45,12 +45,6 @@
[WebGL test #23: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: context.texSubImage2D(context.TEXTURE_2D, 0, 0, 0, 2, 2, context.RGBA, context.UNSIGNED_BYTE, pixels)]
expected: FAIL

[WebGL test #30: context.renderbufferStorage(context.RENDERBUFFER, context.RGBA4, -2, -2) threw exception TypeError: context.renderbufferStorage is not a function]
expected: FAIL

[WebGL test #31: context.renderbufferStorage(context.RENDERBUFFER, context.RGBA4, 16, 16) threw exception TypeError: context.renderbufferStorage is not a function]
expected: FAIL

[WebGL test #44: context.getError() should be 1281. Was 0.]
expected: FAIL

Expand Down
Expand Up @@ -60,9 +60,6 @@
[WebGL test #74: gl.isRenderbuffer(rbo) should be false. Threw exception TypeError: gl.isRenderbuffer is not a function]
expected: FAIL

[WebGL test #83: gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) threw exception TypeError: gl.renderbufferStorage is not a function]
expected: FAIL

[WebGL test #85: gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) threw exception TypeError: gl.framebufferRenderbuffer is not a function]
expected: FAIL

Expand All @@ -72,18 +69,12 @@
[WebGL test #51: getError expected: NO_ERROR. Was INVALID_OPERATION : after evaluating: gl.bindTexture(gl.TEXTURE_2D, t)]
expected: FAIL

[WebGL test #87: gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) threw exception TypeError: gl.renderbufferStorage is not a function]
expected: FAIL

[WebGL test #89: gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) threw exception TypeError: gl.framebufferRenderbuffer is not a function]
expected: FAIL

[WebGL test #94: gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) threw exception TypeError: gl.framebufferTexture2D is not a function]
expected: FAIL

[WebGL test #98: gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) threw exception TypeError: gl.renderbufferStorage is not a function]
expected: FAIL

[WebGL test #100: gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) threw exception TypeError: gl.framebufferRenderbuffer is not a function]
expected: FAIL

Expand Down Expand Up @@ -126,9 +117,6 @@
[WebGL test #156: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)]
expected: FAIL

[WebGL test #171: gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) threw exception TypeError: gl.renderbufferStorage is not a function]
expected: FAIL

[WebGL test #172: gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) threw exception TypeError: gl.framebufferRenderbuffer is not a function]
expected: FAIL

Expand Down
@@ -1,6 +1,6 @@
[uninitialized-test.html]
type: testharness
expected: ERROR
disabled: https://github.com/servo/servo/issues/13710

[WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

@@ -1,9 +1,12 @@
[renderbuffer-initialization.html]
type: testharness
expected: ERROR
disabled: https://github.com/servo/servo/issues/13710

[WebGL test #0: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

[WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

[WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL

0 comments on commit 989c936

Please sign in to comment.