mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #12934 - anholt:webgl-deletion-and-bindings, r=emilio
webgl: object deletion and bindings <!-- Please describe your changes on the following line: --> This PR brings in some fixes to the wpt object-deletion-and-behaviour.html testcase. The test still has many failures, but some of the things that were really getting in the way are fixed. --- <!-- 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 - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12934) <!-- Reviewable:end -->
This commit is contained in:
commit
969aefe01f
2 changed files with 70 additions and 79 deletions
|
@ -61,6 +61,38 @@ macro_rules! handle_potential_webgl_error {
|
|||
};
|
||||
}
|
||||
|
||||
// From the GLES 2.0.25 spec, page 85:
|
||||
//
|
||||
// "If a texture that is currently bound to one of the targets
|
||||
// TEXTURE_2D, or TEXTURE_CUBE_MAP is deleted, it is as though
|
||||
// BindTexture had been executed with the same target and texture
|
||||
// zero."
|
||||
//
|
||||
// and similar text occurs for other object types.
|
||||
macro_rules! handle_object_deletion {
|
||||
($binding:expr, $object:ident) => {
|
||||
if let Some(bound_object) = $binding.get() {
|
||||
if bound_object.id() == $object.id() {
|
||||
$binding.set(None);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! object_binding_to_js_or_null {
|
||||
($cx: expr, $binding:expr) => {
|
||||
{
|
||||
rooted!(in($cx) let mut rval = NullValue());
|
||||
if let Some(bound_object) = $binding.get() {
|
||||
unsafe {
|
||||
bound_object.to_jsval($cx, rval.handle_mut());
|
||||
}
|
||||
}
|
||||
rval.get()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Set of bitflags for texture unpacking (texImage2d, etc...)
|
||||
bitflags! {
|
||||
#[derive(HeapSizeOf, JSTraceable)]
|
||||
|
@ -83,6 +115,7 @@ pub struct WebGLRenderingContext {
|
|||
last_error: Cell<Option<WebGLError>>,
|
||||
texture_unpacking_settings: Cell<TextureUnpacking>,
|
||||
bound_framebuffer: MutNullableHeap<JS<WebGLFramebuffer>>,
|
||||
bound_renderbuffer: MutNullableHeap<JS<WebGLRenderbuffer>>,
|
||||
bound_texture_2d: MutNullableHeap<JS<WebGLTexture>>,
|
||||
bound_texture_cube_map: MutNullableHeap<JS<WebGLTexture>>,
|
||||
bound_buffer_array: MutNullableHeap<JS<WebGLBuffer>>,
|
||||
|
@ -117,6 +150,7 @@ impl WebGLRenderingContext {
|
|||
bound_texture_cube_map: MutNullableHeap::new(None),
|
||||
bound_buffer_array: MutNullableHeap::new(None),
|
||||
bound_buffer_element_array: MutNullableHeap::new(None),
|
||||
bound_renderbuffer: MutNullableHeap::new(None),
|
||||
current_program: MutNullableHeap::new(None),
|
||||
current_vertex_attrib_0: Cell::new((0f32, 0f32, 0f32, 1f32)),
|
||||
}
|
||||
|
@ -513,19 +547,22 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
#[allow(unsafe_code)]
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
|
||||
fn GetParameter(&self, cx: *mut JSContext, parameter: u32) -> JSVal {
|
||||
// Handle the GL_FRAMEBUFFER_BINDING without going all the way
|
||||
// Handle the GL_*_BINDING without going all the way
|
||||
// to the GL, since we would just need to map back from GL's
|
||||
// returned ID to the WebGLFramebuffer we're tracking.
|
||||
// returned ID to the WebGL* object we're tracking.
|
||||
match parameter {
|
||||
constants::FRAMEBUFFER_BINDING => {
|
||||
rooted!(in(cx) let mut rval = NullValue());
|
||||
if let Some(bound_fb) = self.bound_framebuffer.get() {
|
||||
unsafe {
|
||||
bound_fb.to_jsval(cx, rval.handle_mut());
|
||||
}
|
||||
}
|
||||
return rval.get()
|
||||
}
|
||||
constants::ARRAY_BUFFER_BINDING =>
|
||||
return object_binding_to_js_or_null!(cx, &self.bound_buffer_array),
|
||||
constants::ELEMENT_ARRAY_BUFFER_BINDING =>
|
||||
return object_binding_to_js_or_null!(cx, &self.bound_buffer_element_array),
|
||||
constants::FRAMEBUFFER_BINDING =>
|
||||
return object_binding_to_js_or_null!(cx, &self.bound_framebuffer),
|
||||
constants::RENDERBUFFER_BINDING =>
|
||||
return object_binding_to_js_or_null!(cx, &self.bound_renderbuffer),
|
||||
constants::TEXTURE_BINDING_2D =>
|
||||
return object_binding_to_js_or_null!(cx, &self.bound_texture_2d),
|
||||
constants::TEXTURE_BINDING_CUBE_MAP =>
|
||||
return object_binding_to_js_or_null!(cx, &self.bound_texture_cube_map),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -705,13 +742,19 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
return self.webgl_error(InvalidEnum);
|
||||
}
|
||||
|
||||
if let Some(renderbuffer) = renderbuffer {
|
||||
renderbuffer.bind(target)
|
||||
} else {
|
||||
// Unbind the currently bound renderbuffer
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::BindRenderbuffer(target, None)))
|
||||
.unwrap()
|
||||
match renderbuffer {
|
||||
// Implementations differ on what to do in the deleted
|
||||
// case: Chromium currently unbinds, and Gecko silently
|
||||
// returns. The conformance tests don't cover this case.
|
||||
Some(renderbuffer) if !renderbuffer.is_deleted() => {
|
||||
renderbuffer.bind(target)
|
||||
}
|
||||
_ => {
|
||||
// Unbind the currently bound renderbuffer
|
||||
self.ipc_renderer
|
||||
.send(CanvasMsg::WebGL(WebGLCommand::BindRenderbuffer(target, None)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,6 +1138,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
fn DeleteBuffer(&self, buffer: Option<&WebGLBuffer>) {
|
||||
if let Some(buffer) = buffer {
|
||||
handle_object_deletion!(self.bound_buffer_array, buffer);
|
||||
handle_object_deletion!(self.bound_buffer_element_array, buffer);
|
||||
buffer.delete()
|
||||
}
|
||||
}
|
||||
|
@ -1102,11 +1147,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
|
||||
fn DeleteFramebuffer(&self, framebuffer: Option<&WebGLFramebuffer>) {
|
||||
if let Some(framebuffer) = framebuffer {
|
||||
if let Some(bound_fb) = self.bound_framebuffer.get() {
|
||||
if bound_fb.id() == framebuffer.id() {
|
||||
self.bound_framebuffer.set(None);
|
||||
}
|
||||
}
|
||||
handle_object_deletion!(self.bound_framebuffer, framebuffer);
|
||||
framebuffer.delete()
|
||||
}
|
||||
}
|
||||
|
@ -1114,6 +1155,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
|
||||
fn DeleteRenderbuffer(&self, renderbuffer: Option<&WebGLRenderbuffer>) {
|
||||
if let Some(renderbuffer) = renderbuffer {
|
||||
handle_object_deletion!(self.bound_renderbuffer, renderbuffer);
|
||||
renderbuffer.delete()
|
||||
}
|
||||
}
|
||||
|
@ -1121,6 +1163,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
||||
fn DeleteTexture(&self, texture: Option<&WebGLTexture>) {
|
||||
if let Some(texture) = texture {
|
||||
handle_object_deletion!(self.bound_texture_2d, texture);
|
||||
handle_object_deletion!(self.bound_texture_cube_map, texture);
|
||||
texture.delete()
|
||||
}
|
||||
}
|
||||
|
@ -1128,6 +1172,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
|
||||
fn DeleteProgram(&self, program: Option<&WebGLProgram>) {
|
||||
if let Some(program) = program {
|
||||
handle_object_deletion!(self.current_program, program);
|
||||
program.delete()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
[WebGL test #21: gl.isShader(fragmentShader) should be false. Threw exception TypeError: gl.isShader is not a function]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #28: gl.getParameter(gl.TEXTURE_BINDING_2D) should be [object WebGLTexture\]. Was null.]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #29: gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) threw exception TypeError: gl.framebufferTexture2D is not a function]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -35,9 +32,6 @@
|
|||
[WebGL test #31: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) should be 5890. Threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #32: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteTexture(tex)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #33: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) should be 0. Threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -47,46 +41,13 @@
|
|||
[WebGL test #35: gl.isTexture(tex) should be false. Threw exception TypeError: gl.isTexture is not a function]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #37: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindTexture(gl.TEXTURE_2D, tex)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #40: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #41: gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP) should be [object WebGLTexture\]. Was null.]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #42: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteTexture(texCubeMap)]
|
||||
[WebGL test #37: getError expected: NO_ERROR. Was INVALID_OPERATION : after evaluating: gl.bindTexture(gl.TEXTURE_2D, tex)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #43: gl.isTexture(texCubeMap) should be false. Threw exception TypeError: gl.isTexture is not a function]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #45: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #48: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindTexture(gl.TEXTURE_2D, t)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #52: getError expected: INVALID_OPERATION. Was NO_ERROR : after evaluating: gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #56: gl.getParameter(gl.TEXTURE_BINDING_2D) should be [object WebGLTexture\]. Was null.]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #57: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.activeTexture(gl.TEXTURE1)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #59: gl.getParameter(gl.TEXTURE_BINDING_2D) should be [object WebGLTexture\]. Was null.]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #60: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteTexture(t2)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #62: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.activeTexture(gl.TEXTURE0)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #67: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)]
|
||||
[WebGL test #45: getError expected: NO_ERROR. Was INVALID_OPERATION : after evaluating: gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #68: gl.getParameter(gl.RENDERBUFFER_BINDING) should be [object WebGLRenderbuffer\]. Was null.]
|
||||
|
@ -98,9 +59,6 @@
|
|||
[WebGL test #70: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) should be [object WebGLRenderbuffer\]. Threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #71: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteRenderbuffer(rbo)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #72: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) should be 0. Threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -110,24 +68,12 @@
|
|||
[WebGL test #74: gl.isRenderbuffer(rbo) should be false. Threw exception TypeError: gl.isRenderbuffer is not a function]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #76: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #78: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #79: gl.getParameter(gl.RENDERBUFFER_BINDING) should be [object WebGLRenderbuffer\]. Was null.]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #80: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteRenderbuffer(rbo3)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #81: gl.getParameter(gl.RENDERBUFFER_BINDING) should be [object WebGLRenderbuffer\]. Was null.]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #82: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)]
|
||||
expected: FAIL
|
||||
|
||||
[WebGL test #83: gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) threw exception TypeError: gl.renderbufferStorage is not a function]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue