• 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,const EGLint * rects,EGLint n_rects)49 egl::Error SurfaceEGL::swapWithDamage(const gl::Context *context,
50                                       const EGLint *rects,
51                                       EGLint n_rects)
52 {
53     EGLBoolean success;
54     if (mHasSwapBuffersWithDamage)
55     {
56         success = mEGL->swapBuffersWithDamageKHR(mSurface, rects, n_rects);
57     }
58     else
59     {
60         success = mEGL->swapBuffers(mSurface);
61     }
62     if (success == EGL_FALSE)
63     {
64         return egl::Error(mEGL->getError(), "eglSwapBuffersWithDamageKHR failed");
65     }
66     return egl::NoError();
67 }
68 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)69 egl::Error SurfaceEGL::postSubBuffer(const gl::Context *context,
70                                      EGLint x,
71                                      EGLint y,
72                                      EGLint width,
73                                      EGLint height)
74 {
75     UNIMPLEMENTED();
76     return egl::EglBadSurface();
77 }
78 
setPresentationTime(EGLnsecsANDROID time)79 egl::Error SurfaceEGL::setPresentationTime(EGLnsecsANDROID time)
80 {
81     EGLBoolean success = mEGL->presentationTimeANDROID(mSurface, time);
82     if (success == EGL_FALSE)
83     {
84         return egl::Error(mEGL->getError(), "eglPresentationTimeANDROID failed");
85     }
86     return egl::NoError();
87 }
88 
querySurfacePointerANGLE(EGLint attribute,void ** value)89 egl::Error SurfaceEGL::querySurfacePointerANGLE(EGLint attribute, void **value)
90 {
91     UNIMPLEMENTED();
92     return egl::EglBadSurface();
93 }
94 
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)95 egl::Error SurfaceEGL::bindTexImage(const gl::Context *context, gl::Texture *texture, EGLint buffer)
96 {
97     EGLBoolean success = mEGL->bindTexImage(mSurface, buffer);
98     if (success == EGL_FALSE)
99     {
100         return egl::Error(mEGL->getError(), "eglBindTexImage failed");
101     }
102     return egl::NoError();
103 }
104 
releaseTexImage(const gl::Context * context,EGLint buffer)105 egl::Error SurfaceEGL::releaseTexImage(const gl::Context *context, EGLint buffer)
106 {
107     EGLBoolean success = mEGL->releaseTexImage(mSurface, buffer);
108     if (success == EGL_FALSE)
109     {
110         return egl::Error(mEGL->getError(), "eglReleaseTexImage failed");
111     }
112     return egl::NoError();
113 }
114 
setSwapInterval(EGLint interval)115 void SurfaceEGL::setSwapInterval(EGLint interval)
116 {
117     EGLBoolean success = mEGL->swapInterval(interval);
118     if (success == EGL_FALSE)
119     {
120         ERR() << "eglSwapInterval error " << egl::Error(mEGL->getError());
121         ASSERT(false);
122     }
123 }
124 
getWidth() const125 EGLint SurfaceEGL::getWidth() const
126 {
127     EGLint value;
128     EGLBoolean success = mEGL->querySurface(mSurface, EGL_WIDTH, &value);
129     ASSERT(success == EGL_TRUE);
130     return value;
131 }
132 
getHeight() const133 EGLint SurfaceEGL::getHeight() const
134 {
135     EGLint value;
136     EGLBoolean success = mEGL->querySurface(mSurface, EGL_HEIGHT, &value);
137     ASSERT(success == EGL_TRUE);
138     return value;
139 }
140 
isPostSubBufferSupported() const141 EGLint SurfaceEGL::isPostSubBufferSupported() const
142 {
143     UNIMPLEMENTED();
144     return 0;
145 }
146 
getSwapBehavior() const147 EGLint SurfaceEGL::getSwapBehavior() const
148 {
149     EGLint value;
150     EGLBoolean success = mEGL->querySurface(mSurface, EGL_SWAP_BEHAVIOR, &value);
151     ASSERT(success == EGL_TRUE);
152     return value;
153 }
154 
getSurface() const155 EGLSurface SurfaceEGL::getSurface() const
156 {
157     return mSurface;
158 }
159 
setTimestampsEnabled(bool enabled)160 void SurfaceEGL::setTimestampsEnabled(bool enabled)
161 {
162     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
163 
164     EGLBoolean success =
165         mEGL->surfaceAttrib(mSurface, EGL_TIMESTAMPS_ANDROID, enabled ? EGL_TRUE : EGL_FALSE);
166     if (success == EGL_FALSE)
167     {
168         ERR() << "eglSurfaceAttribute failed: " << egl::Error(mEGL->getError());
169     }
170 }
171 
getSupportedCompositorTimings() const172 egl::SupportedCompositorTimings SurfaceEGL::getSupportedCompositorTimings() const
173 {
174     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
175 
176     egl::SupportedCompositorTimings result;
177     for (egl::CompositorTiming name : angle::AllEnums<egl::CompositorTiming>())
178     {
179         result[name] = mEGL->getCompositorTimingSupportedANDROID(mSurface, egl::ToEGLenum(name));
180     }
181     return result;
182 }
183 
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const184 egl::Error SurfaceEGL::getCompositorTiming(EGLint numTimestamps,
185                                            const EGLint *names,
186                                            EGLnsecsANDROID *values) const
187 {
188     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
189 
190     EGLBoolean success = mEGL->getCompositorTimingANDROID(mSurface, numTimestamps, names, values);
191     if (success == EGL_FALSE)
192     {
193         return egl::Error(mEGL->getError(), "eglGetCompositorTimingANDROID failed");
194     }
195     return egl::NoError();
196 }
197 
getNextFrameId(EGLuint64KHR * frameId) const198 egl::Error SurfaceEGL::getNextFrameId(EGLuint64KHR *frameId) const
199 {
200     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
201 
202     EGLBoolean success = mEGL->getNextFrameIdANDROID(mSurface, frameId);
203     if (success == EGL_FALSE)
204     {
205         return egl::Error(mEGL->getError(), "eglGetNextFrameId failed");
206     }
207     return egl::NoError();
208 }
209 
getSupportedTimestamps() const210 egl::SupportedTimestamps SurfaceEGL::getSupportedTimestamps() const
211 {
212     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
213 
214     egl::SupportedTimestamps result;
215     for (egl::Timestamp timestamp : angle::AllEnums<egl::Timestamp>())
216     {
217         result[timestamp] =
218             mEGL->getFrameTimestampSupportedANDROID(mSurface, egl::ToEGLenum(timestamp));
219     }
220     return result;
221 }
222 
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const223 egl::Error SurfaceEGL::getFrameTimestamps(EGLuint64KHR frameId,
224                                           EGLint numTimestamps,
225                                           const EGLint *timestamps,
226                                           EGLnsecsANDROID *values) const
227 {
228     ASSERT(mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"));
229 
230     // The driver may return EGL_BAD_ACCESS at any time if the requested frame is no longer stored.
231     EGLBoolean success =
232         mEGL->getFrameTimestampsANDROID(mSurface, frameId, numTimestamps, timestamps, values);
233     if (success == EGL_FALSE)
234     {
235         return egl::Error(mEGL->getError(), "eglGetFrameTimestampsANDROID failed");
236     }
237     return egl::NoError();
238 }
239 
isExternal() const240 bool SurfaceEGL::isExternal() const
241 {
242     return false;
243 }
244 
245 }  // namespace rx
246