14774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall/*
2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Copyright 2007, The Android Open Source Project
3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
44774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** Licensed under the Apache License, Version 2.0 (the "License");
54774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** you may not use this file except in compliance with the License.
64774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** You may obtain a copy of the License at
7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
84774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall **     http://www.apache.org/licenses/LICENSE-2.0
9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
104774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** Unless required by applicable law or agreed to in writing, software
114774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** distributed under the License is distributed on an "AS IS" BASIS,
124774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall ** See the License for the specific language governing permissions and
14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** limitations under the License.
15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */
16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <ctype.h>
20a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <dlfcn.h>
21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <stdlib.h>
22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <string.h>
23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
24e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner#include <hardware/gralloc1.h>
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/egl.h>
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/eglext.h>
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
29607610786f0950f037812b6801e1bf42e830bb76Craig Donner#include <android/hardware_buffer.h>
3089ed4c8cfd8ad64269dfcff9742e16bdd705b926Mathias Agopian#include <private/android/AHardwareBufferHelpers.h>
3189ed4c8cfd8ad64269dfcff9742e16bdd705b926Mathias Agopian
327db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian#include <cutils/compiler.h>
33a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <cutils/properties.h>
347823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h>
35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
3665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <condition_variable>
3765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <deque>
3865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <mutex>
3965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <unordered_map>
4065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <string>
4165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <thread>
42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
4339c24a20bbc697630d2b92c251b70c04d6f9d00cMathias Agopian#include "../egl_impl.h"
44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_display.h"
46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
4865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include "egl_trace.h"
49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianusing namespace android;
51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
54e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopiannamespace android {
55e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
5665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianusing nsecs_t = int64_t;
5765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
58518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstruct extention_map_t {
59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    const char* name;
60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    __eglMustCastToProperFunctionPointerType address;
61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
63e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian/*
6421558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * This is the list of EGL extensions exposed to applications.
65e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian *
6621558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
6721558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * wrapper and are always available.
68e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian *
6921558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * The rest (gExtensionString) depend on support in the EGL driver, and are
7021558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * only available if the driver supports them. However, some of these must be
7121558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * supported because they are used by the Android system itself; these are
7202b05da60a4669df44c9c0747ec262ec1862cf61Pablo Ceballos * listed as mandatory below and are required by the CDD. The system *assumes*
7321558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * the mandatory extensions are present and may not function properly if some
7421558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * are missing.
7521558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall *
7621558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall * NOTE: Both strings MUST have a single space as the last character.
77e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian */
78737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian
79311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianextern char const * const gBuiltinExtensionString;
80311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianextern char const * const gExtensionString;
81737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian
8221b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter// clang-format off
83311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianchar const * const gBuiltinExtensionString =
8421558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall        "EGL_KHR_get_all_proc_addresses "
8521558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall        "EGL_ANDROID_presentation_time "
86a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        "EGL_KHR_swap_buffers_with_damage "
87607610786f0950f037812b6801e1bf42e830bb76Craig Donner        "EGL_ANDROID_get_native_client_buffer "
8802b05da60a4669df44c9c0747ec262ec1862cf61Pablo Ceballos        "EGL_ANDROID_front_buffer_auto_refresh "
89c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        "EGL_ANDROID_get_frame_timestamps "
9021558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall        ;
91311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian
92311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianchar const * const gExtensionString  =
93e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_image "                        // mandatory
94e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_image_base "                   // mandatory
95e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_image_pixmap "
96e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_lock_surface "
97c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        "EGL_KHR_gl_colorspace "
98e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_gl_texture_2D_image "
99000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_gl_texture_3D_image "
100e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_gl_texture_cubemap_image "
101e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_gl_renderbuffer_image "
102e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_reusable_sync "
103e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_fence_sync "
104f6d1c3930eeba6b089ba12fb82ecad1c6622e550Jamie Gennis        "EGL_KHR_create_context "
105000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_config_attribs "
106000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_surfaceless_context "
107000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream "
108000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_fifo "
109000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_producer_eglsurface "
110000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_consumer_gltexture "
111000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_cross_process_fd "
112e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_EXT_create_context_robustness "
113e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_NV_system_time "
114e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_ANDROID_image_native_buffer "      // mandatory
1152bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian        "EGL_KHR_wait_sync "                    // strongly recommended
116dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis        "EGL_ANDROID_recordable "               // mandatory
117a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        "EGL_KHR_partial_update "               // strongly recommended
1180e4e3955254008e133b9ba14e0782becec3e2343Courtney Goeltzenleuchter        "EGL_EXT_pixel_format_float "
119a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
120408e59f63aaaba30fb6db1477e985025dda085cdJesse Hall        "EGL_KHR_create_context_no_error "
121ceb9ee78bdc7b3a074d01380ce11432f88732094Pablo Ceballos        "EGL_KHR_mutable_render_buffer "
122f37864bc99576b851015f115613cc851a866dbf2Mika Isojärvi        "EGL_EXT_yuv_surface "
123aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner        "EGL_EXT_protected_content "
124a7805f625d84f3f11e74a4631f089a57fc6a01bfChristian Poetzsch        "EGL_IMG_context_priority "
12551d53c4ab3fafa076de8bf85525514de639282a7Pyry Haulos        "EGL_KHR_no_config_context "
126e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        ;
12721b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter// clang-format on
128e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
129e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian// extensions not exposed to applications but used by the ANDROID system
130e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_ANDROID_blob_cache "               // strongly recommended
131e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_IMG_hibernate_process "            // optional
132e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_ANDROID_native_fence_sync "        // strongly recommended
133e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_ANDROID_framebuffer_target "       // mandatory for HWC 1.1
134dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis//      "EGL_ANDROID_image_crop "               // optional
135e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
136e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian/*
137e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * EGL Extensions entry-points exposed to 3rd party applications
138e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * (keep in sync with gExtensionString above)
139e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian *
140e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian */
141e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopianstatic const extention_map_t sExtensionMap[] = {
142e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_KHR_lock_surface
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglLockSurfaceKHR",
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglUnlockSurfaceKHR",
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
147e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
148e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_KHR_image, EGL_KHR_image_base
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglCreateImageKHR",
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglDestroyImageKHR",
152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
153e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
154e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
155e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglCreateSyncKHR",
156e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
157e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglDestroySyncKHR",
158e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
159e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglClientWaitSyncKHR",
160e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
161e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglSignalSyncKHR",
162e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
163e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglGetSyncAttribKHR",
164e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
165e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
166e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_NV_system_time
1671c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    { "eglGetSystemTimeFrequencyNV",
1681c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang            (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
1691c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    { "eglGetSystemTimeNV",
1701c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang            (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
171e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
1722bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    // EGL_KHR_wait_sync
1732bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    { "eglWaitSyncKHR",
1742bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
175e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
176e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_ANDROID_presentation_time
177e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglPresentationTimeANDROID",
178e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
179a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
180a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    // EGL_KHR_swap_buffers_with_damage
181a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    { "eglSwapBuffersWithDamageKHR",
182a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza            (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
183a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
184607610786f0950f037812b6801e1bf42e830bb76Craig Donner    // EGL_ANDROID_get_native_client_buffer
185607610786f0950f037812b6801e1bf42e830bb76Craig Donner    { "eglGetNativeClientBufferANDROID",
186607610786f0950f037812b6801e1bf42e830bb76Craig Donner            (__eglMustCastToProperFunctionPointerType)&eglGetNativeClientBufferANDROID },
187607610786f0950f037812b6801e1bf42e830bb76Craig Donner
188a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    // EGL_KHR_partial_update
189a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    { "eglSetDamageRegionKHR",
190a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza            (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
191000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
192000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglCreateStreamKHR",
193000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
194000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglDestroyStreamKHR",
195000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
196000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamAttribKHR",
197000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
198000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglQueryStreamKHR",
199000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
200000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglQueryStreamu64KHR",
201000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
202000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglQueryStreamTimeKHR",
203000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
204000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglCreateStreamProducerSurfaceKHR",
205000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
206000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamConsumerGLTextureExternalKHR",
207000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
208000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamConsumerAcquireKHR",
209000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
210000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamConsumerReleaseKHR",
211000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
212000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglGetStreamFileDescriptorKHR",
213000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
214000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglCreateStreamFromFileDescriptorKHR",
215000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
216c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
217c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    // EGL_ANDROID_get_frame_timestamps
2181049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    { "eglGetNextFrameIdANDROID",
2191049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetNextFrameIdANDROID },
2200a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    { "eglGetCompositorTimingANDROID",
2210a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingANDROID },
2220a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    { "eglGetCompositorTimingSupportedANDROID",
2230a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingSupportedANDROID },
224c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    { "eglGetFrameTimestampsANDROID",
225c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
2260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    { "eglGetFrameTimestampSupportedANDROID",
2270a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
22855901a20be19b42240aad219f3958c0f07e4c88eCraig Donner
22955901a20be19b42240aad219f3958c0f07e4c88eCraig Donner    // EGL_ANDROID_native_fence_sync
23055901a20be19b42240aad219f3958c0f07e4c88eCraig Donner    { "eglDupNativeFenceFDANDROID",
23155901a20be19b42240aad219f3958c0f07e4c88eCraig Donner            (__eglMustCastToProperFunctionPointerType)&eglDupNativeFenceFDANDROID },
232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
234e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian/*
235e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * These extensions entry-points should not be exposed to applications.
236e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * They're used internally by the Android EGL layer.
237e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian */
238e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian#define FILTER_EXTENSIONS(procname) \
239e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") ||    \
240e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian         !strcmp((procname), "eglHibernateProcessIMG")      ||    \
24155901a20be19b42240aad219f3958c0f07e4c88eCraig Donner         !strcmp((procname), "eglAwakenProcessIMG"))
242e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
243e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
244e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// accesses protected by sExtensionMapMutex
24665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianstatic std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
24765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic int sGLExtentionSlot = 0;
249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic void(*findProcAddress(const char* name,
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const extention_map_t* map, size_t n))() {
253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (uint32_t i=0 ; i<n ; i++) {
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!strcmp(name, map[i].name)) {
255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return map[i].address;
256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return NULL;
259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
264518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern EGLBoolean egl_init_drivers();
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern gl_hooks_t gHooksTrace;
267e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} // namespace android;
269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
270e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
271518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
273518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline void clearError() { egl_tls_t::clearError(); }
274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline EGLContext getContext() { return egl_tls_t::getContext(); }
275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay eglGetDisplay(EGLNativeDisplayType display)
279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
2801508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall    ATRACE_CALL();
281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
283c3289c41e794117817895653300bd2cf7daa0a01Dan Stoza    uintptr_t index = reinterpret_cast<uintptr_t>(display);
284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (index >= NUM_DISPLAYS) {
285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
288518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
289518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
290518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
291518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
292518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return dpy;
294518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
295518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
296518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
297518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Initialization
298518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
300518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
302518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
303518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
304b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = get_display(dpy);
305737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
307518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = dp->initialize(major, minor);
308518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
309518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
310518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
311518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
312518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglTerminate(EGLDisplay dpy)
313518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
314518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // NOTE: don't unload the drivers b/c some APIs can be called
315518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // after eglTerminate() has been called. eglTerminate() only
316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // terminates an EGLDisplay, not a EGL itself.
317518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
318518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
319518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
320b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = get_display(dpy);
321737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
323518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = dp->terminate();
3244774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
325518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
326518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
327518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
328518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
329518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// configuration
330518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
331518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
332518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetConfigs(   EGLDisplay dpy,
333518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLConfig *configs,
334518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint config_size, EGLint *num_config)
335518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
336518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
337518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
338b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
339518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
3417773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (num_config==0) {
342737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
343518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
344518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
3457773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    EGLBoolean res = EGL_FALSE;
3467773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    *num_config = 0;
3477773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian
3487773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
3497773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (cnx->dso) {
3507773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        res = cnx->egl.eglGetConfigs(
3517773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, configs, config_size, num_config);
352518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
3537773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian
3547773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return res;
355518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
356518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
357518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
358518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLConfig *configs, EGLint config_size,
359518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint *num_config)
360518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
361518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
362518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
363b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
364518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
365518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
366518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (num_config==0) {
367737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
368518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
369518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
370518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
371518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    *num_config = 0;
372518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
373ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
374ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
3751cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy        if (attrib_list) {
3761cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            char value[PROPERTY_VALUE_MAX];
3771cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            property_get("debug.egl.force_msaa", value, "false");
3781cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
3791cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            if (!strcmp(value, "true")) {
3801cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                size_t attribCount = 0;
3811cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                EGLint attrib = attrib_list[0];
3821cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
3831cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                // Only enable MSAA if the context is OpenGL ES 2.0 and
384be3c3e4ecad501eecfe1f7a424a792f0f7f3f307Romain Guy                // if no caveat is requested
3851cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                const EGLint *attribRendererable = NULL;
3861cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                const EGLint *attribCaveat = NULL;
3871cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
3881cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                // Count the number of attributes and look for
389be3c3e4ecad501eecfe1f7a424a792f0f7f3f307Romain Guy                // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
3901cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                while (attrib != EGL_NONE) {
3911cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    attrib = attrib_list[attribCount];
3921cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    switch (attrib) {
3931cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        case EGL_RENDERABLE_TYPE:
3941cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            attribRendererable = &attrib_list[attribCount];
3951cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            break;
3961cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        case EGL_CONFIG_CAVEAT:
3971cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            attribCaveat = &attrib_list[attribCount];
3981cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            break;
399737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                        default:
400737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                            break;
4011cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    }
4021cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    attribCount++;
4031cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                }
4041cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4051cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
4061cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
4074774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
4081cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    // Insert 2 extra attributes to force-enable MSAA 4x
4091cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    EGLint aaAttribs[attribCount + 4];
4101cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[0] = EGL_SAMPLE_BUFFERS;
4111cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[1] = 1;
4121cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[2] = EGL_SAMPLES;
4131cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[3] = 4;
4141cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4151cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
4161cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4171cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    EGLint numConfigAA;
4181cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    EGLBoolean resAA = cnx->egl.eglChooseConfig(
4191cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
4201cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4211cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    if (resAA == EGL_TRUE && numConfigAA > 0) {
4221cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        ALOGD("Enabling MSAA 4x");
4231cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        *num_config = numConfigAA;
4241cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        return resAA;
4251cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    }
4261cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                }
4271cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            }
4281cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy        }
4291cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4307773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        res = cnx->egl.eglChooseConfig(
4317773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, attrib_list, configs, config_size, num_config);
432518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
433518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
434518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
437518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint attribute, EGLint *value)
438518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
439518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
440518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
441b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
442b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
443b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (!dp) return EGL_FALSE;
4444774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
445518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return cnx->egl.eglGetConfigAttrib(
4467773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian            dp->disp.dpy, config, attribute, value);
447518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
449518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
450518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// surfaces
451518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
452518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
453c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall// Turn linear formats into corresponding sRGB formats when colorspace is
454c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall// EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
455c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall// formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
45682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala// the modification isn't possible, the original dataSpace is returned.
457eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchterstatic android_dataspace modifyBufferDataspace(android_dataspace dataSpace,
458eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                                               EGLint colorspace) {
459c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
46082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        return HAL_DATASPACE_SRGB_LINEAR;
461c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
46282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        return HAL_DATASPACE_SRGB;
46321b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
46421b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter        return HAL_DATASPACE_DISPLAY_P3;
46521b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT) {
46621b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter        return HAL_DATASPACE_DISPLAY_P3_LINEAR;
46733e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_EXT) {
46833e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter        return HAL_DATASPACE_V0_SCRGB;
46921b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
47021b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter        return HAL_DATASPACE_V0_SCRGB_LINEAR;
471c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
47282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala    return dataSpace;
473c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
474c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
475eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter// Return true if we stripped any EGL_GL_COLORSPACE_KHR attributes.
476eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchterstatic EGLBoolean stripColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
477eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                                           EGLint format,
478eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                                           std::vector<EGLint>& stripped_attrib_list) {
479eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    std::vector<EGLint> allowedColorSpaces;
480eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    switch (format) {
481eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        case HAL_PIXEL_FORMAT_RGBA_8888:
482eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        case HAL_PIXEL_FORMAT_RGB_565:
483eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // driver okay with linear & sRGB for 8888, but can't handle
484eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // Display-P3 or other spaces.
485eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
486eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
487eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            break;
488eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
489eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        case HAL_PIXEL_FORMAT_RGBA_FP16:
490eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        case HAL_PIXEL_FORMAT_RGBA_1010102:
491eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        default:
492eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // driver does not want to see colorspace attributes for 1010102 or fp16.
493eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // Future: if driver supports XXXX extension, we can pass down that colorspace
494eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            break;
495eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
496eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
497eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    bool stripped = false;
498eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
499eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
500eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            if (attr[0] == EGL_GL_COLORSPACE_KHR) {
501eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                EGLint colorSpace = attr[1];
502eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                bool found = false;
503eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                // Verify that color space is allowed
504eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                for (auto it : allowedColorSpaces) {
505eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    if (colorSpace == it) {
506eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                        found = true;
507eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    }
508eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                }
509eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                if (!found) {
510eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    stripped = true;
511eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                } else {
512eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    stripped_attrib_list.push_back(attr[0]);
513eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    stripped_attrib_list.push_back(attr[1]);
514eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                }
515eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            } else {
516eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                stripped_attrib_list.push_back(attr[0]);
517eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                stripped_attrib_list.push_back(attr[1]);
518eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            }
519eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
520eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
521eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    if (stripped) {
522eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        stripped_attrib_list.push_back(EGL_NONE);
523eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        stripped_attrib_list.push_back(EGL_NONE);
524eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
525eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    return stripped;
526eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter}
527eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
528e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchterstatic EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, NativeWindowType window,
529e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                                         const EGLint* attrib_list, EGLint& colorSpace,
530e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                                         android_dataspace& dataSpace) {
531378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
532378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    dataSpace = HAL_DATASPACE_UNKNOWN;
533e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
534378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
535378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
536378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            if (*attr == EGL_GL_COLORSPACE_KHR) {
537378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                colorSpace = attr[1];
538378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                bool found = false;
539e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                bool verify = true;
540378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                // Verify that color space is allowed
541378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
542378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) {
543e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // SRGB and LINEAR are always supported when EGL_KHR_gl_colorspace
544e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // is available, so no need to verify.
545378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    found = true;
546e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    verify = false;
547378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_linear &&
548378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                           dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) {
549378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    found = true;
550378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_pq &&
551378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                           dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) {
552378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    found = true;
55333e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter                } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_EXT &&
55433e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter                           dp->haveExtension("EGL_EXT_gl_colorspace_scrgb")) {
55533e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter                    found = true;
556378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT &&
557378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                           dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) {
558378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    found = true;
559378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT &&
560378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                           dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) {
561378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    found = true;
562378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT &&
563378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                           dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) {
564378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    found = true;
565378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                }
566378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                if (!found) {
567378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    return false;
568378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                }
569e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                if (verify && window) {
570e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    bool wide_color_support = true;
571e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // Ordinarily we'd put a call to native_window_get_wide_color_support
572e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // at the beginning of the function so that we'll have the
573e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // result when needed elsewhere in the function.
574e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // However, because eglCreateWindowSurface is called by SurfaceFlinger and
575e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // SurfaceFlinger is required to answer the call below we would
576e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // end up in a deadlock situation. By moving the call to only happen
577e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // if the application has specifically asked for wide-color we avoid
578e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // the deadlock with SurfaceFlinger since it will not ask for a
579e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    // wide-color surface.
580e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    int err = native_window_get_wide_color_support(window, &wide_color_support);
581e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
582e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    if (err) {
583e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                        ALOGE("getColorSpaceAttribute: invalid window (win=%p) "
584e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                              "failed (%#x) (already connected to another API?)",
585e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                              window, err);
586e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                        return false;
587e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    }
588e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    if (!wide_color_support) {
589e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                        // Application has asked for a wide-color colorspace but
590e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                        // wide-color support isn't available on the display the window is on.
591e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                        return false;
592e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    }
593e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                }
5941d4f7a281c8380c05c3e86998f8ff653e7e5470cCourtney Goeltzenleuchter                // Only change the dataSpace from default if the application
5951d4f7a281c8380c05c3e86998f8ff653e7e5470cCourtney Goeltzenleuchter                // has explicitly set the color space with a EGL_GL_COLORSPACE_KHR attribute.
5961d4f7a281c8380c05c3e86998f8ff653e7e5470cCourtney Goeltzenleuchter                dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
597378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            }
598378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        }
599378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    }
600378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    return true;
601378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter}
602378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter
603e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchterstatic EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
604e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                                         EGLint& colorSpace, android_dataspace& dataSpace) {
605e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter    return getColorSpaceAttribute(dp, NULL, attrib_list, colorSpace, dataSpace);
606e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter}
607e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
608eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchtervoid getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config, EGLint& format) {
609eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // Set the native window's buffers format to match what this config requests.
610eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // Whether to use sRGB gamma is not part of the EGLconfig, but is part
611eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // of our native format. So if sRGB gamma is requested, we have to
612eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // modify the EGLconfig's format before setting the native window's
613eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // format.
614eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
615eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
616eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType);
617eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
618eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint a = 0;
619eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint r, g, b;
620eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    r = g = b = 0;
621eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r);
622eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
623eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b);
624eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
625eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint colorDepth = r + g + b;
626eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
627eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // Today, the driver only understands sRGB and linear on 888X
628eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // formats. Strip other colorspaces from the attribute list and
629eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // only use them to set the dataspace via
630eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // native_window_set_buffers_dataspace
631eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // if pixel format is RGBX 8888
632eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    TBD: Can test for future extensions that indicate that driver
633eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    handles requested color space and we can let it through.
634eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    allow SRGB and LINEAR. All others need to be stripped.
635eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // else if 565, 4444
636eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    TBD: Can we assume these are supported if 8888 is?
637eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // else if FP16 or 1010102
638eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    strip colorspace from attribs.
639eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // endif
640eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    if (a == 0) {
641eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        if (colorDepth <= 16) {
642eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            format = HAL_PIXEL_FORMAT_RGB_565;
643eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        } else {
644eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
645eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                if (colorDepth > 24) {
646eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    format = HAL_PIXEL_FORMAT_RGBA_1010102;
647eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                } else {
648eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                    format = HAL_PIXEL_FORMAT_RGBX_8888;
649eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                }
650eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            } else {
651eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                format = HAL_PIXEL_FORMAT_RGBA_FP16;
652eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            }
653eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
654eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    } else {
655eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
656eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            if (colorDepth > 24) {
657eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                format = HAL_PIXEL_FORMAT_RGBA_1010102;
658eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            } else {
659eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                format = HAL_PIXEL_FORMAT_RGBA_8888;
660eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            }
661eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        } else {
662eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            format = HAL_PIXEL_FORMAT_RGBA_FP16;
663eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
664eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
665eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter}
666eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
667518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
668518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    NativeWindowType window,
669518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
670518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
671518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
672518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
673b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
674b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display_connection(dpy, cnx);
675b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (dp) {
676ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay iDpy = dp->disp.dpy;
677518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
67810e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        if (!window) {
67910e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
68010e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        }
68110e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian
68210e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        int value = 0;
68310e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        window->query(window, NATIVE_WINDOW_IS_VALID, &value);
68410e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        if (!value) {
68510e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
68610e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        }
68710e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian
688d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden        int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
68965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        if (result < 0) {
690d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden            ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
691d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden                    "failed (%#x) (already connected to another API?)",
692d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden                    window, result);
69377a9b4a6bd21188e2744ae9dcd8092c6837bff7cJonathan Hamilton            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
69481a63350527cafce6929309533c58586878f10b5Mathias Agopian        }
69581a63350527cafce6929309533c58586878f10b5Mathias Agopian
6969592156ac406ca84acbcdf47909af3d41cfd5863Mathias Agopian        EGLint format;
697eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        getNativePixelFormat(iDpy, cnx, config, format);
698eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
699eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        // now select correct colorspace and dataspace based on user's attribute list
700378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        EGLint colorSpace;
701378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        android_dataspace dataSpace;
702e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter        if (!getColorSpaceAttribute(dp, window, attrib_list, colorSpace, dataSpace)) {
703378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            ALOGE("error invalid colorspace: %d", colorSpace);
704378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
705518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
706733a80754786d39cdc0fee09509b194472c320bcAlistair Strachan
707eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        std::vector<EGLint> strippedAttribList;
708eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        if (stripColorSpaceAttribute(dp, attrib_list, format, strippedAttribList)) {
709eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // Had to modify the attribute list due to use of color space.
710eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // Use modified list from here on.
711eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            attrib_list = strippedAttribList.data();
712eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
713eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
714c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        if (format != 0) {
715c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall            int err = native_window_set_buffers_format(window, format);
716c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall            if (err != 0) {
717c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                ALOGE("error setting native window pixel format: %s (%d)",
718c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                        strerror(-err), err);
71982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
72082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
72182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            }
72282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        }
72382c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala
72482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        if (dataSpace != 0) {
72582c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            int err = native_window_set_buffers_data_space(window, dataSpace);
72682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            if (err != 0) {
72782c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                ALOGE("error setting native window pixel dataSpace: %s (%d)",
72882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                        strerror(-err), err);
729c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
730c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
731c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall            }
732c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        }
733518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
73459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // the EGL spec requires that a new EGLSurface default to swap interval
73559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // 1, so explicitly set that on the window here.
73659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
73759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        anw->setSwapInterval(anw, 1);
73859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
739518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreateWindowSurface(
7407773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                iDpy, config, window, attrib_list);
741518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
742378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            egl_surface_t* s =
743378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                    new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx);
744518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
745518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
74681a63350527cafce6929309533c58586878f10b5Mathias Agopian
74781a63350527cafce6929309533c58586878f10b5Mathias Agopian        // EGLSurface creation failed
74881a63350527cafce6929309533c58586878f10b5Mathias Agopian        native_window_set_buffers_format(window, 0);
74981a63350527cafce6929309533c58586878f10b5Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
750518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
751518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
752518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
753518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
754518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
755518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    NativePixmapType pixmap,
756518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
757518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
758518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
759518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
760b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
761b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display_connection(dpy, cnx);
762378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    EGLint colorSpace;
763378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    android_dataspace dataSpace;
764b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (dp) {
765378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        // now select a corresponding sRGB format if needed
766378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
767378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            ALOGE("error invalid colorspace: %d", colorSpace);
768378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
769378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        }
770378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter
771518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
7727773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, config, pixmap, attrib_list);
773518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
774378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
775518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
776518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
777518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
778518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
779518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
780518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
781518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
782518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
783518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
784518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
785518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
786b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
787b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display_connection(dpy, cnx);
788b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (dp) {
789eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        EGLDisplay iDpy = dp->disp.dpy;
790eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        EGLint format;
791eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        getNativePixelFormat(iDpy, cnx, config, format);
792eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
793eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        // now select correct colorspace and dataspace based on user's attribute list
794eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        EGLint colorSpace;
795eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        android_dataspace dataSpace;
796378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
797378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            ALOGE("error invalid colorspace: %d", colorSpace);
798378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
799378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        }
800378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter
801eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        // Pbuffers are not displayed so we don't need to store the
802eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        // colorspace. We do need to filter out color spaces the
803eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        // driver doesn't know how to process.
804eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        std::vector<EGLint> strippedAttribList;
805eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        if (stripColorSpaceAttribute(dp, attrib_list, format, strippedAttribList)) {
806eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // Had to modify the attribute list due to use of color space.
807eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            // Use modified list from here on.
808eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            attrib_list = strippedAttribList.data();
809eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
810eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
811518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
8127773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, config, attrib_list);
813518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
814378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
815518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
816518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
817518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
818518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
819518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
8204774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
821518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
822518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
823518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
824518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
825b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
826518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
827518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
828b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
8295b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
830737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
831518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
832518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t * const s = get_surface(surface);
833ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
834518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
835518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        _s.terminate();
836518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
837518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
838518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
839518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
840518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
841518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint attribute, EGLint *value)
842518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
843518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
844518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
845b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
846518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
847518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
848b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
8495b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
850737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
851518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
852518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
853378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    if (attribute == EGL_GL_COLORSPACE_KHR) {
854378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        *value = s->getColorSpace();
855378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        return EGL_TRUE;
856378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    }
8577773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return s->cnx->egl.eglQuerySurface(
8587773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian            dp->disp.dpy, s->surface, attribute, value);
859518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
860518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
861e8696a40e09b24b634214684d18526187b316a2fJamie Gennisvoid EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
8621c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
863e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    clearError();
864e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
865b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
866e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (!dp) {
867e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        return;
868e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
869e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
870b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
871e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (!_s.get()) {
872e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        setError(EGL_BAD_SURFACE, EGL_FALSE);
873e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
874e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
875e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
876518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
877518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Contexts
878518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
879518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
880518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
881518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLContext share_list, const EGLint *attrib_list)
882518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
883518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
884518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
885b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
886b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
8870673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock    if (dp) {
888518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (share_list != EGL_NO_CONTEXT) {
8890673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock            if (!ContextRef(dp.get(), share_list).get()) {
8900673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock                return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
8910673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock            }
892518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_context_t* const c = get_context(share_list);
893518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            share_list = c->context;
894518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
895518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLContext context = cnx->egl.eglCreateContext(
8967773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, config, share_list, attrib_list);
897518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (context != EGL_NO_CONTEXT) {
898518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // figure out if it's a GLESv1 or GLESv2
899518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            int version = 0;
900518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (attrib_list) {
901518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                while (*attrib_list != EGL_NONE) {
902518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    GLint attr = *attrib_list++;
903518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    GLint value = *attrib_list++;
904518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    if (attr == EGL_CONTEXT_CLIENT_VERSION) {
905518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        if (value == 1) {
9067773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                            version = egl_connection_t::GLESv1_INDEX;
9074774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall                        } else if (value == 2 || value == 3) {
9087773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                            version = egl_connection_t::GLESv2_INDEX;
909518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        }
910518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    }
911518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                };
912518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
913b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall            egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
914b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall                    version);
915518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return c;
916518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
917518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
918518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_CONTEXT;
919518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
920518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
921518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
922518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
923518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
924518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
925b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
9265b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!dp)
9275b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return EGL_FALSE;
928518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
929b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
9305b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
931737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
9324774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
933518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
934ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
935518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
936518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        _c.terminate();
937518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
938518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
939518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
940518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
941518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
942518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLSurface read, EGLContext ctx)
943518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
944518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
945518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
946b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display(dpy);
947737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
948518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
9495b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
9505b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
9515b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // a valid but uninitialized display.
952518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
953518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         (draw != EGL_NO_SURFACE) ) {
954737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
955518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
956518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
957518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get a reference to the object passed in
958b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
959b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _d(dp.get(), draw);
960b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _r(dp.get(), read);
961518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
962518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // validate the context (if not EGL_NO_CONTEXT)
9635b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
964518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // EGL_NO_CONTEXT is valid
965737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
966518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
967518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
968518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are the underlying implementation's object
969518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext impl_ctx  = EGL_NO_CONTEXT;
970518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface impl_draw = EGL_NO_SURFACE;
971518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface impl_read = EGL_NO_SURFACE;
972518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
973518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are our objects structs passed in
974518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t       * c = NULL;
975518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * d = NULL;
976518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * r = NULL;
977518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
978518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are the current objects structs
979518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * cur_c = get_context(getContext());
9804774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
981518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx != EGL_NO_CONTEXT) {
982518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        c = get_context(ctx);
983518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_ctx = c->context;
984518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    } else {
985518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // no context given, use the implementation of the current context
9860673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock        if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
9870673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock            // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
988737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_MATCH, (EGLBoolean)EGL_FALSE);
9890673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock        }
990518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cur_c == NULL) {
991518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // no current context
992518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // not an error, there is just no current context.
993518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return EGL_TRUE;
994518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
995518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
996518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
997518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // retrieve the underlying implementation's draw EGLSurface
998518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (draw != EGL_NO_SURFACE) {
999737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        if (!_d.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1000518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        d = get_surface(draw);
1001518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_draw = d->surface;
1002518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1003518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1004518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // retrieve the underlying implementation's read EGLSurface
1005518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (read != EGL_NO_SURFACE) {
1006737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        if (!_r.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1007518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        r = get_surface(read);
1008518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_read = r->surface;
1009518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1010518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1011518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1012b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    EGLBoolean result = dp->makeCurrent(c, cur_c,
1013fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian            draw, read, ctx,
1014fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian            impl_draw, impl_read, impl_ctx);
1015518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1016518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
1017fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
1018518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
1019518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_tls_t::setContext(ctx);
1020518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _c.acquire();
1021518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _r.acquire();
1022518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _d.acquire();
1023518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
1024518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            setGLHooksThreadSpecific(&gHooksNoContext);
1025518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_tls_t::setContext(EGL_NO_CONTEXT);
1026518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
10275fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian    } else {
102802ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan
102947e741bddde799732537116eef2ca30a93bc622cMike Stroyan        if (cur_c != NULL) {
103047e741bddde799732537116eef2ca30a93bc622cMike Stroyan            // Force return to current context for drivers that cannot handle errors
103147e741bddde799732537116eef2ca30a93bc622cMike Stroyan            EGLBoolean restore_result = EGL_FALSE;
103247e741bddde799732537116eef2ca30a93bc622cMike Stroyan            // get a reference to the old current objects
103347e741bddde799732537116eef2ca30a93bc622cMike Stroyan            ContextRef _c2(dp.get(), cur_c);
103447e741bddde799732537116eef2ca30a93bc622cMike Stroyan            SurfaceRef _d2(dp.get(), cur_c->draw);
103547e741bddde799732537116eef2ca30a93bc622cMike Stroyan            SurfaceRef _r2(dp.get(), cur_c->read);
103602ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan
103702ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            c = cur_c;
103802ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            impl_ctx = c->context;
103902ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            impl_draw = EGL_NO_SURFACE;
104002ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            if (cur_c->draw != EGL_NO_SURFACE) {
104102ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                d = get_surface(cur_c->draw);
104202ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                impl_draw = d->surface;
104302ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            }
104402ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            impl_read = EGL_NO_SURFACE;
104502ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            if (cur_c->read != EGL_NO_SURFACE) {
104602ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                r = get_surface(cur_c->read);
104702ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                impl_read = r->surface;
104802ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            }
104902ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            restore_result = dp->makeCurrent(c, cur_c,
105002ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                    cur_c->draw, cur_c->read, cur_c->context,
105102ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                    impl_draw, impl_read, impl_ctx);
105247e741bddde799732537116eef2ca30a93bc622cMike Stroyan            if (restore_result == EGL_TRUE) {
105347e741bddde799732537116eef2ca30a93bc622cMike Stroyan                _c2.acquire();
105447e741bddde799732537116eef2ca30a93bc622cMike Stroyan                _r2.acquire();
105547e741bddde799732537116eef2ca30a93bc622cMike Stroyan                _d2.acquire();
105647e741bddde799732537116eef2ca30a93bc622cMike Stroyan            } else {
105747e741bddde799732537116eef2ca30a93bc622cMike Stroyan                ALOGE("Could not restore original EGL context");
105847e741bddde799732537116eef2ca30a93bc622cMike Stroyan            }
105902ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan        }
1060e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        // this will ALOGE the error
106163108c34ec181e923b68ee840bb7960f205466a7Mathias Agopian        egl_connection_t* const cnx = &gEGLImpl;
1062737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
1063518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1064518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
1065518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1066518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1067518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1068518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
1069518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint attribute, EGLint *value)
1070518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1071518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1072518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1073b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1074518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1075518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1076b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
1077737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1078518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1079518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
10807773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return c->cnx->egl.eglQueryContext(
10817773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian            dp->disp.dpy, c->context, attribute, value);
1082518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1083518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1084518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1085518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext eglGetCurrentContext(void)
1086518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1087518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
1088518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_CONTEXT.
1089518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1090518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1091518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1092518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
1093518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return ctx;
1094518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1095518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1096518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglGetCurrentSurface(EGLint readdraw)
1097518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1098518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
1099518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_SURFACE.
1100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
1104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx) {
1105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t const * const c = get_context(ctx);
1106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        switch (readdraw) {
1108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            case EGL_READ: return c->read;
11094774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall            case EGL_DRAW: return c->draw;
1110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
1111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
1114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay eglGetCurrentDisplay(void)
1117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
1119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_DISPLAY.
1120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
1124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx) {
1125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t const * const c = get_context(ctx);
1126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return c->dpy;
1128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_DISPLAY;
1130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitGL(void)
1133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1136ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1137ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1138737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1139ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1140ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return cnx->egl.eglWaitGL();
1141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitNative(EGLint engine)
1144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1147ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1148ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1149737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1150ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1151ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return cnx->egl.eglWaitNative(engine);
1152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLint eglGetError(void)
1155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1156ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLint err = EGL_SUCCESS;
1157ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1158ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
1159ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        err = cnx->egl.eglGetError();
1160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1161ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (err == EGL_SUCCESS) {
1162ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        err = egl_tls_t::getError();
1163ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    }
1164ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return err;
1165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1167c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chockstatic __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
1168c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall        const char* procname) {
1169c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    const egl_connection_t* cnx = &gEGLImpl;
1170c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    void* proc = NULL;
1171c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1172c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock    proc = dlsym(cnx->libEgl, procname);
1173c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock    if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1174c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock
1175c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    proc = dlsym(cnx->libGles2, procname);
1176c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1177c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1178c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    proc = dlsym(cnx->libGles1, procname);
1179c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1180c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1181c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    return NULL;
1182c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall}
1183c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
1185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // eglGetProcAddress() could be the very first function called
1187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // in which case we must make sure we've initialized ourselves, this
1188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // happens the first time egl_get_display() is called.
1189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        setError(EGL_BAD_PARAMETER, NULL);
1194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return  NULL;
1195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1197e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    if (FILTER_EXTENSIONS(procname)) {
1198aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis        return NULL;
1199aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    }
1200aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
1201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    __eglMustCastToProperFunctionPointerType addr;
1202e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
1203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (addr) return addr;
1204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1205c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock    addr = findBuiltinWrapper(procname);
1206c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    if (addr) return addr;
1207aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
1208518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this protects accesses to sGLExtentionMap and sGLExtentionSlot
1209518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    pthread_mutex_lock(&sExtensionMapMutex);
1210518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1211518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
1212518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * Since eglGetProcAddress() is not associated to anything, it needs
1213518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * to return a function pointer that "works" regardless of what
1214518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * the current context is.
1215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
1216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * For this reason, we return a "forwarder", a small stub that takes
1217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * care of calling the function associated with the context
1218518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * currently bound.
1219518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
1220518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * We first look for extensions we've already resolved, if we're seeing
1221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * this extension for the first time, we go through all our
1222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * implementations and call eglGetProcAddress() and record the
1223518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * result in the appropriate implementation hooks and return the
1224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * address of the forwarder corresponding to that hook set.
1225518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
1226518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
1227518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
122865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        const std::string name(procname);
122965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
123065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    auto& extentionMap = sGLExtentionMap;
123165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    auto pos = extentionMap.find(name);
123265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        addr = (pos != extentionMap.end()) ? pos->second : nullptr;
1233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const int slot = sGLExtentionSlot;
1234518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1235e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
1236518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                "no more slots for eglGetProcAddress(\"%s\")",
1237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                procname);
1238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
1240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            bool found = false;
1241ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1242ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_connection_t* const cnx = &gEGLImpl;
1243ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            if (cnx->dso && cnx->egl.eglGetProcAddress) {
1244ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // Extensions are independent of the bound context
124569d100762c7c26d8328f4bb61cfef026d3a69bbfluliuhui                addr =
12467773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
12477773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
1248ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        cnx->egl.eglGetProcAddress(procname);
124969d100762c7c26d8328f4bb61cfef026d3a69bbfluliuhui                if (addr) found = true;
1250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
1251ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (found) {
1253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                addr = gExtensionForwarders[slot];
125465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                extentionMap[name] = addr;
1255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                sGLExtentionSlot++;
1256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
1257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    pthread_mutex_unlock(&sExtensionMapMutex);
1260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return addr;
1261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
126365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianclass FrameCompletionThread {
126428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennispublic:
126528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
126628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    static void queueSync(EGLSyncKHR sync) {
126765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        static FrameCompletionThread thread;
126865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
126965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        char name[64];
127065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
127165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> lock(thread.mMutex);
127265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        snprintf(name, sizeof(name), "kicked off frame %u", (unsigned int)thread.mFramesQueued);
127365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        ATRACE_NAME(name);
127465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
127565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.mQueue.push_back(sync);
127665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.mCondition.notify_one();
127765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.mFramesQueued++;
127865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        ATRACE_INT("GPU Frames Outstanding", int32_t(thread.mQueue.size()));
127928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
128028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
128128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennisprivate:
128228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
128365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {
128465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::thread thread(&FrameCompletionThread::loop, this);
128565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.detach();
128665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    }
128765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
128865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#pragma clang diagnostic push
128965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#pragma clang diagnostic ignored "-Wmissing-noreturn"
129065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    void loop() {
129165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        while (true) {
129265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            threadLoop();
129365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        }
129465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    }
129565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#pragma clang diagnostic pop
129665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
129765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    void threadLoop() {
129828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        EGLSyncKHR sync;
129928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        uint32_t frameNum;
130028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        {
130165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            std::unique_lock<std::mutex> lock(mMutex);
130265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            while (mQueue.empty()) {
130365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                mCondition.wait(lock);
130428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            }
130528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            sync = mQueue[0];
130628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            frameNum = mFramesCompleted;
130728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        }
130828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
130928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        {
131065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            char name[64];
131165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            snprintf(name, sizeof(name), "waiting for frame %u", (unsigned int)frameNum);
131265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            ATRACE_NAME(name);
131365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
131428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
131528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            if (result == EGL_FALSE) {
131628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis                ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
131728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
131828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis                ALOGE("FrameCompletion: timeout waiting for fence");
131928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            }
132028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            eglDestroySyncKHR(dpy, sync);
132128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        }
132228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        {
132365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            std::lock_guard<std::mutex> lock(mMutex);
132465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            mQueue.pop_front();
132528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            mFramesCompleted++;
1326737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            ATRACE_INT("GPU Frames Outstanding", int32_t(mQueue.size()));
132728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        }
132828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
132928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
133028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    uint32_t mFramesQueued;
133128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    uint32_t mFramesCompleted;
133265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::deque<EGLSyncKHR> mQueue;
133365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::condition_variable mCondition;
133465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::mutex mMutex;
133528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis};
133628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
1337a894d082cfee8d12ee5913163a34ec5dc521d005Dan StozaEGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
1338a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        EGLint *rects, EGLint n_rects)
1339518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
13401c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
1341518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1343b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1344518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1345518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1346b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), draw);
13475b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1348737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1349518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1350518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(draw);
13517db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian
1352ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian    if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1353ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian        EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
1354ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian        if (sync != EGL_NO_SYNC_KHR) {
1355ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian            FrameCompletionThread::queueSync(sync);
1356ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian        }
1357ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian    }
1358ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian
13597db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    if (CC_UNLIKELY(dp->finishOnSwap)) {
13607db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        uint32_t pixel;
13617db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        egl_context_t * const c = get_context( egl_tls_t::getContext() );
13627db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        if (c) {
13637db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian            // glReadPixels() ensures that the frame is complete
13647db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian            s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
13657db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian                    GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
13667db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        }
13677db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    }
13687db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian
1369a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (n_rects == 0) {
1370a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1371a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
1372a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
137365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::vector<android_native_rect_t> androidRects((size_t)n_rects);
1374a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    for (int r = 0; r < n_rects; ++r) {
1375a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int offset = r * 4;
1376a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int x = rects[offset];
1377a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int y = rects[offset + 1];
1378a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int width = rects[offset + 2];
1379a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int height = rects[offset + 3];
1380a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        android_native_rect_t androidRect;
1381a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.left = x;
1382a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.top = y + height;
1383a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.right = x + width;
1384a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.bottom = y;
1385a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRects.push_back(androidRect);
1386a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
138765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(), androidRects.size());
1388a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
1389a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1390a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
1391a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza                rects, n_rects);
1392a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    } else {
1393a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1394a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
1395a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza}
1396a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
1397a894d082cfee8d12ee5913163a34ec5dc521d005Dan StozaEGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1398a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza{
1399a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
1400518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1401518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1402518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
1403518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            NativePixmapType target)
1404518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1405518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1406518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1407b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1408518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1409518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1410b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
14115b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1412737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1413518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1414518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1415ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1416518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1417518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1418518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianconst char* eglQueryString(EGLDisplay dpy, EGLint name)
1419518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1420518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1421518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1422e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // Generate an error quietly when client extensions (as defined by
1423e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // EGL_EXT_client_extensions) are queried.  We do not want to rely on
1424e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // validate_display to generate the error as validate_display would log
1425e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // the error, which can be misleading.
1426e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    //
1427e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // If we want to support EGL_EXT_client_extensions later, we can return
1428e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // the client extension string here instead.
1429e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
1430737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setErrorQuiet(EGL_BAD_DISPLAY, (const char*)0);
1431e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu
1432b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1433518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return (const char *) NULL;
1434518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    switch (name) {
1436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_VENDOR:
14374b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getVendorString();
1438518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_VERSION:
14394b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getVersionString();
1440518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_EXTENSIONS:
14414b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getExtensionString();
1442518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_CLIENT_APIS:
14434b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getClientApiString();
1444737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        default:
1445737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            break;
1446518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1447518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_PARAMETER, (const char *)0);
1448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1449518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
145000b15b8f223976d016e16536e4720771ef634695Jiyong Parkextern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
1451ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian{
1452ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    clearError();
1453ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
1454ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    const egl_display_ptr dp = validate_display(dpy);
1455ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    if (!dp) return (const char *) NULL;
1456ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
1457ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    switch (name) {
1458ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_VENDOR:
1459ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.vendor;
1460ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_VERSION:
1461ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.version;
1462ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_EXTENSIONS:
1463ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.extensions;
1464ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_CLIENT_APIS:
1465ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.clientApi;
1466737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        default:
1467737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            break;
1468ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    }
1469ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    return setError(EGL_BAD_PARAMETER, (const char *)0);
1470ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian}
1471518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1472518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1473518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL 1.1
1474518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1475518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1476518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSurfaceAttrib(
1477518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1478518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1479518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1480518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1481b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1482518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1483518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1484b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
14855b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1486737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1487518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1488c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    egl_surface_t * const s = get_surface(surface);
1489ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
149002b05da60a4669df44c9c0747ec262ec1862cf61Pablo Ceballos    if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
149165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        if (!s->getNativeWindow()) {
1492069b365163470d2736eb6f591c354d208b5da23bBrian Anderson            setError(EGL_BAD_SURFACE, EGL_FALSE);
1493069b365163470d2736eb6f591c354d208b5da23bBrian Anderson        }
149465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        int err = native_window_set_auto_refresh(s->getNativeWindow(), value != 0);
149565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1496ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    }
1497ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
1498c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (attribute == EGL_TIMESTAMPS_ANDROID) {
149965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        if (!s->getNativeWindow()) {
1500737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1501069b365163470d2736eb6f591c354d208b5da23bBrian Anderson        }
150265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0);
150365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1504c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
1505c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
1506518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglSurfaceAttrib) {
1507518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglSurfaceAttrib(
1508ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attribute, value);
1509518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1510737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1511518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1512518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1513518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglBindTexImage(
1514518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1515518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1516518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1517518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1518b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1519518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1520518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1521b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
15225b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1523737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1524518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1525518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1526518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglBindTexImage) {
1527518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglBindTexImage(
1528ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, buffer);
1529518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1530737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1531518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1532518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1533518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglReleaseTexImage(
1534518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1535518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1536518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1537518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1538b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1539518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1540518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1541b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
15425b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1543737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1544518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1545518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1546518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglReleaseTexImage) {
1547518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglReleaseTexImage(
1548ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, buffer);
1549518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1550737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1551518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1552518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1553518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1554518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1555518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1556518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1557b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1558518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1559518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1560518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_TRUE;
1561ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1562ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglSwapInterval) {
1563ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1564518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1565ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1566518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1567518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1568518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1569518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1570518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1571518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL 1.2
1572518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1573518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1574518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitClient(void)
1575518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1576518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1577518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1578ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1579ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1580737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1581ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1582ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean res;
1583ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->egl.eglWaitClient) {
1584ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglWaitClient();
1585ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    } else {
1586ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglWaitGL();
1587518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1588518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1589518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1590518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1591518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglBindAPI(EGLenum api)
1592518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1593518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1594518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1595518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1596737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1597518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1598518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1599518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // bind this API on all EGLs
1600518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_TRUE;
1601ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1602ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglBindAPI) {
1603ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglBindAPI(api);
1604518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1605518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1606518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1607518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1608518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLenum eglQueryAPI(void)
1609518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1610518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1611518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1612518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1613737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1614518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1615518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1616ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1617ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglQueryAPI) {
1618ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglQueryAPI();
1619518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1620ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1621518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // or, it can only be OpenGL ES
1622518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_OPENGL_ES_API;
1623518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1624518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1625518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglReleaseThread(void)
1626518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1627518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1628518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1629ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1630ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglReleaseThread) {
1631ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        cnx->egl.eglReleaseThread();
1632518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
16333ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar
16343ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar    // If there is context bound to the thread, release it
16353ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar    egl_display_t::loseCurrent(get_context(getContext()));
16363ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar
1637518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_tls_t::clearTLS();
1638518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_TRUE;
1639518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1640518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1641518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePbufferFromClientBuffer(
1642518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1643518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian          EGLConfig config, const EGLint *attrib_list)
1644518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1645518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1646518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1647b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
1648b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
1649b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (!dp) return EGL_FALSE;
1650518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1651518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return cnx->egl.eglCreatePbufferFromClientBuffer(
16527773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, buftype, buffer, config, attrib_list);
1653518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1654518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1655518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1656518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1657518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1658518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL_EGLEXT_VERSION 3
1659518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1660518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1661518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
1662518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const EGLint *attrib_list)
1663518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1664518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1665518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1666b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1667518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1668518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1669b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
16705b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1671737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1672518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1673518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1674518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglLockSurfaceKHR) {
1675518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglLockSurfaceKHR(
1676ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attrib_list);
1677518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1678737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1679518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1680518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1681518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
1682518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1683518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1684518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1685b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1686518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1687518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1688b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
16895b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1690737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1691518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1692518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1693518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglUnlockSurfaceKHR) {
1694ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1695518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1696737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1697518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1698518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1699518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1700518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLClientBuffer buffer, const EGLint *attrib_list)
1701518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1702518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1703518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1704b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1705518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_NO_IMAGE_KHR;
1706518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1707b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
17087c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_context_t * const c = _c.get();
1709518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
17107c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    EGLImageKHR result = EGL_NO_IMAGE_KHR;
17117c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17127c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglCreateImageKHR) {
17137c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglCreateImageKHR(
17147c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                dp->disp.dpy,
17157c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                c ? c->context : EGL_NO_CONTEXT,
17167c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                target, buffer, attrib_list);
1717518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
17187c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1719518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1720518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1721518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1722518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1723518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1724518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1725b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1726518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1727518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1728646a5c593f9819dc5da6a1ec859bc70cb7ba096fSteven Holte    EGLBoolean result = EGL_FALSE;
1729ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17307c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
1731646a5c593f9819dc5da6a1ec859bc70cb7ba096fSteven Holte        result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
1732518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1733646a5c593f9819dc5da6a1ec859bc70cb7ba096fSteven Holte    return result;
1734518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1735518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1736518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1737518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL_EGLEXT_VERSION 5
1738518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1739518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1740518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1741518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1742518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1743518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1744518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1745b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1746518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_NO_SYNC_KHR;
1747518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1748518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSyncKHR result = EGL_NO_SYNC_KHR;
17497c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17507c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
17517c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
1752518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
17537c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1754518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1755518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1756518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1757518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1758518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1759518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1760b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1761518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1762518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1763518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean result = EGL_FALSE;
17647c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17657c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
17667c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
1767518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1768518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
1769518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1770518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1771e9b3dfb7d5cc233747407381a51a081c335dc076Mathias AgopianEGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1772e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    clearError();
1773e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
1774e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    const egl_display_ptr dp = validate_display(dpy);
1775e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    if (!dp) return EGL_FALSE;
1776e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
1777e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    EGLBoolean result = EGL_FALSE;
1778e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1779e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    if (cnx->dso && cnx->egl.eglSignalSyncKHR) {
1780e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        result = cnx->egl.eglSignalSyncKHR(
1781e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian                dp->disp.dpy, sync, mode);
1782e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    }
1783e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    return result;
1784e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian}
1785e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
17867c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias AgopianEGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
17877c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        EGLint flags, EGLTimeKHR timeout)
1788518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1789518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1790518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1791b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1792518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1793518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1794737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    EGLint result = EGL_FALSE;
17957c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17967c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
17977c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglClientWaitSyncKHR(
17987c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                dp->disp.dpy, sync, flags, timeout);
1799518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
18007c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1801518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1802518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
18037c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias AgopianEGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
18047c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        EGLint attribute, EGLint *value)
1805518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1806518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1807518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1808b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1809518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1810518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
18117c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    EGLBoolean result = EGL_FALSE;
18127c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
18137c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
18147c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglGetSyncAttribKHR(
18157c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                dp->disp.dpy, sync, attribute, value);
1816518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
18177c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1818518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1819518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1820000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
1821000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1822000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1823000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1824000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1825000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_STREAM_KHR;
1826000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1827000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLStreamKHR result = EGL_NO_STREAM_KHR;
1828000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1829000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
1830000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglCreateStreamKHR(
1831000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, attrib_list);
1832000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1833000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1834000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1835000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1836000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
1837000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1838000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1839000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1840000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1841000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1842000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1843000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1844000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1845000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
1846000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglDestroyStreamKHR(
1847000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
1848000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1849000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1850000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1851000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1852000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
1853000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLint value)
1854000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1855000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1856000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1857000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1858000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1859000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1860000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1861000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1862000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
1863000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamAttribKHR(
1864000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1865000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1866000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1867000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1868000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1869000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
1870000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLint *value)
1871000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1872000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1873000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1874000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1875000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1876000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1877000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1878000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1879000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
1880000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglQueryStreamKHR(
1881000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1882000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1883000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1884000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1885000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1886000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
1887000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLuint64KHR *value)
1888000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1889000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1890000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1891000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1892000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1893000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1894000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1895000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1896000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
1897000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglQueryStreamu64KHR(
1898000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1899000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1900000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1901000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1902000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1903000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
1904000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLTimeKHR *value)
1905000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1906000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1907000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1908000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1909000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1910000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1911000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1912000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1913000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
1914000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglQueryStreamTimeKHR(
1915000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1916000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1917000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1918000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1919000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1920000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
1921000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream, const EGLint *attrib_list)
1922000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1923000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1924000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1925000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_display_ptr dp = validate_display(dpy);
1926000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_SURFACE;
1927000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1928378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
1929378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
1930378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    // TODO: Probably need to update EGL_KHR_stream_producer_eglsurface to
1931378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    // indicate support for EGL_GL_COLORSPACE_KHR.
1932378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    // now select a corresponding sRGB format if needed
1933378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
1934378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        ALOGE("error invalid colorspace: %d", colorSpace);
1935378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
1936378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    }
1937378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter
1938000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1939000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
1940000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
1941000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, config, stream, attrib_list);
1942000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        if (surface != EGL_NO_SURFACE) {
1943378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
1944000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            return s;
1945000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        }
1946000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1947000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return EGL_NO_SURFACE;
1948000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1949000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1950000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
1951000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream)
1952000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1953000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1954000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1955000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1956000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1957000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1958000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1959000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1960000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
1961000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
1962000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
1963000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1964000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1965000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1966000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1967000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
1968000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream)
1969000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1970000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1971000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1972000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1973000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1974000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1975000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1976000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1977000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
1978000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamConsumerAcquireKHR(
1979000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
1980000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1981000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1982000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1983000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1984000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
1985000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream)
1986000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1987000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1988000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1989000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1990000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1991000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1992000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1993000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1994000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
1995000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamConsumerReleaseKHR(
1996000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
1997000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1998000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1999000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2000000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2001000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
2002000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLDisplay dpy, EGLStreamKHR stream)
2003000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2004000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2005000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2006000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2007000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
2008000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2009000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
2010000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2011000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
2012000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglGetStreamFileDescriptorKHR(
2013000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
2014000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2015000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2016000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2017000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2018000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
2019000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
2020000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2021000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2022000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2023000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2024000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_STREAM_KHR;
2025000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2026000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLStreamKHR result = EGL_NO_STREAM_KHR;
2027000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2028000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
2029000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
2030000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, file_descriptor);
2031000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2032000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2033000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2034000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2035518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
20362bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// EGL_EGLEXT_VERSION 15
2037518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
2038518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
20392bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias AgopianEGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
2040331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    clearError();
2041331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    const egl_display_ptr dp = validate_display(dpy);
20422bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    if (!dp) return EGL_FALSE;
20432bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    EGLint result = EGL_FALSE;
2044331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    egl_connection_t* const cnx = &gEGLImpl;
20452bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    if (cnx->dso && cnx->egl.eglWaitSyncKHR) {
20462bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian        result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags);
2047331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    }
2048331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    return result;
2049331841b96b92646c93c87627c03f77b892f711cdJamie Gennis}
20501c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
20512bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// ----------------------------------------------------------------------------
20522bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// ANDROID extensions
20532bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// ----------------------------------------------------------------------------
20542bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian
20552bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias AgopianEGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
2056010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis{
2057010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    clearError();
2058010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis
2059010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    const egl_display_ptr dp = validate_display(dpy);
2060010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
2061010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis
20622bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
2063010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    egl_connection_t* const cnx = &gEGLImpl;
20642bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
20652bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian        result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
2066010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    }
2067010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    return result;
2068010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis}
2069010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis
20707284145d564fa8a422a8e564a38c730fb4a2962bAndy McFaddenEGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
20717284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        EGLnsecsANDROID time)
20727284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden{
20737284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    clearError();
20747284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
20757284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    const egl_display_ptr dp = validate_display(dpy);
20767284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    if (!dp) {
20777284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        return EGL_FALSE;
20787284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    }
20797284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
20807284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    SurfaceRef _s(dp.get(), surface);
20817284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    if (!_s.get()) {
20827284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        setError(EGL_BAD_SURFACE, EGL_FALSE);
20837284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        return EGL_FALSE;
20847284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    }
20857284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
20867284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    egl_surface_t const * const s = get_surface(surface);
208765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    native_window_set_buffers_timestamp(s->getNativeWindow(), time);
20887284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
20897284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    return EGL_TRUE;
20907284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden}
20917284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
2092607610786f0950f037812b6801e1bf42e830bb76Craig DonnerEGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer *buffer) {
2093607610786f0950f037812b6801e1bf42e830bb76Craig Donner    clearError();
2094a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    // AHardwareBuffer_to_ANativeWindowBuffer is a platform-only symbol and thus
2095a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    // this function cannot be implemented when this libEGL is built for
2096a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    // vendors.
2097a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park#ifndef __ANDROID_VNDK__
2098607610786f0950f037812b6801e1bf42e830bb76Craig Donner    if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
2099619634070f2fd5fa6ca0e035323fb2bb2aeea785Mathias Agopian    return const_cast<ANativeWindowBuffer *>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
2100a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park#else
2101a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
2102a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park#endif
2103607610786f0950f037812b6801e1bf42e830bb76Craig Donner}
2104607610786f0950f037812b6801e1bf42e830bb76Craig Donner
21051c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// ----------------------------------------------------------------------------
21061c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// NVIDIA extensions
21071c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// ----------------------------------------------------------------------------
21081c3d72a2291827fb15e2ef311a571c860e0dba41Jonas YangEGLuint64NV eglGetSystemTimeFrequencyNV()
21091c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang{
21101c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    clearError();
21111c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21121c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    if (egl_init_drivers() == EGL_FALSE) {
2113737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
21141c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21151c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21161c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    EGLuint64NV ret = 0;
2117ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
21181c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2119ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
2120ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglGetSystemTimeFrequencyNV();
21211c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21221c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2123737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
21241c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang}
21251c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21261c3d72a2291827fb15e2ef311a571c860e0dba41Jonas YangEGLuint64NV eglGetSystemTimeNV()
21271c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang{
21281c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    clearError();
21291c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21301c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    if (egl_init_drivers() == EGL_FALSE) {
2131737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
21321c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21331c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21341c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    EGLuint64NV ret = 0;
2135ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
21361c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2137ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
2138ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglGetSystemTimeNV();
21391c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21401c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2141737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
21421c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang}
2143a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2144a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza// ----------------------------------------------------------------------------
2145a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza// Partial update extension
2146a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza// ----------------------------------------------------------------------------
2147a894d082cfee8d12ee5913163a34ec5dc521d005Dan StozaEGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
2148a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        EGLint *rects, EGLint n_rects)
2149a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza{
2150a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    clearError();
2151a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2152a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    const egl_display_ptr dp = validate_display(dpy);
2153a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (!dp) {
2154a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        setError(EGL_BAD_DISPLAY, EGL_FALSE);
2155a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return EGL_FALSE;
2156a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
2157a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2158a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    SurfaceRef _s(dp.get(), surface);
2159a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (!_s.get()) {
2160a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        setError(EGL_BAD_SURFACE, EGL_FALSE);
2161a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return EGL_FALSE;
2162a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
2163a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2164a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    egl_surface_t const * const s = get_surface(surface);
2165a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (s->cnx->egl.eglSetDamageRegionKHR) {
2166a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
2167a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza                rects, n_rects);
2168a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
2169a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2170a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    return EGL_FALSE;
2171a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza}
2172c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
21731049d1d0b21ee318e309f9a90098c092cb879c41Brian AndersonEGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface,
21741049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson            EGLuint64KHR *frameId) {
21751049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    clearError();
21761049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
21771049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    const egl_display_ptr dp = validate_display(dpy);
21781049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    if (!dp) {
2179737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
21801049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
21811049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
21821049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    SurfaceRef _s(dp.get(), surface);
21831049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    if (!_s.get()) {
2184737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
21851049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
21861049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
21871049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    egl_surface_t const * const s = get_surface(surface);
21881049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
218965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (!s->getNativeWindow()) {
2190737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
21911049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
21921049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
21931049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    uint64_t nextFrameId = 0;
219465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    int ret = native_window_get_next_frame_id(s->getNativeWindow(), &nextFrameId);
21951049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
219665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (ret != 0) {
21971049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        // This should not happen. Return an error that is not in the spec
21981049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        // so it's obvious something is very wrong.
21991049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        ALOGE("eglGetNextFrameId: Unexpected error.");
2200737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
22011049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
22021049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22031049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    *frameId = nextFrameId;
22041049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    return EGL_TRUE;
22051049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson}
22061049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22070a61b0c813f5991bf462e36a2314dda062727a10Brian AndersonEGLBoolean eglGetCompositorTimingANDROID(EGLDisplay dpy, EGLSurface surface,
22080a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values)
22090a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson{
22100a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    clearError();
22110a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22120a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    const egl_display_ptr dp = validate_display(dpy);
22130a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!dp) {
2214737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
22150a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22160a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22170a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    SurfaceRef _s(dp.get(), surface);
22180a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!_s.get()) {
2219737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22200a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22210a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22220a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    egl_surface_t const * const s = get_surface(surface);
22230a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
222465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (!s->getNativeWindow()) {
2225737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22270a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22280a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t* compositeDeadline = nullptr;
22290a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t* compositeInterval = nullptr;
22300a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t* compositeToPresentLatency = nullptr;
22310a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22320a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    for (int i = 0; i < numTimestamps; i++) {
22330a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        switch (names[i]) {
22340a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            case EGL_COMPOSITE_DEADLINE_ANDROID:
22350a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                compositeDeadline = &values[i];
22360a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                break;
22370a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            case EGL_COMPOSITE_INTERVAL_ANDROID:
22380a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                compositeInterval = &values[i];
22390a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                break;
22400a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
22410a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                compositeToPresentLatency = &values[i];
22420a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                break;
22430a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            default:
2244737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
22450a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        }
22460a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22470a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
224865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    int ret = native_window_get_compositor_timing(s->getNativeWindow(),
22490a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            compositeDeadline, compositeInterval, compositeToPresentLatency);
22500a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22510a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    switch (ret) {
225265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian      case 0:
22530a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        return EGL_TRUE;
225465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian      case -ENOSYS:
2255737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22560a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson      default:
22570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // This should not happen. Return an error that is not in the spec
22580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // so it's obvious something is very wrong.
22590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        ALOGE("eglGetCompositorTiming: Unexpected error.");
2260737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
22610a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
22630a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22640a61b0c813f5991bf462e36a2314dda062727a10Brian AndersonEGLBoolean eglGetCompositorTimingSupportedANDROID(
22650a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        EGLDisplay dpy, EGLSurface surface, EGLint name)
22660a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson{
22670a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    clearError();
22680a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    const egl_display_ptr dp = validate_display(dpy);
22700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!dp) {
2271737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
22720a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22730a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22740a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    SurfaceRef _s(dp.get(), surface);
22750a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!_s.get()) {
2276737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22770a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22780a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22790a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    egl_surface_t const * const s = get_surface(surface);
22800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
228165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    ANativeWindow* window = s->getNativeWindow();
22820a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!window) {
2283737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22840a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22850a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22860a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    switch (name) {
22870a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_DEADLINE_ANDROID:
22880a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_INTERVAL_ANDROID:
22890a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
22900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            return EGL_TRUE;
22910a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        default:
22920a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            return EGL_FALSE;
22930a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22940a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
22950a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
2296c18be29d01cffbb820bcb22b74916de0023e7857Pablo CeballosEGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
22971049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps,
2298c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        EGLnsecsANDROID *values)
2299c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos{
2300c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    clearError();
2301c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2302c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    const egl_display_ptr dp = validate_display(dpy);
2303c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!dp) {
2304737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2305c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2306c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2307c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    SurfaceRef _s(dp.get(), surface);
2308c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!_s.get()) {
2309737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2310c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2311c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2312c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    egl_surface_t const * const s = get_surface(surface);
2313c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
231465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (!s->getNativeWindow()) {
2315737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2316c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2317c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2318dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson    nsecs_t* requestedPresentTime = nullptr;
2319c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    nsecs_t* acquireTime = nullptr;
2320f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* latchTime = nullptr;
2321f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* firstRefreshStartTime = nullptr;
2322b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson    nsecs_t* gpuCompositionDoneTime = nullptr;
2323f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* lastRefreshStartTime = nullptr;
2324069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    nsecs_t* displayPresentTime = nullptr;
2325f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* dequeueReadyTime = nullptr;
2326c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    nsecs_t* releaseTime = nullptr;
2327c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2328c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    for (int i = 0; i < numTimestamps; i++) {
2329c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        switch (timestamps[i]) {
2330dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson            case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2331dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson                requestedPresentTime = &values[i];
2332c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2333c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2334c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                acquireTime = &values[i];
2335c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2336f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2337f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                latchTime = &values[i];
2338c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2339f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2340f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                firstRefreshStartTime = &values[i];
2341f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                break;
2342f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2343f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                lastRefreshStartTime = &values[i];
2344f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                break;
2345b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson            case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2346b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson                gpuCompositionDoneTime = &values[i];
2347c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2348069b365163470d2736eb6f591c354d208b5da23bBrian Anderson            case EGL_DISPLAY_PRESENT_TIME_ANDROID:
2349069b365163470d2736eb6f591c354d208b5da23bBrian Anderson                displayPresentTime = &values[i];
2350069b365163470d2736eb6f591c354d208b5da23bBrian Anderson                break;
2351f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_DEQUEUE_READY_TIME_ANDROID:
2352f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                dequeueReadyTime = &values[i];
2353f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                break;
2354c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            case EGL_READS_DONE_TIME_ANDROID:
2355c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                releaseTime = &values[i];
2356c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2357c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            default:
2358737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2359c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        }
2360c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2361c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
236265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    int ret = native_window_get_frame_timestamps(s->getNativeWindow(), frameId,
2363f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime,
2364b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson            lastRefreshStartTime, gpuCompositionDoneTime, displayPresentTime,
23654e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson            dequeueReadyTime, releaseTime);
2366c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2367069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    switch (ret) {
236865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case 0:
2369737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return EGL_TRUE;
237065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case -ENOENT:
2371737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_ACCESS, (EGLBoolean)EGL_FALSE);
237265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case -ENOSYS:
2373737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
237465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case -EINVAL:
2375737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2376737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        default:
2377737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            // This should not happen. Return an error that is not in the spec
2378737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            // so it's obvious something is very wrong.
2379737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            ALOGE("eglGetFrameTimestamps: Unexpected error.");
2380737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2381c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2382c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos}
2383c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
23840a61b0c813f5991bf462e36a2314dda062727a10Brian AndersonEGLBoolean eglGetFrameTimestampSupportedANDROID(
23850a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        EGLDisplay dpy, EGLSurface surface, EGLint timestamp)
2386c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos{
2387c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    clearError();
2388c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2389c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    const egl_display_ptr dp = validate_display(dpy);
2390c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!dp) {
2391737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2392c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2393c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2394c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    SurfaceRef _s(dp.get(), surface);
2395c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!_s.get()) {
2396737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2397069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    }
2398069b365163470d2736eb6f591c354d208b5da23bBrian Anderson
2399069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    egl_surface_t const * const s = get_surface(surface);
2400069b365163470d2736eb6f591c354d208b5da23bBrian Anderson
240165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    ANativeWindow* window = s->getNativeWindow();
2402069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    if (!window) {
2403737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2404c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2405c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2406c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    switch (timestamp) {
24070a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_DEADLINE_ANDROID:
24080a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_INTERVAL_ANDROID:
24090a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2410dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson        case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2411c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2412f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2413f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2414f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2415b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson        case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2416f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_DEQUEUE_READY_TIME_ANDROID:
2417c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        case EGL_READS_DONE_TIME_ANDROID:
2418c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            return EGL_TRUE;
24196b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
24206b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            int value = 0;
24216b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            window->query(window,
24226b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
24236b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            return value == 0 ? EGL_FALSE : EGL_TRUE;
24246b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        }
2425c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        default:
2426c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            return EGL_FALSE;
2427c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2428c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos}
2429