mirror of
https://github.com/servo/servo.git
synced 2025-07-29 02:00:23 +01:00
Auto merge of #25765 - szeged:mmatyas__webgl_fns_framebuf_readslot, r=jdm
Add initial support for WebGL2 read framebuffer Adds support for binding to the read framebuffer slot and querying its status. <!-- Please describe your changes on the following line: --> Depends on #25752 cc @jdm @zakorgy --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
b20883ce99
5 changed files with 203 additions and 90 deletions
|
@ -503,6 +503,13 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
||||||
self.current_transform_feedback.get()
|
self.current_transform_feedback.get()
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
// NOTE: DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING, handled on the WebGL1 side
|
||||||
|
constants::READ_FRAMEBUFFER_BINDING => unsafe {
|
||||||
|
return optional_root_object_to_js_or_null!(
|
||||||
|
*cx,
|
||||||
|
&self.base.get_read_framebuffer_slot().get()
|
||||||
|
);
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +657,32 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
||||||
|
|
||||||
/// 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>) {
|
||||||
self.base.BindFramebuffer(target, framebuffer)
|
handle_potential_webgl_error!(
|
||||||
|
self.base,
|
||||||
|
self.base.validate_new_framebuffer_binding(framebuffer),
|
||||||
|
return
|
||||||
|
);
|
||||||
|
|
||||||
|
let (bind_read, bind_draw) = match target {
|
||||||
|
constants::FRAMEBUFFER => (true, true),
|
||||||
|
constants::READ_FRAMEBUFFER => (true, false),
|
||||||
|
constants::DRAW_FRAMEBUFFER => (false, true),
|
||||||
|
_ => return self.base.webgl_error(InvalidEnum),
|
||||||
|
};
|
||||||
|
if bind_read {
|
||||||
|
self.base.bind_framebuffer_to(
|
||||||
|
target,
|
||||||
|
framebuffer,
|
||||||
|
&self.base.get_read_framebuffer_slot(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if bind_draw {
|
||||||
|
self.base.bind_framebuffer_to(
|
||||||
|
target,
|
||||||
|
framebuffer,
|
||||||
|
&self.base.get_draw_framebuffer_slot(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
||||||
|
@ -2221,7 +2253,20 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
||||||
|
|
||||||
/// 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 CheckFramebufferStatus(&self, target: u32) -> u32 {
|
fn CheckFramebufferStatus(&self, target: u32) -> u32 {
|
||||||
self.base.CheckFramebufferStatus(target)
|
let fb_slot = match target {
|
||||||
|
constants::FRAMEBUFFER | constants::DRAW_FRAMEBUFFER => {
|
||||||
|
self.base.get_draw_framebuffer_slot()
|
||||||
|
},
|
||||||
|
constants::READ_FRAMEBUFFER => &self.base.get_read_framebuffer_slot(),
|
||||||
|
_ => {
|
||||||
|
self.base.webgl_error(InvalidEnum);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
match fb_slot.get() {
|
||||||
|
Some(fb) => fb.check_status(),
|
||||||
|
None => constants::FRAMEBUFFER_COMPLETE,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
||||||
|
|
|
@ -96,20 +96,24 @@ impl WebGLRenderbuffer {
|
||||||
if !self.is_deleted.get() {
|
if !self.is_deleted.get() {
|
||||||
self.is_deleted.set(true);
|
self.is_deleted.set(true);
|
||||||
|
|
||||||
|
let context = self.upcast::<WebGLObject>().context();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If a renderbuffer object is deleted while its image is attached to the currently
|
If a renderbuffer object is deleted while its image is attached to one or more
|
||||||
bound framebuffer, then it is as if FramebufferRenderbuffer had been called, with
|
attachment points in a currently bound framebuffer object, then it is as if
|
||||||
a renderbuffer of 0, for each attachment point to which this image was attached
|
FramebufferRenderbuffer had been called, with a renderbuffer of zero, for each
|
||||||
in the currently bound framebuffer.
|
attachment point to which this image was attached in that framebuffer object.
|
||||||
- GLES 2.0, 4.4.3, "Attaching Renderbuffer Images to a Framebuffer"
|
In other words,the renderbuffer image is first detached from all attachment points
|
||||||
*/
|
in that frame-buffer object.
|
||||||
let currently_bound_framebuffer =
|
- GLES 3.0, 4.4.2.3, "Attaching Renderbuffer Images to a Framebuffer"
|
||||||
self.upcast::<WebGLObject>().context().bound_framebuffer();
|
*/
|
||||||
if let Some(fb) = currently_bound_framebuffer {
|
if let Some(fb) = context.get_draw_framebuffer_slot().get() {
|
||||||
|
let _ = fb.detach_renderbuffer(self);
|
||||||
|
}
|
||||||
|
if let Some(fb) = context.get_read_framebuffer_slot().get() {
|
||||||
let _ = fb.detach_renderbuffer(self);
|
let _ = fb.detach_renderbuffer(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = self.upcast::<WebGLObject>().context();
|
|
||||||
let cmd = WebGLCommand::DeleteRenderbuffer(self.id);
|
let cmd = WebGLCommand::DeleteRenderbuffer(self.id);
|
||||||
if fallible {
|
if fallible {
|
||||||
context.send_command_ignored(cmd);
|
context.send_command_ignored(cmd);
|
||||||
|
|
|
@ -163,7 +163,10 @@ pub struct WebGLRenderingContext {
|
||||||
texture_unpacking_settings: Cell<TextureUnpacking>,
|
texture_unpacking_settings: Cell<TextureUnpacking>,
|
||||||
// TODO(nox): Should be Cell<u8>.
|
// TODO(nox): Should be Cell<u8>.
|
||||||
texture_unpacking_alignment: Cell<u32>,
|
texture_unpacking_alignment: Cell<u32>,
|
||||||
bound_framebuffer: MutNullableDom<WebGLFramebuffer>,
|
bound_draw_framebuffer: MutNullableDom<WebGLFramebuffer>,
|
||||||
|
// TODO(mmatyas): This was introduced in WebGL2, but listed here because it's used by
|
||||||
|
// Textures and Renderbuffers, but such WebGLObjects have access only to the GL1 context.
|
||||||
|
bound_read_framebuffer: MutNullableDom<WebGLFramebuffer>,
|
||||||
bound_renderbuffer: MutNullableDom<WebGLRenderbuffer>,
|
bound_renderbuffer: MutNullableDom<WebGLRenderbuffer>,
|
||||||
bound_buffer_array: MutNullableDom<WebGLBuffer>,
|
bound_buffer_array: MutNullableDom<WebGLBuffer>,
|
||||||
current_program: MutNullableDom<WebGLProgram>,
|
current_program: MutNullableDom<WebGLProgram>,
|
||||||
|
@ -223,7 +226,8 @@ impl WebGLRenderingContext {
|
||||||
texture_packing_alignment: Cell::new(4),
|
texture_packing_alignment: Cell::new(4),
|
||||||
texture_unpacking_settings: Cell::new(TextureUnpacking::CONVERT_COLORSPACE),
|
texture_unpacking_settings: Cell::new(TextureUnpacking::CONVERT_COLORSPACE),
|
||||||
texture_unpacking_alignment: Cell::new(4),
|
texture_unpacking_alignment: Cell::new(4),
|
||||||
bound_framebuffer: MutNullableDom::new(None),
|
bound_draw_framebuffer: MutNullableDom::new(None),
|
||||||
|
bound_read_framebuffer: MutNullableDom::new(None),
|
||||||
bound_buffer_array: MutNullableDom::new(None),
|
bound_buffer_array: MutNullableDom::new(None),
|
||||||
bound_renderbuffer: MutNullableDom::new(None),
|
bound_renderbuffer: MutNullableDom::new(None),
|
||||||
current_program: MutNullableDom::new(None),
|
current_program: MutNullableDom::new(None),
|
||||||
|
@ -328,7 +332,7 @@ impl WebGLRenderingContext {
|
||||||
// Bound framebuffer must not change when the canvas is resized.
|
// Bound framebuffer must not change when the canvas is resized.
|
||||||
// Right now surfman generates a new FBO on resize.
|
// Right now surfman generates a new FBO on resize.
|
||||||
// Send a command to re-bind the framebuffer, if any.
|
// Send a command to re-bind the framebuffer, if any.
|
||||||
if let Some(fbo) = self.bound_framebuffer.get() {
|
if let Some(fbo) = self.bound_draw_framebuffer.get() {
|
||||||
let id = WebGLFramebufferBindingRequest::Explicit(fbo.id());
|
let id = WebGLFramebufferBindingRequest::Explicit(fbo.id());
|
||||||
self.send_command(WebGLCommand::BindFramebuffer(constants::FRAMEBUFFER, id));
|
self.send_command(WebGLCommand::BindFramebuffer(constants::FRAMEBUFFER, id));
|
||||||
}
|
}
|
||||||
|
@ -402,7 +406,7 @@ impl WebGLRenderingContext {
|
||||||
// The WebGL spec mentions a couple more operations that trigger
|
// The WebGL spec mentions a couple more operations that trigger
|
||||||
// this: clear() and getParameter(IMPLEMENTATION_COLOR_READ_*).
|
// this: clear() and getParameter(IMPLEMENTATION_COLOR_READ_*).
|
||||||
pub fn validate_framebuffer(&self) -> WebGLResult<()> {
|
pub fn validate_framebuffer(&self) -> WebGLResult<()> {
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_draw_framebuffer.get() {
|
||||||
Some(fb) => match fb.check_status_for_rendering() {
|
Some(fb) => match fb.check_status_for_rendering() {
|
||||||
CompleteForRendering::Complete => Ok(()),
|
CompleteForRendering::Complete => Ok(()),
|
||||||
CompleteForRendering::Incomplete => Err(InvalidFramebufferOperation),
|
CompleteForRendering::Incomplete => Err(InvalidFramebufferOperation),
|
||||||
|
@ -478,7 +482,7 @@ impl WebGLRenderingContext {
|
||||||
|
|
||||||
fn mark_as_dirty(&self) {
|
fn mark_as_dirty(&self) {
|
||||||
// If we have a bound framebuffer, then don't mark the canvas as dirty.
|
// If we have a bound framebuffer, then don't mark the canvas as dirty.
|
||||||
if self.bound_framebuffer.get().is_some() {
|
if self.bound_draw_framebuffer.get().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +507,7 @@ impl WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_framebuffer_size(&self) -> Option<(i32, i32)> {
|
pub fn get_current_framebuffer_size(&self) -> Option<(i32, i32)> {
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_draw_framebuffer.get() {
|
||||||
Some(fb) => return fb.size(),
|
Some(fb) => return fb.size(),
|
||||||
|
|
||||||
// The window system framebuffer is bound
|
// The window system framebuffer is bound
|
||||||
|
@ -757,7 +761,7 @@ impl WebGLRenderingContext {
|
||||||
data: pixels.data.into(),
|
data: pixels.data.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(fb) = self.bound_framebuffer.get() {
|
if let Some(fb) = self.bound_draw_framebuffer.get() {
|
||||||
fb.invalidate_texture(&*texture);
|
fb.invalidate_texture(&*texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1124,10 +1128,6 @@ impl WebGLRenderingContext {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bound_framebuffer(&self) -> Option<DomRoot<WebGLFramebuffer>> {
|
|
||||||
self.bound_framebuffer.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extension_manager(&self) -> &WebGLExtensions {
|
pub fn extension_manager(&self) -> &WebGLExtensions {
|
||||||
&self.extension_manager
|
&self.extension_manager
|
||||||
}
|
}
|
||||||
|
@ -1341,6 +1341,50 @@ impl WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
self.uniform_vec_section::<f32>(vec, offset, length, uniform_size, uniform_location)
|
self.uniform_vec_section::<f32>(vec, offset, length, uniform_size, uniform_location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_draw_framebuffer_slot(&self) -> &MutNullableDom<WebGLFramebuffer> {
|
||||||
|
&self.bound_draw_framebuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_read_framebuffer_slot(&self) -> &MutNullableDom<WebGLFramebuffer> {
|
||||||
|
&self.bound_read_framebuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate_new_framebuffer_binding(
|
||||||
|
&self,
|
||||||
|
framebuffer: Option<&WebGLFramebuffer>,
|
||||||
|
) -> WebGLResult<()> {
|
||||||
|
if let Some(fb) = framebuffer {
|
||||||
|
self.validate_ownership(fb)?;
|
||||||
|
if fb.is_deleted() {
|
||||||
|
// From the WebGL spec:
|
||||||
|
//
|
||||||
|
// "An attempt to bind a deleted framebuffer will
|
||||||
|
// generate an INVALID_OPERATION error, and the
|
||||||
|
// current binding will remain untouched."
|
||||||
|
return Err(InvalidOperation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_framebuffer_to(
|
||||||
|
&self,
|
||||||
|
target: u32,
|
||||||
|
framebuffer: Option<&WebGLFramebuffer>,
|
||||||
|
slot: &MutNullableDom<WebGLFramebuffer>,
|
||||||
|
) {
|
||||||
|
match framebuffer {
|
||||||
|
Some(framebuffer) => framebuffer.bind(target),
|
||||||
|
None => {
|
||||||
|
// Bind the default framebuffer
|
||||||
|
let cmd =
|
||||||
|
WebGLCommand::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
|
||||||
|
self.send_command(cmd);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
slot.set(framebuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "webgl_backtrace"))]
|
#[cfg(not(feature = "webgl_backtrace"))]
|
||||||
|
@ -1442,7 +1486,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return optional_root_object_to_js_or_null!(*cx, buffer);
|
return optional_root_object_to_js_or_null!(*cx, buffer);
|
||||||
},
|
},
|
||||||
constants::FRAMEBUFFER_BINDING => unsafe {
|
constants::FRAMEBUFFER_BINDING => unsafe {
|
||||||
return optional_root_object_to_js_or_null!(*cx, &self.bound_framebuffer.get());
|
return optional_root_object_to_js_or_null!(
|
||||||
|
*cx,
|
||||||
|
&self.bound_draw_framebuffer.get()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
constants::RENDERBUFFER_BINDING => unsafe {
|
constants::RENDERBUFFER_BINDING => unsafe {
|
||||||
return optional_root_object_to_js_or_null!(*cx, &self.bound_renderbuffer.get());
|
return optional_root_object_to_js_or_null!(*cx, &self.bound_renderbuffer.get());
|
||||||
|
@ -1845,33 +1892,17 @@ 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 let Some(fb) = framebuffer {
|
handle_potential_webgl_error!(
|
||||||
handle_potential_webgl_error!(self, self.validate_ownership(fb), return);
|
self,
|
||||||
}
|
self.validate_new_framebuffer_binding(framebuffer),
|
||||||
|
return
|
||||||
|
);
|
||||||
|
|
||||||
if target != constants::FRAMEBUFFER {
|
if target != constants::FRAMEBUFFER {
|
||||||
return self.webgl_error(InvalidEnum);
|
return self.webgl_error(InvalidEnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(framebuffer) = framebuffer {
|
self.bind_framebuffer_to(target, framebuffer, &self.bound_draw_framebuffer)
|
||||||
if framebuffer.is_deleted() {
|
|
||||||
// From the WebGL spec:
|
|
||||||
//
|
|
||||||
// "An attempt to bind a deleted framebuffer will
|
|
||||||
// generate an INVALID_OPERATION error, and the
|
|
||||||
// current binding will remain untouched."
|
|
||||||
return self.webgl_error(InvalidOperation);
|
|
||||||
} else {
|
|
||||||
framebuffer.bind(target);
|
|
||||||
self.bound_framebuffer.set(Some(framebuffer));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Bind the default framebuffer
|
|
||||||
let cmd =
|
|
||||||
WebGLCommand::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
|
|
||||||
self.send_command(cmd);
|
|
||||||
self.bound_framebuffer.set(framebuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
||||||
|
@ -2009,7 +2040,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
data: pixels.data.into(),
|
data: pixels.data.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(fb) = self.bound_framebuffer.get() {
|
if let Some(fb) = self.bound_draw_framebuffer.get() {
|
||||||
fb.invalidate_texture(&*texture);
|
fb.invalidate_texture(&*texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2100,7 +2131,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let framebuffer_format = match self.bound_framebuffer.get() {
|
let framebuffer_format = match self.bound_draw_framebuffer.get() {
|
||||||
Some(fb) => match fb.attachment(constants::COLOR_ATTACHMENT0) {
|
Some(fb) => match fb.attachment(constants::COLOR_ATTACHMENT0) {
|
||||||
Some(WebGLFramebufferAttachmentRoot::Renderbuffer(rb)) => {
|
Some(WebGLFramebufferAttachmentRoot::Renderbuffer(rb)) => {
|
||||||
TexFormat::from_gl_constant(rb.internal_format())
|
TexFormat::from_gl_constant(rb.internal_format())
|
||||||
|
@ -2419,10 +2450,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
handle_potential_webgl_error!(self, self.validate_ownership(framebuffer), return);
|
handle_potential_webgl_error!(self, self.validate_ownership(framebuffer), return);
|
||||||
handle_object_deletion!(
|
handle_object_deletion!(
|
||||||
self,
|
self,
|
||||||
self.bound_framebuffer,
|
self.bound_draw_framebuffer,
|
||||||
framebuffer,
|
framebuffer,
|
||||||
Some(WebGLCommand::BindFramebuffer(
|
Some(WebGLCommand::BindFramebuffer(
|
||||||
constants::FRAMEBUFFER,
|
framebuffer.target().unwrap(),
|
||||||
WebGLFramebufferBindingRequest::Default
|
WebGLFramebufferBindingRequest::Default
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -2575,7 +2606,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
pname: u32,
|
pname: u32,
|
||||||
) -> JSVal {
|
) -> JSVal {
|
||||||
// Check if currently bound framebuffer is non-zero as per spec.
|
// Check if currently bound framebuffer is non-zero as per spec.
|
||||||
if let Some(fb) = self.bound_framebuffer.get() {
|
if let Some(fb) = self.bound_draw_framebuffer.get() {
|
||||||
// Opaque framebuffers cannot have their attachments inspected
|
// Opaque framebuffers cannot have their attachments inspected
|
||||||
// https://immersive-web.github.io/webxr/#opaque-framebuffer
|
// https://immersive-web.github.io/webxr/#opaque-framebuffer
|
||||||
handle_potential_webgl_error!(self, fb.validate_transparent(), return NullValue());
|
handle_potential_webgl_error!(self, fb.validate_transparent(), return NullValue());
|
||||||
|
@ -2617,27 +2648,31 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bound_attachment_matches =
|
let bound_attachment_matches = match self
|
||||||
match self.bound_framebuffer.get().unwrap().attachment(attachment) {
|
.bound_draw_framebuffer
|
||||||
Some(attachment_root) => match attachment_root {
|
.get()
|
||||||
WebGLFramebufferAttachmentRoot::Renderbuffer(_) => match pname {
|
.unwrap()
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE |
|
.attachment(attachment)
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME => true,
|
{
|
||||||
_ => false,
|
Some(attachment_root) => match attachment_root {
|
||||||
},
|
WebGLFramebufferAttachmentRoot::Renderbuffer(_) => match pname {
|
||||||
WebGLFramebufferAttachmentRoot::Texture(_) => match pname {
|
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE |
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE |
|
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME => true,
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME |
|
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL |
|
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
_ => match pname {
|
|
||||||
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
};
|
WebGLFramebufferAttachmentRoot::Texture(_) => match pname {
|
||||||
|
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE |
|
||||||
|
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME |
|
||||||
|
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL |
|
||||||
|
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_ => match pname {
|
||||||
|
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
if !target_matches || !attachment_matches || !pname_matches || !bound_attachment_matches {
|
if !target_matches || !attachment_matches || !pname_matches || !bound_attachment_matches {
|
||||||
self.webgl_error(InvalidEnum);
|
self.webgl_error(InvalidEnum);
|
||||||
|
@ -2653,7 +2688,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME {
|
if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME {
|
||||||
// if fb is None, an INVALID_OPERATION is returned
|
// if fb is None, an INVALID_OPERATION is returned
|
||||||
// at the beggining of the function, so `.unwrap()` will never panic
|
// at the beggining of the function, so `.unwrap()` will never panic
|
||||||
let fb = self.bound_framebuffer.get().unwrap();
|
let fb = self.bound_draw_framebuffer.get().unwrap();
|
||||||
if let Some(webgl_attachment) = fb.attachment(attachment) {
|
if let Some(webgl_attachment) = fb.attachment(attachment) {
|
||||||
match webgl_attachment {
|
match webgl_attachment {
|
||||||
WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => unsafe {
|
WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => unsafe {
|
||||||
|
@ -4158,7 +4193,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_draw_framebuffer.get() {
|
||||||
Some(fb) => return fb.check_status(),
|
Some(fb) => return fb.check_status(),
|
||||||
None => return constants::FRAMEBUFFER_COMPLETE,
|
None => return constants::FRAMEBUFFER_COMPLETE,
|
||||||
}
|
}
|
||||||
|
@ -4185,7 +4220,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
self,
|
self,
|
||||||
rb.storage(self.api_type, internal_format, width, height)
|
rb.storage(self.api_type, internal_format, width, height)
|
||||||
);
|
);
|
||||||
if let Some(fb) = self.bound_framebuffer.get() {
|
if let Some(fb) = self.bound_draw_framebuffer.get() {
|
||||||
fb.invalidate_renderbuffer(&*rb);
|
fb.invalidate_renderbuffer(&*rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4208,7 +4243,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return self.webgl_error(InvalidEnum);
|
return self.webgl_error(InvalidEnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_draw_framebuffer.get() {
|
||||||
Some(fb) => handle_potential_webgl_error!(self, fb.renderbuffer(attachment, rb)),
|
Some(fb) => handle_potential_webgl_error!(self, fb.renderbuffer(attachment, rb)),
|
||||||
None => self.webgl_error(InvalidOperation),
|
None => self.webgl_error(InvalidOperation),
|
||||||
};
|
};
|
||||||
|
@ -4231,7 +4266,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return self.webgl_error(InvalidEnum);
|
return self.webgl_error(InvalidEnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.bound_framebuffer.get() {
|
match self.bound_draw_framebuffer.get() {
|
||||||
Some(fb) => handle_potential_webgl_error!(
|
Some(fb) => handle_potential_webgl_error!(
|
||||||
self,
|
self,
|
||||||
fb.texture2d(attachment, textarget, texture, level)
|
fb.texture2d(attachment, textarget, texture, level)
|
||||||
|
|
|
@ -197,15 +197,17 @@ impl WebGLTexture {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If a texture object is deleted while its image is attached to the currently
|
If a texture object is deleted while its image is attached to one or more attachment
|
||||||
bound framebuffer, then it is as if FramebufferTexture2D had been called, with
|
points in a currently bound framebuffer, then it is as if FramebufferTexture had been
|
||||||
a texture of 0, for each attachment point to which this image was attached
|
called, with a texture of zero, for each attachment point to which this im-age was
|
||||||
in the currently bound framebuffer.
|
attached in that framebuffer. In other words, this texture image is firstdetached from
|
||||||
- GLES 2.0, 4.4.3, "Attaching Texture Images to a Framebuffer"
|
all attachment points in a currently bound framebuffer.
|
||||||
*/
|
- GLES 3.0, 4.4.2.3, "Attaching Texture Images to a Framebuffer"
|
||||||
let currently_bound_framebuffer =
|
*/
|
||||||
self.upcast::<WebGLObject>().context().bound_framebuffer();
|
if let Some(fb) = context.get_draw_framebuffer_slot().get() {
|
||||||
if let Some(fb) = currently_bound_framebuffer {
|
let _ = fb.detach_texture(self);
|
||||||
|
}
|
||||||
|
if let Some(fb) = context.get_read_framebuffer_slot().get() {
|
||||||
let _ = fb.detach_texture(self);
|
let _ = fb.detach_texture(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,6 @@
|
||||||
[WebGL test #11: getError expected: NO_ERROR. Was INVALID_ENUM : checkFramebufferStatus(READ_FRAMEBUFFER).]
|
[WebGL test #11: getError expected: NO_ERROR. Was INVALID_ENUM : checkFramebufferStatus(READ_FRAMEBUFFER).]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[WebGL test #10: checkFramebufferStatus(READ_FRAMEBUFFER) should succeed.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #27: getError expected: NO_ERROR. Was INVALID_OPERATION : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
|
[WebGL test #27: getError expected: NO_ERROR. Was INVALID_OPERATION : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -80,9 +77,6 @@
|
||||||
[WebGL test #56: getError expected: NO_ERROR. Was INVALID_ENUM : bind draw framebuffer to default (null) framebuffer.]
|
[WebGL test #56: getError expected: NO_ERROR. Was INVALID_ENUM : bind draw framebuffer to default (null) framebuffer.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[WebGL test #13: bindFramebuffer(READ_FRAMEBUFFER) should change READ_FRAMEBUFFER_BINDING.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[WebGL test #12: getError expected: NO_ERROR. Was INVALID_ENUM : bindFramebuffer(READ_FRAMEBUFFER).]
|
[WebGL test #12: getError expected: NO_ERROR. Was INVALID_ENUM : bindFramebuffer(READ_FRAMEBUFFER).]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -167,3 +161,36 @@
|
||||||
[WebGL test #28: getError expected: NO_ERROR. Was INVALID_ENUM : attach a texture to read/draw framebuffer binding point.]
|
[WebGL test #28: getError expected: NO_ERROR. Was INVALID_ENUM : attach a texture to read/draw framebuffer binding point.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #33: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #42: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #46: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #53: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) on draw framebuffer without color attachment.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #29: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #43: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #34: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #47: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #39: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on draw framebuffer.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #56: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) on draw framebuffer with no attachment.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[WebGL test #30: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue