Skip to content

Commit

Permalink
Implement WebGL getFramebufferAttachmentParameter API
Browse files Browse the repository at this point in the history
  • Loading branch information
gootorov committed Mar 22, 2018
1 parent f92f080 commit ee5bdbb
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 110 deletions.
14 changes: 14 additions & 0 deletions components/canvas/webgl_thread.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ impl WebGLImpl {
Self::active_uniform(ctx.gl(), program_id, index, chan), Self::active_uniform(ctx.gl(), program_id, index, chan),
WebGLCommand::GetAttribLocation(program_id, name, chan) => WebGLCommand::GetAttribLocation(program_id, name, chan) =>
Self::attrib_location(ctx.gl(), program_id, name, chan), Self::attrib_location(ctx.gl(), program_id, name, chan),
WebGLCommand::GetFramebufferAttachmentParameter(target, attachment, pname, chan) =>
Self::get_framebuffer_attachment_parameter(ctx.gl(), target, attachment, pname, chan),
WebGLCommand::GetVertexAttrib(index, pname, chan) => WebGLCommand::GetVertexAttrib(index, pname, chan) =>
Self::vertex_attrib(ctx.gl(), index, pname, chan), Self::vertex_attrib(ctx.gl(), index, pname, chan),
WebGLCommand::GetVertexAttribOffset(index, pname, chan) => WebGLCommand::GetVertexAttribOffset(index, pname, chan) =>
Expand Down Expand Up @@ -1165,6 +1167,18 @@ impl WebGLImpl {
chan.send(gl.get_string(gl::EXTENSIONS)).unwrap(); chan.send(gl.get_string(gl::EXTENSIONS)).unwrap();
} }


// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn get_framebuffer_attachment_parameter(
gl: &gl::Gl,
target: u32,
attachment: u32,
pname: u32,
chan: WebGLSender<i32>
) {
let parameter = gl.get_framebuffer_attachment_parameter_iv(target, attachment, pname);
chan.send(parameter).unwrap();
}

fn uniform_location(gl: &gl::Gl, fn uniform_location(gl: &gl::Gl,
program_id: WebGLProgramId, program_id: WebGLProgramId,
name: String, name: String,
Expand Down
2 changes: 2 additions & 0 deletions components/canvas_traits/webgl.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ pub enum WebGLCommand {
GetVertexAttribOffset(u32, u32, WebGLSender<isize>), GetVertexAttribOffset(u32, u32, WebGLSender<isize>),
GetShaderInfoLog(WebGLShaderId, WebGLSender<String>), GetShaderInfoLog(WebGLShaderId, WebGLSender<String>),
GetProgramInfoLog(WebGLProgramId, WebGLSender<String>), GetProgramInfoLog(WebGLProgramId, WebGLSender<String>),
GetFramebufferAttachmentParameter(u32, u32, u32, WebGLSender<i32>),
PolygonOffset(f32, f32), PolygonOffset(f32, f32),
RenderbufferStorage(u32, u32, i32, i32), RenderbufferStorage(u32, u32, i32, i32),
ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<Vec<u8>>), ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<Vec<u8>>),
Expand Down Expand Up @@ -490,6 +491,7 @@ impl fmt::Debug for WebGLCommand {
GetProgramInfoLog(..) => "GetProgramInfoLog", GetProgramInfoLog(..) => "GetProgramInfoLog",
GetVertexAttrib(..) => "GetVertexAttrib", GetVertexAttrib(..) => "GetVertexAttrib",
GetVertexAttribOffset(..) => "GetVertexAttribOffset", GetVertexAttribOffset(..) => "GetVertexAttribOffset",
GetFramebufferAttachmentParameter(..) => "GetFramebufferAttachmentParameter",
PolygonOffset(..) => "PolygonOffset", PolygonOffset(..) => "PolygonOffset",
ReadPixels(..) => "ReadPixels", ReadPixels(..) => "ReadPixels",
RenderbufferStorage(..) => "RenderbufferStorage", RenderbufferStorage(..) => "RenderbufferStorage",
Expand Down
12 changes: 12 additions & 0 deletions components/script/dom/webgl2renderingcontext.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
self.base.GetExtension(cx, name) self.base.GetExtension(cx, name)
} }


#[allow(unsafe_code)]
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4
unsafe fn GetFramebufferAttachmentParameter(
&self,
cx: *mut JSContext,
target: u32,
attachment: u32,
pname: u32
) -> JSVal {
self.base.GetFramebufferAttachmentParameter(cx, target, attachment, pname)
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ActiveTexture(&self, texture: u32) { fn ActiveTexture(&self, texture: u32) {
self.base.ActiveTexture(texture) self.base.ActiveTexture(texture)
Expand Down
25 changes: 25 additions & 0 deletions components/script/dom/webglframebuffer.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ enum WebGLFramebufferAttachment {
Texture { texture: Dom<WebGLTexture>, level: i32 }, Texture { texture: Dom<WebGLTexture>, level: i32 },
} }


#[derive(Clone, JSTraceable, MallocSizeOf)]
pub enum WebGLFramebufferAttachmentRoot {
Renderbuffer(DomRoot<WebGLRenderbuffer>),
Texture(DomRoot<WebGLTexture>),
}

#[dom_struct] #[dom_struct]
pub struct WebGLFramebuffer { pub struct WebGLFramebuffer {
webgl_object: WebGLObject, webgl_object: WebGLObject,
Expand Down Expand Up @@ -213,6 +219,25 @@ impl WebGLFramebuffer {
Ok(()) Ok(())
} }


pub fn attachment(&self, attachment: u32) -> Option<WebGLFramebufferAttachmentRoot> {
let binding = match attachment {
constants::COLOR_ATTACHMENT0 => &self.color,
constants::DEPTH_ATTACHMENT => &self.depth,
constants::STENCIL_ATTACHMENT => &self.stencil,
constants::DEPTH_STENCIL_ATTACHMENT => &self.depthstencil,
_ => return None,
};

binding.borrow().as_ref().map(|bin| {
match bin {
&WebGLFramebufferAttachment::Renderbuffer(ref rb) =>
WebGLFramebufferAttachmentRoot::Renderbuffer(DomRoot::from_ref(&rb)),
&WebGLFramebufferAttachment::Texture { ref texture, .. } =>
WebGLFramebufferAttachmentRoot::Texture(DomRoot::from_ref(&texture)),
}
})
}

pub fn texture2d(&self, attachment: u32, textarget: u32, texture: Option<&WebGLTexture>, pub fn texture2d(&self, attachment: u32, textarget: u32, texture: Option<&WebGLTexture>,
level: i32) -> WebGLResult<()> { level: i32) -> WebGLResult<()> {
let binding = match attachment { let binding = match attachment {
Expand Down
94 changes: 93 additions & 1 deletion components/script/dom/webglrenderingcontext.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use canvas_traits::webgl::DOMToTextureCommand;
use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::WebGLError::*;
use canvas_traits::webgl::webgl_channel; use canvas_traits::webgl::webgl_channel;
use dom::bindings::cell::DomRefCell; use dom::bindings::cell::DomRefCell;
use dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as WebGL2Constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
Expand All @@ -33,7 +34,7 @@ use dom::webgl_validations::types::{TexDataType, TexFormat, TexImageTarget};
use dom::webglactiveinfo::WebGLActiveInfo; use dom::webglactiveinfo::WebGLActiveInfo;
use dom::webglbuffer::WebGLBuffer; use dom::webglbuffer::WebGLBuffer;
use dom::webglcontextevent::WebGLContextEvent; use dom::webglcontextevent::WebGLContextEvent;
use dom::webglframebuffer::WebGLFramebuffer; use dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferAttachmentRoot};
use dom::webglprogram::WebGLProgram; use dom::webglprogram::WebGLProgram;
use dom::webglrenderbuffer::WebGLRenderbuffer; use dom::webglrenderbuffer::WebGLRenderbuffer;
use dom::webglshader::WebGLShader; use dom::webglshader::WebGLShader;
Expand Down Expand Up @@ -1554,6 +1555,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {


// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn BindFramebuffer(&self, target: u32, framebuffer: Option<&WebGLFramebuffer>) { fn BindFramebuffer(&self, target: u32, framebuffer: Option<&WebGLFramebuffer>) {
if target == WebGL2Constants::READ_FRAMEBUFFER {
return self.webgl_error(InvalidEnum);
}

if target != constants::FRAMEBUFFER { if target != constants::FRAMEBUFFER {
return self.webgl_error(InvalidOperation); return self.webgl_error(InvalidOperation);
} }
Expand Down Expand Up @@ -2297,6 +2302,93 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} }
} }


#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
unsafe fn GetFramebufferAttachmentParameter(
&self,
cx: *mut JSContext,
target: u32,
attachment: u32,
pname: u32
) -> JSVal {
// Check if currently bound framebuffer is non-zero as per spec.
if self.bound_framebuffer.get().is_none() {
self.webgl_error(InvalidOperation);
return NullValue();
}

// Note: commented out stuff is for the WebGL2 standard.
let target_matches = match target {
// constants::READ_FRAMEBUFFER |
// constants::DRAW_FRAMEBUFFER => true,
constants::FRAMEBUFFER => true,
_ => false
};
let attachment_matches = match attachment {
// constants::MAX_COLOR_ATTACHMENTS ... gl::COLOR_ATTACHMENT0 |
// constants::BACK |
constants::COLOR_ATTACHMENT0 |
constants::DEPTH_STENCIL_ATTACHMENT |
constants::DEPTH_ATTACHMENT |
constants::STENCIL_ATTACHMENT => true,
_ => false,
};
let pname_matches = match pname {
// constants::FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE |
// constants::FRAMEBUFFER_ATTACHMENT_BLUE_SIZE |
// constants::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING |
// constants::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE |
// constants::FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE |
// constants::FRAMEBUFFER_ATTACHMENT_GREEN_SIZE |
// constants::FRAMEBUFFER_ATTACHMENT_RED_SIZE |
// constants::FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE |
// constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER |
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME |
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE |
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE |
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL => true,
_ => false
};

if !target_matches || !attachment_matches || !pname_matches {
self.webgl_error(InvalidEnum);
return NullValue();
}

// From the GLES2 spec:
//
// If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE,
// then querying any other pname will generate INVALID_ENUM.
//
// otherwise, return `WebGLRenderbuffer` or `WebGLTexture` dom object
if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME {
// if fb is None, an INVALID_OPERATION is returned
// at the beggining of the function, so `.unwrap()` will never panic
let fb = self.bound_framebuffer.get().unwrap();
if let Some(webgl_attachment) = fb.attachment(attachment) {
match webgl_attachment {
WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => {
rooted!(in(cx) let mut rval = NullValue());
rb.to_jsval(cx, rval.handle_mut());
return rval.get();
},
WebGLFramebufferAttachmentRoot::Texture(texture) => {
rooted!(in(cx) let mut rval = NullValue());
texture.to_jsval(cx, rval.handle_mut());
return rval.get();
},
}
}
self.webgl_error(InvalidEnum);
return NullValue();
}

let (sender, receiver) = webgl_channel().unwrap();
self.send_command(WebGLCommand::GetFramebufferAttachmentParameter(target, attachment, pname, sender));

Int32Value(receiver.recv().unwrap())
}

// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn GetProgramInfoLog(&self, program: Option<&WebGLProgram>) -> Option<DOMString> { fn GetProgramInfoLog(&self, program: Option<&WebGLProgram>) -> Option<DOMString> {
if let Some(program) = program { if let Some(program) = program {
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/webidls/WebGLRenderingContext.webidl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -589,8 +589,8 @@ interface WebGLRenderingContextBase


[WebGLHandlesContextLoss] GLenum getError(); [WebGLHandlesContextLoss] GLenum getError();


//any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, any getFramebufferAttachmentParameter(GLenum target, GLenum attachment,
// GLenum pname); GLenum pname);
any getProgramParameter(WebGLProgram? program, GLenum pname); any getProgramParameter(WebGLProgram? program, GLenum pname);
DOMString? getProgramInfoLog(WebGLProgram? program); DOMString? getProgramInfoLog(WebGLProgram? program);
//any getRenderbufferParameter(GLenum target, GLenum pname); //any getRenderbufferParameter(GLenum target, GLenum pname);
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
[WebGL test #0: Property either does not exist or is not a function: getAttachedShaders] [WebGL test #0: Property either does not exist or is not a function: getAttachedShaders]
expected: FAIL expected: FAIL


[WebGL test #1: Property either does not exist or is not a function: getFramebufferAttachmentParameter] [WebGL test #1: Property either does not exist or is not a function: getRenderbufferParameter]
expected: FAIL expected: FAIL


[WebGL test #2: Property either does not exist or is not a function: getRenderbufferParameter] [WebGL test #2: Property either does not exist or is not a function: getUniform]
expected: FAIL expected: FAIL


[WebGL test #3: Property either does not exist or is not a function: getUniform] [WebGL test #3: Property either does not exist or is not a function: isContextLost]
expected: FAIL

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


This file was deleted.

Loading

0 comments on commit ee5bdbb

Please sign in to comment.