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