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 ApiObjectBase { 34 public: 35 SwapChainBase(DeviceBase* device); 36 37 static SwapChainBase* MakeError(DeviceBase* device); 38 39 ObjectType GetType() const override; 40 41 // Dawn API 42 virtual void APIConfigure(wgpu::TextureFormat format, 43 wgpu::TextureUsage allowedUsage, 44 uint32_t width, 45 uint32_t height) = 0; 46 virtual TextureViewBase* APIGetCurrentTextureView() = 0; 47 virtual void APIPresent() = 0; 48 49 protected: 50 SwapChainBase(DeviceBase* device, ObjectBase::ErrorTag tag); 51 ~SwapChainBase() override; 52 void DestroyImpl() override; 53 }; 54 55 // The base class for implementation-based SwapChains that are deprecated. 56 class OldSwapChainBase : public SwapChainBase { 57 public: 58 OldSwapChainBase(DeviceBase* device, const SwapChainDescriptor* descriptor); 59 60 // Dawn API 61 void APIConfigure(wgpu::TextureFormat format, 62 wgpu::TextureUsage allowedUsage, 63 uint32_t width, 64 uint32_t height) override; 65 TextureViewBase* APIGetCurrentTextureView() override; 66 void APIPresent() override; 67 68 protected: 69 ~OldSwapChainBase() override; 70 const DawnSwapChainImplementation& GetImplementation(); 71 virtual TextureBase* GetNextTextureImpl(const TextureDescriptor*) = 0; 72 virtual MaybeError OnBeforePresent(TextureViewBase* view) = 0; 73 74 private: 75 MaybeError ValidateConfigure(wgpu::TextureFormat format, 76 wgpu::TextureUsage allowedUsage, 77 uint32_t width, 78 uint32_t height) const; 79 MaybeError ValidateGetCurrentTextureView() const; 80 MaybeError ValidatePresent() const; 81 82 DawnSwapChainImplementation mImplementation = {}; 83 wgpu::TextureFormat mFormat = {}; 84 wgpu::TextureUsage mAllowedUsage; 85 uint32_t mWidth = 0; 86 uint32_t mHeight = 0; 87 Ref<TextureBase> mCurrentTexture; 88 Ref<TextureViewBase> mCurrentTextureView; 89 }; 90 91 // The base class for surface-based SwapChains that aren't ready yet. 92 class NewSwapChainBase : public SwapChainBase { 93 public: 94 NewSwapChainBase(DeviceBase* device, 95 Surface* surface, 96 const SwapChainDescriptor* descriptor); 97 98 // This is called when the swapchain is detached when one of the following happens: 99 // 100 // - The surface it is attached to is being destroyed. 101 // - The swapchain is being replaced by another one on the surface. 102 // 103 // Note that the surface has a Ref on the last swapchain that was used on it so the 104 // SwapChain destructor will only be called after one of the things above happens. 105 // 106 // The call for the detaching previous swapchain should be called inside the backend 107 // implementation of SwapChains. This is to allow them to acquire any resources before 108 // calling detach to make a seamless transition from the previous swapchain. 109 // 110 // Likewise the call for the swapchain being destroyed must be done in the backend's 111 // swapchain's destructor since C++ says it is UB to call virtual methods in the base class 112 // destructor. 113 void DetachFromSurface(); 114 115 void SetIsAttached(); 116 117 // Dawn API 118 void APIConfigure(wgpu::TextureFormat format, 119 wgpu::TextureUsage allowedUsage, 120 uint32_t width, 121 uint32_t height) override; 122 TextureViewBase* APIGetCurrentTextureView() override; 123 void APIPresent() override; 124 125 uint32_t GetWidth() const; 126 uint32_t GetHeight() const; 127 wgpu::TextureFormat GetFormat() const; 128 wgpu::TextureUsage GetUsage() const; 129 wgpu::PresentMode GetPresentMode() const; 130 Surface* GetSurface() const; 131 bool IsAttached() const; 132 wgpu::BackendType GetBackendType() const; 133 134 protected: 135 ~NewSwapChainBase() override; 136 137 private: 138 bool mAttached; 139 uint32_t mWidth; 140 uint32_t mHeight; 141 wgpu::TextureFormat mFormat; 142 wgpu::TextureUsage mUsage; 143 wgpu::PresentMode mPresentMode; 144 145 // This is a weak reference to the surface. If the surface is destroyed it will call 146 // DetachFromSurface and mSurface will be updated to nullptr. 147 Surface* mSurface = nullptr; 148 Ref<TextureViewBase> mCurrentTextureView; 149 150 MaybeError ValidatePresent() const; 151 MaybeError ValidateGetCurrentTextureView() const; 152 153 // GetCurrentTextureViewImpl and PresentImpl are guaranteed to be called in an interleaved 154 // manner, starting with GetCurrentTextureViewImpl. 155 156 // The returned texture view must match the swapchain descriptor exactly. 157 virtual ResultOrError<TextureViewBase*> GetCurrentTextureViewImpl() = 0; 158 // The call to present must destroy the current view's texture so further access to it are 159 // invalid. 160 virtual MaybeError PresentImpl() = 0; 161 162 // Guaranteed to be called exactly once during the lifetime of the SwapChain. After it is 163 // called no other virtual method can be called. 164 virtual void DetachFromSurfaceImpl() = 0; 165 }; 166 167 } // namespace dawn_native 168 169 #endif // DAWNNATIVE_SWAPCHAIN_H_ 170