1 //
2 // Copyright 2019 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
7 // SyncEGL.cpp: Implements the rx::SyncEGL class.
8
9 #include "libANGLE/renderer/gl/egl/SyncEGL.h"
10
11 #include "libANGLE/AttributeMap.h"
12 #include "libANGLE/Display.h"
13 #include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
14
15 namespace rx
16 {
17
SyncEGL(const egl::AttributeMap & attribs,const FunctionsEGL * egl)18 SyncEGL::SyncEGL(const egl::AttributeMap &attribs, const FunctionsEGL *egl)
19 : mEGL(egl),
20 mNativeFenceFD(
21 attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID)),
22 mSync(EGL_NO_SYNC_KHR)
23 {}
24
~SyncEGL()25 SyncEGL::~SyncEGL()
26 {
27 ASSERT(mSync == EGL_NO_SYNC_KHR);
28 }
29
onDestroy(const egl::Display * display)30 void SyncEGL::onDestroy(const egl::Display *display)
31 {
32 if (mSync != EGL_NO_SYNC_KHR)
33 {
34 mEGL->destroySyncKHR(mSync);
35 mSync = EGL_NO_SYNC_KHR;
36 }
37 }
38
initialize(const egl::Display * display,const gl::Context * context,EGLenum type)39 egl::Error SyncEGL::initialize(const egl::Display *display,
40 const gl::Context *context,
41 EGLenum type)
42 {
43 ASSERT(type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID);
44
45 constexpr size_t kAttribVectorSize = 3;
46 angle::FixedVector<EGLint, kAttribVectorSize> attribs;
47 if (type == EGL_SYNC_NATIVE_FENCE_ANDROID)
48 {
49 attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID);
50 attribs.push_back(mNativeFenceFD);
51 }
52 attribs.push_back(EGL_NONE);
53
54 mSync = mEGL->createSyncKHR(type, attribs.data());
55 if (mSync == EGL_NO_SYNC_KHR)
56 {
57 return egl::Error(mEGL->getError(), "eglCreateSync failed to create sync object");
58 }
59
60 return egl::NoError();
61 }
62
clientWait(const egl::Display * display,const gl::Context * context,EGLint flags,EGLTime timeout,EGLint * outResult)63 egl::Error SyncEGL::clientWait(const egl::Display *display,
64 const gl::Context *context,
65 EGLint flags,
66 EGLTime timeout,
67 EGLint *outResult)
68 {
69 ASSERT(mSync != EGL_NO_SYNC_KHR);
70 EGLint result = mEGL->clientWaitSyncKHR(mSync, flags, timeout);
71
72 if (result == EGL_FALSE)
73 {
74 return egl::Error(mEGL->getError(), "eglClientWaitSync failed");
75 }
76
77 *outResult = result;
78 return egl::NoError();
79 }
80
serverWait(const egl::Display * display,const gl::Context * context,EGLint flags)81 egl::Error SyncEGL::serverWait(const egl::Display *display,
82 const gl::Context *context,
83 EGLint flags)
84 {
85 ASSERT(mSync != EGL_NO_SYNC_KHR);
86 EGLint result = mEGL->waitSyncKHR(mSync, flags);
87
88 if (result == EGL_FALSE)
89 {
90 return egl::Error(mEGL->getError(), "eglWaitSync failed");
91 }
92
93 return egl::NoError();
94 }
95
getStatus(const egl::Display * display,EGLint * outStatus)96 egl::Error SyncEGL::getStatus(const egl::Display *display, EGLint *outStatus)
97 {
98 ASSERT(mSync != EGL_NO_SYNC_KHR);
99 EGLBoolean result = mEGL->getSyncAttribKHR(mSync, EGL_SYNC_STATUS_KHR, outStatus);
100
101 if (result == EGL_FALSE)
102 {
103 return egl::Error(mEGL->getError(), "eglGetSyncAttribKHR with EGL_SYNC_STATUS_KHR failed");
104 }
105
106 return egl::NoError();
107 }
108
dupNativeFenceFD(const egl::Display * display,EGLint * result) const109 egl::Error SyncEGL::dupNativeFenceFD(const egl::Display *display, EGLint *result) const
110 {
111 ASSERT(mSync != EGL_NO_SYNC_KHR);
112 *result = mEGL->dupNativeFenceFDANDROID(mSync);
113 if (*result == EGL_NO_NATIVE_FENCE_FD_ANDROID)
114 {
115 return egl::Error(mEGL->getError(), "eglDupNativeFenceFDANDROID failed");
116 }
117
118 return egl::NoError();
119 }
120
121 } // namespace rx
122