diff options
author | Eric Anholt <eric@anholt.net> | 2016-09-10 17:29:50 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2016-10-25 22:18:28 -0700 |
commit | 989c936e67b54105b7d9162553070e4fbfcd5853 (patch) | |
tree | 2ccdba9326b3b664f148267793bc8aa2d9c0bce5 /components/script/dom | |
parent | 8a0ca2efba71446a7e49d8bd832de2117fa44a7d (diff) | |
download | servo-989c936e67b54105b7d9162553070e4fbfcd5853.tar.gz servo-989c936e67b54105b7d9162553070e4fbfcd5853.zip |
webgl: Add support for renderbufferStorage().
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.
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/webglrenderbuffer.rs | 29 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 33 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGLRenderingContext.webidl | 4 |
3 files changed, 63 insertions, 3 deletions
diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index de4eaa2d2c8..9e3c516cfbd 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -5,13 +5,14 @@ // 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 { @@ -19,6 +20,7 @@ pub struct WebGLRenderbuffer { 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>, } @@ -33,6 +35,7 @@ impl WebGLRenderbuffer { ever_bound: Cell::new(false), is_deleted: Cell::new(false), renderer: renderer, + internal_format: Cell::new(None), } } @@ -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(()) + } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index c93e80d805e..a40de7da9c8 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -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 { diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 06bd03a9fd7..913eb644545 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -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); |