⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 279298 in webkit


Ignore:
Timestamp:
Jun 25, 2021, 3:06:49 PM (5 years ago)
Author:
dino@apple.com
Message:

Add support for MTLSharedTextures in WebXR
​https://bugs.webkit.org/show_bug.cgi?id=227245
<rdar://problem/79591620>

Reviewed by Tim Horton.

Source/WebCore:

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):

Source/WebCore/PAL:

Define MTLSharedTextureHandle's initWithIOSurface.

  • pal/spi/cocoa/MetalSPI.h:
Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r279296 r279298  
     12021-06-22  Dean Jackson  <dino@apple.com>
     2
     3        Add support for MTLSharedTextures in WebXR
     4        https://bugs.webkit.org/show_bug.cgi?id=227245
     5        <rdar://problem/79591620>
     6
     7        Reviewed by Tim Horton.
     8
     9        Sometimes, the IOSurface passed to WebXR come from a shared MTLTexture. In
     10        this case we can't treat the IOSurface data as a regular single-plane
     11        image. Instead we should use it to recreate the MTLTexture and then
     12        bind that to WebGL's framebuffer.
     13
     14        * Modules/webxr/WebXROpaqueFramebuffer.cpp: Use some new binding methods on GraphicsContextGLOpenGL
     15        if given a shared texture.
     16        (WebCore::WebXROpaqueFramebuffer::startFrame):
     17        (WebCore::WebXROpaqueFramebuffer::endFrame):
     18        * Modules/webxr/WebXROpaqueFramebuffer.h:
     19        * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm: New methods to link an
     20        IOSurface to a GL texture, going through a MTLSharedTexture.
     21        (WebCore::GraphicsContextGLOpenGL::attachIOSurfaceToSharedTexture):
     22        (WebCore::GraphicsContextGLOpenGL::detachIOSurfaceFromSharedTexture):
     23        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
     24        * platform/xr/PlatformXR.h: Add a new "isShared" member to LayerData
     25        to differentiate between normal IOSurfaces and those that came
     26        from a shared texture.
     27        (PlatformXR::Device::FrameData::LayerData::encode const):
     28        (PlatformXR::Device::FrameData::LayerData::decode):
     29
    1302021-06-25  Alex Christensen  <achristensen@webkit.org>
    231
  • trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.cpp

    r278528 r279298  
    126126    GCGLenum textureTarget = GraphicsContextGLOpenGL::drawingBufferTextureTarget();
    127127
    128     auto size = data.surface->size();
    129     if (!size.width() || !size.height())
    130         return;
    131128
    132129    if (!m_opaqueTexture)
    … …  
    140137
    141138    // Tell the GraphicsContextGL to use the IOSurface as the backing store for m_opaqueTexture.
    142     m_ioSurfaceTextureHandle = gCGL->createPbufferAndAttachIOSurface(textureTarget, GraphicsContextGLOpenGL::PbufferAttachmentUsage::Write, GL::BGRA, size.width(), size.height(), GL::UNSIGNED_BYTE, data.surface->surface(), 0);
    143     if (!m_ioSurfaceTextureHandle && m_opaqueTexture) {
     139    if (data.isShared) {
     140        m_ioSurfaceTextureHandle = gCGL->attachIOSurfaceToSharedTexture(textureTarget, data.surface.get());
     141        m_ioSurfaceTextureHandleIsShared = true;
     142    } else {
     143        auto size = data.surface->size();
     144        if (!size.width() || !size.height())
     145            return;
     146        m_ioSurfaceTextureHandle = gCGL->createPbufferAndAttachIOSurface(textureTarget, GraphicsContextGLOpenGL::PbufferAttachmentUsage::Write, GL::BGRA, size.width(), size.height(), GL::UNSIGNED_BYTE, data.surface->surface(), 0);
     147        m_ioSurfaceTextureHandleIsShared = false;
     148    }
     149
     150    if (!m_ioSurfaceTextureHandle) {
    144151        gCGL->deleteTexture(m_opaqueTexture);
     152        m_opaqueTexture = 0;
    145153        return;
    146154    }
    147 
    148     // FIXME: This is assuming multisampling is turned off and we're rendering directly into the framebuffer.
    149155
    150156    // Now set up the framebuffer to use the texture that points to the IOSurface. The depth and
    151157    // stencil buffers were attached by startFrame.
    152158    gl.framebufferTexture2D(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::TEXTURE_2D, m_opaqueTexture, 0);
     159
     160    // FIXME: This is assuming multisampling is turned off and we're rendering directly into the framebuffer.
    153161
    154162    // At this point the framebuffer should be "complete".
    … …  
    188196    if (m_ioSurfaceTextureHandle) {
    189197        auto gCGL = static_cast<GraphicsContextGLOpenGL*>(&gl);
    190         gCGL->destroyPbufferAndDetachIOSurface(m_ioSurfaceTextureHandle);
     198        if (m_ioSurfaceTextureHandleIsShared)
     199            gCGL->detachIOSurfaceFromSharedTexture(m_ioSurfaceTextureHandle);
     200        else
     201            gCGL->destroyPbufferAndDetachIOSurface(m_ioSurfaceTextureHandle);
     202        m_ioSurfaceTextureHandle = nullptr;
     203        m_ioSurfaceTextureHandleIsShared = false;
    191204    }
    192205#else
  • trunk/Source/WebCore/Modules/webxr/WebXROpaqueFramebuffer.h

    r278295 r279298  
    8080#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
    8181    void* m_ioSurfaceTextureHandle { nullptr };
     82    bool m_ioSurfaceTextureHandleIsShared { false };
    8283#endif
    8384};
  • trunk/Source/WebCore/PAL/ChangeLog

    r279290 r279298  
     12021-06-22  Dean Jackson  <dino@apple.com>
     2
     3        Add support for MTLSharedTextures in WebXR
     4        https://bugs.webkit.org/show_bug.cgi?id=227245
     5        <rdar://problem/79591620>
     6
     7        Reviewed by Tim Horton.
     8
     9        Define MTLSharedTextureHandle's initWithIOSurface.
     10
     11        * pal/spi/cocoa/MetalSPI.h:
     12
    1132021-06-25  Wenson Hsieh  <wenson_hsieh@apple.com>
    214
  • trunk/Source/WebCore/PAL/pal/spi/cocoa/MetalSPI.h

    r275403 r279298  
    2626#if USE(APPLE_INTERNAL_SDK)
    2727
     28#import <Metal/MTLTexture_Private.h>
    2829#import <Metal/MetalPrivate.h>
    2930
    … …  
    3132
    3233#import <Foundation/NSObject.h>
     34
     35typedef struct __IOSurface *IOSurfaceRef;
    3336
    3437@protocol MTLDeviceSPI <MTLDevice>
    … …  
    4245@end
    4346
     47@interface MTLSharedTextureHandle(Private)
     48- (instancetype)initWithIOSurface:(IOSurfaceRef)ioSurface label:(NSString*)label;
     49@end
     50
    4451#endif
  • trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm

    r279172 r279298  
    3838#import <CoreGraphics/CGBitmapContext.h>
    3939#import <Metal/Metal.h>
     40#import <pal/spi/cocoa/MetalSPI.h>
    4041#import <wtf/BlockObjCExceptions.h>
    4142#import <wtf/darwin/WeakLinking.h>
    … …  
    685686}
    686687
     688void* GraphicsContextGLOpenGL::attachIOSurfaceToSharedTexture(GCGLenum target, IOSurface* surface)
     689{
     690    constexpr EGLint emptyAttributes[] = { EGL_NONE };
     691
     692    // Create a MTLTexture out of the IOSurface.
     693    // FIXME: We need to use the same device that ANGLE is using, which might not be the default.
     694
     695    RetainPtr<MTLSharedTextureHandle> handle = adoptNS([[MTLSharedTextureHandle alloc] initWithIOSurface:surface->surface() label:@"WebXR"]);
     696    if (!handle) {
     697        LOG(WebGL, "Unable to create a MTLSharedTextureHandle from the IOSurface in attachIOSurfaceToTexture.");
     698        return nullptr;
     699    }
     700
     701    if (!handle.get().device) {
     702        LOG(WebGL, "MTLSharedTextureHandle does not have a Metal device in attachIOSurfaceToTexture.");
     703        return nullptr;
     704    }
     705
     706    auto texture = adoptNS([handle.get().device newSharedTextureWithHandle:handle.get()]);
     707    if (!texture) {
     708        LOG(WebGL, "Unable to create a MTLSharedTexture from the texture handle in attachIOSurfaceToTexture.");
     709        return nullptr;
     710    }
     711
     712    // FIXME: Does the texture have the correct usage mode?
     713
     714    // Create an EGLImage out of the MTLTexture
     715    auto display = platformDisplay();
     716    auto eglImage = EGL_CreateImageKHR(display, EGL_NO_CONTEXT, EGL_METAL_TEXTURE_ANGLE, reinterpret_cast<EGLClientBuffer>(texture.get()), emptyAttributes);
     717    if (!eglImage) {
     718        LOG(WebGL, "Unable to create an EGLImage from the Metal handle in attachIOSurfaceToTexture.");
     719        return nullptr;
     720    }
     721
     722    // Tell the currently bound texture to use the EGLImage.
     723    gl::EGLImageTargetTexture2DOES(target, eglImage);
     724
     725    return eglImage;
     726}
     727
     728void GraphicsContextGLOpenGL::detachIOSurfaceFromSharedTexture(void* handle)
     729{
     730    auto display = platformDisplay();
     731    EGL_DestroyImageKHR(display, handle);
     732}
    687733
    688734bool GraphicsContextGLOpenGL::isGLES2Compliant() const
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h

    r279172 r279298  
    537537    void* createPbufferAndAttachIOSurface(GCGLenum target, PbufferAttachmentUsage, GCGLenum internalFormat, GCGLsizei width, GCGLsizei height, GCGLenum type, IOSurfaceRef, GCGLuint plane);
    538538    void destroyPbufferAndDetachIOSurface(void* handle);
     539    void* attachIOSurfaceToSharedTexture(GCGLenum target, IOSurface*);
     540    void detachIOSurfaceFromSharedTexture(void* handle);
    539541#endif
    540542
  • trunk/Source/WebCore/platform/xr/PlatformXR.h

    r278789 r279298  
    174174#if USE(IOSURFACE_FOR_XR_LAYER_DATA)
    175175            std::unique_ptr<WebCore::IOSurface> surface;
     176            bool isShared { false };
    176177#else
    177178            PlatformGLObject opaqueTexture { 0 };
    … …  
    443444    WTF::MachSendRight surfaceSendRight = surface ? surface->createSendRight() : WTF::MachSendRight();
    444445    encoder << surfaceSendRight;
     446    encoder << isShared;
    445447#else
    446448    encoder << opaqueTexture;
    … …  
    457459        return std::nullopt;
    458460    layerData.surface = WebCore::IOSurface::createFromSendRight(WTFMove(surfaceSendRight), WebCore::DestinationColorSpace::SRGB());
     461    if (!decoder.decode(layerData.isShared))
     462        return std::nullopt;
    459463#else
    460464    if (!decoder.decode(layerData.opaqueTexture))
Note: See TracChangeset for help on using the changeset viewer.