• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  ** Copyright 2007, The Android Open Source Project
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 
17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18 
19 #include <dlfcn.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include <hardware/gralloc.h>
25 #include <system/window.h>
26 
27 #include <EGL/egl.h>
28 #include <EGL/eglext.h>
29 
30 #include <cutils/log.h>
31 #include <cutils/atomic.h>
32 #include <cutils/compiler.h>
33 #include <cutils/properties.h>
34 #include <cutils/memory.h>
35 
36 #include <gui/ISurfaceComposer.h>
37 
38 #include <ui/GraphicBuffer.h>
39 
40 #include <utils/KeyedVector.h>
41 #include <utils/SortedVector.h>
42 #include <utils/String8.h>
43 #include <utils/Trace.h>
44 
45 #include "binder/Binder.h"
46 #include "binder/Parcel.h"
47 #include "binder/IServiceManager.h"
48 
49 #include "../egl_impl.h"
50 #include "../hooks.h"
51 
52 #include "egl_display.h"
53 #include "egl_object.h"
54 #include "egl_tls.h"
55 #include "egldefs.h"
56 
57 using namespace android;
58 
59 // This extension has not been ratified yet, so can't be shipped.
60 // Implementation is incomplete and untested.
61 #define ENABLE_EGL_KHR_GL_COLORSPACE 0
62 
63 #define ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS 0
64 
65 // ----------------------------------------------------------------------------
66 
67 namespace android {
68 
69 struct extention_map_t {
70     const char* name;
71     __eglMustCastToProperFunctionPointerType address;
72 };
73 
74 /*
75  * This is the list of EGL extensions exposed to applications.
76  *
77  * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
78  * wrapper and are always available.
79  *
80  * The rest (gExtensionString) depend on support in the EGL driver, and are
81  * only available if the driver supports them. However, some of these must be
82  * supported because they are used by the Android system itself; these are
83  * listed as mandatory below and are required by the CDD. The system *assumes*
84  * the mandatory extensions are present and may not function properly if some
85  * are missing.
86  *
87  * NOTE: Both strings MUST have a single space as the last character.
88  */
89 extern char const * const gBuiltinExtensionString =
90         "EGL_KHR_get_all_proc_addresses "
91         "EGL_ANDROID_presentation_time "
92         "EGL_KHR_swap_buffers_with_damage "
93         "EGL_ANDROID_create_native_client_buffer "
94         "EGL_ANDROID_front_buffer_auto_refresh "
95 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
96         "EGL_ANDROID_get_frame_timestamps "
97 #endif
98         ;
99 extern char const * const gExtensionString  =
100         "EGL_KHR_image "                        // mandatory
101         "EGL_KHR_image_base "                   // mandatory
102         "EGL_KHR_image_pixmap "
103         "EGL_KHR_lock_surface "
104 #if (ENABLE_EGL_KHR_GL_COLORSPACE != 0)
105         "EGL_KHR_gl_colorspace "
106 #endif
107         "EGL_KHR_gl_texture_2D_image "
108         "EGL_KHR_gl_texture_3D_image "
109         "EGL_KHR_gl_texture_cubemap_image "
110         "EGL_KHR_gl_renderbuffer_image "
111         "EGL_KHR_reusable_sync "
112         "EGL_KHR_fence_sync "
113         "EGL_KHR_create_context "
114         "EGL_KHR_config_attribs "
115         "EGL_KHR_surfaceless_context "
116         "EGL_KHR_stream "
117         "EGL_KHR_stream_fifo "
118         "EGL_KHR_stream_producer_eglsurface "
119         "EGL_KHR_stream_consumer_gltexture "
120         "EGL_KHR_stream_cross_process_fd "
121         "EGL_EXT_create_context_robustness "
122         "EGL_NV_system_time "
123         "EGL_ANDROID_image_native_buffer "      // mandatory
124         "EGL_KHR_wait_sync "                    // strongly recommended
125         "EGL_ANDROID_recordable "               // mandatory
126         "EGL_KHR_partial_update "               // strongly recommended
127         "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
128         "EGL_KHR_create_context_no_error "
129         "EGL_KHR_mutable_render_buffer "
130         "EGL_EXT_yuv_surface "
131         "EGL_EXT_protected_content "
132         ;
133 
134 // extensions not exposed to applications but used by the ANDROID system
135 //      "EGL_ANDROID_blob_cache "               // strongly recommended
136 //      "EGL_IMG_hibernate_process "            // optional
137 //      "EGL_ANDROID_native_fence_sync "        // strongly recommended
138 //      "EGL_ANDROID_framebuffer_target "       // mandatory for HWC 1.1
139 //      "EGL_ANDROID_image_crop "               // optional
140 
141 /*
142  * EGL Extensions entry-points exposed to 3rd party applications
143  * (keep in sync with gExtensionString above)
144  *
145  */
146 static const extention_map_t sExtensionMap[] = {
147     // EGL_KHR_lock_surface
148     { "eglLockSurfaceKHR",
149             (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
150     { "eglUnlockSurfaceKHR",
151             (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
152 
153     // EGL_KHR_image, EGL_KHR_image_base
154     { "eglCreateImageKHR",
155             (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
156     { "eglDestroyImageKHR",
157             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
158 
159     // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
160     { "eglCreateSyncKHR",
161             (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
162     { "eglDestroySyncKHR",
163             (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
164     { "eglClientWaitSyncKHR",
165             (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
166     { "eglSignalSyncKHR",
167             (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
168     { "eglGetSyncAttribKHR",
169             (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
170 
171     // EGL_NV_system_time
172     { "eglGetSystemTimeFrequencyNV",
173             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
174     { "eglGetSystemTimeNV",
175             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
176 
177     // EGL_KHR_wait_sync
178     { "eglWaitSyncKHR",
179             (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
180 
181     // EGL_ANDROID_presentation_time
182     { "eglPresentationTimeANDROID",
183             (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
184 
185     // EGL_KHR_swap_buffers_with_damage
186     { "eglSwapBuffersWithDamageKHR",
187             (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
188 
189     // EGL_ANDROID_native_client_buffer
190     { "eglCreateNativeClientBufferANDROID",
191             (__eglMustCastToProperFunctionPointerType)&eglCreateNativeClientBufferANDROID },
192 
193     // EGL_KHR_partial_update
194     { "eglSetDamageRegionKHR",
195             (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
196 
197     { "eglCreateStreamKHR",
198             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
199     { "eglDestroyStreamKHR",
200             (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
201     { "eglStreamAttribKHR",
202             (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
203     { "eglQueryStreamKHR",
204             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
205     { "eglQueryStreamu64KHR",
206             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
207     { "eglQueryStreamTimeKHR",
208             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
209     { "eglCreateStreamProducerSurfaceKHR",
210             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
211     { "eglStreamConsumerGLTextureExternalKHR",
212             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
213     { "eglStreamConsumerAcquireKHR",
214             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
215     { "eglStreamConsumerReleaseKHR",
216             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
217     { "eglGetStreamFileDescriptorKHR",
218             (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
219     { "eglCreateStreamFromFileDescriptorKHR",
220             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
221 
222     // EGL_ANDROID_get_frame_timestamps
223     { "eglGetFrameTimestampsANDROID",
224             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
225     { "eglQueryTimestampSupportedANDROID",
226             (__eglMustCastToProperFunctionPointerType)&eglQueryTimestampSupportedANDROID },
227 };
228 
229 /*
230  * These extensions entry-points should not be exposed to applications.
231  * They're used internally by the Android EGL layer.
232  */
233 #define FILTER_EXTENSIONS(procname) \
234         (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") ||    \
235          !strcmp((procname), "eglHibernateProcessIMG")      ||    \
236          !strcmp((procname), "eglAwakenProcessIMG")         ||    \
237          !strcmp((procname), "eglDupNativeFenceFDANDROID"))
238 
239 
240 
241 // accesses protected by sExtensionMapMutex
242 static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
243 static int sGLExtentionSlot = 0;
244 static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
245 
findProcAddress(const char * name,const extention_map_t * map,size_t n)246 static void(*findProcAddress(const char* name,
247         const extention_map_t* map, size_t n))() {
248     for (uint32_t i=0 ; i<n ; i++) {
249         if (!strcmp(name, map[i].name)) {
250             return map[i].address;
251         }
252     }
253     return NULL;
254 }
255 
256 // ----------------------------------------------------------------------------
257 
258 extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
259 extern EGLBoolean egl_init_drivers();
260 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
261 extern gl_hooks_t gHooksTrace;
262 
263 } // namespace android;
264 
265 
266 // ----------------------------------------------------------------------------
267 
clearError()268 static inline void clearError() { egl_tls_t::clearError(); }
getContext()269 static inline EGLContext getContext() { return egl_tls_t::getContext(); }
270 
271 // ----------------------------------------------------------------------------
272 
eglGetDisplay(EGLNativeDisplayType display)273 EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
274 {
275     ATRACE_CALL();
276     clearError();
277 
278     uintptr_t index = reinterpret_cast<uintptr_t>(display);
279     if (index >= NUM_DISPLAYS) {
280         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
281     }
282 
283     if (egl_init_drivers() == EGL_FALSE) {
284         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
285     }
286 
287     EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
288     return dpy;
289 }
290 
291 // ----------------------------------------------------------------------------
292 // Initialization
293 // ----------------------------------------------------------------------------
294 
eglInitialize(EGLDisplay dpy,EGLint * major,EGLint * minor)295 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
296 {
297     clearError();
298 
299     egl_display_ptr dp = get_display(dpy);
300     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
301 
302     EGLBoolean res = dp->initialize(major, minor);
303 
304     return res;
305 }
306 
eglTerminate(EGLDisplay dpy)307 EGLBoolean eglTerminate(EGLDisplay dpy)
308 {
309     // NOTE: don't unload the drivers b/c some APIs can be called
310     // after eglTerminate() has been called. eglTerminate() only
311     // terminates an EGLDisplay, not a EGL itself.
312 
313     clearError();
314 
315     egl_display_ptr dp = get_display(dpy);
316     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
317 
318     EGLBoolean res = dp->terminate();
319 
320     return res;
321 }
322 
323 // ----------------------------------------------------------------------------
324 // configuration
325 // ----------------------------------------------------------------------------
326 
eglGetConfigs(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)327 EGLBoolean eglGetConfigs(   EGLDisplay dpy,
328                             EGLConfig *configs,
329                             EGLint config_size, EGLint *num_config)
330 {
331     clearError();
332 
333     const egl_display_ptr dp = validate_display(dpy);
334     if (!dp) return EGL_FALSE;
335 
336     if (num_config==0) {
337         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
338     }
339 
340     EGLBoolean res = EGL_FALSE;
341     *num_config = 0;
342 
343     egl_connection_t* const cnx = &gEGLImpl;
344     if (cnx->dso) {
345         res = cnx->egl.eglGetConfigs(
346                 dp->disp.dpy, configs, config_size, num_config);
347     }
348 
349     return res;
350 }
351 
eglChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)352 EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
353                             EGLConfig *configs, EGLint config_size,
354                             EGLint *num_config)
355 {
356     clearError();
357 
358     const egl_display_ptr dp = validate_display(dpy);
359     if (!dp) return EGL_FALSE;
360 
361     if (num_config==0) {
362         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
363     }
364 
365     EGLBoolean res = EGL_FALSE;
366     *num_config = 0;
367 
368     egl_connection_t* const cnx = &gEGLImpl;
369     if (cnx->dso) {
370         if (attrib_list) {
371             char value[PROPERTY_VALUE_MAX];
372             property_get("debug.egl.force_msaa", value, "false");
373 
374             if (!strcmp(value, "true")) {
375                 size_t attribCount = 0;
376                 EGLint attrib = attrib_list[0];
377 
378                 // Only enable MSAA if the context is OpenGL ES 2.0 and
379                 // if no caveat is requested
380                 const EGLint *attribRendererable = NULL;
381                 const EGLint *attribCaveat = NULL;
382 
383                 // Count the number of attributes and look for
384                 // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
385                 while (attrib != EGL_NONE) {
386                     attrib = attrib_list[attribCount];
387                     switch (attrib) {
388                         case EGL_RENDERABLE_TYPE:
389                             attribRendererable = &attrib_list[attribCount];
390                             break;
391                         case EGL_CONFIG_CAVEAT:
392                             attribCaveat = &attrib_list[attribCount];
393                             break;
394                     }
395                     attribCount++;
396                 }
397 
398                 if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
399                         (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
400 
401                     // Insert 2 extra attributes to force-enable MSAA 4x
402                     EGLint aaAttribs[attribCount + 4];
403                     aaAttribs[0] = EGL_SAMPLE_BUFFERS;
404                     aaAttribs[1] = 1;
405                     aaAttribs[2] = EGL_SAMPLES;
406                     aaAttribs[3] = 4;
407 
408                     memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
409 
410                     EGLint numConfigAA;
411                     EGLBoolean resAA = cnx->egl.eglChooseConfig(
412                             dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
413 
414                     if (resAA == EGL_TRUE && numConfigAA > 0) {
415                         ALOGD("Enabling MSAA 4x");
416                         *num_config = numConfigAA;
417                         return resAA;
418                     }
419                 }
420             }
421         }
422 
423         res = cnx->egl.eglChooseConfig(
424                 dp->disp.dpy, attrib_list, configs, config_size, num_config);
425     }
426     return res;
427 }
428 
eglGetConfigAttrib(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)429 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
430         EGLint attribute, EGLint *value)
431 {
432     clearError();
433 
434     egl_connection_t* cnx = NULL;
435     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
436     if (!dp) return EGL_FALSE;
437 
438     return cnx->egl.eglGetConfigAttrib(
439             dp->disp.dpy, config, attribute, value);
440 }
441 
442 // ----------------------------------------------------------------------------
443 // surfaces
444 // ----------------------------------------------------------------------------
445 
446 // The EGL_KHR_gl_colorspace spec hasn't been ratified yet, so these haven't
447 // been added to the Khronos egl.h.
448 #define EGL_GL_COLORSPACE_KHR           EGL_VG_COLORSPACE
449 #define EGL_GL_COLORSPACE_SRGB_KHR      EGL_VG_COLORSPACE_sRGB
450 #define EGL_GL_COLORSPACE_LINEAR_KHR    EGL_VG_COLORSPACE_LINEAR
451 
452 // Turn linear formats into corresponding sRGB formats when colorspace is
453 // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
454 // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
455 // the modification isn't possible, the original dataSpace is returned.
modifyBufferDataspace(android_dataspace dataSpace,EGLint colorspace)456 static android_dataspace modifyBufferDataspace( android_dataspace dataSpace,
457                                                 EGLint colorspace) {
458     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
459         return HAL_DATASPACE_SRGB_LINEAR;
460     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
461         return HAL_DATASPACE_SRGB;
462     }
463     return dataSpace;
464 }
465 
eglCreateWindowSurface(EGLDisplay dpy,EGLConfig config,NativeWindowType window,const EGLint * attrib_list)466 EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
467                                     NativeWindowType window,
468                                     const EGLint *attrib_list)
469 {
470     clearError();
471 
472     egl_connection_t* cnx = NULL;
473     egl_display_ptr dp = validate_display_connection(dpy, cnx);
474     if (dp) {
475         EGLDisplay iDpy = dp->disp.dpy;
476 
477         int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
478         if (result != OK) {
479             ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
480                     "failed (%#x) (already connected to another API?)",
481                     window, result);
482             return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
483         }
484 
485         // Set the native window's buffers format to match what this config requests.
486         // Whether to use sRGB gamma is not part of the EGLconfig, but is part
487         // of our native format. So if sRGB gamma is requested, we have to
488         // modify the EGLconfig's format before setting the native window's
489         // format.
490 
491         // by default, just pick RGBA_8888
492         EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
493         android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
494 
495         EGLint a = 0;
496         cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
497         if (a > 0) {
498             // alpha-channel requested, there's really only one suitable format
499             format = HAL_PIXEL_FORMAT_RGBA_8888;
500         } else {
501             EGLint r, g, b;
502             r = g = b = 0;
503             cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE,   &r);
504             cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g);
505             cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE,  &b);
506             EGLint colorDepth = r + g + b;
507             if (colorDepth <= 16) {
508                 format = HAL_PIXEL_FORMAT_RGB_565;
509             } else {
510                 format = HAL_PIXEL_FORMAT_RGBX_8888;
511             }
512         }
513 
514         // now select a corresponding sRGB format if needed
515         if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
516             for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
517                 if (*attr == EGL_GL_COLORSPACE_KHR) {
518                     if (ENABLE_EGL_KHR_GL_COLORSPACE) {
519                         dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
520                     } else {
521                         // Normally we'd pass through unhandled attributes to
522                         // the driver. But in case the driver implements this
523                         // extension but we're disabling it, we want to prevent
524                         // it getting through -- support will be broken without
525                         // our help.
526                         ALOGE("sRGB window surfaces not supported");
527                         return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
528                     }
529                 }
530             }
531         }
532 
533         if (format != 0) {
534             int err = native_window_set_buffers_format(window, format);
535             if (err != 0) {
536                 ALOGE("error setting native window pixel format: %s (%d)",
537                         strerror(-err), err);
538                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
539                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
540             }
541         }
542 
543         if (dataSpace != 0) {
544             int err = native_window_set_buffers_data_space(window, dataSpace);
545             if (err != 0) {
546                 ALOGE("error setting native window pixel dataSpace: %s (%d)",
547                         strerror(-err), err);
548                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
549                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
550             }
551         }
552 
553         // the EGL spec requires that a new EGLSurface default to swap interval
554         // 1, so explicitly set that on the window here.
555         ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
556         anw->setSwapInterval(anw, 1);
557 
558         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
559                 iDpy, config, window, attrib_list);
560         if (surface != EGL_NO_SURFACE) {
561             egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
562                     surface, cnx);
563             return s;
564         }
565 
566         // EGLSurface creation failed
567         native_window_set_buffers_format(window, 0);
568         native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
569     }
570     return EGL_NO_SURFACE;
571 }
572 
eglCreatePixmapSurface(EGLDisplay dpy,EGLConfig config,NativePixmapType pixmap,const EGLint * attrib_list)573 EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
574                                     NativePixmapType pixmap,
575                                     const EGLint *attrib_list)
576 {
577     clearError();
578 
579     egl_connection_t* cnx = NULL;
580     egl_display_ptr dp = validate_display_connection(dpy, cnx);
581     if (dp) {
582         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
583                 dp->disp.dpy, config, pixmap, attrib_list);
584         if (surface != EGL_NO_SURFACE) {
585             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
586                     surface, cnx);
587             return s;
588         }
589     }
590     return EGL_NO_SURFACE;
591 }
592 
eglCreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)593 EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
594                                     const EGLint *attrib_list)
595 {
596     clearError();
597 
598     egl_connection_t* cnx = NULL;
599     egl_display_ptr dp = validate_display_connection(dpy, cnx);
600     if (dp) {
601         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
602                 dp->disp.dpy, config, attrib_list);
603         if (surface != EGL_NO_SURFACE) {
604             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
605                     surface, cnx);
606             return s;
607         }
608     }
609     return EGL_NO_SURFACE;
610 }
611 
eglDestroySurface(EGLDisplay dpy,EGLSurface surface)612 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
613 {
614     clearError();
615 
616     const egl_display_ptr dp = validate_display(dpy);
617     if (!dp) return EGL_FALSE;
618 
619     SurfaceRef _s(dp.get(), surface);
620     if (!_s.get())
621         return setError(EGL_BAD_SURFACE, EGL_FALSE);
622 
623     egl_surface_t * const s = get_surface(surface);
624     EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
625     if (result == EGL_TRUE) {
626         _s.terminate();
627     }
628     return result;
629 }
630 
eglQuerySurface(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint * value)631 EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
632                             EGLint attribute, EGLint *value)
633 {
634     clearError();
635 
636     const egl_display_ptr dp = validate_display(dpy);
637     if (!dp) return EGL_FALSE;
638 
639     SurfaceRef _s(dp.get(), surface);
640     if (!_s.get())
641         return setError(EGL_BAD_SURFACE, EGL_FALSE);
642 
643     egl_surface_t const * const s = get_surface(surface);
644     return s->cnx->egl.eglQuerySurface(
645             dp->disp.dpy, s->surface, attribute, value);
646 }
647 
eglBeginFrame(EGLDisplay dpy,EGLSurface surface)648 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
649     ATRACE_CALL();
650     clearError();
651 
652     const egl_display_ptr dp = validate_display(dpy);
653     if (!dp) {
654         return;
655     }
656 
657     SurfaceRef _s(dp.get(), surface);
658     if (!_s.get()) {
659         setError(EGL_BAD_SURFACE, EGL_FALSE);
660         return;
661     }
662 }
663 
664 // ----------------------------------------------------------------------------
665 // Contexts
666 // ----------------------------------------------------------------------------
667 
eglCreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_list,const EGLint * attrib_list)668 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
669                             EGLContext share_list, const EGLint *attrib_list)
670 {
671     clearError();
672 
673     egl_connection_t* cnx = NULL;
674     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
675     if (dp) {
676         if (share_list != EGL_NO_CONTEXT) {
677             if (!ContextRef(dp.get(), share_list).get()) {
678                 return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
679             }
680             egl_context_t* const c = get_context(share_list);
681             share_list = c->context;
682         }
683         EGLContext context = cnx->egl.eglCreateContext(
684                 dp->disp.dpy, config, share_list, attrib_list);
685         if (context != EGL_NO_CONTEXT) {
686             // figure out if it's a GLESv1 or GLESv2
687             int version = 0;
688             if (attrib_list) {
689                 while (*attrib_list != EGL_NONE) {
690                     GLint attr = *attrib_list++;
691                     GLint value = *attrib_list++;
692                     if (attr == EGL_CONTEXT_CLIENT_VERSION) {
693                         if (value == 1) {
694                             version = egl_connection_t::GLESv1_INDEX;
695                         } else if (value == 2 || value == 3) {
696                             version = egl_connection_t::GLESv2_INDEX;
697                         }
698                     }
699                 };
700             }
701             egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
702                     version);
703             return c;
704         }
705     }
706     return EGL_NO_CONTEXT;
707 }
708 
eglDestroyContext(EGLDisplay dpy,EGLContext ctx)709 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
710 {
711     clearError();
712 
713     const egl_display_ptr dp = validate_display(dpy);
714     if (!dp)
715         return EGL_FALSE;
716 
717     ContextRef _c(dp.get(), ctx);
718     if (!_c.get())
719         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
720 
721     egl_context_t * const c = get_context(ctx);
722     EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
723     if (result == EGL_TRUE) {
724         _c.terminate();
725     }
726     return result;
727 }
728 
eglMakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)729 EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
730                             EGLSurface read, EGLContext ctx)
731 {
732     clearError();
733 
734     egl_display_ptr dp = validate_display(dpy);
735     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
736 
737     // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
738     // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
739     // a valid but uninitialized display.
740     if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
741          (draw != EGL_NO_SURFACE) ) {
742         if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
743     }
744 
745     // get a reference to the object passed in
746     ContextRef _c(dp.get(), ctx);
747     SurfaceRef _d(dp.get(), draw);
748     SurfaceRef _r(dp.get(), read);
749 
750     // validate the context (if not EGL_NO_CONTEXT)
751     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
752         // EGL_NO_CONTEXT is valid
753         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
754     }
755 
756     // these are the underlying implementation's object
757     EGLContext impl_ctx  = EGL_NO_CONTEXT;
758     EGLSurface impl_draw = EGL_NO_SURFACE;
759     EGLSurface impl_read = EGL_NO_SURFACE;
760 
761     // these are our objects structs passed in
762     egl_context_t       * c = NULL;
763     egl_surface_t const * d = NULL;
764     egl_surface_t const * r = NULL;
765 
766     // these are the current objects structs
767     egl_context_t * cur_c = get_context(getContext());
768 
769     if (ctx != EGL_NO_CONTEXT) {
770         c = get_context(ctx);
771         impl_ctx = c->context;
772     } else {
773         // no context given, use the implementation of the current context
774         if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
775             // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
776             return setError(EGL_BAD_MATCH, EGL_FALSE);
777         }
778         if (cur_c == NULL) {
779             // no current context
780             // not an error, there is just no current context.
781             return EGL_TRUE;
782         }
783     }
784 
785     // retrieve the underlying implementation's draw EGLSurface
786     if (draw != EGL_NO_SURFACE) {
787         if (!_d.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
788         d = get_surface(draw);
789         impl_draw = d->surface;
790     }
791 
792     // retrieve the underlying implementation's read EGLSurface
793     if (read != EGL_NO_SURFACE) {
794         if (!_r.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
795         r = get_surface(read);
796         impl_read = r->surface;
797     }
798 
799 
800     EGLBoolean result = dp->makeCurrent(c, cur_c,
801             draw, read, ctx,
802             impl_draw, impl_read, impl_ctx);
803 
804     if (result == EGL_TRUE) {
805         if (c) {
806             setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
807             egl_tls_t::setContext(ctx);
808             _c.acquire();
809             _r.acquire();
810             _d.acquire();
811         } else {
812             setGLHooksThreadSpecific(&gHooksNoContext);
813             egl_tls_t::setContext(EGL_NO_CONTEXT);
814         }
815     } else {
816         // this will ALOGE the error
817         egl_connection_t* const cnx = &gEGLImpl;
818         result = setError(cnx->egl.eglGetError(), EGL_FALSE);
819     }
820     return result;
821 }
822 
823 
eglQueryContext(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)824 EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
825                             EGLint attribute, EGLint *value)
826 {
827     clearError();
828 
829     const egl_display_ptr dp = validate_display(dpy);
830     if (!dp) return EGL_FALSE;
831 
832     ContextRef _c(dp.get(), ctx);
833     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
834 
835     egl_context_t * const c = get_context(ctx);
836     return c->cnx->egl.eglQueryContext(
837             dp->disp.dpy, c->context, attribute, value);
838 
839 }
840 
eglGetCurrentContext(void)841 EGLContext eglGetCurrentContext(void)
842 {
843     // could be called before eglInitialize(), but we wouldn't have a context
844     // then, and this function would correctly return EGL_NO_CONTEXT.
845 
846     clearError();
847 
848     EGLContext ctx = getContext();
849     return ctx;
850 }
851 
eglGetCurrentSurface(EGLint readdraw)852 EGLSurface eglGetCurrentSurface(EGLint readdraw)
853 {
854     // could be called before eglInitialize(), but we wouldn't have a context
855     // then, and this function would correctly return EGL_NO_SURFACE.
856 
857     clearError();
858 
859     EGLContext ctx = getContext();
860     if (ctx) {
861         egl_context_t const * const c = get_context(ctx);
862         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
863         switch (readdraw) {
864             case EGL_READ: return c->read;
865             case EGL_DRAW: return c->draw;
866             default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
867         }
868     }
869     return EGL_NO_SURFACE;
870 }
871 
eglGetCurrentDisplay(void)872 EGLDisplay eglGetCurrentDisplay(void)
873 {
874     // could be called before eglInitialize(), but we wouldn't have a context
875     // then, and this function would correctly return EGL_NO_DISPLAY.
876 
877     clearError();
878 
879     EGLContext ctx = getContext();
880     if (ctx) {
881         egl_context_t const * const c = get_context(ctx);
882         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
883         return c->dpy;
884     }
885     return EGL_NO_DISPLAY;
886 }
887 
eglWaitGL(void)888 EGLBoolean eglWaitGL(void)
889 {
890     clearError();
891 
892     egl_connection_t* const cnx = &gEGLImpl;
893     if (!cnx->dso)
894         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
895 
896     return cnx->egl.eglWaitGL();
897 }
898 
eglWaitNative(EGLint engine)899 EGLBoolean eglWaitNative(EGLint engine)
900 {
901     clearError();
902 
903     egl_connection_t* const cnx = &gEGLImpl;
904     if (!cnx->dso)
905         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
906 
907     return cnx->egl.eglWaitNative(engine);
908 }
909 
eglGetError(void)910 EGLint eglGetError(void)
911 {
912     EGLint err = EGL_SUCCESS;
913     egl_connection_t* const cnx = &gEGLImpl;
914     if (cnx->dso) {
915         err = cnx->egl.eglGetError();
916     }
917     if (err == EGL_SUCCESS) {
918         err = egl_tls_t::getError();
919     }
920     return err;
921 }
922 
findBuiltinWrapper(const char * procname)923 static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
924         const char* procname) {
925     const egl_connection_t* cnx = &gEGLImpl;
926     void* proc = NULL;
927 
928     proc = dlsym(cnx->libEgl, procname);
929     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
930 
931     proc = dlsym(cnx->libGles2, procname);
932     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
933 
934     proc = dlsym(cnx->libGles1, procname);
935     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
936 
937     return NULL;
938 }
939 
eglGetProcAddress(const char * procname)940 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
941 {
942     // eglGetProcAddress() could be the very first function called
943     // in which case we must make sure we've initialized ourselves, this
944     // happens the first time egl_get_display() is called.
945 
946     clearError();
947 
948     if (egl_init_drivers() == EGL_FALSE) {
949         setError(EGL_BAD_PARAMETER, NULL);
950         return  NULL;
951     }
952 
953     if (FILTER_EXTENSIONS(procname)) {
954         return NULL;
955     }
956 
957     __eglMustCastToProperFunctionPointerType addr;
958     addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
959     if (addr) return addr;
960 
961     addr = findBuiltinWrapper(procname);
962     if (addr) return addr;
963 
964     // this protects accesses to sGLExtentionMap and sGLExtentionSlot
965     pthread_mutex_lock(&sExtensionMapMutex);
966 
967         /*
968          * Since eglGetProcAddress() is not associated to anything, it needs
969          * to return a function pointer that "works" regardless of what
970          * the current context is.
971          *
972          * For this reason, we return a "forwarder", a small stub that takes
973          * care of calling the function associated with the context
974          * currently bound.
975          *
976          * We first look for extensions we've already resolved, if we're seeing
977          * this extension for the first time, we go through all our
978          * implementations and call eglGetProcAddress() and record the
979          * result in the appropriate implementation hooks and return the
980          * address of the forwarder corresponding to that hook set.
981          *
982          */
983 
984         const String8 name(procname);
985         addr = sGLExtentionMap.valueFor(name);
986         const int slot = sGLExtentionSlot;
987 
988         ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
989                 "no more slots for eglGetProcAddress(\"%s\")",
990                 procname);
991 
992         if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
993             bool found = false;
994 
995             egl_connection_t* const cnx = &gEGLImpl;
996             if (cnx->dso && cnx->egl.eglGetProcAddress) {
997                 // Extensions are independent of the bound context
998                 addr =
999                 cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
1000                 cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
1001                         cnx->egl.eglGetProcAddress(procname);
1002                 if (addr) found = true;
1003             }
1004 
1005             if (found) {
1006                 addr = gExtensionForwarders[slot];
1007                 sGLExtentionMap.add(name, addr);
1008                 sGLExtentionSlot++;
1009             }
1010         }
1011 
1012     pthread_mutex_unlock(&sExtensionMapMutex);
1013     return addr;
1014 }
1015 
1016 class FrameCompletionThread : public Thread {
1017 public:
1018 
queueSync(EGLSyncKHR sync)1019     static void queueSync(EGLSyncKHR sync) {
1020         static sp<FrameCompletionThread> thread(new FrameCompletionThread);
1021         static bool running = false;
1022         if (!running) {
1023             thread->run("GPUFrameCompletion");
1024             running = true;
1025         }
1026         {
1027             Mutex::Autolock lock(thread->mMutex);
1028             ScopedTrace st(ATRACE_TAG, String8::format("kicked off frame %d",
1029                     thread->mFramesQueued).string());
1030             thread->mQueue.push_back(sync);
1031             thread->mCondition.signal();
1032             thread->mFramesQueued++;
1033             ATRACE_INT("GPU Frames Outstanding", thread->mQueue.size());
1034         }
1035     }
1036 
1037 private:
FrameCompletionThread()1038     FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {}
1039 
threadLoop()1040     virtual bool threadLoop() {
1041         EGLSyncKHR sync;
1042         uint32_t frameNum;
1043         {
1044             Mutex::Autolock lock(mMutex);
1045             while (mQueue.isEmpty()) {
1046                 mCondition.wait(mMutex);
1047             }
1048             sync = mQueue[0];
1049             frameNum = mFramesCompleted;
1050         }
1051         EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1052         {
1053             ScopedTrace st(ATRACE_TAG, String8::format("waiting for frame %d",
1054                     frameNum).string());
1055             EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
1056             if (result == EGL_FALSE) {
1057                 ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
1058             } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
1059                 ALOGE("FrameCompletion: timeout waiting for fence");
1060             }
1061             eglDestroySyncKHR(dpy, sync);
1062         }
1063         {
1064             Mutex::Autolock lock(mMutex);
1065             mQueue.removeAt(0);
1066             mFramesCompleted++;
1067             ATRACE_INT("GPU Frames Outstanding", mQueue.size());
1068         }
1069         return true;
1070     }
1071 
1072     uint32_t mFramesQueued;
1073     uint32_t mFramesCompleted;
1074     Vector<EGLSyncKHR> mQueue;
1075     Condition mCondition;
1076     Mutex mMutex;
1077 };
1078 
eglSwapBuffersWithDamageKHR(EGLDisplay dpy,EGLSurface draw,EGLint * rects,EGLint n_rects)1079 EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
1080         EGLint *rects, EGLint n_rects)
1081 {
1082     ATRACE_CALL();
1083     clearError();
1084 
1085     const egl_display_ptr dp = validate_display(dpy);
1086     if (!dp) return EGL_FALSE;
1087 
1088     SurfaceRef _s(dp.get(), draw);
1089     if (!_s.get())
1090         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1091 
1092     egl_surface_t const * const s = get_surface(draw);
1093 
1094     if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1095         EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
1096         if (sync != EGL_NO_SYNC_KHR) {
1097             FrameCompletionThread::queueSync(sync);
1098         }
1099     }
1100 
1101     if (CC_UNLIKELY(dp->finishOnSwap)) {
1102         uint32_t pixel;
1103         egl_context_t * const c = get_context( egl_tls_t::getContext() );
1104         if (c) {
1105             // glReadPixels() ensures that the frame is complete
1106             s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
1107                     GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
1108         }
1109     }
1110 
1111     if (n_rects == 0) {
1112         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1113     }
1114 
1115     Vector<android_native_rect_t> androidRects;
1116     for (int r = 0; r < n_rects; ++r) {
1117         int offset = r * 4;
1118         int x = rects[offset];
1119         int y = rects[offset + 1];
1120         int width = rects[offset + 2];
1121         int height = rects[offset + 3];
1122         android_native_rect_t androidRect;
1123         androidRect.left = x;
1124         androidRect.top = y + height;
1125         androidRect.right = x + width;
1126         androidRect.bottom = y;
1127         androidRects.push_back(androidRect);
1128     }
1129     native_window_set_surface_damage(s->win.get(), androidRects.array(),
1130             androidRects.size());
1131 
1132     if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1133         return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
1134                 rects, n_rects);
1135     } else {
1136         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1137     }
1138 }
1139 
eglSwapBuffers(EGLDisplay dpy,EGLSurface surface)1140 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1141 {
1142     return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
1143 }
1144 
eglCopyBuffers(EGLDisplay dpy,EGLSurface surface,NativePixmapType target)1145 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
1146                             NativePixmapType target)
1147 {
1148     clearError();
1149 
1150     const egl_display_ptr dp = validate_display(dpy);
1151     if (!dp) return EGL_FALSE;
1152 
1153     SurfaceRef _s(dp.get(), surface);
1154     if (!_s.get())
1155         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1156 
1157     egl_surface_t const * const s = get_surface(surface);
1158     return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1159 }
1160 
eglQueryString(EGLDisplay dpy,EGLint name)1161 const char* eglQueryString(EGLDisplay dpy, EGLint name)
1162 {
1163     clearError();
1164 
1165     const egl_display_ptr dp = validate_display(dpy);
1166     if (!dp) return (const char *) NULL;
1167 
1168     switch (name) {
1169         case EGL_VENDOR:
1170             return dp->getVendorString();
1171         case EGL_VERSION:
1172             return dp->getVersionString();
1173         case EGL_EXTENSIONS:
1174             return dp->getExtensionString();
1175         case EGL_CLIENT_APIS:
1176             return dp->getClientApiString();
1177     }
1178     return setError(EGL_BAD_PARAMETER, (const char *)0);
1179 }
1180 
eglQueryStringImplementationANDROID(EGLDisplay dpy,EGLint name)1181 EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
1182 {
1183     clearError();
1184 
1185     const egl_display_ptr dp = validate_display(dpy);
1186     if (!dp) return (const char *) NULL;
1187 
1188     switch (name) {
1189         case EGL_VENDOR:
1190             return dp->disp.queryString.vendor;
1191         case EGL_VERSION:
1192             return dp->disp.queryString.version;
1193         case EGL_EXTENSIONS:
1194             return dp->disp.queryString.extensions;
1195         case EGL_CLIENT_APIS:
1196             return dp->disp.queryString.clientApi;
1197     }
1198     return setError(EGL_BAD_PARAMETER, (const char *)0);
1199 }
1200 
1201 // ----------------------------------------------------------------------------
1202 // EGL 1.1
1203 // ----------------------------------------------------------------------------
1204 
eglSurfaceAttrib(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)1205 EGLBoolean eglSurfaceAttrib(
1206         EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1207 {
1208     clearError();
1209 
1210     const egl_display_ptr dp = validate_display(dpy);
1211     if (!dp) return EGL_FALSE;
1212 
1213     SurfaceRef _s(dp.get(), surface);
1214     if (!_s.get())
1215         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1216 
1217     egl_surface_t * const s = get_surface(surface);
1218 
1219     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
1220         int err = native_window_set_auto_refresh(s->win.get(),
1221             value ? true : false);
1222         return (err == NO_ERROR) ? EGL_TRUE :
1223             setError(EGL_BAD_SURFACE, EGL_FALSE);
1224     }
1225 
1226 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
1227     if (attribute == EGL_TIMESTAMPS_ANDROID) {
1228         s->enableTimestamps = value;
1229         return EGL_TRUE;
1230     }
1231 #endif
1232 
1233     if (s->cnx->egl.eglSurfaceAttrib) {
1234         return s->cnx->egl.eglSurfaceAttrib(
1235                 dp->disp.dpy, s->surface, attribute, value);
1236     }
1237     return setError(EGL_BAD_SURFACE, EGL_FALSE);
1238 }
1239 
eglBindTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1240 EGLBoolean eglBindTexImage(
1241         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1242 {
1243     clearError();
1244 
1245     const egl_display_ptr dp = validate_display(dpy);
1246     if (!dp) return EGL_FALSE;
1247 
1248     SurfaceRef _s(dp.get(), surface);
1249     if (!_s.get())
1250         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1251 
1252     egl_surface_t const * const s = get_surface(surface);
1253     if (s->cnx->egl.eglBindTexImage) {
1254         return s->cnx->egl.eglBindTexImage(
1255                 dp->disp.dpy, s->surface, buffer);
1256     }
1257     return setError(EGL_BAD_SURFACE, EGL_FALSE);
1258 }
1259 
eglReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1260 EGLBoolean eglReleaseTexImage(
1261         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1262 {
1263     clearError();
1264 
1265     const egl_display_ptr dp = validate_display(dpy);
1266     if (!dp) return EGL_FALSE;
1267 
1268     SurfaceRef _s(dp.get(), surface);
1269     if (!_s.get())
1270         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1271 
1272     egl_surface_t const * const s = get_surface(surface);
1273     if (s->cnx->egl.eglReleaseTexImage) {
1274         return s->cnx->egl.eglReleaseTexImage(
1275                 dp->disp.dpy, s->surface, buffer);
1276     }
1277     return setError(EGL_BAD_SURFACE, EGL_FALSE);
1278 }
1279 
eglSwapInterval(EGLDisplay dpy,EGLint interval)1280 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1281 {
1282     clearError();
1283 
1284     const egl_display_ptr dp = validate_display(dpy);
1285     if (!dp) return EGL_FALSE;
1286 
1287     EGLBoolean res = EGL_TRUE;
1288     egl_connection_t* const cnx = &gEGLImpl;
1289     if (cnx->dso && cnx->egl.eglSwapInterval) {
1290         res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1291     }
1292 
1293     return res;
1294 }
1295 
1296 
1297 // ----------------------------------------------------------------------------
1298 // EGL 1.2
1299 // ----------------------------------------------------------------------------
1300 
eglWaitClient(void)1301 EGLBoolean eglWaitClient(void)
1302 {
1303     clearError();
1304 
1305     egl_connection_t* const cnx = &gEGLImpl;
1306     if (!cnx->dso)
1307         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
1308 
1309     EGLBoolean res;
1310     if (cnx->egl.eglWaitClient) {
1311         res = cnx->egl.eglWaitClient();
1312     } else {
1313         res = cnx->egl.eglWaitGL();
1314     }
1315     return res;
1316 }
1317 
eglBindAPI(EGLenum api)1318 EGLBoolean eglBindAPI(EGLenum api)
1319 {
1320     clearError();
1321 
1322     if (egl_init_drivers() == EGL_FALSE) {
1323         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1324     }
1325 
1326     // bind this API on all EGLs
1327     EGLBoolean res = EGL_TRUE;
1328     egl_connection_t* const cnx = &gEGLImpl;
1329     if (cnx->dso && cnx->egl.eglBindAPI) {
1330         res = cnx->egl.eglBindAPI(api);
1331     }
1332     return res;
1333 }
1334 
eglQueryAPI(void)1335 EGLenum eglQueryAPI(void)
1336 {
1337     clearError();
1338 
1339     if (egl_init_drivers() == EGL_FALSE) {
1340         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1341     }
1342 
1343     egl_connection_t* const cnx = &gEGLImpl;
1344     if (cnx->dso && cnx->egl.eglQueryAPI) {
1345         return cnx->egl.eglQueryAPI();
1346     }
1347 
1348     // or, it can only be OpenGL ES
1349     return EGL_OPENGL_ES_API;
1350 }
1351 
eglReleaseThread(void)1352 EGLBoolean eglReleaseThread(void)
1353 {
1354     clearError();
1355 
1356     // If there is context bound to the thread, release it
1357     egl_display_t::loseCurrent(get_context(getContext()));
1358 
1359     egl_connection_t* const cnx = &gEGLImpl;
1360     if (cnx->dso && cnx->egl.eglReleaseThread) {
1361         cnx->egl.eglReleaseThread();
1362     }
1363     egl_tls_t::clearTLS();
1364     return EGL_TRUE;
1365 }
1366 
eglCreatePbufferFromClientBuffer(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)1367 EGLSurface eglCreatePbufferFromClientBuffer(
1368           EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1369           EGLConfig config, const EGLint *attrib_list)
1370 {
1371     clearError();
1372 
1373     egl_connection_t* cnx = NULL;
1374     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
1375     if (!dp) return EGL_FALSE;
1376     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1377         return cnx->egl.eglCreatePbufferFromClientBuffer(
1378                 dp->disp.dpy, buftype, buffer, config, attrib_list);
1379     }
1380     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1381 }
1382 
1383 // ----------------------------------------------------------------------------
1384 // EGL_EGLEXT_VERSION 3
1385 // ----------------------------------------------------------------------------
1386 
eglLockSurfaceKHR(EGLDisplay dpy,EGLSurface surface,const EGLint * attrib_list)1387 EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
1388         const EGLint *attrib_list)
1389 {
1390     clearError();
1391 
1392     const egl_display_ptr dp = validate_display(dpy);
1393     if (!dp) return EGL_FALSE;
1394 
1395     SurfaceRef _s(dp.get(), surface);
1396     if (!_s.get())
1397         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1398 
1399     egl_surface_t const * const s = get_surface(surface);
1400     if (s->cnx->egl.eglLockSurfaceKHR) {
1401         return s->cnx->egl.eglLockSurfaceKHR(
1402                 dp->disp.dpy, s->surface, attrib_list);
1403     }
1404     return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1405 }
1406 
eglUnlockSurfaceKHR(EGLDisplay dpy,EGLSurface surface)1407 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
1408 {
1409     clearError();
1410 
1411     const egl_display_ptr dp = validate_display(dpy);
1412     if (!dp) return EGL_FALSE;
1413 
1414     SurfaceRef _s(dp.get(), surface);
1415     if (!_s.get())
1416         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1417 
1418     egl_surface_t const * const s = get_surface(surface);
1419     if (s->cnx->egl.eglUnlockSurfaceKHR) {
1420         return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1421     }
1422     return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1423 }
1424 
eglCreateImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)1425 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1426         EGLClientBuffer buffer, const EGLint *attrib_list)
1427 {
1428     clearError();
1429 
1430     const egl_display_ptr dp = validate_display(dpy);
1431     if (!dp) return EGL_NO_IMAGE_KHR;
1432 
1433     ContextRef _c(dp.get(), ctx);
1434     egl_context_t * const c = _c.get();
1435 
1436     EGLImageKHR result = EGL_NO_IMAGE_KHR;
1437     egl_connection_t* const cnx = &gEGLImpl;
1438     if (cnx->dso && cnx->egl.eglCreateImageKHR) {
1439         result = cnx->egl.eglCreateImageKHR(
1440                 dp->disp.dpy,
1441                 c ? c->context : EGL_NO_CONTEXT,
1442                 target, buffer, attrib_list);
1443     }
1444     return result;
1445 }
1446 
eglDestroyImageKHR(EGLDisplay dpy,EGLImageKHR img)1447 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1448 {
1449     clearError();
1450 
1451     const egl_display_ptr dp = validate_display(dpy);
1452     if (!dp) return EGL_FALSE;
1453 
1454     EGLBoolean result = EGL_FALSE;
1455     egl_connection_t* const cnx = &gEGLImpl;
1456     if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
1457         result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
1458     }
1459     return result;
1460 }
1461 
1462 // ----------------------------------------------------------------------------
1463 // EGL_EGLEXT_VERSION 5
1464 // ----------------------------------------------------------------------------
1465 
1466 
eglCreateSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)1467 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1468 {
1469     clearError();
1470 
1471     const egl_display_ptr dp = validate_display(dpy);
1472     if (!dp) return EGL_NO_SYNC_KHR;
1473 
1474     EGLSyncKHR result = EGL_NO_SYNC_KHR;
1475     egl_connection_t* const cnx = &gEGLImpl;
1476     if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
1477         result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
1478     }
1479     return result;
1480 }
1481 
eglDestroySyncKHR(EGLDisplay dpy,EGLSyncKHR sync)1482 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1483 {
1484     clearError();
1485 
1486     const egl_display_ptr dp = validate_display(dpy);
1487     if (!dp) return EGL_FALSE;
1488 
1489     EGLBoolean result = EGL_FALSE;
1490     egl_connection_t* const cnx = &gEGLImpl;
1491     if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
1492         result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
1493     }
1494     return result;
1495 }
1496 
eglSignalSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLenum mode)1497 EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1498     clearError();
1499 
1500     const egl_display_ptr dp = validate_display(dpy);
1501     if (!dp) return EGL_FALSE;
1502 
1503     EGLBoolean result = EGL_FALSE;
1504     egl_connection_t* const cnx = &gEGLImpl;
1505     if (cnx->dso && cnx->egl.eglSignalSyncKHR) {
1506         result = cnx->egl.eglSignalSyncKHR(
1507                 dp->disp.dpy, sync, mode);
1508     }
1509     return result;
1510 }
1511 
eglClientWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout)1512 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
1513         EGLint flags, EGLTimeKHR timeout)
1514 {
1515     clearError();
1516 
1517     const egl_display_ptr dp = validate_display(dpy);
1518     if (!dp) return EGL_FALSE;
1519 
1520     EGLBoolean result = EGL_FALSE;
1521     egl_connection_t* const cnx = &gEGLImpl;
1522     if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
1523         result = cnx->egl.eglClientWaitSyncKHR(
1524                 dp->disp.dpy, sync, flags, timeout);
1525     }
1526     return result;
1527 }
1528 
eglGetSyncAttribKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,EGLint * value)1529 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
1530         EGLint attribute, EGLint *value)
1531 {
1532     clearError();
1533 
1534     const egl_display_ptr dp = validate_display(dpy);
1535     if (!dp) return EGL_FALSE;
1536 
1537     EGLBoolean result = EGL_FALSE;
1538     egl_connection_t* const cnx = &gEGLImpl;
1539     if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
1540         result = cnx->egl.eglGetSyncAttribKHR(
1541                 dp->disp.dpy, sync, attribute, value);
1542     }
1543     return result;
1544 }
1545 
eglCreateStreamKHR(EGLDisplay dpy,const EGLint * attrib_list)1546 EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
1547 {
1548     clearError();
1549 
1550     const egl_display_ptr dp = validate_display(dpy);
1551     if (!dp) return EGL_NO_STREAM_KHR;
1552 
1553     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1554     egl_connection_t* const cnx = &gEGLImpl;
1555     if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
1556         result = cnx->egl.eglCreateStreamKHR(
1557                 dp->disp.dpy, attrib_list);
1558     }
1559     return result;
1560 }
1561 
eglDestroyStreamKHR(EGLDisplay dpy,EGLStreamKHR stream)1562 EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
1563 {
1564     clearError();
1565 
1566     const egl_display_ptr dp = validate_display(dpy);
1567     if (!dp) return EGL_FALSE;
1568 
1569     EGLBoolean result = EGL_FALSE;
1570     egl_connection_t* const cnx = &gEGLImpl;
1571     if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
1572         result = cnx->egl.eglDestroyStreamKHR(
1573                 dp->disp.dpy, stream);
1574     }
1575     return result;
1576 }
1577 
eglStreamAttribKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint value)1578 EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
1579         EGLenum attribute, EGLint value)
1580 {
1581     clearError();
1582 
1583     const egl_display_ptr dp = validate_display(dpy);
1584     if (!dp) return EGL_FALSE;
1585 
1586     EGLBoolean result = EGL_FALSE;
1587     egl_connection_t* const cnx = &gEGLImpl;
1588     if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
1589         result = cnx->egl.eglStreamAttribKHR(
1590                 dp->disp.dpy, stream, attribute, value);
1591     }
1592     return result;
1593 }
1594 
eglQueryStreamKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint * value)1595 EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
1596         EGLenum attribute, EGLint *value)
1597 {
1598     clearError();
1599 
1600     const egl_display_ptr dp = validate_display(dpy);
1601     if (!dp) return EGL_FALSE;
1602 
1603     EGLBoolean result = EGL_FALSE;
1604     egl_connection_t* const cnx = &gEGLImpl;
1605     if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
1606         result = cnx->egl.eglQueryStreamKHR(
1607                 dp->disp.dpy, stream, attribute, value);
1608     }
1609     return result;
1610 }
1611 
eglQueryStreamu64KHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLuint64KHR * value)1612 EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
1613         EGLenum attribute, EGLuint64KHR *value)
1614 {
1615     clearError();
1616 
1617     const egl_display_ptr dp = validate_display(dpy);
1618     if (!dp) return EGL_FALSE;
1619 
1620     EGLBoolean result = EGL_FALSE;
1621     egl_connection_t* const cnx = &gEGLImpl;
1622     if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
1623         result = cnx->egl.eglQueryStreamu64KHR(
1624                 dp->disp.dpy, stream, attribute, value);
1625     }
1626     return result;
1627 }
1628 
eglQueryStreamTimeKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLTimeKHR * value)1629 EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
1630         EGLenum attribute, EGLTimeKHR *value)
1631 {
1632     clearError();
1633 
1634     const egl_display_ptr dp = validate_display(dpy);
1635     if (!dp) return EGL_FALSE;
1636 
1637     EGLBoolean result = EGL_FALSE;
1638     egl_connection_t* const cnx = &gEGLImpl;
1639     if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
1640         result = cnx->egl.eglQueryStreamTimeKHR(
1641                 dp->disp.dpy, stream, attribute, value);
1642     }
1643     return result;
1644 }
1645 
eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy,EGLConfig config,EGLStreamKHR stream,const EGLint * attrib_list)1646 EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
1647         EGLStreamKHR stream, const EGLint *attrib_list)
1648 {
1649     clearError();
1650 
1651     egl_display_ptr dp = validate_display(dpy);
1652     if (!dp) return EGL_NO_SURFACE;
1653 
1654     egl_connection_t* const cnx = &gEGLImpl;
1655     if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
1656         EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
1657                 dp->disp.dpy, config, stream, attrib_list);
1658         if (surface != EGL_NO_SURFACE) {
1659             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
1660                     surface, cnx);
1661             return s;
1662         }
1663     }
1664     return EGL_NO_SURFACE;
1665 }
1666 
eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,EGLStreamKHR stream)1667 EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
1668         EGLStreamKHR stream)
1669 {
1670     clearError();
1671 
1672     const egl_display_ptr dp = validate_display(dpy);
1673     if (!dp) return EGL_FALSE;
1674 
1675     EGLBoolean result = EGL_FALSE;
1676     egl_connection_t* const cnx = &gEGLImpl;
1677     if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
1678         result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
1679                 dp->disp.dpy, stream);
1680     }
1681     return result;
1682 }
1683 
eglStreamConsumerAcquireKHR(EGLDisplay dpy,EGLStreamKHR stream)1684 EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
1685         EGLStreamKHR stream)
1686 {
1687     clearError();
1688 
1689     const egl_display_ptr dp = validate_display(dpy);
1690     if (!dp) return EGL_FALSE;
1691 
1692     EGLBoolean result = EGL_FALSE;
1693     egl_connection_t* const cnx = &gEGLImpl;
1694     if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
1695         result = cnx->egl.eglStreamConsumerAcquireKHR(
1696                 dp->disp.dpy, stream);
1697     }
1698     return result;
1699 }
1700 
eglStreamConsumerReleaseKHR(EGLDisplay dpy,EGLStreamKHR stream)1701 EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
1702         EGLStreamKHR stream)
1703 {
1704     clearError();
1705 
1706     const egl_display_ptr dp = validate_display(dpy);
1707     if (!dp) return EGL_FALSE;
1708 
1709     EGLBoolean result = EGL_FALSE;
1710     egl_connection_t* const cnx = &gEGLImpl;
1711     if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
1712         result = cnx->egl.eglStreamConsumerReleaseKHR(
1713                 dp->disp.dpy, stream);
1714     }
1715     return result;
1716 }
1717 
eglGetStreamFileDescriptorKHR(EGLDisplay dpy,EGLStreamKHR stream)1718 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
1719         EGLDisplay dpy, EGLStreamKHR stream)
1720 {
1721     clearError();
1722 
1723     const egl_display_ptr dp = validate_display(dpy);
1724     if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
1725 
1726     EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
1727     egl_connection_t* const cnx = &gEGLImpl;
1728     if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
1729         result = cnx->egl.eglGetStreamFileDescriptorKHR(
1730                 dp->disp.dpy, stream);
1731     }
1732     return result;
1733 }
1734 
eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy,EGLNativeFileDescriptorKHR file_descriptor)1735 EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
1736         EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
1737 {
1738     clearError();
1739 
1740     const egl_display_ptr dp = validate_display(dpy);
1741     if (!dp) return EGL_NO_STREAM_KHR;
1742 
1743     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1744     egl_connection_t* const cnx = &gEGLImpl;
1745     if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
1746         result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
1747                 dp->disp.dpy, file_descriptor);
1748     }
1749     return result;
1750 }
1751 
1752 // ----------------------------------------------------------------------------
1753 // EGL_EGLEXT_VERSION 15
1754 // ----------------------------------------------------------------------------
1755 
eglWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags)1756 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
1757     clearError();
1758     const egl_display_ptr dp = validate_display(dpy);
1759     if (!dp) return EGL_FALSE;
1760     EGLint result = EGL_FALSE;
1761     egl_connection_t* const cnx = &gEGLImpl;
1762     if (cnx->dso && cnx->egl.eglWaitSyncKHR) {
1763         result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags);
1764     }
1765     return result;
1766 }
1767 
1768 // ----------------------------------------------------------------------------
1769 // ANDROID extensions
1770 // ----------------------------------------------------------------------------
1771 
eglDupNativeFenceFDANDROID(EGLDisplay dpy,EGLSyncKHR sync)1772 EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
1773 {
1774     clearError();
1775 
1776     const egl_display_ptr dp = validate_display(dpy);
1777     if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
1778 
1779     EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
1780     egl_connection_t* const cnx = &gEGLImpl;
1781     if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
1782         result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
1783     }
1784     return result;
1785 }
1786 
eglPresentationTimeANDROID(EGLDisplay dpy,EGLSurface surface,EGLnsecsANDROID time)1787 EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
1788         EGLnsecsANDROID time)
1789 {
1790     clearError();
1791 
1792     const egl_display_ptr dp = validate_display(dpy);
1793     if (!dp) {
1794         return EGL_FALSE;
1795     }
1796 
1797     SurfaceRef _s(dp.get(), surface);
1798     if (!_s.get()) {
1799         setError(EGL_BAD_SURFACE, EGL_FALSE);
1800         return EGL_FALSE;
1801     }
1802 
1803     egl_surface_t const * const s = get_surface(surface);
1804     native_window_set_buffers_timestamp(s->win.get(), time);
1805 
1806     return EGL_TRUE;
1807 }
1808 
eglCreateNativeClientBufferANDROID(const EGLint * attrib_list)1809 EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
1810 {
1811     clearError();
1812 
1813     int usage = 0;
1814     uint32_t width = 0;
1815     uint32_t height = 0;
1816     uint32_t format = 0;
1817     uint32_t red_size = 0;
1818     uint32_t green_size = 0;
1819     uint32_t blue_size = 0;
1820     uint32_t alpha_size = 0;
1821 
1822 #define GET_NONNEGATIVE_VALUE(case_name, target) \
1823     case case_name: \
1824         if (value >= 0) { \
1825             target = value; \
1826         } else { \
1827             return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); \
1828         } \
1829         break
1830 
1831     if (attrib_list) {
1832         while (*attrib_list != EGL_NONE) {
1833             GLint attr = *attrib_list++;
1834             GLint value = *attrib_list++;
1835             switch (attr) {
1836                 GET_NONNEGATIVE_VALUE(EGL_WIDTH, width);
1837                 GET_NONNEGATIVE_VALUE(EGL_HEIGHT, height);
1838                 GET_NONNEGATIVE_VALUE(EGL_RED_SIZE, red_size);
1839                 GET_NONNEGATIVE_VALUE(EGL_GREEN_SIZE, green_size);
1840                 GET_NONNEGATIVE_VALUE(EGL_BLUE_SIZE, blue_size);
1841                 GET_NONNEGATIVE_VALUE(EGL_ALPHA_SIZE, alpha_size);
1842                 case EGL_NATIVE_BUFFER_USAGE_ANDROID:
1843                     if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) {
1844                         usage |= GRALLOC_USAGE_PROTECTED;
1845                     }
1846                     if (value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) {
1847                         usage |= GRALLOC_USAGE_HW_RENDER;
1848                     }
1849                     if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) {
1850                         usage |= GRALLOC_USAGE_HW_TEXTURE;
1851                     }
1852                     break;
1853                 default:
1854                     return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
1855             }
1856         }
1857     }
1858 #undef GET_NONNEGATIVE_VALUE
1859 
1860     // Validate format.
1861     if (red_size == 8 && green_size == 8 && blue_size == 8) {
1862         if (alpha_size == 8) {
1863             format = HAL_PIXEL_FORMAT_RGBA_8888;
1864         } else {
1865             format = HAL_PIXEL_FORMAT_RGB_888;
1866         }
1867     } else if (red_size == 5 && green_size == 6 && blue_size == 5 &&
1868                alpha_size == 0) {
1869         format = HAL_PIXEL_FORMAT_RGB_565;
1870     } else {
1871         ALOGE("Invalid native pixel format { r=%d, g=%d, b=%d, a=%d }",
1872                 red_size, green_size, blue_size, alpha_size);
1873         return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
1874     }
1875 
1876 #define CHECK_ERROR_CONDITION(message) \
1877     if (err != NO_ERROR) { \
1878         ALOGE(message); \
1879         goto error_condition; \
1880     }
1881 
1882     // The holder is used to destroy the buffer if an error occurs.
1883     GraphicBuffer* gBuffer = new GraphicBuffer();
1884     sp<IServiceManager> sm = defaultServiceManager();
1885     sp<IBinder> surfaceFlinger = sm->getService(String16("SurfaceFlinger"));
1886     sp<IBinder> allocator;
1887     Parcel sc_data, sc_reply, data, reply;
1888     status_t err = NO_ERROR;
1889     if (sm == NULL) {
1890         ALOGE("Unable to connect to ServiceManager");
1891         goto error_condition;
1892     }
1893 
1894     // Obtain an allocator.
1895     if (surfaceFlinger == NULL) {
1896         ALOGE("Unable to connect to SurfaceFlinger");
1897         goto error_condition;
1898     }
1899     sc_data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
1900     err = surfaceFlinger->transact(
1901             BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, sc_data, &sc_reply);
1902     CHECK_ERROR_CONDITION("Unable to obtain allocator from SurfaceFlinger");
1903     allocator = sc_reply.readStrongBinder();
1904 
1905     if (allocator == NULL) {
1906         ALOGE("Unable to obtain an ISurfaceComposer");
1907         goto error_condition;
1908     }
1909     data.writeInterfaceToken(String16("android.ui.IGraphicBufferAlloc"));
1910     err = data.writeUint32(width);
1911     CHECK_ERROR_CONDITION("Unable to write width");
1912     err = data.writeUint32(height);
1913     CHECK_ERROR_CONDITION("Unable to write height");
1914     err = data.writeInt32(static_cast<int32_t>(format));
1915     CHECK_ERROR_CONDITION("Unable to write format");
1916     err = data.writeUint32(usage);
1917     CHECK_ERROR_CONDITION("Unable to write usage");
1918     err = data.writeUtf8AsUtf16(
1919             std::string("[eglCreateNativeClientBufferANDROID pid ") +
1920             std::to_string(getpid()) + ']');
1921     CHECK_ERROR_CONDITION("Unable to write requestor name");
1922     err = allocator->transact(IBinder::FIRST_CALL_TRANSACTION, data,
1923             &reply);
1924     CHECK_ERROR_CONDITION(
1925             "Unable to request buffer allocation from surface composer");
1926     err = reply.readInt32();
1927     CHECK_ERROR_CONDITION("Unable to obtain buffer from surface composer");
1928     err = reply.read(*gBuffer);
1929     CHECK_ERROR_CONDITION("Unable to read buffer from surface composer");
1930 
1931     err = gBuffer->initCheck();
1932     if (err != NO_ERROR) {
1933         ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
1934                 width, height, format, usage, err);
1935         goto error_condition;
1936     }
1937     ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
1938             gBuffer, width, height, format, usage);
1939     return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
1940 
1941 #undef CHECK_ERROR_CONDITION
1942 
1943 error_condition:
1944     // Delete the buffer.
1945     sp<GraphicBuffer> holder(gBuffer);
1946     return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
1947 }
1948 
1949 // ----------------------------------------------------------------------------
1950 // NVIDIA extensions
1951 // ----------------------------------------------------------------------------
eglGetSystemTimeFrequencyNV()1952 EGLuint64NV eglGetSystemTimeFrequencyNV()
1953 {
1954     clearError();
1955 
1956     if (egl_init_drivers() == EGL_FALSE) {
1957         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1958     }
1959 
1960     EGLuint64NV ret = 0;
1961     egl_connection_t* const cnx = &gEGLImpl;
1962 
1963     if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
1964         return cnx->egl.eglGetSystemTimeFrequencyNV();
1965     }
1966 
1967     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
1968 }
1969 
eglGetSystemTimeNV()1970 EGLuint64NV eglGetSystemTimeNV()
1971 {
1972     clearError();
1973 
1974     if (egl_init_drivers() == EGL_FALSE) {
1975         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1976     }
1977 
1978     EGLuint64NV ret = 0;
1979     egl_connection_t* const cnx = &gEGLImpl;
1980 
1981     if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
1982         return cnx->egl.eglGetSystemTimeNV();
1983     }
1984 
1985     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
1986 }
1987 
1988 // ----------------------------------------------------------------------------
1989 // Partial update extension
1990 // ----------------------------------------------------------------------------
eglSetDamageRegionKHR(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)1991 EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1992         EGLint *rects, EGLint n_rects)
1993 {
1994     clearError();
1995 
1996     const egl_display_ptr dp = validate_display(dpy);
1997     if (!dp) {
1998         setError(EGL_BAD_DISPLAY, EGL_FALSE);
1999         return EGL_FALSE;
2000     }
2001 
2002     SurfaceRef _s(dp.get(), surface);
2003     if (!_s.get()) {
2004         setError(EGL_BAD_SURFACE, EGL_FALSE);
2005         return EGL_FALSE;
2006     }
2007 
2008     egl_surface_t const * const s = get_surface(surface);
2009     if (s->cnx->egl.eglSetDamageRegionKHR) {
2010         return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
2011                 rects, n_rects);
2012     }
2013 
2014     return EGL_FALSE;
2015 }
2016 
eglGetFrameTimestampsANDROID(EGLDisplay dpy,EGLSurface surface,EGLint framesAgo,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values)2017 EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
2018         EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps,
2019         EGLnsecsANDROID *values)
2020 {
2021     clearError();
2022 
2023     const egl_display_ptr dp = validate_display(dpy);
2024     if (!dp) {
2025         setError(EGL_BAD_DISPLAY, EGL_FALSE);
2026         return EGL_FALSE;
2027     }
2028 
2029     SurfaceRef _s(dp.get(), surface);
2030     if (!_s.get()) {
2031         setError(EGL_BAD_SURFACE, EGL_FALSE);
2032         return EGL_FALSE;
2033     }
2034 
2035     egl_surface_t const * const s = get_surface(surface);
2036 
2037     if (!s->enableTimestamps) {
2038         setError(EGL_BAD_SURFACE, EGL_FALSE);
2039         return EGL_FALSE;
2040     }
2041 
2042     nsecs_t* postedTime = nullptr;
2043     nsecs_t* acquireTime = nullptr;
2044     nsecs_t* refreshStartTime = nullptr;
2045     nsecs_t* GLCompositionDoneTime = nullptr;
2046     nsecs_t* displayRetireTime = nullptr;
2047     nsecs_t* releaseTime = nullptr;
2048 
2049     for (int i = 0; i < numTimestamps; i++) {
2050         switch (timestamps[i]) {
2051             case EGL_QUEUE_TIME_ANDROID:
2052                 postedTime = &values[i];
2053                 break;
2054             case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2055                 acquireTime = &values[i];
2056                 break;
2057             case EGL_COMPOSITION_START_TIME_ANDROID:
2058                 refreshStartTime = &values[i];
2059                 break;
2060             case EGL_COMPOSITION_FINISHED_TIME_ANDROID:
2061                 GLCompositionDoneTime = &values[i];
2062                 break;
2063             case EGL_DISPLAY_RETIRE_TIME_ANDROID:
2064                 displayRetireTime = &values[i];
2065                 break;
2066             case EGL_READS_DONE_TIME_ANDROID:
2067                 releaseTime = &values[i];
2068                 break;
2069             default:
2070                 setError(EGL_BAD_PARAMETER, EGL_FALSE);
2071                 return EGL_FALSE;
2072         }
2073     }
2074 
2075     status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo,
2076             postedTime, acquireTime, refreshStartTime, GLCompositionDoneTime,
2077             displayRetireTime, releaseTime);
2078 
2079     if (ret != NO_ERROR) {
2080         setError(EGL_BAD_ACCESS, EGL_FALSE);
2081         return EGL_FALSE;
2082     }
2083 
2084     return EGL_TRUE;
2085 }
2086 
eglQueryTimestampSupportedANDROID(EGLDisplay dpy,EGLSurface surface,EGLint timestamp)2087 EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface,
2088         EGLint timestamp)
2089 {
2090     clearError();
2091 
2092     const egl_display_ptr dp = validate_display(dpy);
2093     if (!dp) {
2094         setError(EGL_BAD_DISPLAY, EGL_FALSE);
2095         return EGL_FALSE;
2096     }
2097 
2098     SurfaceRef _s(dp.get(), surface);
2099     if (!_s.get()) {
2100         setError(EGL_BAD_SURFACE, EGL_FALSE);
2101         return EGL_FALSE;
2102     }
2103 
2104     switch (timestamp) {
2105 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
2106         case EGL_QUEUE_TIME_ANDROID:
2107         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2108         case EGL_COMPOSITION_START_TIME_ANDROID:
2109         case EGL_COMPOSITION_FINISHED_TIME_ANDROID:
2110         case EGL_DISPLAY_RETIRE_TIME_ANDROID:
2111         case EGL_READS_DONE_TIME_ANDROID:
2112             return EGL_TRUE;
2113 #endif
2114         default:
2115             return EGL_FALSE;
2116     }
2117 }
2118