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