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