Delete old Metal interop APIs

Also fixes inconsistency reported in crbug.com/40275042

Bug: 42241241
Fixed: 40275042
Change-Id: Iec5fbdb1aa15a96cec09d4996ca8d111bdaf41c0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/186847
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/include/dawn/native/MetalBackend.h b/include/dawn/native/MetalBackend.h
index c07349a..b4d6c34 100644
--- a/include/dawn/native/MetalBackend.h
+++ b/include/dawn/native/MetalBackend.h
@@ -28,61 +28,11 @@
 #ifndef INCLUDE_DAWN_NATIVE_METALBACKEND_H_
 #define INCLUDE_DAWN_NATIVE_METALBACKEND_H_
 
-#include <vector>
-
-#include "dawn/native/DawnNative.h"
-
-// The specifics of the Metal backend expose types in function signatures that might not be
-// available in dependent's minimum supported SDK version. Suppress all availability errors using
-// clang's pragmas. Dependents using the types without guarded availability will still get errors
-// when using the types.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunguarded-availability"
-
-struct __IOSurface;
-typedef __IOSurface* IOSurfaceRef;
-
-#ifdef __OBJC__
-#import <Metal/Metal.h>
-#endif  // __OBJC__
+#include "dawn/native/dawn_native_export.h"
+#include "dawn/webgpu.h"
 
 namespace dawn::native::metal {
 
-struct DAWN_NATIVE_EXPORT ExternalImageMTLSharedEventDescriptor {
-    // Shared event handle `id<MTLSharedEvent>`.
-    // This never passes ownership to the callee (when used as an input
-    // parameter) or to the caller (when used as a return value or output parameter).
-#ifdef __OBJC__
-    id<MTLSharedEvent> sharedEvent = nil;
-    static_assert(sizeof(id<MTLSharedEvent>) == sizeof(void*));
-    static_assert(alignof(id<MTLSharedEvent>) == alignof(void*));
-#else
-    void* sharedEvent = nullptr;
-#endif
-
-    // The value that was previously signaled on this event and should be waited on.
-    uint64_t signaledValue = 0;
-};
-
-struct DAWN_NATIVE_EXPORT ExternalImageDescriptorIOSurface : ExternalImageDescriptor {
-  public:
-    ExternalImageDescriptorIOSurface();
-    ~ExternalImageDescriptorIOSurface();
-
-    IOSurfaceRef ioSurface;
-
-    // A list of events to wait on before accessing the texture.
-    std::vector<ExternalImageMTLSharedEventDescriptor> waitEvents;
-};
-
-struct DAWN_NATIVE_EXPORT ExternalImageIOSurfaceEndAccessDescriptor
-    : ExternalImageMTLSharedEventDescriptor {
-    bool isInitialized;
-};
-
-DAWN_NATIVE_EXPORT void IOSurfaceEndAccess(WGPUTexture texture,
-                                           ExternalImageIOSurfaceEndAccessDescriptor* descriptor);
-
 // When making Metal interop with other APIs, we need to be careful that QueueSubmit doesn't
 // mean that the operations will be visible to other APIs/Metal devices right away. macOS
 // does have a global queue of graphics operations, but the command buffers are inserted there
@@ -92,6 +42,4 @@
 
 }  // namespace dawn::native::metal
 
-#pragma clang diagnostic pop
-
 #endif  // INCLUDE_DAWN_NATIVE_METALBACKEND_H_
diff --git a/src/dawn/native/metal/MetalBackend.mm b/src/dawn/native/metal/MetalBackend.mm
index 87b71ea..6791ebb 100644
--- a/src/dawn/native/metal/MetalBackend.mm
+++ b/src/dawn/native/metal/MetalBackend.mm
@@ -36,19 +36,6 @@
 
 namespace dawn::native::metal {
 
-ExternalImageDescriptorIOSurface::ExternalImageDescriptorIOSurface()
-    : ExternalImageDescriptor(ExternalImageType::IOSurface) {}
-
-ExternalImageDescriptorIOSurface::~ExternalImageDescriptorIOSurface() = default;
-
-void IOSurfaceEndAccess(WGPUTexture cTexture,
-                        ExternalImageIOSurfaceEndAccessDescriptor* descriptor) {
-    Texture* texture = ToBackend(FromAPI(cTexture));
-    auto device = texture->GetDevice();
-    auto deviceLock(device->GetScopedLock());
-    texture->IOSurfaceEndAccess(descriptor);
-}
-
 void WaitForCommandsToBeScheduled(WGPUDevice device) {
     Device* backendDevice = ToBackend(FromAPI(device));
     auto deviceLock(backendDevice->GetScopedLock());
diff --git a/src/dawn/native/metal/QueueMTL.h b/src/dawn/native/metal/QueueMTL.h
index d3f03dd..593d8d2 100644
--- a/src/dawn/native/metal/QueueMTL.h
+++ b/src/dawn/native/metal/QueueMTL.h
@@ -37,11 +37,11 @@
 #include "dawn/native/Queue.h"
 #include "dawn/native/SystemEvent.h"
 #include "dawn/native/metal/CommandRecordingContext.h"
+#include "dawn/native/metal/SharedFenceMTL.h"
 
 namespace dawn::native::metal {
 
 class Device;
-struct ExternalImageMTLSharedEventDescriptor;
 
 class Queue final : public QueueBase {
   public:
@@ -50,7 +50,7 @@
     CommandRecordingContext* GetPendingCommandContext(SubmitMode submitMode = SubmitMode::Normal);
     MaybeError SubmitPendingCommandBuffer();
     void WaitForCommandsToBeScheduled();
-    void ExportLastSignaledEvent(ExternalImageMTLSharedEventDescriptor* desc);
+    ResultOrError<Ref<SharedFence>> GetOrCreateSharedFence();
 
     Ref<SystemEvent> CreateWorkDoneSystemEvent(ExecutionSerial serial);
     ResultOrError<bool> WaitForQueueSerial(ExecutionSerial serial, Nanoseconds timeout) override;
@@ -91,7 +91,9 @@
 
     // A shared event that can be exported for synchronization with other users of Metal.
     // MTLSharedEvent is not available until macOS 10.14+ so use just `id`.
-    NSPRef<id> mMtlSharedEvent = nullptr;
+    NSPRef<id> mMtlSharedEvent;
+    // The shared event wrapped as a SharedFence object.
+    Ref<SharedFence> mSharedFence;
 };
 
 }  // namespace dawn::native::metal
diff --git a/src/dawn/native/metal/QueueMTL.mm b/src/dawn/native/metal/QueueMTL.mm
index e439d94..e788e96 100644
--- a/src/dawn/native/metal/QueueMTL.mm
+++ b/src/dawn/native/metal/QueueMTL.mm
@@ -59,10 +59,9 @@
     mCommandQueue = nullptr;
     mLastSubmittedCommands = nullptr;
 
+    mSharedFence = nullptr;
     // Don't free mMtlSharedEvent because it can be queried after device destruction for
     // synchronization needs.
-
-    QueueBase::DestroyImpl();
 }
 
 MaybeError Queue::Initialize() {
@@ -74,7 +73,7 @@
     }
 
     if (@available(macOS 10.14, iOS 12.0, *)) {
-        mMtlSharedEvent.Acquire([mtlDevice newSharedEvent]);
+        DAWN_TRY_ASSIGN(mSharedFence, GetOrCreateSharedFence());
     }
 
     return mCommandContext.PrepareNextCommandBuffer(*mCommandQueue);
@@ -183,18 +182,25 @@
     TRACE_EVENT_ASYNC_BEGIN0(platform, GPUWork, "DeviceMTL::SubmitPendingCommandBuffer",
                              uint64_t(pendingSerial));
     if (@available(macOS 10.14, iOS 12.0, *)) {
-        id rawEvent = *mMtlSharedEvent;
-        id<MTLSharedEvent> sharedEvent = static_cast<id<MTLSharedEvent>>(rawEvent);
-        [*pendingCommands encodeSignalEvent:sharedEvent value:static_cast<uint64_t>(pendingSerial)];
+        DAWN_ASSERT(mSharedFence);
+        [*pendingCommands encodeSignalEvent:mSharedFence->GetMTLSharedEvent()
+                                      value:static_cast<uint64_t>(pendingSerial)];
     }
     [*pendingCommands commit];
 
     return mCommandContext.PrepareNextCommandBuffer(*mCommandQueue);
 }
 
-void Queue::ExportLastSignaledEvent(ExternalImageMTLSharedEventDescriptor* desc) {
-    desc->sharedEvent = *mMtlSharedEvent;
-    desc->signaledValue = static_cast<uint64_t>(GetLastSubmittedCommandSerial());
+ResultOrError<Ref<SharedFence>> Queue::GetOrCreateSharedFence() {
+    if (mSharedFence) {
+        return mSharedFence;
+    }
+    if (!mMtlSharedEvent) {
+        mMtlSharedEvent.Acquire([ToBackend(GetDevice())->GetMTLDevice() newSharedEvent]);
+    }
+    SharedFenceMTLSharedEventDescriptor desc;
+    desc.sharedEvent = mMtlSharedEvent.Get();
+    return SharedFence::Create(ToBackend(GetDevice()), "Internal MTLSharedEvent", &desc);
 }
 
 MaybeError Queue::SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) {
diff --git a/src/dawn/native/metal/SharedFenceMTL.h b/src/dawn/native/metal/SharedFenceMTL.h
index 210b99d..ec36996 100644
--- a/src/dawn/native/metal/SharedFenceMTL.h
+++ b/src/dawn/native/metal/SharedFenceMTL.h
@@ -41,21 +41,22 @@
 
 class Device;
 
-class API_AVAILABLE(macos(10.14), ios(12.0)) SharedFence final : public SharedFenceBase {
+class SharedFence final : public SharedFenceBase {
   public:
     static ResultOrError<Ref<SharedFence>> Create(
         Device* device,
         const char* label,
         const SharedFenceMTLSharedEventDescriptor* descriptor);
 
-    id<MTLSharedEvent> GetMTLSharedEvent() const;
+    id<MTLSharedEvent> GetMTLSharedEvent() const API_AVAILABLE(macos(10.14), ios(12.0));
 
   private:
-    SharedFence(Device* device, const char* label, id<MTLSharedEvent> sharedEvent);
+    SharedFence(Device* device, const char* label, id<MTLSharedEvent> sharedEvent)
+        API_AVAILABLE(macos(10.14), ios(12.0));
 
     MaybeError ExportInfoImpl(UnpackedPtr<SharedFenceExportInfo>& info) const override;
 
-    NSPRef<id<MTLSharedEvent>> mSharedEvent;
+    NSPRef<id> mSharedEvent;
 };
 
 }  // namespace dawn::native::metal
diff --git a/src/dawn/native/metal/SharedFenceMTL.mm b/src/dawn/native/metal/SharedFenceMTL.mm
index d69c954..bde8bfe 100644
--- a/src/dawn/native/metal/SharedFenceMTL.mm
+++ b/src/dawn/native/metal/SharedFenceMTL.mm
@@ -38,8 +38,12 @@
     const char* label,
     const SharedFenceMTLSharedEventDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->sharedEvent == nullptr, "MTLSharedEvent is missing.");
-    return AcquireRef(
-        new SharedFence(device, label, static_cast<id<MTLSharedEvent>>(descriptor->sharedEvent)));
+    if (@available(macOS 10.14, iOS 12.0, *)) {
+        return AcquireRef(new SharedFence(
+            device, label, static_cast<id<MTLSharedEvent>>(descriptor->sharedEvent)));
+    } else {
+        return DAWN_INTERNAL_ERROR("MTLSharedEvent not supported.");
+    }
 }
 
 SharedFence::SharedFence(Device* device, const char* label, id<MTLSharedEvent> sharedEvent)
diff --git a/src/dawn/native/metal/SharedTextureMemoryMTL.mm b/src/dawn/native/metal/SharedTextureMemoryMTL.mm
index ef8cb2d..a826d02 100644
--- a/src/dawn/native/metal/SharedTextureMemoryMTL.mm
+++ b/src/dawn/native/metal/SharedTextureMemoryMTL.mm
@@ -203,24 +203,11 @@
     DAWN_INVALID_IF(!GetDevice()->HasFeature(Feature::SharedFenceMTLSharedEvent),
                     "Required feature (%s) is missing.",
                     wgpu::FeatureName::SharedFenceMTLSharedEvent);
-
-    if (@available(macOS 10.14, iOS 12.0, *)) {
-        ExternalImageIOSurfaceEndAccessDescriptor oldEndAccessDesc;
-        ToBackend(GetDevice()->GetQueue())->ExportLastSignaledEvent(&oldEndAccessDesc);
-
-        SharedFenceMTLSharedEventDescriptor newDesc;
-        newDesc.sharedEvent = oldEndAccessDesc.sharedEvent;
-
-        Ref<SharedFence> fence;
-        DAWN_TRY_ASSIGN(fence, SharedFence::Create(ToBackend(GetDevice()),
-                                                   "Internal MTLSharedEvent", &newDesc));
-
-        return FenceAndSignalValue{
-            std::move(fence),
-            static_cast<uint64_t>(
-                texture->GetSharedResourceMemoryContents()->GetLastUsageSerial())};
-    }
-    DAWN_UNREACHABLE();
+    Ref<SharedFence> fence;
+    DAWN_TRY_ASSIGN(fence, ToBackend(GetDevice()->GetQueue())->GetOrCreateSharedFence());
+    return FenceAndSignalValue{
+        std::move(fence),
+        static_cast<uint64_t>(texture->GetSharedResourceMemoryContents()->GetLastUsageSerial())};
 }
 
 MaybeError SharedTextureMemory::CreateMtlTextures() {
diff --git a/src/dawn/native/metal/TextureMTL.h b/src/dawn/native/metal/TextureMTL.h
index 8d63897..0471735 100644
--- a/src/dawn/native/metal/TextureMTL.h
+++ b/src/dawn/native/metal/TextureMTL.h
@@ -73,7 +73,6 @@
                                                    const SubresourceRange& range);
 
     void SynchronizeTextureBeforeUse(CommandRecordingContext* commandContext);
-    void IOSurfaceEndAccess(ExternalImageIOSurfaceEndAccessDescriptor* descriptor);
 
   private:
     using TextureBase::TextureBase;
diff --git a/src/dawn/native/metal/TextureMTL.mm b/src/dawn/native/metal/TextureMTL.mm
index ec1c571..999856e 100644
--- a/src/dawn/native/metal/TextureMTL.mm
+++ b/src/dawn/native/metal/TextureMTL.mm
@@ -441,14 +441,6 @@
     }
 }
 
-void Texture::IOSurfaceEndAccess(ExternalImageIOSurfaceEndAccessDescriptor* descriptor) {
-    DAWN_ASSERT(descriptor);
-    ToBackend(GetDevice()->GetQueue())->ExportLastSignaledEvent(descriptor);
-    descriptor->isInitialized = IsSubresourceContentInitialized(GetAllSubresources());
-    // Destroy the texture as it should not longer be used after EndAccess.
-    Destroy();
-}
-
 Texture::Texture(DeviceBase* dev, const UnpackedPtr<TextureDescriptor>& desc)
     : TextureBase(dev, desc) {}