Commit a6a81c36 authored by Artem Bolgar's avatar Artem Bolgar Committed by Commit Bot

Fixing stencil buffer functionality in WebXR

WebXR is using so called 'opaque' framebuffer, i.e. all attachments are made on GL level and not visible by WebGL. When 'enable(gl.STENICL_TEST)' is called, the on WebGL context checks the WebGLFramebuffer object for presence of the STENCIL attachment and fails (because the opaque framebuffer doesn't have those).
I am adding an additional state to WebGLFramebuffer to track if the opaque framebuffer has the stencil buffer or not. Note, I can't check if the actual GL framebuffer object has the corresponding attachment, since the framebuffer might not be bound (yet).

The repro case: https://artyom17.github.io/webxr-samples/tests/stencil-cube-sea.html
In 2D mode you'll see that the green triangle has a cutout, while in VR mode it doesn't. This is because gl.enable(gl.STENCIL_TEST) is failing.

Bug: 1057571
Change-Id: I8b94a60de8c14ac7e435f17e57523ec430f22fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2084067Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Commit-Queue: Artem Bolgar <artyom@fb.com>
Cr-Commit-Position: refs/heads/master@{#747074}
parent 46f965b9
......@@ -183,9 +183,12 @@ void WebGLTextureAttachment::Unattach(gpu::gles2::GLES2Interface* gl,
WebGLFramebuffer::WebGLAttachment::WebGLAttachment() = default;
WebGLFramebuffer* WebGLFramebuffer::CreateOpaque(
WebGLRenderingContextBase* ctx) {
return MakeGarbageCollected<WebGLFramebuffer>(ctx, true);
WebGLFramebuffer* WebGLFramebuffer::CreateOpaque(WebGLRenderingContextBase* ctx,
bool has_stencil) {
WebGLFramebuffer* const fb =
MakeGarbageCollected<WebGLFramebuffer>(ctx, true);
fb->SetOpaqueHasStencil(has_stencil);
return fb;
}
WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx, bool opaque)
......@@ -366,10 +369,14 @@ GLenum WebGLFramebuffer::CheckDepthStencilStatus(const char** reason) const {
}
bool WebGLFramebuffer::HasStencilBuffer() const {
WebGLAttachment* attachment = GetAttachment(GL_STENCIL_ATTACHMENT);
if (!attachment)
attachment = GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT);
return attachment && attachment->Valid();
if (opaque_) {
return opaque_has_stencil_;
} else {
WebGLAttachment* attachment = GetAttachment(GL_STENCIL_ATTACHMENT);
if (!attachment)
attachment = GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT);
return attachment && attachment->Valid();
}
}
void WebGLFramebuffer::DeleteObjectImpl(gpu::gles2::GLES2Interface* gl) {
......
......@@ -71,7 +71,8 @@ class WebGLFramebuffer final : public WebGLContextObject {
// An opaque framebuffer is one whose attachments are created and managed by
// the browser and not inspectable or alterable via Javascript. This is
// primarily used by the VRWebGLLayer interface.
static WebGLFramebuffer* CreateOpaque(WebGLRenderingContextBase*);
static WebGLFramebuffer* CreateOpaque(WebGLRenderingContextBase*,
bool has_stencil);
GLuint Object() const { return object_; }
......@@ -108,6 +109,9 @@ class WebGLFramebuffer final : public WebGLContextObject {
bool Opaque() const { return opaque_; }
void MarkOpaqueBufferComplete(bool complete) { opaque_complete_ = complete; }
void SetOpaqueHasStencil(bool has_stencil) {
opaque_has_stencil_ = has_stencil;
}
// Wrapper for drawBuffersEXT/drawBuffersARB to work around a driver bug.
void DrawBuffers(const Vector<GLenum>& bufs);
......@@ -160,6 +164,7 @@ class WebGLFramebuffer final : public WebGLContextObject {
bool web_gl1_depth_stencil_consistent_;
bool contents_changed_ = false;
const bool opaque_;
bool opaque_has_stencil_ = false;
bool opaque_complete_ = false;
Vector<GLenum> draw_buffers_;
......
......@@ -122,7 +122,8 @@ XRWebGLLayer* XRWebGLLayer::Create(
framebuffers_size.Height() * framebuffer_scale);
// Create an opaque WebGL Framebuffer
WebGLFramebuffer* framebuffer = WebGLFramebuffer::CreateOpaque(webgl_context);
WebGLFramebuffer* framebuffer =
WebGLFramebuffer::CreateOpaque(webgl_context, want_stencil_buffer);
scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer =
XRWebGLDrawingBuffer::Create(webgl_context->GetDrawingBuffer(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment