From 6c91a810e7ee70363e0f9e9a888ed7f29837a841 Mon Sep 17 00:00:00 2001 From: "Myles C. Maxfield" Date: Wed, 18 Jan 2023 03:00:22 -0800 Subject: [PATCH] [WebGPU] Virtualize PresentationContext https://bugs.webkit.org/show_bug.cgi?id=250632 rdar://104270153 Reviewed by Tadeu Zagallo. PresentationContext is how we composite results into a window. Its implementation in https://bugs.webkit.org/show_bug.cgi?id=247587 is set up only for WebKit's compositing using IOSurfaces. However, it's convenient if we could have another implementation of them that could use CAMetalLayer directly, so that we could develop WebGPU without having to build all of WebCore. This patch turns PresentationContext into a base class with virtual methods, and provides two implementations of them: One for IOSurfaces, that WebKit will use, and one for CAMetalLayer. The IOSurface implementation isn't modified at all; it's simply moved from the existing implementation. This patch doesn't actually implement the CAMetalLayer implementation; this patch is already quite large without it, and I want to keep my patches small to aid reviewing. I will implement getCurrentTextureView() and present() in my next patch. No test because there is no behavior change. * Source/WebGPU/WebGPU.xcodeproj/project.pbxproj: * Source/WebGPU/WebGPU/Device.h: * Source/WebGPU/WebGPU/PresentationContext.h: (WebGPU::PresentationContext::createInvalid): (WebGPU::PresentationContext::isPresentationContextIOSurface const): (WebGPU::PresentationContext::isPresentationContextCoreAnimation const): (WebGPU::PresentationContext::create): Deleted. (WebGPU::PresentationContext::displayBuffer const): Deleted. (WebGPU::PresentationContext::drawingBuffer const): Deleted. * Source/WebGPU/WebGPU/PresentationContext.mm: (WebGPU::PresentationContext::create): (WebGPU::PresentationContext::getPreferredFormat): (WebGPU::PresentationContext::present): (WebGPU::optionsFor32BitSurface): Deleted. (WebGPU::createIOSurface): Deleted. (WebGPU::createSurfaceFromDescriptor): Deleted. (WebGPU::Device::createSurface): Deleted. (WebGPU::PresentationContext::PresentationContext): Deleted. (WebGPU::PresentationContext::nextDrawable): Deleted. (wgpuSurfaceCocoaCustomSurfaceGetDisplayBuffer): Deleted. (wgpuSurfaceCocoaCustomSurfaceGetDrawingBuffer): Deleted. * Source/WebGPU/WebGPU/PresentationContextCoreAnimation.h: Copied from Source/WebGPU/WebGPU/PresentationContext.h. (WebGPU::PresentationContextCoreAnimation::create): * Source/WebGPU/WebGPU/PresentationContextCoreAnimation.mm: Copied from Source/WebGPU/WebGPU/PresentationContext.h. (WebGPU::PresentationContextCoreAnimation::PresentationContextCoreAnimation): (WebGPU::PresentationContextCoreAnimation::configure): (WebGPU::PresentationContextCoreAnimation::present): (WebGPU::PresentationContextCoreAnimation::getCurrentTextureView): * Source/WebGPU/WebGPU/PresentationContextIOSurface.h: Copied from Source/WebGPU/WebGPU/PresentationContext.h. (WebGPU::PresentationContextIOSurface::create): (WebGPU::PresentationContextIOSurface::displayBuffer const): (WebGPU::PresentationContextIOSurface::drawingBuffer const): * Source/WebGPU/WebGPU/PresentationContextIOSurface.mm: Copied from Source/WebGPU/WebGPU/PresentationContext.mm. (WebGPU::optionsFor32BitSurface): (WebGPU::createIOSurface): (WebGPU::createSurfaceFromDescriptor): (WebGPU::PresentationContextIOSurface::PresentationContextIOSurface): (WebGPU::PresentationContextIOSurface::configure): (WebGPU::PresentationContextIOSurface::present): (WebGPU::PresentationContextIOSurface::getCurrentTextureView): (WebGPU::PresentationContextIOSurface::nextDrawable): (wgpuSurfaceCocoaCustomSurfaceGetDisplayBuffer): (wgpuSurfaceCocoaCustomSurfaceGetDrawingBuffer): Canonical link: https://commits.webkit.org/259022@main --- .../WebGPU/WebGPU.xcodeproj/project.pbxproj | 26 ++-- Source/WebGPU/WebGPU/Device.h | 1 - Source/WebGPU/WebGPU/PresentationContext.h | 32 ++-- Source/WebGPU/WebGPU/PresentationContext.mm | 105 +++----------- .../WebGPU/PresentationContextCoreAnimation.h | 58 ++++++++ .../PresentationContextCoreAnimation.mm | 56 +++++++ .../WebGPU/PresentationContextIOSurface.h | 65 +++++++++ .../WebGPU/PresentationContextIOSurface.mm | 137 ++++++++++++++++++ 8 files changed, 362 insertions(+), 118 deletions(-) create mode 100644 Source/WebGPU/WebGPU/PresentationContextCoreAnimation.h create mode 100644 Source/WebGPU/WebGPU/PresentationContextCoreAnimation.mm create mode 100644 Source/WebGPU/WebGPU/PresentationContextIOSurface.h create mode 100644 Source/WebGPU/WebGPU/PresentationContextIOSurface.mm diff --git a/Source/WebGPU/WebGPU.xcodeproj/project.pbxproj b/Source/WebGPU/WebGPU.xcodeproj/project.pbxproj index 7dcaf263fc92..62dc55f0e6d5 100644 --- a/Source/WebGPU/WebGPU.xcodeproj/project.pbxproj +++ b/Source/WebGPU/WebGPU.xcodeproj/project.pbxproj @@ -7,14 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - 0D4D2E81294A89CF0000A1AB /* BindableResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D4D2E80294A89CF0000A1AB /* BindableResource.h */; }; 1C0F41EE280940650005886D /* HardwareCapabilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C0F41EC280940650005886D /* HardwareCapabilities.mm */; }; - 1C0F41EF280940650005886D /* HardwareCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C0F41ED280940650005886D /* HardwareCapabilities.h */; }; 1C2CEDEE271E8A7300EDC16F /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C2CEDED271E8A7300EDC16F /* Metal.framework */; }; - 1C33755F27FA23B8002F1644 /* IsValidToUseWith.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C33755D27FA23B8002F1644 /* IsValidToUseWith.h */; }; 1C582FF927E04131009B40F0 /* CommandsMixin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C582FF727E04131009B40F0 /* CommandsMixin.mm */; }; - 1C582FFA27E04131009B40F0 /* CommandsMixin.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C582FF827E04131009B40F0 /* CommandsMixin.h */; }; - 1C58301827E16823009B40F0 /* APIConversions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C58301727E16823009B40F0 /* APIConversions.h */; }; 1C5ACA94273A41C20095F8D5 /* Instance.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACA92273A41C20095F8D5 /* Instance.mm */; }; 1C5ACAB6273A426D0095F8D5 /* RenderPipeline.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACA98273A426D0095F8D5 /* RenderPipeline.mm */; }; 1C5ACABB273A426D0095F8D5 /* Buffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACA9D273A426D0095F8D5 /* Buffer.mm */; }; @@ -30,7 +25,6 @@ 1C5ACACE273A426E0095F8D5 /* ShaderModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACAB0273A426D0095F8D5 /* ShaderModule.mm */; }; 1C5ACACF273A426E0095F8D5 /* Texture.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACAB1273A426D0095F8D5 /* Texture.mm */; }; 1C5ACAD3273A4C860095F8D5 /* WebGPUExt.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C5ACAD2273A4C860095F8D5 /* WebGPUExt.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1C5ACAD7273A4D700095F8D5 /* BindGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C5ACAD5273A4D700095F8D5 /* BindGroup.h */; }; 1C5ACADF273A55AF0095F8D5 /* BindGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACADE273A55AF0095F8D5 /* BindGroup.mm */; }; 1C5ACAE1273A55C10095F8D5 /* BindGroupLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACAE0273A55C10095F8D5 /* BindGroupLayout.mm */; }; 1C5ACAE3273A55CD0095F8D5 /* CommandBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACAE2273A55CD0095F8D5 /* CommandBuffer.mm */; }; @@ -39,8 +33,9 @@ 1C5ACAE9273A55FD0095F8D5 /* Sampler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACAE8273A55FD0095F8D5 /* Sampler.mm */; }; 1C5ACAEB273A560D0095F8D5 /* TextureView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C5ACAEA273A560D0095F8D5 /* TextureView.mm */; }; 1C9F7CDF29762F51006B5BE9 /* PresentationContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C9F7CDD29762F51006B5BE9 /* PresentationContext.mm */; }; - 1C9F7CE029762F51006B5BE9 /* PresentationContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C9F7CDE29762F51006B5BE9 /* PresentationContext.h */; }; 1CBAB0922718CCA0006080BB /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CBAB0912718CCA0006080BB /* JavaScriptCore.framework */; }; + 1CBD2E972977DAC900BBF52C /* PresentationContextCoreAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CBD2E932977DAC900BBF52C /* PresentationContextCoreAnimation.mm */; }; + 1CBD2E992977DAC900BBF52C /* PresentationContextIOSurface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CBD2E952977DAC900BBF52C /* PresentationContextIOSurface.mm */; }; 1CEBD7E72716AFBA00A5254D /* WebGPU.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CEBD7E62716AFBA00A5254D /* WebGPU.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1CEBD7F82716B34400A5254D /* WGSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CEBD7F72716B34400A5254D /* WGSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1CEBD8032716BF8200A5254D /* WGSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CEBD8022716BF8200A5254D /* WGSL.cpp */; }; @@ -262,6 +257,10 @@ 1CAB8D3C2866DA0E00347F21 /* NSSet.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NSSet.hpp; sourceTree = ""; }; 1CAB8D3D2866DA2D00347F21 /* CAMetalLayer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CAMetalLayer.hpp; sourceTree = ""; }; 1CBAB0912718CCA0006080BB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1CBD2E922977DAC900BBF52C /* PresentationContextCoreAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PresentationContextCoreAnimation.h; sourceTree = ""; }; + 1CBD2E932977DAC900BBF52C /* PresentationContextCoreAnimation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PresentationContextCoreAnimation.mm; sourceTree = ""; }; + 1CBD2E942977DAC900BBF52C /* PresentationContextIOSurface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PresentationContextIOSurface.h; sourceTree = ""; }; + 1CBD2E952977DAC900BBF52C /* PresentationContextIOSurface.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PresentationContextIOSurface.mm; sourceTree = ""; }; 1CC0C8C9273A7D8900D0B481 /* WebGPU.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = WebGPU.modulemap; sourceTree = ""; }; 1CEBD7E32716AFBA00A5254D /* WebGPU.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WebGPU.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1CEBD7E62716AFBA00A5254D /* WebGPU.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPU.h; sourceTree = ""; }; @@ -562,6 +561,10 @@ 1C5ACAE4273A55DD0095F8D5 /* PipelineLayout.mm */, 1C9F7CDE29762F51006B5BE9 /* PresentationContext.h */, 1C9F7CDD29762F51006B5BE9 /* PresentationContext.mm */, + 1CBD2E922977DAC900BBF52C /* PresentationContextCoreAnimation.h */, + 1CBD2E932977DAC900BBF52C /* PresentationContextCoreAnimation.mm */, + 1CBD2E942977DAC900BBF52C /* PresentationContextIOSurface.h */, + 1CBD2E952977DAC900BBF52C /* PresentationContextIOSurface.mm */, 1C5ACAAC273A426D0095F8D5 /* QuerySet.h */, 1C5ACA9F273A426D0095F8D5 /* QuerySet.mm */, 1C5ACA9C273A426D0095F8D5 /* Queue.h */, @@ -683,13 +686,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 1C58301827E16823009B40F0 /* APIConversions.h in Headers */, - 0D4D2E81294A89CF0000A1AB /* BindableResource.h in Headers */, - 1C5ACAD7273A4D700095F8D5 /* BindGroup.h in Headers */, - 1C582FFA27E04131009B40F0 /* CommandsMixin.h in Headers */, - 1C0F41EF280940650005886D /* HardwareCapabilities.h in Headers */, - 1C33755F27FA23B8002F1644 /* IsValidToUseWith.h in Headers */, - 1C9F7CE029762F51006B5BE9 /* PresentationContext.h in Headers */, 1CEBD7E72716AFBA00A5254D /* WebGPU.h in Headers */, 1C5ACAD3273A4C860095F8D5 /* WebGPUExt.h in Headers */, ); @@ -907,6 +903,8 @@ 1C5ACA94273A41C20095F8D5 /* Instance.mm in Sources */, 1C5ACAE5273A55DD0095F8D5 /* PipelineLayout.mm in Sources */, 1C9F7CDF29762F51006B5BE9 /* PresentationContext.mm in Sources */, + 1CBD2E972977DAC900BBF52C /* PresentationContextCoreAnimation.mm in Sources */, + 1CBD2E992977DAC900BBF52C /* PresentationContextIOSurface.mm in Sources */, 1C5ACABD273A426D0095F8D5 /* QuerySet.mm in Sources */, 1C5ACACB273A426E0095F8D5 /* Queue.mm in Sources */, 1C5ACAE7273A55EF0095F8D5 /* RenderBundle.mm in Sources */, diff --git a/Source/WebGPU/WebGPU/Device.h b/Source/WebGPU/WebGPU/Device.h index 777a0954319d..b87e874bcfb4 100644 --- a/Source/WebGPU/WebGPU/Device.h +++ b/Source/WebGPU/WebGPU/Device.h @@ -83,7 +83,6 @@ class Device : public WGPUDeviceImpl, public ThreadSafeRefCountedAndCanMakeThrea void createRenderPipelineAsync(const WGPURenderPipelineDescriptor&, CompletionHandler&&, String&& message)>&& callback); Ref createSampler(const WGPUSamplerDescriptor&); Ref createShaderModule(const WGPUShaderModuleDescriptor&); - Ref createSurface(const WGPUSurfaceDescriptor&); Ref createSwapChain(PresentationContext&, const WGPUSwapChainDescriptor&); Ref createTexture(const WGPUTextureDescriptor&); void destroy(); diff --git a/Source/WebGPU/WebGPU/PresentationContext.h b/Source/WebGPU/WebGPU/PresentationContext.h index 2112234be37d..5e38a828ec55 100644 --- a/Source/WebGPU/WebGPU/PresentationContext.h +++ b/Source/WebGPU/WebGPU/PresentationContext.h @@ -29,6 +29,7 @@ #import #import #import +#import struct WGPUSurfaceImpl { }; @@ -45,30 +46,31 @@ class TextureView; class PresentationContext : public WGPUSurfaceImpl, public WGPUSwapChainImpl, public RefCounted { WTF_MAKE_FAST_ALLOCATED; public: - static Ref create(const WGPUSurfaceDescriptor& descriptor) + static Ref create(const WGPUSurfaceDescriptor&); + static Ref createInvalid() { - return adoptRef(*new PresentationContext(descriptor)); + return adoptRef(*new PresentationContext()); } - ~PresentationContext(); + virtual ~PresentationContext(); WGPUTextureFormat getPreferredFormat(const Adapter&); - void configure(Device&, const WGPUSwapChainDescriptor&); + virtual void configure(Device&, const WGPUSwapChainDescriptor&); - void present(); - TextureView* getCurrentTextureView(); // FIXME: This should return a TextureView&. + virtual void present(); + virtual TextureView* getCurrentTextureView(); // FIXME: This should return a TextureView&. - RetainPtr displayBuffer() const { return m_displayBuffer; } - RetainPtr drawingBuffer() const { return m_drawingBuffer; } - RetainPtr nextDrawable(); + virtual bool isPresentationContextIOSurface() const { return false; } + virtual bool isPresentationContextCoreAnimation() const { return false; } -private: - PresentationContext(const WGPUSurfaceDescriptor&); - PresentationContext(int, int); - - RetainPtr m_displayBuffer; - RetainPtr m_drawingBuffer; +protected: + PresentationContext(); }; } // namespace WebGPU + +#define SPECIALIZE_TYPE_TRAITS_WEBGPU_PRESENTATION_CONTEXT(ToValueTypeName, predicate) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebGPU::ToValueTypeName) \ + static bool isType(const WebGPU::PresentationContext& presentationContext) { return presentationContext.predicate; } \ +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebGPU/WebGPU/PresentationContext.mm b/Source/WebGPU/WebGPU/PresentationContext.mm index f757f01e0bbf..3f5e17c2c87c 100644 --- a/Source/WebGPU/WebGPU/PresentationContext.mm +++ b/Source/WebGPU/WebGPU/PresentationContext.mm @@ -28,88 +28,38 @@ #import "APIConversions.h" #import "Adapter.h" - -#import - -// borrowed from pal/spi/cocoa/IOTypesSPI.h -#if PLATFORM(MAC) || USE(APPLE_INTERNAL_SDK) -#include -#else - -enum { - kIOWriteCombineCache = 4, -}; - -enum { - kIOMapCacheShift = 8, - kIOMapWriteCombineCache = kIOWriteCombineCache << kIOMapCacheShift, -}; -#endif +#import "PresentationContextCoreAnimation.h" +#import "PresentationContextIOSurface.h" namespace WebGPU { -static NSDictionary *optionsFor32BitSurface(int width, int height, unsigned pixelFormat) -{ - unsigned bytesPerElement = 4; - unsigned bytesPerPixel = 4; - - size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerPixel); - ASSERT(bytesPerRow); - - size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow); - ASSERT(totalBytes); - - return @{ - (id)kIOSurfaceWidth: @(width), - (id)kIOSurfaceHeight: @(height), - (id)kIOSurfacePixelFormat: @(pixelFormat), - (id)kIOSurfaceBytesPerElement: @(bytesPerElement), - (id)kIOSurfaceBytesPerRow: @(bytesPerRow), - (id)kIOSurfaceAllocSize: @(totalBytes), -#if PLATFORM(IOS_FAMILY) - (id)kIOSurfaceCacheMode: @(kIOMapWriteCombineCache), -#endif - (id)kIOSurfaceElementHeight: @(1) - }; -} - -static RetainPtr createIOSurface(int width, int height) -{ - NSDictionary *options = optionsFor32BitSurface(width, height, 'BGRA'); - return adoptCF(IOSurfaceCreate((CFDictionaryRef)options)); -} - -static RetainPtr createSurfaceFromDescriptor(const WGPUSurfaceDescriptor& descriptor) -{ - if (!descriptor.nextInChain || descriptor.nextInChain->sType != static_cast(WGPUSTypeExtended_SurfaceDescriptorCocoaSurfaceBacking)) - return nullptr; - - auto widthHeight = ((const WGPUSurfaceDescriptorCocoaCustomSurface*)descriptor.nextInChain); - return createIOSurface(widthHeight->width, widthHeight->height); -} - -Ref Device::createSurface(const WGPUSurfaceDescriptor& descriptor) -{ - return PresentationContext::create(descriptor); -} - Ref Device::createSwapChain(PresentationContext& presentationContext, const WGPUSwapChainDescriptor& descriptor) { presentationContext.configure(*this, descriptor); return presentationContext; } -PresentationContext::PresentationContext(const WGPUSurfaceDescriptor& descriptor) - : m_displayBuffer(createSurfaceFromDescriptor(descriptor)) - , m_drawingBuffer(createSurfaceFromDescriptor(descriptor)) +Ref PresentationContext::create(const WGPUSurfaceDescriptor& descriptor) { + if (!descriptor.nextInChain || descriptor.nextInChain->next) + return PresentationContext::createInvalid(); + + switch (static_cast(descriptor.nextInChain->sType)) { + case WGPUSTypeExtended_SurfaceDescriptorCocoaSurfaceBacking: + return PresentationContextIOSurface::create(descriptor); + case WGPUSType_SurfaceDescriptorFromMetalLayer: + return PresentationContextCoreAnimation::create(descriptor); + default: + return PresentationContext::createInvalid(); + } } +PresentationContext::PresentationContext() = default; + PresentationContext::~PresentationContext() = default; -WGPUTextureFormat PresentationContext::getPreferredFormat(const Adapter& adapter) +WGPUTextureFormat PresentationContext::getPreferredFormat(const Adapter&) { - UNUSED_PARAM(adapter); return WGPUTextureFormat_BGRA8Unorm; } @@ -119,7 +69,6 @@ void PresentationContext::present() { - nextDrawable(); } TextureView* PresentationContext::getCurrentTextureView() @@ -127,16 +76,6 @@ return nullptr; } -RetainPtr PresentationContext::nextDrawable() -{ - // FIXME: wait until a buffer is available - auto nextBuffer = m_drawingBuffer; - m_drawingBuffer = m_displayBuffer; - m_displayBuffer = nextBuffer; - - return m_drawingBuffer; -} - } // namespace WebGPU #pragma mark WGPU Stubs @@ -156,16 +95,6 @@ WGPUTextureFormat wgpuSurfaceGetPreferredFormat(WGPUSurface surface, WGPUAdapter return WebGPU::fromAPI(surface).getPreferredFormat(WebGPU::fromAPI(adapter)); } -IOSurfaceRef wgpuSurfaceCocoaCustomSurfaceGetDisplayBuffer(WGPUSurface surface) -{ - return WebGPU::fromAPI(surface).displayBuffer().get(); -} - -IOSurfaceRef wgpuSurfaceCocoaCustomSurfaceGetDrawingBuffer(WGPUSurface surface) -{ - return WebGPU::fromAPI(surface).drawingBuffer().get(); -} - WGPUTextureView wgpuSwapChainGetCurrentTextureView(WGPUSwapChain swapChain) { return WebGPU::fromAPI(swapChain).getCurrentTextureView(); diff --git a/Source/WebGPU/WebGPU/PresentationContextCoreAnimation.h b/Source/WebGPU/WebGPU/PresentationContextCoreAnimation.h new file mode 100644 index 000000000000..add0d650c53c --- /dev/null +++ b/Source/WebGPU/WebGPU/PresentationContextCoreAnimation.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2022 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#import "PresentationContext.h" + +namespace WebGPU { + +class Device; +class TextureView; + +class PresentationContextCoreAnimation : public PresentationContext { + WTF_MAKE_FAST_ALLOCATED; +public: + static Ref create(const WGPUSurfaceDescriptor& descriptor) + { + return adoptRef(*new PresentationContextCoreAnimation(descriptor)); + } + + virtual ~PresentationContextCoreAnimation(); + + void configure(Device&, const WGPUSwapChainDescriptor&) override; + + void present() override; + TextureView* getCurrentTextureView() override; // FIXME: This should return a TextureView&. + + bool isPresentationContextCoreAnimation() const override { return true; } + +private: + PresentationContextCoreAnimation(const WGPUSurfaceDescriptor&); +}; + +} // namespace WebGPU + +SPECIALIZE_TYPE_TRAITS_WEBGPU_PRESENTATION_CONTEXT(PresentationContextCoreAnimation, isPresentationContextCoreAnimation()); diff --git a/Source/WebGPU/WebGPU/PresentationContextCoreAnimation.mm b/Source/WebGPU/WebGPU/PresentationContextCoreAnimation.mm new file mode 100644 index 000000000000..56310f88da53 --- /dev/null +++ b/Source/WebGPU/WebGPU/PresentationContextCoreAnimation.mm @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021-2022 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "PresentationContextCoreAnimation.h" + +#import "APIConversions.h" +#import "Adapter.h" + +namespace WebGPU { + +PresentationContextCoreAnimation::PresentationContextCoreAnimation(const WGPUSurfaceDescriptor&) +{ +} + +PresentationContextCoreAnimation::~PresentationContextCoreAnimation() = default; + +void PresentationContextCoreAnimation::configure(Device&, const WGPUSwapChainDescriptor&) +{ + // FIXME: Implement this. +} + +void PresentationContextCoreAnimation::present() +{ + // FIXME: Implement this. +} + +TextureView* PresentationContextCoreAnimation::getCurrentTextureView() +{ + // FIXME: Implement this. + return nullptr; +} + +} // namespace WebGPU diff --git a/Source/WebGPU/WebGPU/PresentationContextIOSurface.h b/Source/WebGPU/WebGPU/PresentationContextIOSurface.h new file mode 100644 index 000000000000..5dac9e4a0f34 --- /dev/null +++ b/Source/WebGPU/WebGPU/PresentationContextIOSurface.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021-2022 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#import "PresentationContext.h" + +namespace WebGPU { + +class Device; +class TextureView; + +class PresentationContextIOSurface : public PresentationContext { + WTF_MAKE_FAST_ALLOCATED; +public: + static Ref create(const WGPUSurfaceDescriptor& descriptor) + { + return adoptRef(*new PresentationContextIOSurface(descriptor)); + } + + virtual ~PresentationContextIOSurface(); + + void configure(Device&, const WGPUSwapChainDescriptor&) override; + + void present() override; + TextureView* getCurrentTextureView() override; // FIXME: This should return a TextureView&. + + RetainPtr displayBuffer() const { return m_displayBuffer; } + RetainPtr drawingBuffer() const { return m_drawingBuffer; } + RetainPtr nextDrawable(); + + bool isPresentationContextIOSurface() const override { return true; } + +private: + PresentationContextIOSurface(const WGPUSurfaceDescriptor&); + + RetainPtr m_displayBuffer; + RetainPtr m_drawingBuffer; +}; + +} // namespace WebGPU + +SPECIALIZE_TYPE_TRAITS_WEBGPU_PRESENTATION_CONTEXT(PresentationContextIOSurface, isPresentationContextIOSurface()); diff --git a/Source/WebGPU/WebGPU/PresentationContextIOSurface.mm b/Source/WebGPU/WebGPU/PresentationContextIOSurface.mm new file mode 100644 index 000000000000..5ddacda81bdb --- /dev/null +++ b/Source/WebGPU/WebGPU/PresentationContextIOSurface.mm @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021-2022 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "PresentationContextIOSurface.h" + +#import "APIConversions.h" +#import "Adapter.h" + +// borrowed from pal/spi/cocoa/IOTypesSPI.h +#if PLATFORM(MAC) || USE(APPLE_INTERNAL_SDK) +#include +#else + +enum { + kIOWriteCombineCache = 4, +}; + +enum { + kIOMapCacheShift = 8, + kIOMapWriteCombineCache = kIOWriteCombineCache << kIOMapCacheShift, +}; +#endif + +namespace WebGPU { + +static NSDictionary *optionsFor32BitSurface(int width, int height, unsigned pixelFormat) +{ + unsigned bytesPerElement = 4; + unsigned bytesPerPixel = 4; + + size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerPixel); + ASSERT(bytesPerRow); + + size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow); + ASSERT(totalBytes); + + return @{ + (id)kIOSurfaceWidth: @(width), + (id)kIOSurfaceHeight: @(height), + (id)kIOSurfacePixelFormat: @(pixelFormat), + (id)kIOSurfaceBytesPerElement: @(bytesPerElement), + (id)kIOSurfaceBytesPerRow: @(bytesPerRow), + (id)kIOSurfaceAllocSize: @(totalBytes), +#if PLATFORM(IOS_FAMILY) + (id)kIOSurfaceCacheMode: @(kIOMapWriteCombineCache), +#endif + (id)kIOSurfaceElementHeight: @(1) + }; +} + +static RetainPtr createIOSurface(int width, int height) +{ + NSDictionary *options = optionsFor32BitSurface(width, height, 'BGRA'); + return adoptCF(IOSurfaceCreate((CFDictionaryRef)options)); +} + +static RetainPtr createSurfaceFromDescriptor(const WGPUSurfaceDescriptor& descriptor) +{ + if (!descriptor.nextInChain || descriptor.nextInChain->sType != static_cast(WGPUSTypeExtended_SurfaceDescriptorCocoaSurfaceBacking)) + return nullptr; + + auto widthHeight = reinterpret_cast(descriptor.nextInChain); + return createIOSurface(widthHeight->width, widthHeight->height); +} + +PresentationContextIOSurface::PresentationContextIOSurface(const WGPUSurfaceDescriptor& descriptor) + : m_displayBuffer(createSurfaceFromDescriptor(descriptor)) + , m_drawingBuffer(createSurfaceFromDescriptor(descriptor)) +{ +} + +PresentationContextIOSurface::~PresentationContextIOSurface() = default; + +void PresentationContextIOSurface::configure(Device&, const WGPUSwapChainDescriptor&) +{ +} + +void PresentationContextIOSurface::present() +{ + nextDrawable(); +} + +TextureView* PresentationContextIOSurface::getCurrentTextureView() +{ + return nullptr; +} + +RetainPtr PresentationContextIOSurface::nextDrawable() +{ + // FIXME: wait until a buffer is available + auto nextBuffer = m_drawingBuffer; + m_drawingBuffer = m_displayBuffer; + m_displayBuffer = nextBuffer; + + return m_drawingBuffer; +} + +} // namespace WebGPU + +#pragma mark WGPU Stubs + +IOSurfaceRef wgpuSurfaceCocoaCustomSurfaceGetDisplayBuffer(WGPUSurface surface) +{ + if (auto* presentationContextIOSurface = downcast(&WebGPU::fromAPI(surface))) + return presentationContextIOSurface->displayBuffer().get(); + return nullptr; +} + +IOSurfaceRef wgpuSurfaceCocoaCustomSurfaceGetDrawingBuffer(WGPUSurface surface) +{ + if (auto* presentationContextIOSurface = downcast(&WebGPU::fromAPI(surface))) + return presentationContextIOSurface->drawingBuffer().get(); + return nullptr; +}