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