Title: [285544] trunk/Source/WebCore
Revision
285544
Author
d...@apple.com
Date
2021-11-09 16:45:46 -0800 (Tue, 09 Nov 2021)

Log Message

[WebXR] three.js demos don't work
https://bugs.webkit.org/show_bug.cgi?id=232798
rdar://83559881

Reviewed by Myles C. Maxfield.

Any content using three.js for WebXR was failing for
a couple of reasons. Firstly, we were not correctly
restoring the framebuffer, read, draw and texture
bindings in the native code, and three.js was correctly
assuming it didn't need to rebind.

Secondly, we were not resolving the multisample
framebuffer if the context was created with no alpha.
The issue is that our framebuffer from XR always has
an alpha channel, and you can't blit from RGB to RGBA.

* Modules/webxr/WebXROpaqueFramebuffer.cpp:
(WebCore::WebXROpaqueFramebuffer::startFrame): Make sure to restore the
bound texture target when exiting the function. Also ensure that we
tell the resolved FBO where its texture data comes from.
(WebCore::WebXROpaqueFramebuffer::endFrame): Restore the framebuffer binding.
(WebCore::WebXROpaqueFramebuffer::setupFramebuffer): Use the correct format.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (285543 => 285544)


--- trunk/Source/WebCore/ChangeLog	2021-11-10 00:40:53 UTC (rev 285543)
+++ trunk/Source/WebCore/ChangeLog	2021-11-10 00:45:46 UTC (rev 285544)
@@ -1,3 +1,29 @@
+2021-11-09  Dean Jackson  <d...@apple.com>
+
+        [WebXR] three.js demos don't work
+        https://bugs.webkit.org/show_bug.cgi?id=232798
+        rdar://83559881
+
+        Reviewed by Myles C. Maxfield.
+
+        Any content using three.js for WebXR was failing for
+        a couple of reasons. Firstly, we were not correctly
+        restoring the framebuffer, read, draw and texture
+        bindings in the native code, and three.js was correctly
+        assuming it didn't need to rebind.
+
+        Secondly, we were not resolving the multisample
+        framebuffer if the context was created with no alpha.
+        The issue is that our framebuffer from XR always has
+        an alpha channel, and you can't blit from RGB to RGBA.
+
+        * Modules/webxr/WebXROpaqueFramebuffer.cpp:
+        (WebCore::WebXROpaqueFramebuffer::startFrame): Make sure to restore the
+        bound texture target when exiting the function. Also ensure that we
+        tell the resolved FBO where its texture data comes from.
+        (WebCore::WebXROpaqueFramebuffer::endFrame): Restore the framebuffer binding.
+        (WebCore::WebXROpaqueFramebuffer::setupFramebuffer): Use the correct format.
+
 2021-11-09  Said Abou-Hallawa  <s...@apple.com>
 
         [GPU Process] Introduce FilterFunction and make it the base class of Filter and FilterEffect

Modified: trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp (285543 => 285544)


--- trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp	2021-11-10 00:40:53 UTC (rev 285543)
+++ trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp	2021-11-10 00:45:46 UTC (rev 285544)
@@ -103,13 +103,25 @@
         return;
     auto& gl = *m_context.graphicsContextGL();
 
+#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
+    auto gCGL = static_cast<GraphicsContextGLOpenGL*>(m_context.graphicsContextGL());
+    GCGLenum textureTarget = gCGL->drawingBufferTextureTarget();
+    GCGLenum textureTargetBinding = gCGL->drawingBufferTextureTargetQueryForDrawingTarget(textureTarget);
+#else
+    GCGLenum textureTarget = GL::TEXTURE_2D;
+    GCGLenum textureTargetBinding = GL::TEXTURE_BINDING_2D;
+#endif
+
     m_framebuffer->setOpaqueActive(true);
 
     GCGLint boundFBO { 0 };
+    GCGLint boundTexture { 0 };
+    gl.getIntegerv(GL::FRAMEBUFFER_BINDING, makeGCGLSpan(&boundFBO, 1));
+    gl.getIntegerv(textureTargetBinding, makeGCGLSpan(&boundTexture, 1));
 
-    gl.getIntegerv(GL::FRAMEBUFFER_BINDING, makeGCGLSpan(&boundFBO, 1));
-    auto scopedFBOs = makeScopeExit([&gl, boundFBO]() {
+    auto scopedBindings = makeScopeExit([&gl, boundFBO, boundTexture, textureTarget]() {
         gl.bindFramebuffer(GL::FRAMEBUFFER, boundFBO);
+        gl.bindTexture(textureTarget, boundTexture);
     });
 
     gl.bindFramebuffer(GraphicsContextGL::FRAMEBUFFER, m_framebuffer->object());
@@ -122,9 +134,6 @@
 #if USE(IOSURFACE_FOR_XR_LAYER_DATA)
     ASSERT(data.surface);
 
-    auto gCGL = static_cast<GraphicsContextGLOpenGL*>(m_context.graphicsContextGL());
-    GCGLenum textureTarget = gCGL->drawingBufferTextureTarget();
-
     if (!m_opaqueTexture)
         m_opaqueTexture = gCGL->createTexture();
 
@@ -156,11 +165,12 @@
         return;
     }
 
-    // If we're not multisampling, set up the framebuffer to use the texture that points to the IOSurface. The depth and
-    // stencil buffers were attached by setupFramebuffer. If we are multisampling, the framebuffer was initialized in setupFramebuffer,
-    // and we'll resolve into the m_opaqueTexture in endFrame.
-    if (!m_multisampleColorBuffer)
-        gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::TEXTURE_2D, m_opaqueTexture, 0);
+    // Set up the framebuffer to use the texture that points to the IOSurface. If we're not multisampling,
+    // the target framebuffer is m_framebuffer->object() (bound above). If we are multisampling, the target
+    // is the resolved framebuffer we created in setupFramebuffer.
+    if (m_multisampleColorBuffer)
+        gl.bindFramebuffer(GL::FRAMEBUFFER, m_resolvedFBO);
+    gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, textureTarget, m_opaqueTexture, 0);
 
     // At this point the framebuffer should be "complete".
     ASSERT(gl.checkFramebufferStatus(GL::FRAMEBUFFER) == GL::FRAMEBUFFER_COMPLETE);
@@ -199,20 +209,21 @@
         TemporaryOpenGLSetting scopedStencil(GL::STENCIL_TEST, 0);
 #endif
 
+        GCGLint boundFBO { 0 };
         GCGLint boundReadFBO { 0 };
         GCGLint boundDrawFBO { 0 };
+        gl.getIntegerv(GL::FRAMEBUFFER_BINDING, makeGCGLSpan(&boundFBO, 1));
         gl.getIntegerv(GL::READ_FRAMEBUFFER_BINDING, makeGCGLSpan(&boundReadFBO, 1));
         gl.getIntegerv(GL::DRAW_FRAMEBUFFER_BINDING, makeGCGLSpan(&boundDrawFBO, 1));
 
-        auto scopedFBOs = makeScopeExit([&gl, boundReadFBO, boundDrawFBO]() {
+        auto scopedBindings = makeScopeExit([&gl, boundFBO, boundReadFBO, boundDrawFBO]() {
+            gl.bindFramebuffer(GL::FRAMEBUFFER, boundFBO);
             gl.bindFramebuffer(GL::READ_FRAMEBUFFER, boundReadFBO);
             gl.bindFramebuffer(GL::DRAW_FRAMEBUFFER, boundDrawFBO);
         });
 
+        gl.bindFramebuffer(GL::READ_FRAMEBUFFER, m_framebuffer->object());
         gl.bindFramebuffer(GL::DRAW_FRAMEBUFFER, m_resolvedFBO);
-        gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::TEXTURE_2D, m_opaqueTexture, 0);
-
-        gl.bindFramebuffer(GL::READ_FRAMEBUFFER, m_framebuffer->object());
         gl.blitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL::COLOR_BUFFER_BIT, GL::NEAREST);
     }
 
@@ -245,12 +256,13 @@
         return false;
     auto& gl = *m_context.graphicsContextGL();
 
-    // Bind current FBOs when exiting the function
+    // Restore bindings when exiting the function.
     GCGLint boundFBO { 0 };
     GCGLint boundRenderbuffer { 0 };
     gl.getIntegerv(GL::FRAMEBUFFER_BINDING, makeGCGLSpan(&boundFBO, 1));
     gl.getIntegerv(GL::RENDERBUFFER_BINDING, makeGCGLSpan(&boundRenderbuffer, 1));
-    auto scopedFBO = makeScopeExit([&gl, boundFBO, boundRenderbuffer]() {
+
+    auto scopedBindings = makeScopeExit([&gl, boundFBO, boundRenderbuffer]() {
         gl.bindFramebuffer(GL::FRAMEBUFFER, boundFBO);
         gl.bindRenderbuffer(GL::RENDERBUFFER, boundRenderbuffer);
     });
@@ -257,7 +269,6 @@
 
     // Set up color, depth and stencil formats
     bool hasDepthOrStencil = m_attributes.stencil || m_attributes.depth;
-    auto colorFormat = m_attributes.alpha ? GL::RGBA8 : GL::RGB8;
 #if USE(OPENGL_ES)
     auto& extensions = reinterpret_cast<ExtensionsGLOpenGLES&>(gl.getExtensions());
     bool platformSupportsPackedDepthStencil = hasDepthOrStencil && extensions.supports("GL_OES_packed_depth_stencil");
@@ -325,7 +336,7 @@
         m_multisampleColorBuffer = gl.createRenderbuffer();
         gl.bindFramebuffer(GL::FRAMEBUFFER, m_framebuffer->object());
         gl.bindRenderbuffer(GL::RENDERBUFFER, m_multisampleColorBuffer);
-        gl.renderbufferStorageMultisample(GL::RENDERBUFFER, m_sampleCount, colorFormat, m_width, m_height);
+        gl.renderbufferStorageMultisample(GL::RENDERBUFFER, m_sampleCount, GL::RGBA8, m_width, m_height);
         gl.framebufferRenderbuffer(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::RENDERBUFFER, m_multisampleColorBuffer);
         if (hasDepthOrStencil) {
             m_depthStencilBuffer = gl.createRenderbuffer();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to