• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SyncVk:
7 //    Defines the class interface for SyncVk, implementing SyncImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_
12 
13 #include "libANGLE/renderer/EGLSyncImpl.h"
14 #include "libANGLE/renderer/SyncImpl.h"
15 #include "libANGLE/renderer/vulkan/ResourceVk.h"
16 
17 namespace egl
18 {
19 class AttributeMap;
20 }
21 
22 namespace rx
23 {
24 namespace vk
25 {
26 
27 // Represents an invalid native fence FD.
28 constexpr int kInvalidFenceFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
29 
30 class ExternalFence final : angle::NonCopyable
31 {
32   public:
33     ExternalFence();
34     ~ExternalFence();
35 
36     VkResult init(VkDevice device, const VkFenceCreateInfo &createInfo);
37     void init(int fenceFd);
38 
getHandle()39     VkFence getHandle() const { return mFence.getHandle(); }
40     VkResult getStatus(VkDevice device) const;
41     VkResult wait(VkDevice device, uint64_t timeout) const;
42 
43     void exportFd(VkDevice device, const VkFenceGetFdInfoKHR &fenceGetFdInfo);
getFenceFdStatus()44     VkResult getFenceFdStatus() const { return mFenceFdStatus; }
getFenceFd()45     int getFenceFd() const { return mFenceFd; }
46 
47   private:
48     VkDevice mDevice;
49     Fence mFence;
50     VkResult mFenceFdStatus;
51     int mFenceFd;
52 };
53 
54 using SharedExternalFence = std::shared_ptr<ExternalFence>;
55 
56 class SyncHelperInterface : angle::NonCopyable
57 {
58   public:
59     virtual ~SyncHelperInterface() = default;
60 
61     virtual void releaseToRenderer(RendererVk *renderer) = 0;
62 
63     virtual angle::Result clientWait(Context *context,
64                                      ContextVk *contextVk,
65                                      bool flushCommands,
66                                      uint64_t timeout,
67                                      VkResult *outResult)                                      = 0;
68     virtual angle::Result serverWait(ContextVk *contextVk)                                     = 0;
69     virtual angle::Result getStatus(Context *context, ContextVk *contextVk, bool *signaledOut) = 0;
70     virtual angle::Result dupNativeFenceFD(Context *context, int *fdOut) const                 = 0;
71 };
72 
73 // Implementation of fence types - glFenceSync, and EGLSync(EGL_SYNC_FENCE_KHR).
74 // The behaviors of SyncVk and EGLFenceSyncVk as fence syncs are currently
75 // identical for the Vulkan backend, and this class implements both interfaces.
76 class SyncHelper final : public vk::Resource, public SyncHelperInterface
77 {
78   public:
79     SyncHelper();
80     ~SyncHelper() override;
81 
82     angle::Result initialize(ContextVk *contextVk, bool isEGLSyncObject);
83 
84     // SyncHelperInterface
85 
86     void releaseToRenderer(RendererVk *renderer) override;
87 
88     angle::Result clientWait(Context *context,
89                              ContextVk *contextVk,
90                              bool flushCommands,
91                              uint64_t timeout,
92                              VkResult *outResult) override;
93     angle::Result serverWait(ContextVk *contextVk) override;
94     angle::Result getStatus(Context *context, ContextVk *contextVk, bool *signaledOut) override;
dupNativeFenceFD(Context * context,int * fdOut)95     angle::Result dupNativeFenceFD(Context *context, int *fdOut) const override
96     {
97         return angle::Result::Stop;
98     }
99 
100   private:
101     angle::Result submitSyncIfDeferred(ContextVk *contextVk, RenderPassClosureReason reason);
102 };
103 
104 // Implementation of sync types: EGLSync(EGL_SYNC_ANDROID_NATIVE_FENCE_ANDROID).
105 class SyncHelperNativeFence final : public SyncHelperInterface
106 {
107   public:
108     SyncHelperNativeFence();
109     ~SyncHelperNativeFence() override;
110 
111     angle::Result initializeWithFd(ContextVk *contextVk, int inFd);
112 
113     // SyncHelperInterface
114 
115     void releaseToRenderer(RendererVk *renderer) override;
116 
117     angle::Result clientWait(Context *context,
118                              ContextVk *contextVk,
119                              bool flushCommands,
120                              uint64_t timeout,
121                              VkResult *outResult) override;
122     angle::Result serverWait(ContextVk *contextVk) override;
123     angle::Result getStatus(Context *context, ContextVk *contextVk, bool *signaledOut) override;
124     angle::Result dupNativeFenceFD(Context *context, int *fdOut) const override;
125 
126   private:
127     SharedExternalFence mExternalFence;
128 };
129 
130 }  // namespace vk
131 
132 // Implementor for glFenceSync.
133 class SyncVk final : public SyncImpl
134 {
135   public:
136     SyncVk();
137     ~SyncVk() override;
138 
139     void onDestroy(const gl::Context *context) override;
140 
141     angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override;
142     angle::Result clientWait(const gl::Context *context,
143                              GLbitfield flags,
144                              GLuint64 timeout,
145                              GLenum *outResult) override;
146     angle::Result serverWait(const gl::Context *context,
147                              GLbitfield flags,
148                              GLuint64 timeout) override;
149     angle::Result getStatus(const gl::Context *context, GLint *outResult) override;
150 
151   private:
152     vk::SyncHelper mSyncHelper;
153 };
154 
155 // Implementor for EGLSync.
156 class EGLSyncVk final : public EGLSyncImpl
157 {
158   public:
159     EGLSyncVk(const egl::AttributeMap &attribs);
160     ~EGLSyncVk() override;
161 
162     void onDestroy(const egl::Display *display) override;
163 
164     egl::Error initialize(const egl::Display *display,
165                           const gl::Context *context,
166                           EGLenum type) override;
167     egl::Error clientWait(const egl::Display *display,
168                           const gl::Context *context,
169                           EGLint flags,
170                           EGLTime timeout,
171                           EGLint *outResult) override;
172     egl::Error serverWait(const egl::Display *display,
173                           const gl::Context *context,
174                           EGLint flags) override;
175     egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
176 
177     egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const override;
178 
179   private:
180     EGLenum mType;
181     // SyncHelper or SyncHelperNativeFence decided at run-time.
182     vk::SyncHelperInterface *mSyncHelper;
183     EGLint mNativeFenceFD;
184 };
185 }  // namespace rx
186 
187 #endif  // LIBANGLE_RENDERER_VULKAN_FENCESYNCVK_H_
188