xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/SurfaceVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // SurfaceVk.h:
7*8975f5c5SAndroid Build Coastguard Worker //    Defines the class interface for SurfaceVk, implementing SurfaceImpl.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
11*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include "common/CircularBuffer.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/SimpleMutex.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/vulkan/vk_headers.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/SurfaceImpl.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CommandProcessor.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_helpers.h"
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker namespace rx
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker class SurfaceVk : public SurfaceImpl, public angle::ObserverInterface, public vk::Resource
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker   public:
26*8975f5c5SAndroid Build Coastguard Worker     angle::Result getAttachmentRenderTarget(const gl::Context *context,
27*8975f5c5SAndroid Build Coastguard Worker                                             GLenum binding,
28*8975f5c5SAndroid Build Coastguard Worker                                             const gl::ImageIndex &imageIndex,
29*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei samples,
30*8975f5c5SAndroid Build Coastguard Worker                                             FramebufferAttachmentRenderTarget **rtOut) override;
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker   protected:
33*8975f5c5SAndroid Build Coastguard Worker     SurfaceVk(const egl::SurfaceState &surfaceState);
34*8975f5c5SAndroid Build Coastguard Worker     ~SurfaceVk() override;
35*8975f5c5SAndroid Build Coastguard Worker 
36*8975f5c5SAndroid Build Coastguard Worker     void destroy(const egl::Display *display) override;
37*8975f5c5SAndroid Build Coastguard Worker     // We monitor the staging buffer for changes. This handles staged data from outside this class.
38*8975f5c5SAndroid Build Coastguard Worker     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker     // width and height can change with client window resizing
41*8975f5c5SAndroid Build Coastguard Worker     EGLint getWidth() const override;
42*8975f5c5SAndroid Build Coastguard Worker     EGLint getHeight() const override;
43*8975f5c5SAndroid Build Coastguard Worker 
44*8975f5c5SAndroid Build Coastguard Worker     EGLint mWidth;
45*8975f5c5SAndroid Build Coastguard Worker     EGLint mHeight;
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker     RenderTargetVk mColorRenderTarget;
48*8975f5c5SAndroid Build Coastguard Worker     RenderTargetVk mDepthStencilRenderTarget;
49*8975f5c5SAndroid Build Coastguard Worker };
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker class OffscreenSurfaceVk : public SurfaceVk
52*8975f5c5SAndroid Build Coastguard Worker {
53*8975f5c5SAndroid Build Coastguard Worker   public:
54*8975f5c5SAndroid Build Coastguard Worker     OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, vk::Renderer *renderer);
55*8975f5c5SAndroid Build Coastguard Worker     ~OffscreenSurfaceVk() override;
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker     egl::Error initialize(const egl::Display *display) override;
58*8975f5c5SAndroid Build Coastguard Worker     void destroy(const egl::Display *display) override;
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker     egl::Error unMakeCurrent(const gl::Context *context) override;
getColorImage()61*8975f5c5SAndroid Build Coastguard Worker     const vk::ImageHelper *getColorImage() const { return &mColorAttachment.image; }
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker     egl::Error swap(const gl::Context *context) override;
64*8975f5c5SAndroid Build Coastguard Worker     egl::Error postSubBuffer(const gl::Context *context,
65*8975f5c5SAndroid Build Coastguard Worker                              EGLint x,
66*8975f5c5SAndroid Build Coastguard Worker                              EGLint y,
67*8975f5c5SAndroid Build Coastguard Worker                              EGLint width,
68*8975f5c5SAndroid Build Coastguard Worker                              EGLint height) override;
69*8975f5c5SAndroid Build Coastguard Worker     egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
70*8975f5c5SAndroid Build Coastguard Worker     egl::Error bindTexImage(const gl::Context *context,
71*8975f5c5SAndroid Build Coastguard Worker                             gl::Texture *texture,
72*8975f5c5SAndroid Build Coastguard Worker                             EGLint buffer) override;
73*8975f5c5SAndroid Build Coastguard Worker     egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
74*8975f5c5SAndroid Build Coastguard Worker     egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
75*8975f5c5SAndroid Build Coastguard Worker     egl::Error getMscRate(EGLint *numerator, EGLint *denominator) override;
76*8975f5c5SAndroid Build Coastguard Worker     void setSwapInterval(const egl::Display *display, EGLint interval) override;
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker     EGLint isPostSubBufferSupported() const override;
79*8975f5c5SAndroid Build Coastguard Worker     EGLint getSwapBehavior() const override;
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker     angle::Result initializeContents(const gl::Context *context,
82*8975f5c5SAndroid Build Coastguard Worker                                      GLenum binding,
83*8975f5c5SAndroid Build Coastguard Worker                                      const gl::ImageIndex &imageIndex) override;
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper *getColorAttachmentImage();
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker     egl::Error lockSurface(const egl::Display *display,
88*8975f5c5SAndroid Build Coastguard Worker                            EGLint usageHint,
89*8975f5c5SAndroid Build Coastguard Worker                            bool preservePixels,
90*8975f5c5SAndroid Build Coastguard Worker                            uint8_t **bufferPtrOut,
91*8975f5c5SAndroid Build Coastguard Worker                            EGLint *bufferPitchOut) override;
92*8975f5c5SAndroid Build Coastguard Worker     egl::Error unlockSurface(const egl::Display *display, bool preservePixels) override;
93*8975f5c5SAndroid Build Coastguard Worker     EGLint origin() const override;
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     egl::Error attachToFramebuffer(const gl::Context *context,
96*8975f5c5SAndroid Build Coastguard Worker                                    gl::Framebuffer *framebuffer) override;
97*8975f5c5SAndroid Build Coastguard Worker     egl::Error detachFromFramebuffer(const gl::Context *context,
98*8975f5c5SAndroid Build Coastguard Worker                                      gl::Framebuffer *framebuffer) override;
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker   protected:
101*8975f5c5SAndroid Build Coastguard Worker     struct AttachmentImage final : angle::NonCopyable
102*8975f5c5SAndroid Build Coastguard Worker     {
103*8975f5c5SAndroid Build Coastguard Worker         AttachmentImage(SurfaceVk *surfaceVk);
104*8975f5c5SAndroid Build Coastguard Worker         ~AttachmentImage();
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker         angle::Result initialize(DisplayVk *displayVk,
107*8975f5c5SAndroid Build Coastguard Worker                                  EGLint width,
108*8975f5c5SAndroid Build Coastguard Worker                                  EGLint height,
109*8975f5c5SAndroid Build Coastguard Worker                                  const vk::Format &vkFormat,
110*8975f5c5SAndroid Build Coastguard Worker                                  GLint samples,
111*8975f5c5SAndroid Build Coastguard Worker                                  bool isRobustResourceInitEnabled,
112*8975f5c5SAndroid Build Coastguard Worker                                  bool hasProtectedContent);
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker         void destroy(const egl::Display *display);
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker         vk::ImageHelper image;
117*8975f5c5SAndroid Build Coastguard Worker         vk::ImageViewHelper imageViews;
118*8975f5c5SAndroid Build Coastguard Worker         angle::ObserverBinding imageObserverBinding;
119*8975f5c5SAndroid Build Coastguard Worker     };
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker     virtual angle::Result initializeImpl(DisplayVk *displayVk);
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     AttachmentImage mColorAttachment;
124*8975f5c5SAndroid Build Coastguard Worker     AttachmentImage mDepthStencilAttachment;
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker     // EGL_KHR_lock_surface3
127*8975f5c5SAndroid Build Coastguard Worker     vk::BufferHelper mLockBufferHelper;
128*8975f5c5SAndroid Build Coastguard Worker };
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker // Data structures used in WindowSurfaceVk
131*8975f5c5SAndroid Build Coastguard Worker namespace impl
132*8975f5c5SAndroid Build Coastguard Worker {
133*8975f5c5SAndroid Build Coastguard Worker static constexpr size_t kSwapHistorySize = 2;
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker // Old swapchain and associated present fences/semaphores that need to be scheduled for
136*8975f5c5SAndroid Build Coastguard Worker // recycling/destruction when appropriate.
137*8975f5c5SAndroid Build Coastguard Worker struct SwapchainCleanupData : angle::NonCopyable
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker     SwapchainCleanupData();
140*8975f5c5SAndroid Build Coastguard Worker     SwapchainCleanupData(SwapchainCleanupData &&other);
141*8975f5c5SAndroid Build Coastguard Worker     ~SwapchainCleanupData();
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     // Fences must not be empty (VK_EXT_swapchain_maintenance1 is supported).
144*8975f5c5SAndroid Build Coastguard Worker     VkResult getFencesStatus(VkDevice device) const;
145*8975f5c5SAndroid Build Coastguard Worker     // Waits fences if any. Use before force destroying the swapchain.
146*8975f5c5SAndroid Build Coastguard Worker     void waitFences(VkDevice device, uint64_t timeout) const;
147*8975f5c5SAndroid Build Coastguard Worker     void destroy(VkDevice device,
148*8975f5c5SAndroid Build Coastguard Worker                  vk::Recycler<vk::Fence> *fenceRecycler,
149*8975f5c5SAndroid Build Coastguard Worker                  vk::Recycler<vk::Semaphore> *semaphoreRecycler);
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker     // The swapchain to be destroyed.
152*8975f5c5SAndroid Build Coastguard Worker     VkSwapchainKHR swapchain = VK_NULL_HANDLE;
153*8975f5c5SAndroid Build Coastguard Worker     // Any present fences/semaphores that were pending recycle at the time the swapchain was
154*8975f5c5SAndroid Build Coastguard Worker     // recreated will be scheduled for recycling at the same time as the swapchain's destruction.
155*8975f5c5SAndroid Build Coastguard Worker     // fences must be in the present operation order.
156*8975f5c5SAndroid Build Coastguard Worker     std::vector<vk::Fence> fences;
157*8975f5c5SAndroid Build Coastguard Worker     std::vector<vk::Semaphore> semaphores;
158*8975f5c5SAndroid Build Coastguard Worker };
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker // Each present operation is associated with a wait semaphore.  To know when that semaphore can be
161*8975f5c5SAndroid Build Coastguard Worker // recycled, a swapSerial is used.  When that swapSerial is finished, the semaphore used in the
162*8975f5c5SAndroid Build Coastguard Worker // previous present operation involving imageIndex can be recycled.  See doc/PresentSemaphores.md
163*8975f5c5SAndroid Build Coastguard Worker // for details.
164*8975f5c5SAndroid Build Coastguard Worker // When VK_EXT_swapchain_maintenance1 is supported, present fence is used instead of the swapSerial.
165*8975f5c5SAndroid Build Coastguard Worker //
166*8975f5c5SAndroid Build Coastguard Worker // Old swapchains are scheduled to be destroyed at the same time as the last wait semaphore used to
167*8975f5c5SAndroid Build Coastguard Worker // present an image to the old swapchains can be recycled (only relevant when
168*8975f5c5SAndroid Build Coastguard Worker // VK_EXT_swapchain_maintenance1 is not supported).
169*8975f5c5SAndroid Build Coastguard Worker struct ImagePresentOperation : angle::NonCopyable
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker     ImagePresentOperation();
172*8975f5c5SAndroid Build Coastguard Worker     ImagePresentOperation(ImagePresentOperation &&other);
173*8975f5c5SAndroid Build Coastguard Worker     ImagePresentOperation &operator=(ImagePresentOperation &&other);
174*8975f5c5SAndroid Build Coastguard Worker     ~ImagePresentOperation();
175*8975f5c5SAndroid Build Coastguard Worker 
176*8975f5c5SAndroid Build Coastguard Worker     void destroy(VkDevice device,
177*8975f5c5SAndroid Build Coastguard Worker                  vk::Recycler<vk::Fence> *fenceRecycler,
178*8975f5c5SAndroid Build Coastguard Worker                  vk::Recycler<vk::Semaphore> *semaphoreRecycler);
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker     // fence is only used when VK_EXT_swapchain_maintenance1 is supported.
181*8975f5c5SAndroid Build Coastguard Worker     vk::Fence fence;
182*8975f5c5SAndroid Build Coastguard Worker     vk::Semaphore semaphore;
183*8975f5c5SAndroid Build Coastguard Worker 
184*8975f5c5SAndroid Build Coastguard Worker     // Below members only relevant when VK_EXT_swapchain_maintenance1 is not supported.
185*8975f5c5SAndroid Build Coastguard Worker     // Used to associate a swapSerial with the previous present operation of the image.
186*8975f5c5SAndroid Build Coastguard Worker     uint32_t imageIndex;
187*8975f5c5SAndroid Build Coastguard Worker     QueueSerial queueSerial;
188*8975f5c5SAndroid Build Coastguard Worker     std::deque<SwapchainCleanupData> oldSwapchains;
189*8975f5c5SAndroid Build Coastguard Worker };
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker // Swapchain images and their associated objects.
192*8975f5c5SAndroid Build Coastguard Worker struct SwapchainImage : angle::NonCopyable
193*8975f5c5SAndroid Build Coastguard Worker {
194*8975f5c5SAndroid Build Coastguard Worker     SwapchainImage();
195*8975f5c5SAndroid Build Coastguard Worker     SwapchainImage(SwapchainImage &&other);
196*8975f5c5SAndroid Build Coastguard Worker     ~SwapchainImage();
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<vk::ImageHelper> image;
199*8975f5c5SAndroid Build Coastguard Worker     vk::ImageViewHelper imageViews;
200*8975f5c5SAndroid Build Coastguard Worker     vk::Framebuffer framebuffer;
201*8975f5c5SAndroid Build Coastguard Worker     vk::Framebuffer fetchFramebuffer;
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker     uint64_t frameNumber = 0;
204*8975f5c5SAndroid Build Coastguard Worker };
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker enum class ImageAcquireState
207*8975f5c5SAndroid Build Coastguard Worker {
208*8975f5c5SAndroid Build Coastguard Worker     Ready,
209*8975f5c5SAndroid Build Coastguard Worker     NeedToAcquire,
210*8975f5c5SAndroid Build Coastguard Worker     NeedToProcessResult,
211*8975f5c5SAndroid Build Coastguard Worker };
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker // Associated data for a call to vkAcquireNextImageKHR without necessarily holding the share group
214*8975f5c5SAndroid Build Coastguard Worker // and global locks but ONLY from a thread where Surface is current.
215*8975f5c5SAndroid Build Coastguard Worker struct UnlockedAcquireData : angle::NonCopyable
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker     // Given that the CPU is throttled after a number of swaps, there is an upper bound to the
218*8975f5c5SAndroid Build Coastguard Worker     // number of semaphores that are used to acquire swapchain images, and that is
219*8975f5c5SAndroid Build Coastguard Worker     // kSwapHistorySize+1:
220*8975f5c5SAndroid Build Coastguard Worker     //
221*8975f5c5SAndroid Build Coastguard Worker     //             Unrelated submission in     Submission as part of
222*8975f5c5SAndroid Build Coastguard Worker     //               the middle of frame          buffer swap
223*8975f5c5SAndroid Build Coastguard Worker     //                              |                 |
224*8975f5c5SAndroid Build Coastguard Worker     //                              V                 V
225*8975f5c5SAndroid Build Coastguard Worker     //     Frame i:     ... ANI ... QS (fence Fa) ... QS (Fence Fb) QP Wait(..)
226*8975f5c5SAndroid Build Coastguard Worker     //     Frame i+1:   ... ANI ... QS (fence Fc) ... QS (Fence Fd) QP Wait(..) <--\
227*8975f5c5SAndroid Build Coastguard Worker     //     Frame i+2:   ... ANI ... QS (fence Fe) ... QS (Fence Ff) QP Wait(Fb)    |
228*8975f5c5SAndroid Build Coastguard Worker     //                                                                  ^          |
229*8975f5c5SAndroid Build Coastguard Worker     //                                                                  |          |
230*8975f5c5SAndroid Build Coastguard Worker     //                                                           CPU throttling    |
231*8975f5c5SAndroid Build Coastguard Worker     //                                                                             |
232*8975f5c5SAndroid Build Coastguard Worker     //                               Note: app should throttle itself here (equivalent of Wait(Fb))
233*8975f5c5SAndroid Build Coastguard Worker     //
234*8975f5c5SAndroid Build Coastguard Worker     // In frame i+2 (2 is kSwapHistorySize), ANGLE waits on fence Fb which means that the semaphore
235*8975f5c5SAndroid Build Coastguard Worker     // used for Frame i's ANI can be reused (because Fb-is-signalled implies Fa-is-signalled).
236*8975f5c5SAndroid Build Coastguard Worker     // Before this wait, there were three acquire semaphores in use corresponding to frames i, i+1
237*8975f5c5SAndroid Build Coastguard Worker     // and i+2.  Frame i+3 can reuse the semaphore of frame i.
238*8975f5c5SAndroid Build Coastguard Worker     angle::CircularBuffer<vk::Semaphore, impl::kSwapHistorySize + 1> acquireImageSemaphores;
239*8975f5c5SAndroid Build Coastguard Worker };
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker struct UnlockedAcquireResult : angle::NonCopyable
242*8975f5c5SAndroid Build Coastguard Worker {
243*8975f5c5SAndroid Build Coastguard Worker     // The result of the call to vkAcquireNextImageKHR.
244*8975f5c5SAndroid Build Coastguard Worker     VkResult result = VK_SUCCESS;
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker     // Semaphore to signal.
247*8975f5c5SAndroid Build Coastguard Worker     VkSemaphore acquireSemaphore = VK_NULL_HANDLE;
248*8975f5c5SAndroid Build Coastguard Worker 
249*8975f5c5SAndroid Build Coastguard Worker     // Image index that was acquired
250*8975f5c5SAndroid Build Coastguard Worker     uint32_t imageIndex = std::numeric_limits<uint32_t>::max();
251*8975f5c5SAndroid Build Coastguard Worker };
252*8975f5c5SAndroid Build Coastguard Worker 
253*8975f5c5SAndroid Build Coastguard Worker struct ImageAcquireOperation : angle::NonCopyable
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker     // Initially image needs to be acquired.
256*8975f5c5SAndroid Build Coastguard Worker     ImageAcquireState state = ImageAcquireState::NeedToAcquire;
257*8975f5c5SAndroid Build Coastguard Worker 
258*8975f5c5SAndroid Build Coastguard Worker     // No synchronization is necessary when making the vkAcquireNextImageKHR call since it is ONLY
259*8975f5c5SAndroid Build Coastguard Worker     // possible on a thread where Surface is current.
260*8975f5c5SAndroid Build Coastguard Worker     UnlockedAcquireData unlockedAcquireData;
261*8975f5c5SAndroid Build Coastguard Worker     UnlockedAcquireResult unlockedAcquireResult;
262*8975f5c5SAndroid Build Coastguard Worker };
263*8975f5c5SAndroid Build Coastguard Worker }  // namespace impl
264*8975f5c5SAndroid Build Coastguard Worker 
265*8975f5c5SAndroid Build Coastguard Worker class WindowSurfaceVk : public SurfaceVk
266*8975f5c5SAndroid Build Coastguard Worker {
267*8975f5c5SAndroid Build Coastguard Worker   public:
268*8975f5c5SAndroid Build Coastguard Worker     WindowSurfaceVk(const egl::SurfaceState &surfaceState, EGLNativeWindowType window);
269*8975f5c5SAndroid Build Coastguard Worker     ~WindowSurfaceVk() override;
270*8975f5c5SAndroid Build Coastguard Worker 
271*8975f5c5SAndroid Build Coastguard Worker     void destroy(const egl::Display *display) override;
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     egl::Error initialize(const egl::Display *display) override;
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     egl::Error unMakeCurrent(const gl::Context *context) override;
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker     angle::Result getAttachmentRenderTarget(const gl::Context *context,
278*8975f5c5SAndroid Build Coastguard Worker                                             GLenum binding,
279*8975f5c5SAndroid Build Coastguard Worker                                             const gl::ImageIndex &imageIndex,
280*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei samples,
281*8975f5c5SAndroid Build Coastguard Worker                                             FramebufferAttachmentRenderTarget **rtOut) override;
282*8975f5c5SAndroid Build Coastguard Worker     egl::Error prepareSwap(const gl::Context *context) override;
283*8975f5c5SAndroid Build Coastguard Worker     egl::Error swap(const gl::Context *context) override;
284*8975f5c5SAndroid Build Coastguard Worker     egl::Error swapWithDamage(const gl::Context *context,
285*8975f5c5SAndroid Build Coastguard Worker                               const EGLint *rects,
286*8975f5c5SAndroid Build Coastguard Worker                               EGLint n_rects) override;
287*8975f5c5SAndroid Build Coastguard Worker     egl::Error postSubBuffer(const gl::Context *context,
288*8975f5c5SAndroid Build Coastguard Worker                              EGLint x,
289*8975f5c5SAndroid Build Coastguard Worker                              EGLint y,
290*8975f5c5SAndroid Build Coastguard Worker                              EGLint width,
291*8975f5c5SAndroid Build Coastguard Worker                              EGLint height) override;
292*8975f5c5SAndroid Build Coastguard Worker     egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
293*8975f5c5SAndroid Build Coastguard Worker     egl::Error bindTexImage(const gl::Context *context,
294*8975f5c5SAndroid Build Coastguard Worker                             gl::Texture *texture,
295*8975f5c5SAndroid Build Coastguard Worker                             EGLint buffer) override;
296*8975f5c5SAndroid Build Coastguard Worker     egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
297*8975f5c5SAndroid Build Coastguard Worker     egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
298*8975f5c5SAndroid Build Coastguard Worker     egl::Error getMscRate(EGLint *numerator, EGLint *denominator) override;
299*8975f5c5SAndroid Build Coastguard Worker     void setSwapInterval(const egl::Display *display, EGLint interval) override;
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker     // Note: windows cannot be resized on Android.  The approach requires
302*8975f5c5SAndroid Build Coastguard Worker     // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR.  However, that is
303*8975f5c5SAndroid Build Coastguard Worker     // expensive; and there are troublesome timing issues for other parts of
304*8975f5c5SAndroid Build Coastguard Worker     // ANGLE (which cause test failures and crashes).  Therefore, a
305*8975f5c5SAndroid Build Coastguard Worker     // special-Android-only path is created just for the querying of EGL_WIDTH
306*8975f5c5SAndroid Build Coastguard Worker     // and EGL_HEIGHT.
307*8975f5c5SAndroid Build Coastguard Worker     // https://issuetracker.google.com/issues/153329980
308*8975f5c5SAndroid Build Coastguard Worker     egl::Error getUserWidth(const egl::Display *display, EGLint *value) const override;
309*8975f5c5SAndroid Build Coastguard Worker     egl::Error getUserHeight(const egl::Display *display, EGLint *value) const override;
310*8975f5c5SAndroid Build Coastguard Worker     angle::Result getUserExtentsImpl(DisplayVk *displayVk,
311*8975f5c5SAndroid Build Coastguard Worker                                      VkSurfaceCapabilitiesKHR *surfaceCaps) const;
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     EGLint isPostSubBufferSupported() const override;
314*8975f5c5SAndroid Build Coastguard Worker     EGLint getSwapBehavior() const override;
315*8975f5c5SAndroid Build Coastguard Worker 
316*8975f5c5SAndroid Build Coastguard Worker     angle::Result initializeContents(const gl::Context *context,
317*8975f5c5SAndroid Build Coastguard Worker                                      GLenum binding,
318*8975f5c5SAndroid Build Coastguard Worker                                      const gl::ImageIndex &imageIndex) override;
319*8975f5c5SAndroid Build Coastguard Worker 
320*8975f5c5SAndroid Build Coastguard Worker     vk::Framebuffer &chooseFramebuffer();
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     angle::Result getCurrentFramebuffer(ContextVk *context,
323*8975f5c5SAndroid Build Coastguard Worker                                         vk::FramebufferFetchMode fetchMode,
324*8975f5c5SAndroid Build Coastguard Worker                                         const vk::RenderPass &compatibleRenderPass,
325*8975f5c5SAndroid Build Coastguard Worker                                         vk::Framebuffer *framebufferOut);
326*8975f5c5SAndroid Build Coastguard Worker 
getPreTransform()327*8975f5c5SAndroid Build Coastguard Worker     VkSurfaceTransformFlagBitsKHR getPreTransform() const
328*8975f5c5SAndroid Build Coastguard Worker     {
329*8975f5c5SAndroid Build Coastguard Worker         if (mEmulatedPreTransform != VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
330*8975f5c5SAndroid Build Coastguard Worker         {
331*8975f5c5SAndroid Build Coastguard Worker             return mEmulatedPreTransform;
332*8975f5c5SAndroid Build Coastguard Worker         }
333*8975f5c5SAndroid Build Coastguard Worker         return mPreTransform;
334*8975f5c5SAndroid Build Coastguard Worker     }
335*8975f5c5SAndroid Build Coastguard Worker 
336*8975f5c5SAndroid Build Coastguard Worker     egl::Error setAutoRefreshEnabled(bool enabled) override;
337*8975f5c5SAndroid Build Coastguard Worker 
338*8975f5c5SAndroid Build Coastguard Worker     egl::Error getBufferAge(const gl::Context *context, EGLint *age) override;
339*8975f5c5SAndroid Build Coastguard Worker 
340*8975f5c5SAndroid Build Coastguard Worker     egl::Error setRenderBuffer(EGLint renderBuffer) override;
341*8975f5c5SAndroid Build Coastguard Worker 
isSharedPresentMode()342*8975f5c5SAndroid Build Coastguard Worker     bool isSharedPresentMode() const
343*8975f5c5SAndroid Build Coastguard Worker     {
344*8975f5c5SAndroid Build Coastguard Worker         return (mSwapchainPresentMode == vk::PresentMode::SharedDemandRefreshKHR ||
345*8975f5c5SAndroid Build Coastguard Worker                 mSwapchainPresentMode == vk::PresentMode::SharedContinuousRefreshKHR);
346*8975f5c5SAndroid Build Coastguard Worker     }
347*8975f5c5SAndroid Build Coastguard Worker 
isSharedPresentModeDesired()348*8975f5c5SAndroid Build Coastguard Worker     bool isSharedPresentModeDesired() const
349*8975f5c5SAndroid Build Coastguard Worker     {
350*8975f5c5SAndroid Build Coastguard Worker         return (mDesiredSwapchainPresentMode == vk::PresentMode::SharedDemandRefreshKHR ||
351*8975f5c5SAndroid Build Coastguard Worker                 mDesiredSwapchainPresentMode == vk::PresentMode::SharedContinuousRefreshKHR);
352*8975f5c5SAndroid Build Coastguard Worker     }
353*8975f5c5SAndroid Build Coastguard Worker 
354*8975f5c5SAndroid Build Coastguard Worker     egl::Error lockSurface(const egl::Display *display,
355*8975f5c5SAndroid Build Coastguard Worker                            EGLint usageHint,
356*8975f5c5SAndroid Build Coastguard Worker                            bool preservePixels,
357*8975f5c5SAndroid Build Coastguard Worker                            uint8_t **bufferPtrOut,
358*8975f5c5SAndroid Build Coastguard Worker                            EGLint *bufferPitchOut) override;
359*8975f5c5SAndroid Build Coastguard Worker     egl::Error unlockSurface(const egl::Display *display, bool preservePixels) override;
360*8975f5c5SAndroid Build Coastguard Worker     EGLint origin() const override;
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker     egl::Error attachToFramebuffer(const gl::Context *context,
363*8975f5c5SAndroid Build Coastguard Worker                                    gl::Framebuffer *framebuffer) override;
364*8975f5c5SAndroid Build Coastguard Worker     egl::Error detachFromFramebuffer(const gl::Context *context,
365*8975f5c5SAndroid Build Coastguard Worker                                      gl::Framebuffer *framebuffer) override;
366*8975f5c5SAndroid Build Coastguard Worker 
367*8975f5c5SAndroid Build Coastguard Worker     angle::Result onSharedPresentContextFlush(const gl::Context *context);
368*8975f5c5SAndroid Build Coastguard Worker 
369*8975f5c5SAndroid Build Coastguard Worker     bool hasStagedUpdates() const;
370*8975f5c5SAndroid Build Coastguard Worker 
371*8975f5c5SAndroid Build Coastguard Worker     void setTimestampsEnabled(bool enabled) override;
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker   protected:
374*8975f5c5SAndroid Build Coastguard Worker     angle::Result swapImpl(const gl::Context *context,
375*8975f5c5SAndroid Build Coastguard Worker                            const EGLint *rects,
376*8975f5c5SAndroid Build Coastguard Worker                            EGLint n_rects,
377*8975f5c5SAndroid Build Coastguard Worker                            const void *pNextChain);
378*8975f5c5SAndroid Build Coastguard Worker     // Called when a swapchain image whose acquisition was deferred must be acquired.  This method
379*8975f5c5SAndroid Build Coastguard Worker     // will recreate the swapchain (if needed due to present returning OUT_OF_DATE, swap interval
380*8975f5c5SAndroid Build Coastguard Worker     // changing, surface size changing etc, by calling prepareForAcquireNextSwapchainImage()) and
381*8975f5c5SAndroid Build Coastguard Worker     // call the doDeferredAcquireNextImageWithUsableSwapchain() method.
382*8975f5c5SAndroid Build Coastguard Worker     angle::Result doDeferredAcquireNextImage(const gl::Context *context,
383*8975f5c5SAndroid Build Coastguard Worker                                              bool forceSwapchainRecreate);
384*8975f5c5SAndroid Build Coastguard Worker     // Calls acquireNextSwapchainImage() and sets up the acquired image.  On some platforms,
385*8975f5c5SAndroid Build Coastguard Worker     // vkAcquireNextImageKHR returns OUT_OF_DATE instead of present, so this function may still
386*8975f5c5SAndroid Build Coastguard Worker     // recreate the swapchain.  The main difference with doDeferredAcquireNextImage is that it does
387*8975f5c5SAndroid Build Coastguard Worker     // not check for surface property changes for the purposes of swapchain recreation (because
388*8975f5c5SAndroid Build Coastguard Worker     // that's already done by prepareForAcquireNextSwapchainImage.
389*8975f5c5SAndroid Build Coastguard Worker     angle::Result doDeferredAcquireNextImageWithUsableSwapchain(const gl::Context *context);
390*8975f5c5SAndroid Build Coastguard Worker 
391*8975f5c5SAndroid Build Coastguard Worker     EGLNativeWindowType mNativeWindowType;
392*8975f5c5SAndroid Build Coastguard Worker     VkSurfaceKHR mSurface;
393*8975f5c5SAndroid Build Coastguard Worker     VkSurfaceCapabilitiesKHR mSurfaceCaps;
394*8975f5c5SAndroid Build Coastguard Worker     VkBool32 mSupportsProtectedSwapchain;
395*8975f5c5SAndroid Build Coastguard Worker 
396*8975f5c5SAndroid Build Coastguard Worker   private:
397*8975f5c5SAndroid Build Coastguard Worker     virtual angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut)      = 0;
398*8975f5c5SAndroid Build Coastguard Worker     virtual angle::Result getCurrentWindowSize(vk::Context *context, gl::Extents *extentsOut) = 0;
399*8975f5c5SAndroid Build Coastguard Worker 
400*8975f5c5SAndroid Build Coastguard Worker     void setSwapInterval(DisplayVk *displayVk, EGLint interval);
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker     angle::Result initializeImpl(DisplayVk *displayVk, bool *anyMatchesOut);
403*8975f5c5SAndroid Build Coastguard Worker     angle::Result recreateSwapchain(ContextVk *contextVk, const gl::Extents &extents);
404*8975f5c5SAndroid Build Coastguard Worker     angle::Result createSwapChain(vk::Context *context, const gl::Extents &extents);
405*8975f5c5SAndroid Build Coastguard Worker     angle::Result collectOldSwapchain(ContextVk *contextVk, VkSwapchainKHR swapchain);
406*8975f5c5SAndroid Build Coastguard Worker     angle::Result queryAndAdjustSurfaceCaps(ContextVk *contextVk,
407*8975f5c5SAndroid Build Coastguard Worker                                             VkSurfaceCapabilitiesKHR *surfaceCaps);
408*8975f5c5SAndroid Build Coastguard Worker     angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk, bool forceRecreate);
409*8975f5c5SAndroid Build Coastguard Worker     angle::Result resizeSwapchainImages(vk::Context *context, uint32_t imageCount);
410*8975f5c5SAndroid Build Coastguard Worker     void releaseSwapchainImages(ContextVk *contextVk);
411*8975f5c5SAndroid Build Coastguard Worker     void destroySwapChainImages(DisplayVk *displayVk);
412*8975f5c5SAndroid Build Coastguard Worker     angle::Result prepareForAcquireNextSwapchainImage(const gl::Context *context,
413*8975f5c5SAndroid Build Coastguard Worker                                                       bool forceSwapchainRecreate);
414*8975f5c5SAndroid Build Coastguard Worker     // This method calls vkAcquireNextImageKHR() to acquire the next swapchain image.  It is called
415*8975f5c5SAndroid Build Coastguard Worker     // when the swapchain is initially created and when present() finds the swapchain out of date.
416*8975f5c5SAndroid Build Coastguard Worker     // Otherwise, it is scheduled to be called later by deferAcquireNextImage().
417*8975f5c5SAndroid Build Coastguard Worker     VkResult acquireNextSwapchainImage(vk::Context *context);
418*8975f5c5SAndroid Build Coastguard Worker     // Process the result of vkAcquireNextImageKHR.
419*8975f5c5SAndroid Build Coastguard Worker     VkResult postProcessUnlockedAcquire(vk::Context *context);
420*8975f5c5SAndroid Build Coastguard Worker     // This method is called when a swapchain image is presented.  It schedules
421*8975f5c5SAndroid Build Coastguard Worker     // acquireNextSwapchainImage() to be called later.
422*8975f5c5SAndroid Build Coastguard Worker     void deferAcquireNextImage();
423*8975f5c5SAndroid Build Coastguard Worker     bool skipAcquireNextSwapchainImageForSharedPresentMode() const;
424*8975f5c5SAndroid Build Coastguard Worker 
425*8975f5c5SAndroid Build Coastguard Worker     angle::Result computePresentOutOfDate(vk::Context *context,
426*8975f5c5SAndroid Build Coastguard Worker                                           VkResult result,
427*8975f5c5SAndroid Build Coastguard Worker                                           bool *presentOutOfDate);
428*8975f5c5SAndroid Build Coastguard Worker     angle::Result prePresentSubmit(ContextVk *contextVk, const vk::Semaphore &presentSemaphore);
429*8975f5c5SAndroid Build Coastguard Worker     angle::Result present(ContextVk *contextVk,
430*8975f5c5SAndroid Build Coastguard Worker                           const EGLint *rects,
431*8975f5c5SAndroid Build Coastguard Worker                           EGLint n_rects,
432*8975f5c5SAndroid Build Coastguard Worker                           const void *pNextChain,
433*8975f5c5SAndroid Build Coastguard Worker                           bool *presentOutOfDate);
434*8975f5c5SAndroid Build Coastguard Worker 
435*8975f5c5SAndroid Build Coastguard Worker     angle::Result cleanUpPresentHistory(vk::Context *context);
436*8975f5c5SAndroid Build Coastguard Worker     angle::Result cleanUpOldSwapchains(vk::Context *context);
437*8975f5c5SAndroid Build Coastguard Worker 
438*8975f5c5SAndroid Build Coastguard Worker     // Throttle the CPU such that application's logic and command buffer recording doesn't get more
439*8975f5c5SAndroid Build Coastguard Worker     // than two frame ahead of the frame being rendered (and three frames ahead of the one being
440*8975f5c5SAndroid Build Coastguard Worker     // presented).  This is a failsafe, as the application should ensure command buffer recording is
441*8975f5c5SAndroid Build Coastguard Worker     // not ahead of the frame being rendered by *one* frame.
442*8975f5c5SAndroid Build Coastguard Worker     angle::Result throttleCPU(vk::Context *context, const QueueSerial &currentSubmitSerial);
443*8975f5c5SAndroid Build Coastguard Worker 
444*8975f5c5SAndroid Build Coastguard Worker     // Finish all GPU operations on the surface
445*8975f5c5SAndroid Build Coastguard Worker     angle::Result finish(vk::Context *context);
446*8975f5c5SAndroid Build Coastguard Worker 
447*8975f5c5SAndroid Build Coastguard Worker     void updateOverlay(ContextVk *contextVk) const;
448*8975f5c5SAndroid Build Coastguard Worker     bool overlayHasEnabledWidget(ContextVk *contextVk) const;
449*8975f5c5SAndroid Build Coastguard Worker     angle::Result drawOverlay(ContextVk *contextVk, impl::SwapchainImage *image) const;
450*8975f5c5SAndroid Build Coastguard Worker 
451*8975f5c5SAndroid Build Coastguard Worker     bool isMultiSampled() const;
452*8975f5c5SAndroid Build Coastguard Worker 
453*8975f5c5SAndroid Build Coastguard Worker     bool supportsPresentMode(vk::PresentMode presentMode) const;
454*8975f5c5SAndroid Build Coastguard Worker 
455*8975f5c5SAndroid Build Coastguard Worker     bool updateColorSpace(DisplayVk *displayVk);
456*8975f5c5SAndroid Build Coastguard Worker 
457*8975f5c5SAndroid Build Coastguard Worker     angle::FormatID getIntendedFormatID(vk::Renderer *renderer);
458*8975f5c5SAndroid Build Coastguard Worker     angle::FormatID getActualFormatID(vk::Renderer *renderer);
459*8975f5c5SAndroid Build Coastguard Worker 
460*8975f5c5SAndroid Build Coastguard Worker     std::vector<vk::PresentMode> mPresentModes;
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker     VkSwapchainKHR mSwapchain;      // Current swapchain (same as last created or NULL)
463*8975f5c5SAndroid Build Coastguard Worker     VkSwapchainKHR mLastSwapchain;  // Last created non retired swapchain (or NULL if retired)
464*8975f5c5SAndroid Build Coastguard Worker     vk::SwapchainStatus mSwapchainStatus;
465*8975f5c5SAndroid Build Coastguard Worker     // Cached information used to recreate swapchains.
466*8975f5c5SAndroid Build Coastguard Worker     vk::PresentMode mSwapchainPresentMode;         // Current swapchain mode
467*8975f5c5SAndroid Build Coastguard Worker     vk::PresentMode mDesiredSwapchainPresentMode;  // Desired mode set through setSwapInterval()
468*8975f5c5SAndroid Build Coastguard Worker     uint32_t mMinImageCount;
469*8975f5c5SAndroid Build Coastguard Worker     VkSurfaceTransformFlagBitsKHR mPreTransform;
470*8975f5c5SAndroid Build Coastguard Worker     VkSurfaceTransformFlagBitsKHR mEmulatedPreTransform;
471*8975f5c5SAndroid Build Coastguard Worker     VkCompositeAlphaFlagBitsKHR mCompositeAlpha;
472*8975f5c5SAndroid Build Coastguard Worker     VkColorSpaceKHR mSurfaceColorSpace;
473*8975f5c5SAndroid Build Coastguard Worker 
474*8975f5c5SAndroid Build Coastguard Worker     // Present modes that are compatible with the current mode.  If mDesiredSwapchainPresentMode is
475*8975f5c5SAndroid Build Coastguard Worker     // in this list, mode switch can happen without the need to recreate the swapchain.
476*8975f5c5SAndroid Build Coastguard Worker     // There are currently only 6 possible present modes but vector is bigger for a workaround.
477*8975f5c5SAndroid Build Coastguard Worker     static constexpr uint32_t kCompatiblePresentModesSize = 10;
478*8975f5c5SAndroid Build Coastguard Worker     angle::FixedVector<VkPresentModeKHR, kCompatiblePresentModesSize> mCompatiblePresentModes;
479*8975f5c5SAndroid Build Coastguard Worker 
480*8975f5c5SAndroid Build Coastguard Worker     // A circular buffer that stores the serial of the submission fence of the context on every
481*8975f5c5SAndroid Build Coastguard Worker     // swap. The CPU is throttled by waiting for the 2nd previous serial to finish.  This should
482*8975f5c5SAndroid Build Coastguard Worker     // normally be a no-op, as the application should pace itself to avoid input lag, and is
483*8975f5c5SAndroid Build Coastguard Worker     // implemented in ANGLE as a fail safe.  Removing this throttling requires untangling it from
484*8975f5c5SAndroid Build Coastguard Worker     // acquire semaphore recycling (see mAcquireImageSemaphores above)
485*8975f5c5SAndroid Build Coastguard Worker     angle::CircularBuffer<QueueSerial, impl::kSwapHistorySize> mSwapHistory;
486*8975f5c5SAndroid Build Coastguard Worker 
487*8975f5c5SAndroid Build Coastguard Worker     // The previous swapchain which needs to be scheduled for destruction when appropriate.  This
488*8975f5c5SAndroid Build Coastguard Worker     // will be done when the first image of the current swapchain is presented or when fences are
489*8975f5c5SAndroid Build Coastguard Worker     // signaled (when VK_EXT_swapchain_maintenance1 is supported).  If there were older swapchains
490*8975f5c5SAndroid Build Coastguard Worker     // pending destruction when the swapchain is recreated, they will accumulate and be destroyed
491*8975f5c5SAndroid Build Coastguard Worker     // with the previous swapchain.
492*8975f5c5SAndroid Build Coastguard Worker     //
493*8975f5c5SAndroid Build Coastguard Worker     // Note that if the user resizes the window such that the swapchain is recreated every frame,
494*8975f5c5SAndroid Build Coastguard Worker     // this array can go grow indefinitely.
495*8975f5c5SAndroid Build Coastguard Worker     std::deque<impl::SwapchainCleanupData> mOldSwapchains;
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     std::vector<impl::SwapchainImage> mSwapchainImages;
498*8975f5c5SAndroid Build Coastguard Worker     std::vector<angle::ObserverBinding> mSwapchainImageBindings;
499*8975f5c5SAndroid Build Coastguard Worker     uint32_t mCurrentSwapchainImageIndex;
500*8975f5c5SAndroid Build Coastguard Worker 
501*8975f5c5SAndroid Build Coastguard Worker     // There is no direct signal from Vulkan regarding when a Present semaphore can be be reused.
502*8975f5c5SAndroid Build Coastguard Worker     // During window resizing when swapchains are recreated every frame, the number of in-flight
503*8975f5c5SAndroid Build Coastguard Worker     // present semaphores can grow indefinitely.  See doc/PresentSemaphores.md.
504*8975f5c5SAndroid Build Coastguard Worker     vk::Recycler<vk::Semaphore> mPresentSemaphoreRecycler;
505*8975f5c5SAndroid Build Coastguard Worker     // Fences are associated with present semaphores to know when they can be recycled.
506*8975f5c5SAndroid Build Coastguard Worker     vk::Recycler<vk::Fence> mPresentFenceRecycler;
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker     // The presentation history, used to recycle semaphores and destroy old swapchains.
509*8975f5c5SAndroid Build Coastguard Worker     std::deque<impl::ImagePresentOperation> mPresentHistory;
510*8975f5c5SAndroid Build Coastguard Worker 
511*8975f5c5SAndroid Build Coastguard Worker     // Depth/stencil image.  Possibly multisampled.
512*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper mDepthStencilImage;
513*8975f5c5SAndroid Build Coastguard Worker     vk::ImageViewHelper mDepthStencilImageViews;
514*8975f5c5SAndroid Build Coastguard Worker     angle::ObserverBinding mDepthStencilImageBinding;
515*8975f5c5SAndroid Build Coastguard Worker 
516*8975f5c5SAndroid Build Coastguard Worker     // Multisample color image, view and framebuffer, if multisampling enabled.
517*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper mColorImageMS;
518*8975f5c5SAndroid Build Coastguard Worker     vk::ImageViewHelper mColorImageMSViews;
519*8975f5c5SAndroid Build Coastguard Worker     angle::ObserverBinding mColorImageMSBinding;
520*8975f5c5SAndroid Build Coastguard Worker     vk::Framebuffer mFramebufferMS;
521*8975f5c5SAndroid Build Coastguard Worker 
522*8975f5c5SAndroid Build Coastguard Worker     impl::ImageAcquireOperation mAcquireOperation;
523*8975f5c5SAndroid Build Coastguard Worker 
524*8975f5c5SAndroid Build Coastguard Worker     // EGL_EXT_buffer_age: Track frame count.
525*8975f5c5SAndroid Build Coastguard Worker     uint64_t mFrameCount;
526*8975f5c5SAndroid Build Coastguard Worker 
527*8975f5c5SAndroid Build Coastguard Worker     // EGL_KHR_lock_surface3
528*8975f5c5SAndroid Build Coastguard Worker     vk::BufferHelper mLockBufferHelper;
529*8975f5c5SAndroid Build Coastguard Worker 
530*8975f5c5SAndroid Build Coastguard Worker     // EGL_KHR_partial_update
531*8975f5c5SAndroid Build Coastguard Worker     uint64_t mBufferAgeQueryFrameNumber;
532*8975f5c5SAndroid Build Coastguard Worker 
533*8975f5c5SAndroid Build Coastguard Worker     // GL_EXT_shader_framebuffer_fetch
534*8975f5c5SAndroid Build Coastguard Worker     vk::FramebufferFetchMode mFramebufferFetchMode = vk::FramebufferFetchMode::None;
535*8975f5c5SAndroid Build Coastguard Worker };
536*8975f5c5SAndroid Build Coastguard Worker 
537*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
538*8975f5c5SAndroid Build Coastguard Worker 
539*8975f5c5SAndroid Build Coastguard Worker #endif  // LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
540