• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2020 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 // SyncMtl:
7 //    Defines the class interface for SyncMtl, implementing SyncImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_METAL_SYNCMTL_H_
11 #define LIBANGLE_RENDERER_METAL_SYNCMTL_H_
12 
13 #include <condition_variable>
14 #include <mutex>
15 
16 #include "libANGLE/renderer/EGLSyncImpl.h"
17 #include "libANGLE/renderer/FenceNVImpl.h"
18 #include "libANGLE/renderer/SyncImpl.h"
19 #include "libANGLE/renderer/metal/mtl_common.h"
20 
21 namespace egl
22 {
23 class AttributeMap;
24 }
25 
26 namespace rx
27 {
28 
29 class ContextMtl;
30 
31 namespace mtl
32 {
33 
34 // Common class to be used by both SyncImpl and EGLSyncImpl.
35 // NOTE: SharedEvent is only declared on iOS 12.0+ or mac 10.14+
36 #if defined(__IPHONE_12_0) || defined(__MAC_10_14)
37 class Sync
38 {
39   public:
40     Sync();
41     ~Sync();
42 
43     void onDestroy();
44 
45     angle::Result initialize(ContextMtl *contextMtl);
46 
47     angle::Result set(ContextMtl *contextMtl, GLenum condition, GLbitfield flags);
48     angle::Result clientWait(ContextMtl *contextMtl,
49                              bool flushCommands,
50                              uint64_t timeout,
51                              GLenum *outResult);
52     void serverWait(ContextMtl *contextMtl);
53     angle::Result getStatus(bool *signaled);
54 
55   private:
56     SharedEventRef mMetalSharedEvent;
57     uint64_t mSetCounter = 0;
58 
59     std::shared_ptr<std::condition_variable> mCv;
60     std::shared_ptr<std::mutex> mLock;
61 };
62 #else   // #if defined(__IPHONE_12_0) || defined(__MAC_10_14)
63 class Sync
64 {
65   public:
66     void onDestroy() { UNREACHABLE(); }
67 
68     angle::Result initialize(ContextMtl *context)
69     {
70         UNREACHABLE();
71         return angle::Result::Stop;
72     }
73     angle::Result set(ContextMtl *contextMtl, GLenum condition, GLbitfield flags)
74     {
75         UNREACHABLE();
76         return angle::Result::Stop;
77     }
78     angle::Result clientWait(ContextMtl *context,
79                              bool flushCommands,
80                              uint64_t timeout,
81                              GLenum *outResult)
82     {
83         UNREACHABLE();
84         return angle::Result::Stop;
85     }
86     void serverWait(ContextMtl *contextMtl) { UNREACHABLE(); }
87     angle::Result getStatus(bool *signaled)
88     {
89         UNREACHABLE();
90         return angle::Result::Stop;
91     }
92 };
93 #endif  // #if defined(__IPHONE_12_0) || defined(__MAC_10_14)
94 }  // namespace mtl
95 
96 class FenceNVMtl : public FenceNVImpl
97 {
98   public:
99     FenceNVMtl();
100     ~FenceNVMtl() override;
101     void onDestroy(const gl::Context *context) override;
102     angle::Result set(const gl::Context *context, GLenum condition) override;
103     angle::Result test(const gl::Context *context, GLboolean *outFinished) override;
104     angle::Result finish(const gl::Context *context) override;
105 
106   private:
107     mtl::Sync mSync;
108 };
109 
110 class SyncMtl : public SyncImpl
111 {
112   public:
113     SyncMtl();
114     ~SyncMtl() override;
115 
116     void onDestroy(const gl::Context *context) override;
117 
118     angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override;
119     angle::Result clientWait(const gl::Context *context,
120                              GLbitfield flags,
121                              GLuint64 timeout,
122                              GLenum *outResult) override;
123     angle::Result serverWait(const gl::Context *context,
124                              GLbitfield flags,
125                              GLuint64 timeout) override;
126     angle::Result getStatus(const gl::Context *context, GLint *outResult) override;
127 
128   private:
129     mtl::Sync mSync;
130 };
131 
132 class EGLSyncMtl final : public EGLSyncImpl
133 {
134   public:
135     EGLSyncMtl(const egl::AttributeMap &attribs);
136     ~EGLSyncMtl() override;
137 
138     void onDestroy(const egl::Display *display) override;
139 
140     egl::Error initialize(const egl::Display *display,
141                           const gl::Context *context,
142                           EGLenum type) override;
143     egl::Error clientWait(const egl::Display *display,
144                           const gl::Context *context,
145                           EGLint flags,
146                           EGLTime timeout,
147                           EGLint *outResult) override;
148     egl::Error serverWait(const egl::Display *display,
149                           const gl::Context *context,
150                           EGLint flags) override;
151     egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
152 
153     egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *result) const override;
154 
155   private:
156     mtl::Sync mSync;
157 };
158 
159 }  // namespace rx
160 
161 #endif
162