1 // Copyright 2017 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_SWAPCHAIN_H_ 16 #define DAWNNATIVE_SWAPCHAIN_H_ 17 18 #include "dawn_native/Error.h" 19 #include "dawn_native/Forward.h" 20 #include "dawn_native/ObjectBase.h" 21 22 #include "dawn/dawn_wsi.h" 23 #include "dawn_native/dawn_platform.h" 24 25 namespace dawn_native { 26 27 MaybeError ValidateSwapChainDescriptor(const DeviceBase* device, 28 const Surface* surface, 29 const SwapChainDescriptor* descriptor); 30 31 TextureDescriptor GetSwapChainBaseTextureDescriptor(NewSwapChainBase* swapChain); 32 33 class SwapChainBase : public ObjectBase { 34 public: 35 SwapChainBase(DeviceBase* device); 36 37 static SwapChainBase* MakeError(DeviceBase* device); 38 39 // Dawn API 40 virtual void Configure(wgpu::TextureFormat format, 41 wgpu::TextureUsage allowedUsage, 42 uint32_t width, 43 uint32_t height) = 0; 44 virtual TextureViewBase* GetCurrentTextureView() = 0; 45 virtual void Present() = 0; 46 47 protected: 48 SwapChainBase(DeviceBase* device, ObjectBase::ErrorTag tag); 49 ~SwapChainBase() override; 50 }; 51 52 // The base class for implementation-based SwapChains that are deprecated. 53 class OldSwapChainBase : public SwapChainBase { 54 public: 55 OldSwapChainBase(DeviceBase* device, const SwapChainDescriptor* descriptor); 56 57 static SwapChainBase* MakeError(DeviceBase* device); 58 59 // Dawn API 60 void Configure(wgpu::TextureFormat format, 61 wgpu::TextureUsage allowedUsage, 62 uint32_t width, 63 uint32_t height) override; 64 TextureViewBase* GetCurrentTextureView() override; 65 void Present() override; 66 67 protected: 68 ~OldSwapChainBase() override; 69 const DawnSwapChainImplementation& GetImplementation(); 70 virtual TextureBase* GetNextTextureImpl(const TextureDescriptor*) = 0; 71 virtual MaybeError OnBeforePresent(TextureViewBase* view) = 0; 72 73 private: 74 MaybeError ValidateConfigure(wgpu::TextureFormat format, 75 wgpu::TextureUsage allowedUsage, 76 uint32_t width, 77 uint32_t height) const; 78 MaybeError ValidateGetCurrentTextureView() const; 79 MaybeError ValidatePresent() const; 80 81 DawnSwapChainImplementation mImplementation = {}; 82 wgpu::TextureFormat mFormat = {}; 83 wgpu::TextureUsage mAllowedUsage; 84 uint32_t mWidth = 0; 85 uint32_t mHeight = 0; 86 Ref<TextureBase> mCurrentTexture; 87 Ref<TextureViewBase> mCurrentTextureView; 88 }; 89 90 // The base class for surface-based SwapChains that aren't ready yet. 91 class NewSwapChainBase : public SwapChainBase { 92 public: 93 NewSwapChainBase(DeviceBase* device, 94 Surface* surface, 95 const SwapChainDescriptor* descriptor); 96 97 // This is called when the swapchain is detached when one of the following happens: 98 // 99 // - The surface it is attached to is being destroyed. 100 // - The swapchain is being replaced by another one on the surface. 101 // 102 // Note that the surface has a Ref on the last swapchain that was used on it so the 103 // SwapChain destructor will only be called after one of the things above happens. 104 // 105 // The call for the detaching previous swapchain should be called inside the backend 106 // implementation of SwapChains. This is to allow them to acquire any resources before 107 // calling detach to make a seamless transition from the previous swapchain. 108 // 109 // Likewise the call for the swapchain being destroyed must be done in the backend's 110 // swapchain's destructor since C++ says it is UB to call virtual methods in the base class 111 // destructor. 112 void DetachFromSurface(); 113 114 void SetIsAttached(); 115 116 // Dawn API 117 void Configure(wgpu::TextureFormat format, 118 wgpu::TextureUsage allowedUsage, 119 uint32_t width, 120 uint32_t height) override; 121 TextureViewBase* GetCurrentTextureView() override; 122 void Present() override; 123 124 uint32_t GetWidth() const; 125 uint32_t GetHeight() const; 126 wgpu::TextureFormat GetFormat() const; 127 wgpu::TextureUsage GetUsage() const; 128 wgpu::PresentMode GetPresentMode() const; 129 Surface* GetSurface() const; 130 bool IsAttached() const; 131 wgpu::BackendType GetBackendType() const; 132 133 protected: 134 ~NewSwapChainBase() override; 135 136 private: 137 bool mAttached; 138 uint32_t mWidth; 139 uint32_t mHeight; 140 wgpu::TextureFormat mFormat; 141 wgpu::TextureUsage mUsage; 142 wgpu::PresentMode mPresentMode; 143 144 // This is a weak reference to the surface. If the surface is destroyed it will call 145 // DetachFromSurface and mSurface will be updated to nullptr. 146 Surface* mSurface = nullptr; 147 Ref<TextureViewBase> mCurrentTextureView; 148 149 MaybeError ValidatePresent() const; 150 MaybeError ValidateGetCurrentTextureView() const; 151 152 // GetCurrentTextureViewImpl and PresentImpl are guaranteed to be called in an interleaved 153 // manner, starting with GetCurrentTextureViewImpl. 154 155 // The returned texture view must match the swapchain descriptor exactly. 156 virtual ResultOrError<TextureViewBase*> GetCurrentTextureViewImpl() = 0; 157 // The call to present must destroy the current view's texture so further access to it are 158 // invalid. 159 virtual MaybeError PresentImpl() = 0; 160 161 // Guaranteed to be called exactly once during the lifetime of the SwapChain. After it is 162 // called no other virtual method can be called. 163 virtual void DetachFromSurfaceImpl() = 0; 164 }; 165 166 } // namespace dawn_native 167 168 #endif // DAWNNATIVE_SWAPCHAIN_H_ 169