Title: [278295] trunk/Source/WebCore
Revision
278295
Author
[email protected]
Date
2021-05-31 21:52:51 -0700 (Mon, 31 May 2021)

Log Message

[WebXR] Attach IOSurface to WebXROpaqueFramebuffer
https://bugs.webkit.org/show_bug.cgi?id=225896
<rdar://problem/78128289>

Reviewed by Sam Weinig.

Implement binding of incoming IOSurfaces (via FrameData)
into the WebGL framebuffer that the page will use as
a rendering target.

Currently only single-sample (non-antialiased) buffers
are supported and the canvas context must be WebGL 2.

* Modules/webxr/WebXROpaqueFramebuffer.cpp:
(WebCore::WebXROpaqueFramebuffer::startFrame): Create a texture if necessary, then
bind its backing store to the incoming IOSurface, then hook it up to the framebuffer.
(WebCore::WebXROpaqueFramebuffer::endFrame): Release the Pbuffer we used in startFrame.
(WebCore::WebXROpaqueFramebuffer::setupFramebuffer): Add Cocoa+ANGLE specific implementation.
* Modules/webxr/WebXROpaqueFramebuffer.h: Keep a member variable for the Pbuffer.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (278294 => 278295)


--- trunk/Source/WebCore/ChangeLog	2021-06-01 04:31:04 UTC (rev 278294)
+++ trunk/Source/WebCore/ChangeLog	2021-06-01 04:52:51 UTC (rev 278295)
@@ -1,3 +1,25 @@
+2021-05-31  Dean Jackson  <[email protected]>
+
+        [WebXR] Attach IOSurface to WebXROpaqueFramebuffer
+        https://bugs.webkit.org/show_bug.cgi?id=225896
+        <rdar://problem/78128289>
+
+        Reviewed by Sam Weinig.
+
+        Implement binding of incoming IOSurfaces (via FrameData)
+        into the WebGL framebuffer that the page will use as
+        a rendering target.
+
+        Currently only single-sample (non-antialiased) buffers
+        are supported and the canvas context must be WebGL 2.
+
+        * Modules/webxr/WebXROpaqueFramebuffer.cpp:
+        (WebCore::WebXROpaqueFramebuffer::startFrame): Create a texture if necessary, then
+        bind its backing store to the incoming IOSurface, then hook it up to the framebuffer.
+        (WebCore::WebXROpaqueFramebuffer::endFrame): Release the Pbuffer we used in startFrame.
+        (WebCore::WebXROpaqueFramebuffer::setupFramebuffer): Add Cocoa+ANGLE specific implementation.
+        * Modules/webxr/WebXROpaqueFramebuffer.h: Keep a member variable for the Pbuffer.
+
 2021-05-31  Alan Bujtas  <[email protected]>
 
         [LFC][TFC] Decouple stretching and final cell layouts

Modified: trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp (278294 => 278295)


--- trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp	2021-06-01 04:31:04 UTC (rev 278294)
+++ trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp	2021-06-01 04:52:51 UTC (rev 278295)
@@ -50,6 +50,11 @@
 #include "WebGLRenderingContextBase.h"
 #include <wtf/Scope.h>
 
+#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
+#include "ANGLEHeaders.h"
+#include "GraphicsContextGLOpenGL.h"
+#endif
+
 namespace WebCore {
 
 using GL = GraphicsContextGL;
@@ -111,10 +116,41 @@
     // the textures/renderbuffers.
 
 #if USE(IOSURFACE_FOR_XR_LAYER_DATA)
-    UNUSED_PARAM(data);
+    auto gCGL = static_cast<GraphicsContextGLOpenGL*>(m_context.graphicsContextGL());
+    GCGLenum textureTarget = GraphicsContextGLOpenGL::drawingBufferTextureTarget();
+
+    auto size = data.surface->size();
+
+    if (!m_opaqueTexture)
+        m_opaqueTexture = gCGL->createTexture();
+
+    gCGL->bindTexture(textureTarget, m_opaqueTexture);
+    gCGL->texParameteri(textureTarget, GL::TEXTURE_MAG_FILTER, GL::LINEAR);
+    gCGL->texParameteri(textureTarget, GL::TEXTURE_MIN_FILTER, GL::LINEAR);
+    gCGL->texParameteri(textureTarget, GL::TEXTURE_WRAP_S, GL::CLAMP_TO_EDGE);
+    gCGL->texParameteri(textureTarget, GL::TEXTURE_WRAP_T, GL::CLAMP_TO_EDGE);
+
+    // Tell the GraphicsContextGL to use the IOSurface as the backing store for m_opaqueTexture.
+    m_ioSurfaceTextureHandle = gCGL->createPbufferAndAttachIOSurface(textureTarget, GraphicsContextGLOpenGL::PbufferAttachmentUsage::Write, GL::BGRA, size.width(), size.height(), GL::UNSIGNED_BYTE, data.surface->surface(), 0);
+    if (!m_ioSurfaceTextureHandle && m_opaqueTexture) {
+        gCGL->deleteTexture(m_opaqueTexture);
+        return;
+    }
+
+    // FIXME: This is assuming multisampling is turned off and we're rendering directly into the framebuffer.
+
+    // Now set up the framebuffer to use the textures/renderbuffers we have created.
+    gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::TEXTURE_2D, m_opaqueTexture, 0);
+
+    if (m_attributes.stencil)
+        gl.framebufferRenderbuffer(GL::FRAMEBUFFER, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, m_depthStencilBuffer);
+    if (m_attributes.depth)
+        gl.framebufferRenderbuffer(GL::FRAMEBUFFER, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, m_depthStencilBuffer);
+
+    // At this point the framebuffer should be "complete".
+    ASSERT(gl.checkFramebufferStatus(GL::FRAMEBUFFER) == GL::FRAMEBUFFER_COMPLETE);
 #else
     m_opaqueTexture = data.opaqueTexture;
-#endif
 
 #if USE(OPENGL_ES)
     auto& extensions = reinterpret_cast<ExtensionsGLOpenGLES&>(gl.getExtensions());
@@ -126,6 +162,7 @@
 
     if (!m_multisampleColorBuffer)
         gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::TEXTURE_2D, m_opaqueTexture, 0);
+#endif
 }
 
 void WebXROpaqueFramebuffer::endFrame()
@@ -134,8 +171,22 @@
 
     if (!m_context.graphicsContextGL())
         return;
+
     auto& gl = *m_context.graphicsContextGL();
 
+#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
+    // FIXME: We have to call finish rather than flush because we only want to disconnect
+    // the IOSurface and signal the DeviceProxy when we know the content has been rendered.
+    // It might be possible to set this up so the completion of the rendering triggers
+    // the endFrame call.
+    gl.finish();
+
+    if (m_ioSurfaceTextureHandle) {
+        auto gCGL = static_cast<GraphicsContextGLOpenGL*>(&gl);
+        gCGL->destroyPbufferAndDetachIOSurface(m_ioSurfaceTextureHandle);
+    }
+#else
+
     if (m_multisampleColorBuffer) {
 #if !USE(ANGLE)
         // FIXME: These may be needed when using ANGLE, but it didn't compile in the initial implementation.
@@ -162,8 +213,9 @@
         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::LINEAR);
     }
-    
+
     gl.flush();
+#endif
 }
 
 bool WebXROpaqueFramebuffer::setupFramebuffer()
@@ -184,7 +236,7 @@
 
     // Set up color, depth and stencil formats
     bool useDepthStencil = m_attributes.stencil || m_attributes.depth;
-    auto colorFormat = m_attributes.alpha ? GraphicsContextGL::RGBA8 : GraphicsContextGL::RGB8;
+    auto colorFormat = m_attributes.alpha ? GL::RGBA8 : GL::RGB8;
 #if USE(OPENGL_ES)
     auto& extensions = reinterpret_cast<ExtensionsGLOpenGLES&>(gl.getExtensions());
     bool supportsPackedDepthStencil = useDepthStencil && extensions.supports("GL_OES_packed_depth_stencil");
@@ -191,9 +243,7 @@
     auto depthFormat = supportsPackedDepthStencil ? GL::DEPTH24_STENCIL8 : GL::DEPTH_COMPONENT16;
     auto stencilFormat = GL::STENCIL_INDEX8;
 #elif USE(ANGLE)
-    // FIXME: These values were chosen just to get this to compile successfully.
-    // Make sure they are correct.
-    bool supportsPackedDepthStencil = false;
+    bool supportsPackedDepthStencil = true;
     auto depthFormat = supportsPackedDepthStencil ? GL::DEPTH24_STENCIL8 : GL::DEPTH_COMPONENT;
     auto stencilFormat = GL::STENCIL_INDEX8;
 #else
@@ -208,12 +258,11 @@
     if (m_attributes.antialias) {
         GCGLint maxSampleCount;
 #if USE(ANGLE)
-        // FIXME: This probably is not correct.
-        maxSampleCount = 0;
+        gl.getIntegerv(GL::MAX_SAMPLES, makeGCGLSpan(&maxSampleCount, 1));
 #else
         gl.getIntegerv(ExtensionsGL::MAX_SAMPLES, makeGCGLSpan(&maxSampleCount, 1));
 #endif
-        // Using more than 4 samples might be overhead.
+        // Cap the maxiumum multisample count at 4. Any more than this is likely overkill and will impact performance.
         m_sampleCount = std::min(4, maxSampleCount);
     }
 
@@ -251,7 +300,6 @@
 #endif // USE(OPENGL_ES)
 
     if (m_attributes.antialias && m_context.isWebGL2()) {
-        // Use an extra FBO for multisample if multisampled_render_to_texture is not supported.
         m_resolvedFBO = gl.createFramebuffer();
         m_multisampleColorBuffer = gl.createRenderbuffer();
         gl.bindFramebuffer(GL::FRAMEBUFFER, m_framebuffer->object());

Modified: trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h (278294 => 278295)


--- trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h	2021-06-01 04:31:04 UTC (rev 278294)
+++ trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h	2021-06-01 04:52:51 UTC (rev 278295)
@@ -77,6 +77,9 @@
     PlatformGLObject m_resolvedFBO { 0 };
     GCGLint m_sampleCount { 0 };
     PlatformGLObject m_opaqueTexture { 0 };
+#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
+    void* m_ioSurfaceTextureHandle { nullptr };
+#endif
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to