Diff
Modified: trunk/Source/WebCore/ChangeLog (279297 => 279298)
--- trunk/Source/WebCore/ChangeLog 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/ChangeLog 2021-06-25 22:06:49 UTC (rev 279298)
@@ -1,3 +1,32 @@
+2021-06-22 Dean Jackson <[email protected]>
+
+ Add support for MTLSharedTextures in WebXR
+ https://bugs.webkit.org/show_bug.cgi?id=227245
+ <rdar://problem/79591620>
+
+ Reviewed by Tim Horton.
+
+ Sometimes, the IOSurface passed to WebXR come from a shared MTLTexture. In
+ this case we can't treat the IOSurface data as a regular single-plane
+ image. Instead we should use it to recreate the MTLTexture and then
+ bind that to WebGL's framebuffer.
+
+ * Modules/webxr/WebXROpaqueFramebuffer.cpp: Use some new binding methods on GraphicsContextGLOpenGL
+ if given a shared texture.
+ (WebCore::WebXROpaqueFramebuffer::startFrame):
+ (WebCore::WebXROpaqueFramebuffer::endFrame):
+ * Modules/webxr/WebXROpaqueFramebuffer.h:
+ * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm: New methods to link an
+ IOSurface to a GL texture, going through a MTLSharedTexture.
+ (WebCore::GraphicsContextGLOpenGL::attachIOSurfaceToSharedTexture):
+ (WebCore::GraphicsContextGLOpenGL::detachIOSurfaceFromSharedTexture):
+ * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
+ * platform/xr/PlatformXR.h: Add a new "isShared" member to LayerData
+ to differentiate between normal IOSurfaces and those that came
+ from a shared texture.
+ (PlatformXR::Device::FrameData::LayerData::encode const):
+ (PlatformXR::Device::FrameData::LayerData::decode):
+
2021-06-25 Alex Christensen <[email protected]>
Fix null crash in AudioMediaStreamTrackRendererCocoa::start
Modified: trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp (279297 => 279298)
--- trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp 2021-06-25 22:06:49 UTC (rev 279298)
@@ -125,9 +125,6 @@
auto gCGL = static_cast<GraphicsContextGLOpenGL*>(m_context.graphicsContextGL());
GCGLenum textureTarget = GraphicsContextGLOpenGL::drawingBufferTextureTarget();
- auto size = data.surface->size();
- if (!size.width() || !size.height())
- return;
if (!m_opaqueTexture)
m_opaqueTexture = gCGL->createTexture();
@@ -139,18 +136,29 @@
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) {
+ if (data.isShared) {
+ m_ioSurfaceTextureHandle = gCGL->attachIOSurfaceToSharedTexture(textureTarget, data.surface.get());
+ m_ioSurfaceTextureHandleIsShared = true;
+ } else {
+ auto size = data.surface->size();
+ if (!size.width() || !size.height())
+ return;
+ m_ioSurfaceTextureHandle = gCGL->createPbufferAndAttachIOSurface(textureTarget, GraphicsContextGLOpenGL::PbufferAttachmentUsage::Write, GL::BGRA, size.width(), size.height(), GL::UNSIGNED_BYTE, data.surface->surface(), 0);
+ m_ioSurfaceTextureHandleIsShared = false;
+ }
+
+ if (!m_ioSurfaceTextureHandle) {
gCGL->deleteTexture(m_opaqueTexture);
+ m_opaqueTexture = 0;
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 texture that points to the IOSurface. The depth and
// stencil buffers were attached by startFrame.
gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::TEXTURE_2D, m_opaqueTexture, 0);
+ // FIXME: This is assuming multisampling is turned off and we're rendering directly into the framebuffer.
+
// At this point the framebuffer should be "complete".
ASSERT(gl.checkFramebufferStatus(GL::FRAMEBUFFER) == GL::FRAMEBUFFER_COMPLETE);
#else
@@ -187,7 +195,12 @@
if (m_ioSurfaceTextureHandle) {
auto gCGL = static_cast<GraphicsContextGLOpenGL*>(&gl);
- gCGL->destroyPbufferAndDetachIOSurface(m_ioSurfaceTextureHandle);
+ if (m_ioSurfaceTextureHandleIsShared)
+ gCGL->detachIOSurfaceFromSharedTexture(m_ioSurfaceTextureHandle);
+ else
+ gCGL->destroyPbufferAndDetachIOSurface(m_ioSurfaceTextureHandle);
+ m_ioSurfaceTextureHandle = nullptr;
+ m_ioSurfaceTextureHandleIsShared = false;
}
#else
Modified: trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h (279297 => 279298)
--- trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h 2021-06-25 22:06:49 UTC (rev 279298)
@@ -79,6 +79,7 @@
PlatformGLObject m_opaqueTexture { 0 };
#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
void* m_ioSurfaceTextureHandle { nullptr };
+ bool m_ioSurfaceTextureHandleIsShared { false };
#endif
};
Modified: trunk/Source/WebCore/PAL/ChangeLog (279297 => 279298)
--- trunk/Source/WebCore/PAL/ChangeLog 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/PAL/ChangeLog 2021-06-25 22:06:49 UTC (rev 279298)
@@ -1,3 +1,15 @@
+2021-06-22 Dean Jackson <[email protected]>
+
+ Add support for MTLSharedTextures in WebXR
+ https://bugs.webkit.org/show_bug.cgi?id=227245
+ <rdar://problem/79591620>
+
+ Reviewed by Tim Horton.
+
+ Define MTLSharedTextureHandle's initWithIOSurface.
+
+ * pal/spi/cocoa/MetalSPI.h:
+
2021-06-25 Wenson Hsieh <[email protected]>
Unreviewed, fix the macOS Monterey build
Modified: trunk/Source/WebCore/PAL/pal/spi/cocoa/MetalSPI.h (279297 => 279298)
--- trunk/Source/WebCore/PAL/pal/spi/cocoa/MetalSPI.h 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/PAL/pal/spi/cocoa/MetalSPI.h 2021-06-25 22:06:49 UTC (rev 279298)
@@ -25,6 +25,7 @@
#if USE(APPLE_INTERNAL_SDK)
+#import <Metal/MTLTexture_Private.h>
#import <Metal/MetalPrivate.h>
#else
@@ -31,6 +32,8 @@
#import <Foundation/NSObject.h>
+typedef struct __IOSurface *IOSurfaceRef;
+
@protocol MTLDeviceSPI <MTLDevice>
- (NSString*)vendorName;
- (NSString*)familyName;
@@ -41,4 +44,8 @@
- (void)_purgeDevice;
@end
+@interface MTLSharedTextureHandle(Private)
+- (instancetype)initWithIOSurface:(IOSurfaceRef)ioSurface label:(NSString*)label;
+@end
+
#endif
Modified: trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm (279297 => 279298)
--- trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm 2021-06-25 22:06:49 UTC (rev 279298)
@@ -37,6 +37,7 @@
#import "WebGLLayer.h"
#import <CoreGraphics/CGBitmapContext.h>
#import <Metal/Metal.h>
+#import <pal/spi/cocoa/MetalSPI.h>
#import <wtf/BlockObjCExceptions.h>
#import <wtf/darwin/WeakLinking.h>
#import <wtf/text/CString.h>
@@ -684,7 +685,52 @@
EGL_DestroySurface(display, handle);
}
+void* GraphicsContextGLOpenGL::attachIOSurfaceToSharedTexture(GCGLenum target, IOSurface* surface)
+{
+ constexpr EGLint emptyAttributes[] = { EGL_NONE };
+ // Create a MTLTexture out of the IOSurface.
+ // FIXME: We need to use the same device that ANGLE is using, which might not be the default.
+
+ RetainPtr<MTLSharedTextureHandle> handle = adoptNS([[MTLSharedTextureHandle alloc] initWithIOSurface:surface->surface() label:@"WebXR"]);
+ if (!handle) {
+ LOG(WebGL, "Unable to create a MTLSharedTextureHandle from the IOSurface in attachIOSurfaceToTexture.");
+ return nullptr;
+ }
+
+ if (!handle.get().device) {
+ LOG(WebGL, "MTLSharedTextureHandle does not have a Metal device in attachIOSurfaceToTexture.");
+ return nullptr;
+ }
+
+ auto texture = adoptNS([handle.get().device newSharedTextureWithHandle:handle.get()]);
+ if (!texture) {
+ LOG(WebGL, "Unable to create a MTLSharedTexture from the texture handle in attachIOSurfaceToTexture.");
+ return nullptr;
+ }
+
+ // FIXME: Does the texture have the correct usage mode?
+
+ // Create an EGLImage out of the MTLTexture
+ auto display = platformDisplay();
+ auto eglImage = EGL_CreateImageKHR(display, EGL_NO_CONTEXT, EGL_METAL_TEXTURE_ANGLE, reinterpret_cast<EGLClientBuffer>(texture.get()), emptyAttributes);
+ if (!eglImage) {
+ LOG(WebGL, "Unable to create an EGLImage from the Metal handle in attachIOSurfaceToTexture.");
+ return nullptr;
+ }
+
+ // Tell the currently bound texture to use the EGLImage.
+ gl::EGLImageTargetTexture2DOES(target, eglImage);
+
+ return eglImage;
+}
+
+void GraphicsContextGLOpenGL::detachIOSurfaceFromSharedTexture(void* handle)
+{
+ auto display = platformDisplay();
+ EGL_DestroyImageKHR(display, handle);
+}
+
bool GraphicsContextGLOpenGL::isGLES2Compliant() const
{
return m_isForWebGL2;
Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h (279297 => 279298)
--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h 2021-06-25 22:06:49 UTC (rev 279298)
@@ -536,6 +536,8 @@
// detach call below.
void* createPbufferAndAttachIOSurface(GCGLenum target, PbufferAttachmentUsage, GCGLenum internalFormat, GCGLsizei width, GCGLsizei height, GCGLenum type, IOSurfaceRef, GCGLuint plane);
void destroyPbufferAndDetachIOSurface(void* handle);
+ void* attachIOSurfaceToSharedTexture(GCGLenum target, IOSurface*);
+ void detachIOSurfaceFromSharedTexture(void* handle);
#endif
private:
Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (279297 => 279298)
--- trunk/Source/WebCore/platform/xr/PlatformXR.h 2021-06-25 20:50:25 UTC (rev 279297)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h 2021-06-25 22:06:49 UTC (rev 279298)
@@ -173,6 +173,7 @@
struct LayerData {
#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
std::unique_ptr<WebCore::IOSurface> surface;
+ bool isShared { false };
#else
PlatformGLObject opaqueTexture { 0 };
#endif
@@ -442,6 +443,7 @@
#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
WTF::MachSendRight surfaceSendRight = surface ? surface->createSendRight() : WTF::MachSendRight();
encoder << surfaceSendRight;
+ encoder << isShared;
#else
encoder << opaqueTexture;
#endif
@@ -456,6 +458,8 @@
if (!decoder.decode(surfaceSendRight))
return std::nullopt;
layerData.surface = WebCore::IOSurface::createFromSendRight(WTFMove(surfaceSendRight), WebCore::DestinationColorSpace::SRGB());
+ if (!decoder.decode(layerData.isShared))
+ return std::nullopt;
#else
if (!decoder.decode(layerData.opaqueTexture))
return std::nullopt;