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 ASSERT(mSync != EGL_NO_SYNC_KHR);
33 mEGL->destroySyncKHR(mSync);
34 mSync = EGL_NO_SYNC_KHR;
35 }
36
initialize(const egl::Display * display,const gl::Context * context,EGLenum type)37 egl::Error SyncEGL::initialize(const egl::Display *display,
38 const gl::Context *context,
39 EGLenum type)
40 {
41 ASSERT(type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID);
42
43 std::vector<EGLint> attribs;
44 if (type == EGL_SYNC_NATIVE_FENCE_ANDROID)
45 {
46 attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID);
47 attribs.push_back(mNativeFenceFD);
48 }
49 attribs.push_back(EGL_NONE);
50
51 mSync = mEGL->createSyncKHR(type, attribs.data());
52 if (mSync == EGL_NO_SYNC_KHR)
53 {
54 return egl::Error(mEGL->getError(), "eglCreateSync failed to create sync object");
55 }
56
57 return egl::NoError();
58 }
59
clientWait(const egl::Display * display,const gl::Context * context,EGLint flags,EGLTime timeout,EGLint * outResult)60 egl::Error SyncEGL::clientWait(const egl::Display *display,
61 const gl::Context *context,
62 EGLint flags,
63 EGLTime timeout,
64 EGLint *outResult)
65 {
66 ASSERT(mSync != EGL_NO_SYNC_KHR);
67 EGLint result = mEGL->clientWaitSyncKHR(mSync, flags, timeout);
68
69 if (result == EGL_FALSE)
70 {
71 return egl::Error(mEGL->getError(), "eglClientWaitSync failed");
72 }
73
74 *outResult = result;
75 return egl::NoError();
76 }
77
serverWait(const egl::Display * display,const gl::Context * context,EGLint flags)78 egl::Error SyncEGL::serverWait(const egl::Display *display,
79 const gl::Context *context,
80 EGLint flags)
81 {
82 ASSERT(mSync != EGL_NO_SYNC_KHR);
83 EGLint result = mEGL->waitSyncKHR(mSync, flags);
84
85 if (result == EGL_FALSE)
86 {
87 return egl::Error(mEGL->getError(), "eglWaitSync failed");
88 }
89
90 return egl::NoError();
91 }
92
getStatus(const egl::Display * display,EGLint * outStatus)93 egl::Error SyncEGL::getStatus(const egl::Display *display, EGLint *outStatus)
94 {
95 ASSERT(mSync != EGL_NO_SYNC_KHR);
96 EGLBoolean result = mEGL->getSyncAttribKHR(mSync, EGL_SYNC_STATUS_KHR, outStatus);
97
98 if (result == EGL_FALSE)
99 {
100 return egl::Error(mEGL->getError(), "eglGetSyncAttribKHR with EGL_SYNC_STATUS_KHR failed");
101 }
102
103 return egl::NoError();
104 }
105
dupNativeFenceFD(const egl::Display * display,EGLint * result) const106 egl::Error SyncEGL::dupNativeFenceFD(const egl::Display *display, EGLint *result) const
107 {
108 ASSERT(mSync != EGL_NO_SYNC_KHR);
109 *result = mEGL->dupNativeFenceFDANDROID(mSync);
110 if (*result == EGL_NO_NATIVE_FENCE_FD_ANDROID)
111 {
112 return egl::Error(mEGL->getError(), "eglDupNativeFenceFDANDROID failed");
113 }
114
115 return egl::NoError();
116 }
117
118 } // namespace rx
119