• 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 
7 // SurfaceEGL.cpp: EGL implementation of egl::Surface
8 
9 #include "libANGLE/renderer/gl/egl/SurfaceEGL.h"
10 
11 #include "common/debug.h"
12 
13 namespace rx
14 {
15 
SurfaceEGL(const egl::SurfaceState & state,const FunctionsEGL * egl,EGLConfig config)16 SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state, const FunctionsEGL *egl, EGLConfig config)
17     : SurfaceGL(state),
18       mEGL(egl),
19       mConfig(config),
20       mSurface(EGL_NO_SURFACE),
21       mHasSwapBuffersWithDamage(mEGL->hasExtension("EGL_KHR_swap_buffers_with_damage"))
22 {}
23 
~SurfaceEGL()24 SurfaceEGL::~SurfaceEGL()
25 {
26     if (mSurface != EGL_NO_SURFACE)
27     {
28         EGLBoolean success = mEGL->destroySurface(mSurface);
29         ASSERT(success == EGL_TRUE);
30     }
31 }
32 
makeCurrent(const gl::Context * context)33 egl::Error SurfaceEGL::makeCurrent(const gl::Context *context)
34 {
35     // Handling of makeCurrent is done in DisplayEGL
36     return egl::NoError();
37 }
38 
swap(const gl::Context * context)39 egl::Error SurfaceEGL::swap(const gl::Context *context)
40 {
41     EGLBoolean success = mEGL->swapBuffers(mSurface);
42     if (success == EGL_FALSE)
43     {
44         return egl::Error(mEGL->getError(), "eglSwapBuffers failed");
45     }
46     return egl::NoError();
47 }
48 
swapWithDamage(const gl::Context * context,EGLint * rects,EGLint n_rects)49 egl::Error SurfaceEGL::swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects)
50 {
51     EGLBoolean success;
52     if (mHasSwapBuffersWithDamage)
53     {
54         success = mEGL->swapBuffersWithDamageKHR(mSurface, rects, n_rects);
55     }
56     else
57     {
58         success = mEGL->swapBuffers(mSurface);
59     }
60     if (success == EGL_FALSE)
61     {
62         return egl::Error(mEGL->getError(), "eglSwapBuffersWithDamageKHR failed");
63     }
64     return egl::NoError();
65 }
66 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)67 egl::Error SurfaceEGL::postSubBuffer(const gl::Context *context,
68                                      EGLint x,
69                                      EGLint y,
70                                      EGLint width,
71                                      EGLint height)
72 {
73     UNIMPLEMENTED();
74     return egl::EglBadSurface();
75 }
76 
setPresentationTime(EGLnsecsANDROID time)77 egl::Error SurfaceEGL::setPresentationTime(EGLnsecsANDROID time)
78 {
79     EGLBoolean success = mEGL->presentationTimeANDROID(mSurface, time);
80     if (success == EGL_FALSE)
81     {
82         return egl::Error(mEGL->getError(), "eglPresentationTimeANDROID failed");
83     }
84     return egl::NoError();
85 }
86 
querySurfacePointerANGLE(EGLint attribute,void ** value)87 egl::Error SurfaceEGL::querySurfacePointerANGLE(EGLint attribute, void **value)
88 {
89     UNIMPLEMENTED();
90     return egl::EglBadSurface();
91 }
92 
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)93 egl::Error SurfaceEGL::bindTexImage(const gl::Context *context, gl::Texture *texture, EGLint buffer)
94 {
95     EGLBoolean success = mEGL->bindTexImage(mSurface, buffer);
96     if (success == EGL_FALSE)
97     {
98         return egl::Error(mEGL->getError(), "eglBindTexImage failed");
99     }
100     return egl::NoError();
101 }
102 
releaseTexImage(const gl::Context * context,EGLint buffer)103 egl::Error SurfaceEGL::releaseTexImage(const gl::Context *context, EGLint buffer)
104 {
105     EGLBoolean success = mEGL->releaseTexImage(mSurface, buffer);
106     if (success == EGL_FALSE)
107     {
108         return egl::Error(mEGL->getError(), "eglReleaseTexImage failed");
109     }
110     return egl::NoError();
111 }
112 
setSwapInterval(EGLint interval)113 void SurfaceEGL::setSwapInterval(EGLint interval)
114 {
115     EGLBoolean success = mEGL->swapInterval(interval);
116     if (success == EGL_FALSE)
117     {
118         ERR() << "eglSwapInterval error " << egl::Error(mEGL->getError());
119         ASSERT(false);
120     }
121 }
122 
getWidth() const123 EGLint SurfaceEGL::getWidth() const
124 {
125     EGLint value;
126     EGLBoolean success = mEGL->querySurface(mSurface, EGL_WIDTH, &value);
127     ASSERT(success == EGL_TRUE);
128     return value;
129 }
130 
getHeight() const131 EGLint SurfaceEGL::getHeight() const
132 {
133     EGLint value;
134     EGLBoolean success = mEGL->querySurface(mSurface, EGL_HEIGHT, &value);
135     ASSERT(success == EGL_TRUE);
136     return value;
137 }
138 
isPostSubBufferSupported() const139 EGLint SurfaceEGL::isPostSubBufferSupported() const
140 {
141     UNIMPLEMENTED();
142     return 0;
143 }
144 
getSwapBehavior() const145 EGLint SurfaceEGL::getSwapBehavior() const
146 {
147     EGLint value;
148     EGLBoolean success = mEGL->querySurface(mSurface, EGL_SWAP_BEHAVIOR, &value);
149     ASSERT(success == EGL_TRUE);
150     return value;
151 }
152 
getSurface() const153 EGLSurface SurfaceEGL::getSurface() const
154 {
155     return mSurface;
156 }
157 
setTimestampsEnabled(bool enabled)158 void SurfaceEGL::setTimestampsEnabled(bool enabled)
159 {
160     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
161 
162     EGLBoolean success =
163         mEGL->surfaceAttrib(mSurface, EGL_TIMESTAMPS_ANDROID, enabled ? EGL_TRUE : EGL_FALSE);
164     if (success == EGL_FALSE)
165     {
166         ERR() << "eglSurfaceAttribute failed: " << egl::Error(mEGL->getError());
167     }
168 }
169 
getSupportedCompositorTimings() const170 egl::SupportedCompositorTimings SurfaceEGL::getSupportedCompositorTimings() const
171 {
172     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
173 
174     egl::SupportedCompositorTimings result;
175     for (egl::CompositorTiming name : angle::AllEnums<egl::CompositorTiming>())
176     {
177         result[name] = mEGL->getCompositorTimingSupportedANDROID(mSurface, egl::ToEGLenum(name));
178     }
179     return result;
180 }
181 
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const182 egl::Error SurfaceEGL::getCompositorTiming(EGLint numTimestamps,
183                                            const EGLint *names,
184                                            EGLnsecsANDROID *values) const
185 {
186     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
187 
188     EGLBoolean success = mEGL->getCompositorTimingANDROID(mSurface, numTimestamps, names, values);
189     if (success == EGL_FALSE)
190     {
191         return egl::Error(mEGL->getError(), "eglGetCompositorTimingANDROID failed");
192     }
193     return egl::NoError();
194 }
195 
getNextFrameId(EGLuint64KHR * frameId) const196 egl::Error SurfaceEGL::getNextFrameId(EGLuint64KHR *frameId) const
197 {
198     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
199 
200     EGLBoolean success = mEGL->getNextFrameIdANDROID(mSurface, frameId);
201     if (success == EGL_FALSE)
202     {
203         return egl::Error(mEGL->getError(), "eglGetNextFrameId failed");
204     }
205     return egl::NoError();
206 }
207 
getSupportedTimestamps() const208 egl::SupportedTimestamps SurfaceEGL::getSupportedTimestamps() const
209 {
210     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
211 
212     egl::SupportedTimestamps result;
213     for (egl::Timestamp timestamp : angle::AllEnums<egl::Timestamp>())
214     {
215         result[timestamp] =
216             mEGL->getFrameTimestampSupportedANDROID(mSurface, egl::ToEGLenum(timestamp));
217     }
218     return result;
219 }
220 
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const221 egl::Error SurfaceEGL::getFrameTimestamps(EGLuint64KHR frameId,
222                                           EGLint numTimestamps,
223                                           const EGLint *timestamps,
224                                           EGLnsecsANDROID *values) const
225 {
226     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
227 
228     // The driver may return EGL_BAD_ACCESS at any time if the requested frame is no longer stored.
229     EGLBoolean success =
230         mEGL->getFrameTimestampsANDROID(mSurface, frameId, numTimestamps, timestamps, values);
231     if (success == EGL_FALSE)
232     {
233         return egl::Error(mEGL->getError(), "eglGetFrameTimestampsANDROID failed");
234     }
235     return egl::NoError();
236 }
237 
238 }  // namespace rx
239