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