Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement WebGL getFrameBufferAttachmentParameter API #20317

Merged
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Implement WebGL getFramebufferAttachmentParameter API

  • Loading branch information
gootorov committed Mar 22, 2018
commit ee5bdbbd8b99b58eda19c117b1a06e4a90a61bb1
@@ -750,6 +750,8 @@ impl WebGLImpl {
Self::active_uniform(ctx.gl(), program_id, index, chan),
WebGLCommand::GetAttribLocation(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) =>
Self::vertex_attrib(ctx.gl(), index, pname, chan),
WebGLCommand::GetVertexAttribOffset(index, pname, chan) =>
@@ -1165,6 +1167,18 @@ impl WebGLImpl {
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,
program_id: WebGLProgramId,
name: String,
@@ -219,6 +219,7 @@ pub enum WebGLCommand {
GetVertexAttribOffset(u32, u32, WebGLSender<isize>),
GetShaderInfoLog(WebGLShaderId, WebGLSender<String>),
GetProgramInfoLog(WebGLProgramId, WebGLSender<String>),
GetFramebufferAttachmentParameter(u32, u32, u32, WebGLSender<i32>),
PolygonOffset(f32, f32),
RenderbufferStorage(u32, u32, i32, i32),
ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<Vec<u8>>),
@@ -490,6 +491,7 @@ impl fmt::Debug for WebGLCommand {
GetProgramInfoLog(..) => "GetProgramInfoLog",
GetVertexAttrib(..) => "GetVertexAttrib",
GetVertexAttribOffset(..) => "GetVertexAttribOffset",
GetFramebufferAttachmentParameter(..) => "GetFramebufferAttachmentParameter",
PolygonOffset(..) => "PolygonOffset",
ReadPixels(..) => "ReadPixels",
RenderbufferStorage(..) => "RenderbufferStorage",
@@ -142,6 +142,18 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
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
fn ActiveTexture(&self, texture: u32) {
self.base.ActiveTexture(texture)
@@ -25,6 +25,12 @@ enum WebGLFramebufferAttachment {
Texture { texture: Dom<WebGLTexture>, level: i32 },
}

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

#[dom_struct]
pub struct WebGLFramebuffer {
webgl_object: WebGLObject,
@@ -213,6 +219,25 @@ impl WebGLFramebuffer {
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>,
level: i32) -> WebGLResult<()> {
let binding = match attachment {
@@ -10,6 +10,7 @@ use canvas_traits::webgl::DOMToTextureCommand;
use canvas_traits::webgl::WebGLError::*;
use canvas_traits::webgl::webgl_channel;
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::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
@@ -33,7 +34,7 @@ use dom::webgl_validations::types::{TexDataType, TexFormat, TexImageTarget};
use dom::webglactiveinfo::WebGLActiveInfo;
use dom::webglbuffer::WebGLBuffer;
use dom::webglcontextevent::WebGLContextEvent;
use dom::webglframebuffer::WebGLFramebuffer;
use dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferAttachmentRoot};
use dom::webglprogram::WebGLProgram;
use dom::webglrenderbuffer::WebGLRenderbuffer;
use dom::webglshader::WebGLShader;
@@ -1554,6 +1555,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {

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

if target != constants::FRAMEBUFFER {
return self.webgl_error(InvalidOperation);
}
@@ -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
fn GetProgramInfoLog(&self, program: Option<&WebGLProgram>) -> Option<DOMString> {
if let Some(program) = program {
@@ -589,8 +589,8 @@ interface WebGLRenderingContextBase

[WebGLHandlesContextLoss] GLenum getError();

//any getFramebufferAttachmentParameter(GLenum target, GLenum attachment,
// GLenum pname);
any getFramebufferAttachmentParameter(GLenum target, GLenum attachment,
GLenum pname);
any getProgramParameter(WebGLProgram? program, GLenum pname);
DOMString? getProgramInfoLog(WebGLProgram? program);
//any getRenderbufferParameter(GLenum target, GLenum pname);
@@ -3,15 +3,12 @@
[WebGL test #0: Property either does not exist or is not a function: getAttachedShaders]
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

[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

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

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

This file was deleted.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.