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
83f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// Extensions implemented by the EGL wrapper.
84311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianchar const * const gBuiltinExtensionString =
8521558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall        "EGL_KHR_get_all_proc_addresses "
8621558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall        "EGL_ANDROID_presentation_time "
87a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        "EGL_KHR_swap_buffers_with_damage "
88607610786f0950f037812b6801e1bf42e830bb76Craig Donner        "EGL_ANDROID_get_native_client_buffer "
8902b05da60a4669df44c9c0747ec262ec1862cf61Pablo Ceballos        "EGL_ANDROID_front_buffer_auto_refresh "
90c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        "EGL_ANDROID_get_frame_timestamps "
91a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchter        "EGL_EXT_surface_SMPTE2086_metadata "
92a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchter        "EGL_EXT_surface_CTA861_3_metadata "
9321558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall        ;
94311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian
95f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// Whitelist of extensions exposed to applications if implemented in the vendor driver.
96311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianchar const * const gExtensionString  =
97e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_image "                        // mandatory
98e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_image_base "                   // mandatory
9941171c5a46f5238e90319aa242bf325a83d66aecKrzysztof Kosiński        "EGL_EXT_image_gl_colorspace "
100e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_image_pixmap "
101e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_lock_surface "
102c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        "EGL_KHR_gl_colorspace "
103e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_gl_texture_2D_image "
104000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_gl_texture_3D_image "
105e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_gl_texture_cubemap_image "
106e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_gl_renderbuffer_image "
107e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_reusable_sync "
108e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_KHR_fence_sync "
109f6d1c3930eeba6b089ba12fb82ecad1c6622e550Jamie Gennis        "EGL_KHR_create_context "
110000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_config_attribs "
111000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_surfaceless_context "
112000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream "
113000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_fifo "
114000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_producer_eglsurface "
115000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_consumer_gltexture "
116000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        "EGL_KHR_stream_cross_process_fd "
117e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_EXT_create_context_robustness "
118e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_NV_system_time "
119e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        "EGL_ANDROID_image_native_buffer "      // mandatory
1202bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian        "EGL_KHR_wait_sync "                    // strongly recommended
121dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis        "EGL_ANDROID_recordable "               // mandatory
122a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        "EGL_KHR_partial_update "               // strongly recommended
1230e4e3955254008e133b9ba14e0782becec3e2343Courtney Goeltzenleuchter        "EGL_EXT_pixel_format_float "
124a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
125408e59f63aaaba30fb6db1477e985025dda085cdJesse Hall        "EGL_KHR_create_context_no_error "
126ceb9ee78bdc7b3a074d01380ce11432f88732094Pablo Ceballos        "EGL_KHR_mutable_render_buffer "
127f37864bc99576b851015f115613cc851a866dbf2Mika Isojärvi        "EGL_EXT_yuv_surface "
128aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner        "EGL_EXT_protected_content "
129a7805f625d84f3f11e74a4631f089a57fc6a01bfChristian Poetzsch        "EGL_IMG_context_priority "
13051d53c4ab3fafa076de8bf85525514de639282a7Pyry Haulos        "EGL_KHR_no_config_context "
131e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        ;
13221b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter// clang-format on
133e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
134e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian// extensions not exposed to applications but used by the ANDROID system
135e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_ANDROID_blob_cache "               // strongly recommended
136e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_IMG_hibernate_process "            // optional
137e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_ANDROID_native_fence_sync "        // strongly recommended
138e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian//      "EGL_ANDROID_framebuffer_target "       // mandatory for HWC 1.1
139dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis//      "EGL_ANDROID_image_crop "               // optional
140e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
141e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian/*
142e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * EGL Extensions entry-points exposed to 3rd party applications
143e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * (keep in sync with gExtensionString above)
144e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian *
145e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian */
146e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopianstatic const extention_map_t sExtensionMap[] = {
147e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_KHR_lock_surface
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglLockSurfaceKHR",
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglUnlockSurfaceKHR",
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
152e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
153e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_KHR_image, EGL_KHR_image_base
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglCreateImageKHR",
155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglDestroyImageKHR",
157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
158e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
159e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
160e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglCreateSyncKHR",
161e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
162e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglDestroySyncKHR",
163e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
164e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglClientWaitSyncKHR",
165e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
166e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglSignalSyncKHR",
167e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
168e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglGetSyncAttribKHR",
169e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
170e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
171e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_NV_system_time
1721c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    { "eglGetSystemTimeFrequencyNV",
1731c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang            (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
1741c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    { "eglGetSystemTimeNV",
1751c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang            (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
176e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
1772bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    // EGL_KHR_wait_sync
1782bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    { "eglWaitSyncKHR",
1792bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
180e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
181e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    // EGL_ANDROID_presentation_time
182e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    { "eglPresentationTimeANDROID",
183e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
184a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
185a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    // EGL_KHR_swap_buffers_with_damage
186a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    { "eglSwapBuffersWithDamageKHR",
187a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza            (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
188a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
189607610786f0950f037812b6801e1bf42e830bb76Craig Donner    // EGL_ANDROID_get_native_client_buffer
190607610786f0950f037812b6801e1bf42e830bb76Craig Donner    { "eglGetNativeClientBufferANDROID",
191607610786f0950f037812b6801e1bf42e830bb76Craig Donner            (__eglMustCastToProperFunctionPointerType)&eglGetNativeClientBufferANDROID },
192607610786f0950f037812b6801e1bf42e830bb76Craig Donner
193a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    // EGL_KHR_partial_update
194a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    { "eglSetDamageRegionKHR",
195a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza            (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
196000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
197000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglCreateStreamKHR",
198000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
199000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglDestroyStreamKHR",
200000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
201000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamAttribKHR",
202000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
203000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglQueryStreamKHR",
204000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
205000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglQueryStreamu64KHR",
206000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
207000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglQueryStreamTimeKHR",
208000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
209000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglCreateStreamProducerSurfaceKHR",
210000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
211000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamConsumerGLTextureExternalKHR",
212000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
213000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamConsumerAcquireKHR",
214000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
215000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglStreamConsumerReleaseKHR",
216000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
217000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglGetStreamFileDescriptorKHR",
218000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
219000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    { "eglCreateStreamFromFileDescriptorKHR",
220000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
221c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
222c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    // EGL_ANDROID_get_frame_timestamps
2231049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    { "eglGetNextFrameIdANDROID",
2241049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetNextFrameIdANDROID },
2250a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    { "eglGetCompositorTimingANDROID",
2260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingANDROID },
2270a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    { "eglGetCompositorTimingSupportedANDROID",
2280a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingSupportedANDROID },
229c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    { "eglGetFrameTimestampsANDROID",
230c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
2310a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    { "eglGetFrameTimestampSupportedANDROID",
2320a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
23355901a20be19b42240aad219f3958c0f07e4c88eCraig Donner
23455901a20be19b42240aad219f3958c0f07e4c88eCraig Donner    // EGL_ANDROID_native_fence_sync
23555901a20be19b42240aad219f3958c0f07e4c88eCraig Donner    { "eglDupNativeFenceFDANDROID",
23655901a20be19b42240aad219f3958c0f07e4c88eCraig Donner            (__eglMustCastToProperFunctionPointerType)&eglDupNativeFenceFDANDROID },
237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
239e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian/*
240e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * These extensions entry-points should not be exposed to applications.
241e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian * They're used internally by the Android EGL layer.
242e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian */
243e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian#define FILTER_EXTENSIONS(procname) \
244e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") ||    \
245e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian         !strcmp((procname), "eglHibernateProcessIMG")      ||    \
24655901a20be19b42240aad219f3958c0f07e4c88eCraig Donner         !strcmp((procname), "eglAwakenProcessIMG"))
247e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// accesses protected by sExtensionMapMutex
24965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianstatic std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
25065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic int sGLExtentionSlot = 0;
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic void(*findProcAddress(const char* name,
255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const extention_map_t* map, size_t n))() {
256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (uint32_t i=0 ; i<n ; i++) {
257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!strcmp(name, map[i].name)) {
258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return map[i].address;
259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return NULL;
262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
264518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern EGLBoolean egl_init_drivers();
268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern gl_hooks_t gHooksTrace;
270e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
271518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} // namespace android;
272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
273e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline void clearError() { egl_tls_t::clearError(); }
277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline EGLContext getContext() { return egl_tls_t::getContext(); }
278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay eglGetDisplay(EGLNativeDisplayType display)
282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
2831508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall    ATRACE_CALL();
284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
286c3289c41e794117817895653300bd2cf7daa0a01Dan Stoza    uintptr_t index = reinterpret_cast<uintptr_t>(display);
287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (index >= NUM_DISPLAYS) {
288518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
289518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
290518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
291518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
292518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
294518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
295518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
296518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return dpy;
297518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
298518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
300518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Initialization
301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
302518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
303518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
304518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
305518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
307b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = get_display(dpy);
308737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
309518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
310518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = dp->initialize(major, minor);
311518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
312518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
313518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
314518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
315518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglTerminate(EGLDisplay dpy)
316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
317518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // NOTE: don't unload the drivers b/c some APIs can be called
318518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // after eglTerminate() has been called. eglTerminate() only
319518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // terminates an EGLDisplay, not a EGL itself.
320518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
321518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
323b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = get_display(dpy);
324737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
325518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
326518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = dp->terminate();
3274774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
328518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
329518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
330518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
331518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
332518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// configuration
333518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
334518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
335518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetConfigs(   EGLDisplay dpy,
336518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLConfig *configs,
337518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint config_size, EGLint *num_config)
338518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
339518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
341b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
343518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
3447773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (num_config==0) {
345737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
3487773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    EGLBoolean res = EGL_FALSE;
3497773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    *num_config = 0;
3507773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian
3517773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
3527773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (cnx->dso) {
3537773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        res = cnx->egl.eglGetConfigs(
3547773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, configs, config_size, num_config);
355518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
3567773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian
3577773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return res;
358518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
359518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
360518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
361518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLConfig *configs, EGLint config_size,
362518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint *num_config)
363518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
364518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
365518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
366b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
367518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
368518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
369518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (num_config==0) {
370737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
371518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
372518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
373518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
374518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    *num_config = 0;
375518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
376ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
377ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
3781cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy        if (attrib_list) {
3791cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            char value[PROPERTY_VALUE_MAX];
3801cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            property_get("debug.egl.force_msaa", value, "false");
3811cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
3821cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            if (!strcmp(value, "true")) {
3831cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                size_t attribCount = 0;
3841cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                EGLint attrib = attrib_list[0];
3851cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
3861cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                // Only enable MSAA if the context is OpenGL ES 2.0 and
387be3c3e4ecad501eecfe1f7a424a792f0f7f3f307Romain Guy                // if no caveat is requested
3881cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                const EGLint *attribRendererable = NULL;
3891cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                const EGLint *attribCaveat = NULL;
3901cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
3911cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                // Count the number of attributes and look for
392be3c3e4ecad501eecfe1f7a424a792f0f7f3f307Romain Guy                // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
3931cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                while (attrib != EGL_NONE) {
3941cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    attrib = attrib_list[attribCount];
3951cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    switch (attrib) {
3961cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        case EGL_RENDERABLE_TYPE:
3971cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            attribRendererable = &attrib_list[attribCount];
3981cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            break;
3991cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        case EGL_CONFIG_CAVEAT:
4001cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            attribCaveat = &attrib_list[attribCount];
4011cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            break;
402737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                        default:
403737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                            break;
4041cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    }
4051cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    attribCount++;
4061cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                }
4071cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4081cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
4091cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
4104774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
4111cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    // Insert 2 extra attributes to force-enable MSAA 4x
4121cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    EGLint aaAttribs[attribCount + 4];
4131cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[0] = EGL_SAMPLE_BUFFERS;
4141cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[1] = 1;
4151cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[2] = EGL_SAMPLES;
4161cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    aaAttribs[3] = 4;
4171cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4181cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
4191cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4201cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    EGLint numConfigAA;
4211cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    EGLBoolean resAA = cnx->egl.eglChooseConfig(
4221cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                            dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
4231cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4241cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    if (resAA == EGL_TRUE && numConfigAA > 0) {
4251cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        ALOGD("Enabling MSAA 4x");
4261cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        *num_config = numConfigAA;
4271cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                        return resAA;
4281cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                    }
4291cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy                }
4301cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy            }
4311cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy        }
4321cffc80f978c55f09203d9d9a905775b951ba59aRomain Guy
4337773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        res = cnx->egl.eglChooseConfig(
4347773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, attrib_list, configs, config_size, num_config);
435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
437518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
438518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
439518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
440518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint attribute, EGLint *value)
441518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
442518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
443518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
444b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
445b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
446b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (!dp) return EGL_FALSE;
4474774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return cnx->egl.eglGetConfigAttrib(
4497773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian            dp->disp.dpy, config, attribute, value);
450518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
451518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
452518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
453518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// surfaces
454518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
455518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
456f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// Translates EGL color spaces to Android data spaces.
457f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosińskistatic android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace) {
458c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
45982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        return HAL_DATASPACE_SRGB_LINEAR;
460c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
46182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        return HAL_DATASPACE_SRGB;
46221b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
46321b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter        return HAL_DATASPACE_DISPLAY_P3;
46421b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT) {
46521b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter        return HAL_DATASPACE_DISPLAY_P3_LINEAR;
46633e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_EXT) {
46733e2b781a05f1caf274e95c143005a862223e9bfCourtney Goeltzenleuchter        return HAL_DATASPACE_V0_SCRGB;
46821b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
46921b33cbdfeb31fd5aac7c11ddeb7088632eb1316Courtney Goeltzenleuchter        return HAL_DATASPACE_V0_SCRGB_LINEAR;
47012ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_BT2020_LINEAR_EXT) {
47112ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        return HAL_DATASPACE_BT2020_LINEAR;
47212ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
47312ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        return HAL_DATASPACE_BT2020_PQ;
474c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
475f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    return HAL_DATASPACE_UNKNOWN;
476c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
477c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
47812752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński// Get the colorspace value that should be reported from queries. When the colorspace
47912752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński// is unknown (no attribute passed), default to reporting LINEAR.
48012752442419a83901691471c8c52a43146c213e4Krzysztof Kosińskistatic EGLint getReportedColorSpace(EGLint colorspace) {
48112752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński    return colorspace == EGL_UNKNOWN ? EGL_GL_COLORSPACE_LINEAR_KHR : colorspace;
48212752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński}
48312752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński
484f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// Returns a list of color spaces understood by the vendor EGL driver.
485f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosińskistatic std::vector<EGLint> getDriverColorSpaces(egl_display_ptr dp,
486f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                                                android_pixel_format format) {
487f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    std::vector<EGLint> colorSpaces;
488f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (!dp->hasColorSpaceSupport) return colorSpaces;
489f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
490f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // OpenGL drivers only support sRGB encoding with 8-bit formats.
491f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // RGB_888 is never returned by getNativePixelFormat, but is included for completeness.
492f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    const bool formatSupportsSRGBEncoding =
493f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        format == HAL_PIXEL_FORMAT_RGBA_8888 || format == HAL_PIXEL_FORMAT_RGBX_8888 ||
494f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        format == HAL_PIXEL_FORMAT_RGB_888;
495f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    const bool formatIsFloatingPoint = format == HAL_PIXEL_FORMAT_RGBA_FP16;
496f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
497f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (formatSupportsSRGBEncoding) {
498f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // sRGB and linear are always supported when color space support is present.
499f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        colorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
500f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        colorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
501f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // DCI-P3 uses the sRGB transfer function, so it's only relevant for 8-bit formats.
502f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (findExtension(dp->disp.queryString.extensions,
503f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                              "EGL_EXT_gl_colorspace_display_p3")) {
504f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
505f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        }
506eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
507eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
508f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // According to the spec, scRGB is only supported for floating point formats.
509f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // For non-linear scRGB, the application is responsible for applying the
510f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // transfer function.
511f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (formatIsFloatingPoint) {
512f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (findExtension(dp->disp.queryString.extensions,
513f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                  "EGL_EXT_gl_colorspace_scrgb")) {
514f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_EXT);
515f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        }
516f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (findExtension(dp->disp.queryString.extensions,
517f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                  "EGL_EXT_gl_colorspace_scrgb_linear")) {
518f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
519eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
520eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
52112ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter
522f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // BT2020 can be used with any pixel format. PQ encoding must be applied by the
523f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // application and does not affect the behavior of OpenGL.
524f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (findExtension(dp->disp.queryString.extensions,
525f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                          "EGL_EXT_gl_colorspace_bt2020_linear")) {
526f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
527f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    }
528f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (findExtension(dp->disp.queryString.extensions,
529f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                          "EGL_EXT_gl_colorspace_bt2020_pq")) {
530f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
531eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
532f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
533f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // Linear DCI-P3 simply uses different primaries than standard RGB and thus
534f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // can be used with any pixel format.
535f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (findExtension(dp->disp.queryString.extensions,
536f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                          "EGL_EXT_gl_colorspace_display_p3_linear")) {
537f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
538f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    }
539f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    return colorSpaces;
540eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter}
541eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
542f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// Cleans up color space related parameters that the driver does not understand.
543f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// If there is no color space attribute in attrib_list, colorSpace is left
544f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// unmodified.
545f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosińskistatic EGLBoolean processAttributes(egl_display_ptr dp, NativeWindowType window,
546f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                                    android_pixel_format format, const EGLint* attrib_list,
547f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                                    EGLint* colorSpace,
548f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                                    std::vector<EGLint>* strippedAttribList) {
549f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    for (const EGLint* attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
550f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        bool copyAttribute = true;
551f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (attr[0] == EGL_GL_COLORSPACE_KHR) {
552f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            // Fail immediately if the driver doesn't have color space support at all.
553f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            if (!dp->hasColorSpaceSupport) return false;
554f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            *colorSpace = attr[1];
555f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
556f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            // Strip the attribute if the driver doesn't understand it.
557f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            copyAttribute = false;
558f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            std::vector<EGLint> driverColorSpaces = getDriverColorSpaces(dp, format);
559f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            for (auto driverColorSpace : driverColorSpaces) {
560f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                if (attr[1] == driverColorSpace) {
561f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                    copyAttribute = true;
562f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                    break;
563378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter                }
564378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            }
565378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        }
566f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (copyAttribute) {
567f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            strippedAttribList->push_back(attr[0]);
568f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            strippedAttribList->push_back(attr[1]);
569f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        }
570f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    }
571f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // Terminate the attribute list.
572f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    strippedAttribList->push_back(EGL_NONE);
573f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
574f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // If the passed color space has wide color gamut, check whether the target native window
575f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    // supports wide color.
576f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    const bool colorSpaceIsNarrow =
577f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        *colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
57812752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński        *colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR ||
57912752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński        *colorSpace == EGL_UNKNOWN;
580f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński    if (window && !colorSpaceIsNarrow) {
581f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        bool windowSupportsWideColor = true;
582f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // Ordinarily we'd put a call to native_window_get_wide_color_support
583f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // at the beginning of the function so that we'll have the
584f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // result when needed elsewhere in the function.
585f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // However, because eglCreateWindowSurface is called by SurfaceFlinger and
586f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // SurfaceFlinger is required to answer the call below we would
587f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // end up in a deadlock situation. By moving the call to only happen
588f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // if the application has specifically asked for wide-color we avoid
589f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // the deadlock with SurfaceFlinger since it will not ask for a
590f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // wide-color surface.
591f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        int err = native_window_get_wide_color_support(window, &windowSupportsWideColor);
592f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
593f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (err) {
594f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            ALOGE("processAttributes: invalid window (win=%p) "
595f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                  "failed (%#x) (already connected to another API?)",
596f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                  window, err);
597f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            return false;
598f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        }
599f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (!windowSupportsWideColor) {
600f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            // Application has asked for a wide-color colorspace but
601f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            // wide-color support isn't available on the display the window is on.
602f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            return false;
603f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        }
604378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    }
605378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    return true;
606378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter}
607378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter
608f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński// Gets the native pixel format corrsponding to the passed EGLConfig.
609f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosińskivoid getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
610f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                          android_pixel_format* format) {
611eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // Set the native window's buffers format to match what this config requests.
612eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // Whether to use sRGB gamma is not part of the EGLconfig, but is part
613eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // of our native format. So if sRGB gamma is requested, we have to
614eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // modify the EGLconfig's format before setting the native window's
615eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // format.
616eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
617eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
618eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType);
619eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
620eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint a = 0;
621eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint r, g, b;
622eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    r = g = b = 0;
623eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r);
624eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
625eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b);
626eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
627eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    EGLint colorDepth = r + g + b;
628eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
629eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // Today, the driver only understands sRGB and linear on 888X
630eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // formats. Strip other colorspaces from the attribute list and
631eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // only use them to set the dataspace via
632eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // native_window_set_buffers_dataspace
633eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // if pixel format is RGBX 8888
634eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    TBD: Can test for future extensions that indicate that driver
635eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    handles requested color space and we can let it through.
636eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    allow SRGB and LINEAR. All others need to be stripped.
637eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // else if 565, 4444
638eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    TBD: Can we assume these are supported if 8888 is?
639eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // else if FP16 or 1010102
640eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    //    strip colorspace from attribs.
641eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    // endif
642eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    if (a == 0) {
643eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        if (colorDepth <= 16) {
644f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            *format = HAL_PIXEL_FORMAT_RGB_565;
645eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        } else {
646eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
647eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                if (colorDepth > 24) {
648f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                    *format = HAL_PIXEL_FORMAT_RGBA_1010102;
649eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                } else {
650f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                    *format = HAL_PIXEL_FORMAT_RGBX_8888;
651eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter                }
652eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            } else {
653f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                *format = HAL_PIXEL_FORMAT_RGBA_FP16;
654eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            }
655eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
656eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    } else {
657eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
658eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            if (colorDepth > 24) {
659f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                *format = HAL_PIXEL_FORMAT_RGBA_1010102;
660eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            } else {
661f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                *format = HAL_PIXEL_FORMAT_RGBA_8888;
662eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter            }
663eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        } else {
664f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński            *format = HAL_PIXEL_FORMAT_RGBA_FP16;
665eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        }
666eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter    }
667eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter}
668eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
669936799c1d4bb80f5595153ef9efddbef4983526bCourtney GoeltzenleuchterEGLBoolean sendSurfaceMetadata(egl_surface_t* s) {
670936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    android_smpte2086_metadata smpteMetadata;
671936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    if (s->getSmpte2086Metadata(smpteMetadata)) {
672936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter        int err =
673936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter                native_window_set_buffers_smpte2086_metadata(s->getNativeWindow(), &smpteMetadata);
674936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter        s->resetSmpte2086Metadata();
67512ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        if (err != 0) {
67612ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            ALOGE("error setting native window smpte2086 metadata: %s (%d)",
67712ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter                  strerror(-err), err);
67812ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            return EGL_FALSE;
67912ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        }
68012ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    }
681936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    android_cta861_3_metadata cta8613Metadata;
682936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    if (s->getCta8613Metadata(cta8613Metadata)) {
683936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter        int err =
684936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter                native_window_set_buffers_cta861_3_metadata(s->getNativeWindow(), &cta8613Metadata);
685936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter        s->resetCta8613Metadata();
68612ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        if (err != 0) {
68712ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            ALOGE("error setting native window CTS 861.3 metadata: %s (%d)",
68812ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter                  strerror(-err), err);
68912ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            return EGL_FALSE;
69012ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        }
69112ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    }
69212ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    return EGL_TRUE;
69312ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter}
69412ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter
695518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
696518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    NativeWindowType window,
697518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
698518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
69912ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    const EGLint *origAttribList = attrib_list;
700518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
701518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
702b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
703b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display_connection(dpy, cnx);
704b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (dp) {
70510e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        if (!window) {
70610e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
70710e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        }
70810e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian
70910e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        int value = 0;
71010e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        window->query(window, NATIVE_WINDOW_IS_VALID, &value);
71110e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        if (!value) {
71210e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
71310e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian        }
71410e9ab50517330d1972234b4c167d5467d01abbfMathias Agopian
715d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden        int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
71665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        if (result < 0) {
717d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden            ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
718d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden                    "failed (%#x) (already connected to another API?)",
719d566ce3a26ce781ecdbc479aaba0e172b7c807a9Andy McFadden                    window, result);
72077a9b4a6bd21188e2744ae9dcd8092c6837bff7cJonathan Hamilton            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
72181a63350527cafce6929309533c58586878f10b5Mathias Agopian        }
72281a63350527cafce6929309533c58586878f10b5Mathias Agopian
723f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        EGLDisplay iDpy = dp->disp.dpy;
724f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        android_pixel_format format;
725f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        getNativePixelFormat(iDpy, cnx, config, &format);
726eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
727eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        // now select correct colorspace and dataspace based on user's attribute list
72812752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński        EGLint colorSpace = EGL_UNKNOWN;
729f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        std::vector<EGLint> strippedAttribList;
730f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (!processAttributes(dp, window, format, attrib_list, &colorSpace,
731f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                               &strippedAttribList)) {
732378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            ALOGE("error invalid colorspace: %d", colorSpace);
733378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
734518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
735f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        attrib_list = strippedAttribList.data();
736733a80754786d39cdc0fee09509b194472c320bcAlistair Strachan
737f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        {
738c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall            int err = native_window_set_buffers_format(window, format);
739c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall            if (err != 0) {
740c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                ALOGE("error setting native window pixel format: %s (%d)",
741f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                      strerror(-err), err);
74282c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
74382c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
74482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            }
74582c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala        }
74682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala
747f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
748f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (dataSpace != HAL_DATASPACE_UNKNOWN) {
74982c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            int err = native_window_set_buffers_data_space(window, dataSpace);
75082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            if (err != 0) {
75182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala                ALOGE("error setting native window pixel dataSpace: %s (%d)",
752f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                      strerror(-err), err);
753c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
754c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
755c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall            }
756c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        }
757518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
75859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // the EGL spec requires that a new EGLSurface default to swap interval
75959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // 1, so explicitly set that on the window here.
76059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
76159769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        anw->setSwapInterval(anw, 1);
76259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
763518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreateWindowSurface(
7647773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                iDpy, config, window, attrib_list);
765518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
766378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            egl_surface_t* s =
76712752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński                    new egl_surface_t(dp.get(), config, window, surface,
76812752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński                                      getReportedColorSpace(colorSpace), cnx);
769a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchter            return s;
770518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
77181a63350527cafce6929309533c58586878f10b5Mathias Agopian
77281a63350527cafce6929309533c58586878f10b5Mathias Agopian        // EGLSurface creation failed
77381a63350527cafce6929309533c58586878f10b5Mathias Agopian        native_window_set_buffers_format(window, 0);
77481a63350527cafce6929309533c58586878f10b5Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
775518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
776518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
777518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
778518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
779518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
780518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    NativePixmapType pixmap,
781518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
782518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
783518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
784518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
785b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
786b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display_connection(dpy, cnx);
787b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (dp) {
788f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        EGLDisplay iDpy = dp->disp.dpy;
789f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        android_pixel_format format;
790f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        getNativePixelFormat(iDpy, cnx, config, &format);
791f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
792378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        // now select a corresponding sRGB format if needed
79312752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński        EGLint colorSpace = EGL_UNKNOWN;
794f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        std::vector<EGLint> strippedAttribList;
795f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (!processAttributes(dp, nullptr, format, attrib_list, &colorSpace,
796f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                               &strippedAttribList)) {
797378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            ALOGE("error invalid colorspace: %d", colorSpace);
798378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
799378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        }
800f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        attrib_list = strippedAttribList.data();
801378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter
802518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
8037773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, config, pixmap, attrib_list);
804518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
80512752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński            egl_surface_t* s =
80612752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński                    new egl_surface_t(dp.get(), config, NULL, surface,
80712752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński                                      getReportedColorSpace(colorSpace), cnx);
808518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
809518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
810518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
811518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
812518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
813518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
814518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
815518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
816518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
817518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
818518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
819b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
820b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display_connection(dpy, cnx);
821b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (dp) {
822eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter        EGLDisplay iDpy = dp->disp.dpy;
823f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        android_pixel_format format;
824f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        getNativePixelFormat(iDpy, cnx, config, &format);
825eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
826f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // Select correct colorspace based on user's attribute list
82712752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński        EGLint colorSpace = EGL_UNKNOWN;
828f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        std::vector<EGLint> strippedAttribList;
829f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (!processAttributes(dp, nullptr, format, attrib_list, &colorSpace,
830f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński                               &strippedAttribList)) {
831378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            ALOGE("error invalid colorspace: %d", colorSpace);
832378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
833378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        }
834f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        attrib_list = strippedAttribList.data();
835eeaa52bc65b5cfaca1f0de44635b57919179df29Courtney Goeltzenleuchter
836518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
8377773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, config, attrib_list);
838518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
83912752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński            egl_surface_t* s =
84012752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński                    new egl_surface_t(dp.get(), config, NULL, surface,
84112752442419a83901691471c8c52a43146c213e4Krzysztof Kosiński                                      getReportedColorSpace(colorSpace), cnx);
842518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
843518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
844518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
845518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
846518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
8474774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
848518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
849518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
850518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
851518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
852b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
853518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
854518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
855b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
8565b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
857737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
858518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
859518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t * const s = get_surface(surface);
860ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
861518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
862518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        _s.terminate();
863518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
864518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
865518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
866518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
867518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
868518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint attribute, EGLint *value)
869518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
870518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
871518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
872b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
873518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
874518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
875b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
8765b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
877737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
878518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
879518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
88012ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    if (s->getColorSpaceAttribute(attribute, value)) {
88112ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        return EGL_TRUE;
88212ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    } else if (s->getSmpte2086Attribute(attribute, value)) {
88312ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        return EGL_TRUE;
88412ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    } else if (s->getCta8613Attribute(attribute, value)) {
885378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter        return EGL_TRUE;
886378365716852e0474899f968810ca1df7d30d7f6Courtney Goeltzenleuchter    }
88712ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter    return s->cnx->egl.eglQuerySurface(dp->disp.dpy, s->surface, attribute, value);
888518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
889518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
890e8696a40e09b24b634214684d18526187b316a2fJamie Gennisvoid EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
8911c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
892e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    clearError();
893e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
894b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
895e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (!dp) {
896e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        return;
897e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
898e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
899b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
900e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (!_s.get()) {
901e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        setError(EGL_BAD_SURFACE, EGL_FALSE);
902e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
903e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
904e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
905518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
906518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Contexts
907518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
908518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
909518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
910518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLContext share_list, const EGLint *attrib_list)
911518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
912518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
913518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
914b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
915b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
9160673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock    if (dp) {
917518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (share_list != EGL_NO_CONTEXT) {
9180673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock            if (!ContextRef(dp.get(), share_list).get()) {
9190673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock                return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
9200673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock            }
921518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_context_t* const c = get_context(share_list);
922518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            share_list = c->context;
923518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
924518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLContext context = cnx->egl.eglCreateContext(
9257773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, config, share_list, attrib_list);
926518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (context != EGL_NO_CONTEXT) {
927518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // figure out if it's a GLESv1 or GLESv2
928518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            int version = 0;
929518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (attrib_list) {
930518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                while (*attrib_list != EGL_NONE) {
931518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    GLint attr = *attrib_list++;
932518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    GLint value = *attrib_list++;
933518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    if (attr == EGL_CONTEXT_CLIENT_VERSION) {
934518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        if (value == 1) {
9357773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                            version = egl_connection_t::GLESv1_INDEX;
9364774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall                        } else if (value == 2 || value == 3) {
9377773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                            version = egl_connection_t::GLESv2_INDEX;
938518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        }
939518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    }
940518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                };
941518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
942b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall            egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
943b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall                    version);
944518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return c;
945518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
946518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
947518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_CONTEXT;
948518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
949518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
950518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
951518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
952518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
953518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
954b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
9555b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!dp)
9565b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return EGL_FALSE;
957518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
958b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
9595b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
960737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
9614774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
962518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
963ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
964518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
965518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        _c.terminate();
966518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
967518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
968518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
969518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
970518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
971518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLSurface read, EGLContext ctx)
972518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
973518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
974518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
975b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_display_ptr dp = validate_display(dpy);
976737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
977518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
9785b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
9795b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
9805b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // a valid but uninitialized display.
981518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
982518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         (draw != EGL_NO_SURFACE) ) {
983737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
984518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
985518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
986518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get a reference to the object passed in
987b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
988b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _d(dp.get(), draw);
989b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _r(dp.get(), read);
990518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
991518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // validate the context (if not EGL_NO_CONTEXT)
9925b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
993518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // EGL_NO_CONTEXT is valid
994737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
995518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
996518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
997518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are the underlying implementation's object
998518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext impl_ctx  = EGL_NO_CONTEXT;
999518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface impl_draw = EGL_NO_SURFACE;
1000518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface impl_read = EGL_NO_SURFACE;
1001518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1002518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are our objects structs passed in
1003518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t       * c = NULL;
1004518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * d = NULL;
1005518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * r = NULL;
1006518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1007518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are the current objects structs
1008518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * cur_c = get_context(getContext());
10094774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall
1010518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx != EGL_NO_CONTEXT) {
1011518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        c = get_context(ctx);
1012518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_ctx = c->context;
1013518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    } else {
1014518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // no context given, use the implementation of the current context
10150673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock        if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
10160673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock            // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
1017737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_MATCH, (EGLBoolean)EGL_FALSE);
10180673e1e2d77c673c2e9bc57616a02c3188b55ad1Michael Chock        }
1019518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cur_c == NULL) {
1020518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // no current context
1021518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // not an error, there is just no current context.
1022518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return EGL_TRUE;
1023518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1024518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1025518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1026518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // retrieve the underlying implementation's draw EGLSurface
1027518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (draw != EGL_NO_SURFACE) {
1028737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        if (!_d.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1029518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        d = get_surface(draw);
1030518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_draw = d->surface;
1031518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1032518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1033518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // retrieve the underlying implementation's read EGLSurface
1034518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (read != EGL_NO_SURFACE) {
1035737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        if (!_r.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1036518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        r = get_surface(read);
1037518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_read = r->surface;
1038518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1039518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1040518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1041b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    EGLBoolean result = dp->makeCurrent(c, cur_c,
1042fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian            draw, read, ctx,
1043fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian            impl_draw, impl_read, impl_ctx);
1044518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1045518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
1046fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
1047518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
1048518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_tls_t::setContext(ctx);
1049518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _c.acquire();
1050518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _r.acquire();
1051518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _d.acquire();
1052518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
1053518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            setGLHooksThreadSpecific(&gHooksNoContext);
1054518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_tls_t::setContext(EGL_NO_CONTEXT);
1055518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
10565fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian    } else {
105702ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan
105847e741bddde799732537116eef2ca30a93bc622cMike Stroyan        if (cur_c != NULL) {
105947e741bddde799732537116eef2ca30a93bc622cMike Stroyan            // Force return to current context for drivers that cannot handle errors
106047e741bddde799732537116eef2ca30a93bc622cMike Stroyan            EGLBoolean restore_result = EGL_FALSE;
106147e741bddde799732537116eef2ca30a93bc622cMike Stroyan            // get a reference to the old current objects
106247e741bddde799732537116eef2ca30a93bc622cMike Stroyan            ContextRef _c2(dp.get(), cur_c);
106347e741bddde799732537116eef2ca30a93bc622cMike Stroyan            SurfaceRef _d2(dp.get(), cur_c->draw);
106447e741bddde799732537116eef2ca30a93bc622cMike Stroyan            SurfaceRef _r2(dp.get(), cur_c->read);
106502ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan
106602ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            c = cur_c;
106702ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            impl_ctx = c->context;
106802ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            impl_draw = EGL_NO_SURFACE;
106902ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            if (cur_c->draw != EGL_NO_SURFACE) {
107002ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                d = get_surface(cur_c->draw);
107102ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                impl_draw = d->surface;
107202ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            }
107302ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            impl_read = EGL_NO_SURFACE;
107402ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            if (cur_c->read != EGL_NO_SURFACE) {
107502ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                r = get_surface(cur_c->read);
107602ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                impl_read = r->surface;
107702ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            }
107802ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan            restore_result = dp->makeCurrent(c, cur_c,
107902ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                    cur_c->draw, cur_c->read, cur_c->context,
108002ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan                    impl_draw, impl_read, impl_ctx);
108147e741bddde799732537116eef2ca30a93bc622cMike Stroyan            if (restore_result == EGL_TRUE) {
108247e741bddde799732537116eef2ca30a93bc622cMike Stroyan                _c2.acquire();
108347e741bddde799732537116eef2ca30a93bc622cMike Stroyan                _r2.acquire();
108447e741bddde799732537116eef2ca30a93bc622cMike Stroyan                _d2.acquire();
108547e741bddde799732537116eef2ca30a93bc622cMike Stroyan            } else {
108647e741bddde799732537116eef2ca30a93bc622cMike Stroyan                ALOGE("Could not restore original EGL context");
108747e741bddde799732537116eef2ca30a93bc622cMike Stroyan            }
108802ba5c7387266ace4ee83bb2a31b750e17416f48Mike Stroyan        }
1089e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        // this will ALOGE the error
109063108c34ec181e923b68ee840bb7960f205466a7Mathias Agopian        egl_connection_t* const cnx = &gEGLImpl;
1091737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
1092518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1093518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
1094518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1095518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1096518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1097518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
1098518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint attribute, EGLint *value)
1099518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1102b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1105b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
1106737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
11097773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return c->cnx->egl.eglQueryContext(
11107773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian            dp->disp.dpy, c->context, attribute, value);
1111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext eglGetCurrentContext(void)
1115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
1117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_CONTEXT.
1118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
1122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return ctx;
1123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglGetCurrentSurface(EGLint readdraw)
1126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
1128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_SURFACE.
1129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
1133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx) {
1134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t const * const c = get_context(ctx);
1135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        switch (readdraw) {
1137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            case EGL_READ: return c->read;
11384774338bd0ad1ebe42c311fd0c72f13786b5c800Jesse Hall            case EGL_DRAW: return c->draw;
1139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
1140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
1143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay eglGetCurrentDisplay(void)
1146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
1148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_DISPLAY.
1149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
1153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx) {
1154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t const * const c = get_context(ctx);
1155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return c->dpy;
1157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_DISPLAY;
1159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitGL(void)
1162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1165ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1166ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1167737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1168ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1169ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return cnx->egl.eglWaitGL();
1170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitNative(EGLint engine)
1173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1176ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1177ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1178737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1179ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1180ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return cnx->egl.eglWaitNative(engine);
1181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLint eglGetError(void)
1184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1185ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLint err = EGL_SUCCESS;
1186ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1187ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
1188ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        err = cnx->egl.eglGetError();
1189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1190ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (err == EGL_SUCCESS) {
1191ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        err = egl_tls_t::getError();
1192ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    }
1193ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return err;
1194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1196c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chockstatic __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
1197c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall        const char* procname) {
1198c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    const egl_connection_t* cnx = &gEGLImpl;
1199c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    void* proc = NULL;
1200c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1201c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock    proc = dlsym(cnx->libEgl, procname);
1202c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock    if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1203c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock
1204c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    proc = dlsym(cnx->libGles2, procname);
1205c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1206c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1207c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    proc = dlsym(cnx->libGles1, procname);
1208c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1209c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1210c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    return NULL;
1211c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall}
1212c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall
1213518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
1214518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // eglGetProcAddress() could be the very first function called
1216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // in which case we must make sure we've initialized ourselves, this
1217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // happens the first time egl_get_display() is called.
1218518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1219518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1220518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        setError(EGL_BAD_PARAMETER, NULL);
1223518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return  NULL;
1224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1225518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1226e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    if (FILTER_EXTENSIONS(procname)) {
1227aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis        return NULL;
1228aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    }
1229aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
1230518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    __eglMustCastToProperFunctionPointerType addr;
1231e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
1232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (addr) return addr;
1233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1234c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock    addr = findBuiltinWrapper(procname);
1235c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall    if (addr) return addr;
1236aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
1237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this protects accesses to sGLExtentionMap and sGLExtentionSlot
1238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    pthread_mutex_lock(&sExtensionMapMutex);
1239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
1241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * Since eglGetProcAddress() is not associated to anything, it needs
1242518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * to return a function pointer that "works" regardless of what
1243518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * the current context is.
1244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
1245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * For this reason, we return a "forwarder", a small stub that takes
1246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * care of calling the function associated with the context
1247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * currently bound.
1248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
1249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * We first look for extensions we've already resolved, if we're seeing
1250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * this extension for the first time, we go through all our
1251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * implementations and call eglGetProcAddress() and record the
1252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * result in the appropriate implementation hooks and return the
1253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * address of the forwarder corresponding to that hook set.
1254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
1255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
1256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
125765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        const std::string name(procname);
125865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
125965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    auto& extentionMap = sGLExtentionMap;
126065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    auto pos = extentionMap.find(name);
126165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        addr = (pos != extentionMap.end()) ? pos->second : nullptr;
1262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const int slot = sGLExtentionSlot;
1263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1264e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
1265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                "no more slots for eglGetProcAddress(\"%s\")",
1266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                procname);
1267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
1269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            bool found = false;
1270ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1271ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_connection_t* const cnx = &gEGLImpl;
1272ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            if (cnx->dso && cnx->egl.eglGetProcAddress) {
1273ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // Extensions are independent of the bound context
127469d100762c7c26d8328f4bb61cfef026d3a69bbfluliuhui                addr =
12757773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
12767773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
1277ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        cnx->egl.eglGetProcAddress(procname);
127869d100762c7c26d8328f4bb61cfef026d3a69bbfluliuhui                if (addr) found = true;
1279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
1280ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (found) {
1282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                addr = gExtensionForwarders[slot];
128365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                extentionMap[name] = addr;
1284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                sGLExtentionSlot++;
1285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
1286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1288518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    pthread_mutex_unlock(&sExtensionMapMutex);
1289518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return addr;
1290518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1291518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
129265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianclass FrameCompletionThread {
129328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennispublic:
129428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
129528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    static void queueSync(EGLSyncKHR sync) {
129665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        static FrameCompletionThread thread;
129765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
129865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        char name[64];
129965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
130065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> lock(thread.mMutex);
130165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        snprintf(name, sizeof(name), "kicked off frame %u", (unsigned int)thread.mFramesQueued);
130265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        ATRACE_NAME(name);
130365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
130465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.mQueue.push_back(sync);
130565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.mCondition.notify_one();
130665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.mFramesQueued++;
130765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        ATRACE_INT("GPU Frames Outstanding", int32_t(thread.mQueue.size()));
130828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
130928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
131028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennisprivate:
131128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
131265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {
131365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::thread thread(&FrameCompletionThread::loop, this);
131465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        thread.detach();
131565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    }
131665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
131765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#pragma clang diagnostic push
131865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#pragma clang diagnostic ignored "-Wmissing-noreturn"
131965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    void loop() {
132065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        while (true) {
132165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            threadLoop();
132265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        }
132365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    }
132465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#pragma clang diagnostic pop
132565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
132665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    void threadLoop() {
132728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        EGLSyncKHR sync;
132828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        uint32_t frameNum;
132928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        {
133065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            std::unique_lock<std::mutex> lock(mMutex);
133165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            while (mQueue.empty()) {
133265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                mCondition.wait(lock);
133328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            }
133428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            sync = mQueue[0];
133528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            frameNum = mFramesCompleted;
133628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        }
133728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
133828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        {
133965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            char name[64];
134065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            snprintf(name, sizeof(name), "waiting for frame %u", (unsigned int)frameNum);
134165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            ATRACE_NAME(name);
134265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian
134328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
134428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            if (result == EGL_FALSE) {
134528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis                ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
134628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
134728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis                ALOGE("FrameCompletion: timeout waiting for fence");
134828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            }
134928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            eglDestroySyncKHR(dpy, sync);
135028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        }
135128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        {
135265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            std::lock_guard<std::mutex> lock(mMutex);
135365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            mQueue.pop_front();
135428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis            mFramesCompleted++;
1355737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            ATRACE_INT("GPU Frames Outstanding", int32_t(mQueue.size()));
135628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        }
135728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
135828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
135928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    uint32_t mFramesQueued;
136028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    uint32_t mFramesCompleted;
136165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::deque<EGLSyncKHR> mQueue;
136265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::condition_variable mCondition;
136365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::mutex mMutex;
136428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis};
136528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
1366a894d082cfee8d12ee5913163a34ec5dc521d005Dan StozaEGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
1367a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        EGLint *rects, EGLint n_rects)
1368518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
13691c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
1370518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1371518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1372b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1373518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1374518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1375b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), draw);
13765b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1377737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1378518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1379936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    egl_surface_t* const s = get_surface(draw);
13807db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian
1381ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian    if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1382ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian        EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
1383ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian        if (sync != EGL_NO_SYNC_KHR) {
1384ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian            FrameCompletionThread::queueSync(sync);
1385ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian        }
1386ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian    }
1387ed6d08b70d775852f4827471814c83eba3606aaaMathias Agopian
13887db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    if (CC_UNLIKELY(dp->finishOnSwap)) {
13897db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        uint32_t pixel;
13907db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        egl_context_t * const c = get_context( egl_tls_t::getContext() );
13917db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        if (c) {
13927db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian            // glReadPixels() ensures that the frame is complete
13937db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian            s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
13947db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian                    GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
13957db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        }
13967db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    }
13977db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian
1398936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    if (!sendSurfaceMetadata(s)) {
1399936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter        native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
1400936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter        return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
1401936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter    }
1402936799c1d4bb80f5595153ef9efddbef4983526bCourtney Goeltzenleuchter
1403a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (n_rects == 0) {
1404a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1405a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
1406a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
140765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::vector<android_native_rect_t> androidRects((size_t)n_rects);
1408a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    for (int r = 0; r < n_rects; ++r) {
1409a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int offset = r * 4;
1410a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int x = rects[offset];
1411a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int y = rects[offset + 1];
1412a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int width = rects[offset + 2];
1413a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        int height = rects[offset + 3];
1414a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        android_native_rect_t androidRect;
1415a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.left = x;
1416a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.top = y + height;
1417a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.right = x + width;
1418a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRect.bottom = y;
1419a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        androidRects.push_back(androidRect);
1420a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
142165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(), androidRects.size());
1422a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
1423a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1424a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
1425a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza                rects, n_rects);
1426a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    } else {
1427a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1428a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
1429a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza}
1430a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
1431a894d082cfee8d12ee5913163a34ec5dc521d005Dan StozaEGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1432a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza{
1433a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
1434518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
1437518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            NativePixmapType target)
1438518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1439518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1440518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1441b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1442518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1443518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1444b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
14455b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1446737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1447518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1449ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1450518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1451518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1452518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianconst char* eglQueryString(EGLDisplay dpy, EGLint name)
1453518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1454518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1455518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1456e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // Generate an error quietly when client extensions (as defined by
1457e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // EGL_EXT_client_extensions) are queried.  We do not want to rely on
1458e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // validate_display to generate the error as validate_display would log
1459e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // the error, which can be misleading.
1460e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    //
1461e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // If we want to support EGL_EXT_client_extensions later, we can return
1462e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    // the client extension string here instead.
1463e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
1464737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setErrorQuiet(EGL_BAD_DISPLAY, (const char*)0);
1465e57d1357aa3fa2783c1928b202837afdb8f0f2f0Chia-I Wu
1466b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1467518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return (const char *) NULL;
1468518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1469518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    switch (name) {
1470518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_VENDOR:
14714b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getVendorString();
1472518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_VERSION:
14734b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getVersionString();
1474518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_EXTENSIONS:
14754b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getExtensionString();
1476518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_CLIENT_APIS:
14774b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getClientApiString();
1478737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        default:
1479737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            break;
1480518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1481518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_PARAMETER, (const char *)0);
1482518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1483518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
148400b15b8f223976d016e16536e4720771ef634695Jiyong Parkextern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
1485ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian{
1486ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    clearError();
1487ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
1488ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    const egl_display_ptr dp = validate_display(dpy);
1489ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    if (!dp) return (const char *) NULL;
1490ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
1491ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    switch (name) {
1492ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_VENDOR:
1493ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.vendor;
1494ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_VERSION:
1495ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.version;
1496ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_EXTENSIONS:
1497ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.extensions;
1498ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian        case EGL_CLIENT_APIS:
1499ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            return dp->disp.queryString.clientApi;
1500737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        default:
1501737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            break;
1502ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    }
1503ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    return setError(EGL_BAD_PARAMETER, (const char *)0);
1504ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian}
1505518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1506518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1507518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL 1.1
1508518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1509518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1510518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSurfaceAttrib(
1511518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1512518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1513518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1514518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1515b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1516518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1517518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1518b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
15195b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1520737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1521518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1522c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    egl_surface_t * const s = get_surface(surface);
1523ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
152402b05da60a4669df44c9c0747ec262ec1862cf61Pablo Ceballos    if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
152565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        if (!s->getNativeWindow()) {
1526069b365163470d2736eb6f591c354d208b5da23bBrian Anderson            setError(EGL_BAD_SURFACE, EGL_FALSE);
1527069b365163470d2736eb6f591c354d208b5da23bBrian Anderson        }
152865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        int err = native_window_set_auto_refresh(s->getNativeWindow(), value != 0);
152965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1530ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    }
1531ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
1532c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (attribute == EGL_TIMESTAMPS_ANDROID) {
153365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        if (!s->getNativeWindow()) {
1534737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1535069b365163470d2736eb6f591c354d208b5da23bBrian Anderson        }
153665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0);
153765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1538c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
1539c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
1540786ab8840b5726362c777496686106df27160cfbCourtney Goeltzenleuchter    if (s->setSmpte2086Attribute(attribute, value)) {
1541786ab8840b5726362c777496686106df27160cfbCourtney Goeltzenleuchter        return EGL_TRUE;
1542786ab8840b5726362c777496686106df27160cfbCourtney Goeltzenleuchter    } else if (s->setCta8613Attribute(attribute, value)) {
1543786ab8840b5726362c777496686106df27160cfbCourtney Goeltzenleuchter        return EGL_TRUE;
1544786ab8840b5726362c777496686106df27160cfbCourtney Goeltzenleuchter    } else if (s->cnx->egl.eglSurfaceAttrib) {
1545518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglSurfaceAttrib(
1546ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attribute, value);
1547518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1548737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1549518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1550518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1551518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglBindTexImage(
1552518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1553518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1554518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1555518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1556b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1557518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1558518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1559b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
15605b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1561737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1562518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1563518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1564518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglBindTexImage) {
1565518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglBindTexImage(
1566ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, buffer);
1567518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1568737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1569518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1570518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1571518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglReleaseTexImage(
1572518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1573518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1574518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1575518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1576b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1577518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1578518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1579b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
15805b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1581737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1582518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1583518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1584518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglReleaseTexImage) {
1585518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglReleaseTexImage(
1586ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, buffer);
1587518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1588737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1589518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1590518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1591518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1592518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1593518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1594518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1595b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1596518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1597518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1598518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_TRUE;
1599ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1600ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglSwapInterval) {
1601ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1602518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1603ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1604518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1605518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1606518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1607518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1608518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1609518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL 1.2
1610518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1611518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1612518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitClient(void)
1613518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1614518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1615518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1616ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1617ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1618737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1619ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1620ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean res;
1621ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->egl.eglWaitClient) {
1622ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglWaitClient();
1623ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    } else {
1624ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglWaitGL();
1625518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1626518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1627518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1628518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1629518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglBindAPI(EGLenum api)
1630518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1631518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1632518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1633518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1634737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1635518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1636518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1637518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // bind this API on all EGLs
1638518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_TRUE;
1639ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1640ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglBindAPI) {
1641ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglBindAPI(api);
1642518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1643518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1644518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1645518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1646518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLenum eglQueryAPI(void)
1647518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1648518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1649518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1650518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1651737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1652518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1653518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1654ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1655ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglQueryAPI) {
1656ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglQueryAPI();
1657518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1658ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1659518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // or, it can only be OpenGL ES
1660518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_OPENGL_ES_API;
1661518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1662518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1663518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglReleaseThread(void)
1664518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1665518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1666518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1667ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1668ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglReleaseThread) {
1669ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        cnx->egl.eglReleaseThread();
1670518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
16713ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar
16723ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar    // If there is context bound to the thread, release it
16733ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar    egl_display_t::loseCurrent(get_context(getContext()));
16743ac517a852386e7b7c93d5fb7adee90fe7bf7d86Sai Kiran Korwar
1675518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_tls_t::clearTLS();
1676518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_TRUE;
1677518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1678518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1679518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePbufferFromClientBuffer(
1680518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1681518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian          EGLConfig config, const EGLint *attrib_list)
1682518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1683518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1684518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1685b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    egl_connection_t* cnx = NULL;
1686b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display_connection(dpy, cnx);
1687b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    if (!dp) return EGL_FALSE;
1688518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1689518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return cnx->egl.eglCreatePbufferFromClientBuffer(
16907773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian                dp->disp.dpy, buftype, buffer, config, attrib_list);
1691518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1692518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1693518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1694518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1695518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1696518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL_EGLEXT_VERSION 3
1697518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1698518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1699518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
1700518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        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_FALSE;
1706518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1707b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
17085b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1709737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1710518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1711518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1712518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglLockSurfaceKHR) {
1713518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglLockSurfaceKHR(
1714ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attrib_list);
1715518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1716737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1717518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1718518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1719518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
1720518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1721518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1722518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1723b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1724518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1725518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1726b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    SurfaceRef _s(dp.get(), surface);
17275b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
1728737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1729518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1730518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1731518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglUnlockSurfaceKHR) {
1732ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1733518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1734737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1735518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1736518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1737518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1738518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLClientBuffer buffer, const EGLint *attrib_list)
1739518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1740518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1741518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1742b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1743518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_NO_IMAGE_KHR;
1744518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1745b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ContextRef _c(dp.get(), ctx);
17467c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_context_t * const c = _c.get();
1747518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1748ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    // Temporary hack: eglImageCreateKHR should accept EGL_GL_COLORSPACE_LINEAR_KHR,
1749ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    // EGL_GL_COLORSPACE_SRGB_KHR and EGL_GL_COLORSPACE_DEFAULT_EXT if
1750ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    // EGL_EXT_image_gl_colorspace is supported, but some drivers don't like
1751ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    // the DEFAULT value and generate an error.
1752ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    std::vector<EGLint> strippedAttribList;
1753ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    for (const EGLint *attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
1754ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński        if (attr[0] == EGL_GL_COLORSPACE_KHR &&
1755ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński            dp->haveExtension("EGL_EXT_image_gl_colorspace")) {
1756ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński            if (attr[1] != EGL_GL_COLORSPACE_LINEAR_KHR &&
1757ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński                attr[1] != EGL_GL_COLORSPACE_SRGB_KHR) {
1758ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński                continue;
1759ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński            }
1760ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński        }
1761ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński        strippedAttribList.push_back(attr[0]);
1762ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński        strippedAttribList.push_back(attr[1]);
1763ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    }
1764ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński    strippedAttribList.push_back(EGL_NONE);
1765ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński
17667c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    EGLImageKHR result = EGL_NO_IMAGE_KHR;
17677c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17687c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglCreateImageKHR) {
17697c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglCreateImageKHR(
17707c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                dp->disp.dpy,
17717c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                c ? c->context : EGL_NO_CONTEXT,
1772ae98af57f47fc85cb11781ab3185dc540b6759a1Krzysztof Kosiński                target, buffer, strippedAttribList.data());
1773518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
17747c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1775518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1776518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1777518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1778518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1779518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1780518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1781b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1782518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1783518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1784646a5c593f9819dc5da6a1ec859bc70cb7ba096fSteven Holte    EGLBoolean result = EGL_FALSE;
1785ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
17867c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
1787646a5c593f9819dc5da6a1ec859bc70cb7ba096fSteven Holte        result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
1788518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1789646a5c593f9819dc5da6a1ec859bc70cb7ba096fSteven Holte    return result;
1790518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1791518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1792518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1793518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL_EGLEXT_VERSION 5
1794518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1795518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1796518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1797518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1798518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1799518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1800518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1801b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1802518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_NO_SYNC_KHR;
1803518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1804518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSyncKHR result = EGL_NO_SYNC_KHR;
18057c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
18067c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
18077c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
1808518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
18097c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1810518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1811518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1812518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1813518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1814518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1815518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1816b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1817518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1818518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1819518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean result = EGL_FALSE;
18207c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
18217c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
18227c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
1823518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1824518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
1825518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1826518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1827e9b3dfb7d5cc233747407381a51a081c335dc076Mathias AgopianEGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1828e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    clearError();
1829e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
1830e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    const egl_display_ptr dp = validate_display(dpy);
1831e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    if (!dp) return EGL_FALSE;
1832e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
1833e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    EGLBoolean result = EGL_FALSE;
1834e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1835e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    if (cnx->dso && cnx->egl.eglSignalSyncKHR) {
1836e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian        result = cnx->egl.eglSignalSyncKHR(
1837e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian                dp->disp.dpy, sync, mode);
1838e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    }
1839e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian    return result;
1840e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian}
1841e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopian
18427c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias AgopianEGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
18437c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        EGLint flags, EGLTimeKHR timeout)
1844518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1845518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1846518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1847b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1848518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1849518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1850737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    EGLint result = EGL_FALSE;
18517c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
18527c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
18537c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglClientWaitSyncKHR(
18547c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                dp->disp.dpy, sync, flags, timeout);
1855518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
18567c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1857518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1858518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
18597c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias AgopianEGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
18607c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        EGLint attribute, EGLint *value)
1861518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1862518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1863518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1864b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    const egl_display_ptr dp = validate_display(dpy);
1865518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1866518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
18677c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    EGLBoolean result = EGL_FALSE;
18687c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
18697c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
18707c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian        result = cnx->egl.eglGetSyncAttribKHR(
18717c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian                dp->disp.dpy, sync, attribute, value);
1872518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
18737c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian    return result;
1874518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1875518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1876000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
1877000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1878000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1879000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1880000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1881000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_STREAM_KHR;
1882000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1883000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLStreamKHR result = EGL_NO_STREAM_KHR;
1884000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1885000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
1886000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglCreateStreamKHR(
1887000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, attrib_list);
1888000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1889000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1890000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1891000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1892000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
1893000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1894000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1895000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1896000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1897000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1898000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1899000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1900000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1901000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
1902000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglDestroyStreamKHR(
1903000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
1904000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1905000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1906000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1907000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1908000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
1909000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLint value)
1910000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1911000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1912000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1913000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1914000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1915000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1916000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1917000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1918000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
1919000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamAttribKHR(
1920000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1921000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1922000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1923000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1924000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1925000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
1926000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLint *value)
1927000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1928000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1929000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1930000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1931000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1932000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1933000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1934000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1935000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
1936000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglQueryStreamKHR(
1937000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1938000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1939000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1940000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1941000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1942000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
1943000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLuint64KHR *value)
1944000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1945000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1946000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1947000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1948000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1949000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1950000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1951000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1952000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
1953000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglQueryStreamu64KHR(
1954000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1955000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1956000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1957000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1958000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1959000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
1960000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLenum attribute, EGLTimeKHR *value)
1961000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1962000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1963000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1964000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
1965000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
1966000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1967000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
1968000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1969000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
1970000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglQueryStreamTimeKHR(
1971000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream, attribute, value);
1972000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1973000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
1974000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1975000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1976000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
1977000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream, const EGLint *attrib_list)
1978000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
1979000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
1980000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1981000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_display_ptr dp = validate_display(dpy);
1982000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_SURFACE;
1983000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1984000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
1985000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
1986000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
1987000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, config, stream, attrib_list);
1988000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        if (surface != EGL_NO_SURFACE) {
1989b1d70ecc36dd928269066e9cf65e1080c00dc56cCourtney Goeltzenleuchter            egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface,
1990b1d70ecc36dd928269066e9cf65e1080c00dc56cCourtney Goeltzenleuchter                                                 EGL_GL_COLORSPACE_LINEAR_KHR, cnx);
1991000d88f02680607f45f600dde4e53ebe5b3895abSeason Li            return s;
1992000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        }
1993000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
1994000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return EGL_NO_SURFACE;
1995000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
1996000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
1997000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
1998000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream)
1999000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2000000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2001000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2002000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2003000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
2004000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2005000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
2006000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2007000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
2008000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
2009000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
2010000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2011000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2012000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2013000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2014000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
2015000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream)
2016000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2017000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2018000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2019000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2020000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
2021000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2022000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
2023000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2024000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
2025000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamConsumerAcquireKHR(
2026000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
2027000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2028000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2029000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2030000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2031000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
2032000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLStreamKHR stream)
2033000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2034000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2035000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2036000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2037000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_FALSE;
2038000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2039000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLBoolean result = EGL_FALSE;
2040000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2041000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
2042000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglStreamConsumerReleaseKHR(
2043000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
2044000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2045000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2046000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2047000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2048000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
2049000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLDisplay dpy, EGLStreamKHR stream)
2050000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2051000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2052000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2053000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2054000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
2055000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2056000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
2057000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2058000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
2059000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglGetStreamFileDescriptorKHR(
2060000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, stream);
2061000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2062000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2063000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2064000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2065000d88f02680607f45f600dde4e53ebe5b3895abSeason LiEGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
2066000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
2067000d88f02680607f45f600dde4e53ebe5b3895abSeason Li{
2068000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    clearError();
2069000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2070000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    const egl_display_ptr dp = validate_display(dpy);
2071000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (!dp) return EGL_NO_STREAM_KHR;
2072000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2073000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    EGLStreamKHR result = EGL_NO_STREAM_KHR;
2074000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    egl_connection_t* const cnx = &gEGLImpl;
2075000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
2076000d88f02680607f45f600dde4e53ebe5b3895abSeason Li        result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
2077000d88f02680607f45f600dde4e53ebe5b3895abSeason Li                dp->disp.dpy, file_descriptor);
2078000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    }
2079000d88f02680607f45f600dde4e53ebe5b3895abSeason Li    return result;
2080000d88f02680607f45f600dde4e53ebe5b3895abSeason Li}
2081000d88f02680607f45f600dde4e53ebe5b3895abSeason Li
2082518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
20832bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// EGL_EGLEXT_VERSION 15
2084518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
2085518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
20862bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias AgopianEGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
2087331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    clearError();
2088331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    const egl_display_ptr dp = validate_display(dpy);
20892bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    if (!dp) return EGL_FALSE;
20902bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    EGLint result = EGL_FALSE;
2091331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    egl_connection_t* const cnx = &gEGLImpl;
20922bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    if (cnx->dso && cnx->egl.eglWaitSyncKHR) {
20932bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian        result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags);
2094331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    }
2095331841b96b92646c93c87627c03f77b892f711cdJamie Gennis    return result;
2096331841b96b92646c93c87627c03f77b892f711cdJamie Gennis}
20971c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
20982bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// ----------------------------------------------------------------------------
20992bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// ANDROID extensions
21002bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian// ----------------------------------------------------------------------------
21012bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian
21022bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias AgopianEGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
2103010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis{
2104010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    clearError();
2105010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis
2106010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    const egl_display_ptr dp = validate_display(dpy);
2107010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
2108010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis
21092bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
2110010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    egl_connection_t* const cnx = &gEGLImpl;
21112bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian    if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
21122bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian        result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
2113010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    }
2114010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis    return result;
2115010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis}
2116010dd4fb892aecf71e4631c22148fe57ef5b3958Jamie Gennis
21177284145d564fa8a422a8e564a38c730fb4a2962bAndy McFaddenEGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
21187284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        EGLnsecsANDROID time)
21197284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden{
21207284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    clearError();
21217284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
21227284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    const egl_display_ptr dp = validate_display(dpy);
21237284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    if (!dp) {
21247284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        return EGL_FALSE;
21257284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    }
21267284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
21277284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    SurfaceRef _s(dp.get(), surface);
21287284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    if (!_s.get()) {
21297284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        setError(EGL_BAD_SURFACE, EGL_FALSE);
21307284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden        return EGL_FALSE;
21317284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    }
21327284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
21337284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    egl_surface_t const * const s = get_surface(surface);
213465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    native_window_set_buffers_timestamp(s->getNativeWindow(), time);
21357284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
21367284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden    return EGL_TRUE;
21377284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden}
21387284145d564fa8a422a8e564a38c730fb4a2962bAndy McFadden
2139607610786f0950f037812b6801e1bf42e830bb76Craig DonnerEGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer *buffer) {
2140607610786f0950f037812b6801e1bf42e830bb76Craig Donner    clearError();
2141a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    // AHardwareBuffer_to_ANativeWindowBuffer is a platform-only symbol and thus
2142a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    // this function cannot be implemented when this libEGL is built for
2143a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    // vendors.
2144a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park#ifndef __ANDROID_VNDK__
2145607610786f0950f037812b6801e1bf42e830bb76Craig Donner    if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
2146619634070f2fd5fa6ca0e035323fb2bb2aeea785Mathias Agopian    return const_cast<ANativeWindowBuffer *>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
2147a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park#else
2148a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park    return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
2149a243e5dc36b5c75fb963d51064b132ea5367372eJiyong Park#endif
2150607610786f0950f037812b6801e1bf42e830bb76Craig Donner}
2151607610786f0950f037812b6801e1bf42e830bb76Craig Donner
21521c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// ----------------------------------------------------------------------------
21531c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// NVIDIA extensions
21541c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// ----------------------------------------------------------------------------
21551c3d72a2291827fb15e2ef311a571c860e0dba41Jonas YangEGLuint64NV eglGetSystemTimeFrequencyNV()
21561c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang{
21571c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    clearError();
21581c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21591c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    if (egl_init_drivers() == EGL_FALSE) {
2160737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
21611c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21621c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21631c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    EGLuint64NV ret = 0;
2164ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
21651c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2166ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
2167ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglGetSystemTimeFrequencyNV();
21681c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21691c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2170737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
21711c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang}
21721c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21731c3d72a2291827fb15e2ef311a571c860e0dba41Jonas YangEGLuint64NV eglGetSystemTimeNV()
21741c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang{
21751c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    clearError();
21761c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21771c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    if (egl_init_drivers() == EGL_FALSE) {
2178737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
21791c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21801c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
21811c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    EGLuint64NV ret = 0;
2182ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
21831c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2184ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
2185ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglGetSystemTimeNV();
21861c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
21871c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
2188737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian    return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
21891c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang}
2190a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2191a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza// ----------------------------------------------------------------------------
2192a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza// Partial update extension
2193a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza// ----------------------------------------------------------------------------
2194a894d082cfee8d12ee5913163a34ec5dc521d005Dan StozaEGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
2195a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        EGLint *rects, EGLint n_rects)
2196a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza{
2197a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    clearError();
2198a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2199a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    const egl_display_ptr dp = validate_display(dpy);
2200a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (!dp) {
2201a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        setError(EGL_BAD_DISPLAY, EGL_FALSE);
2202a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return EGL_FALSE;
2203a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
2204a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2205a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    SurfaceRef _s(dp.get(), surface);
2206a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (!_s.get()) {
2207a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        setError(EGL_BAD_SURFACE, EGL_FALSE);
2208a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return EGL_FALSE;
2209a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
2210a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2211a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    egl_surface_t const * const s = get_surface(surface);
2212a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    if (s->cnx->egl.eglSetDamageRegionKHR) {
2213a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza        return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
2214a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza                rects, n_rects);
2215a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    }
2216a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza
2217a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza    return EGL_FALSE;
2218a894d082cfee8d12ee5913163a34ec5dc521d005Dan Stoza}
2219c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
22201049d1d0b21ee318e309f9a90098c092cb879c41Brian AndersonEGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface,
22211049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson            EGLuint64KHR *frameId) {
22221049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    clearError();
22231049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22241049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    const egl_display_ptr dp = validate_display(dpy);
22251049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    if (!dp) {
2226737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
22271049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
22281049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22291049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    SurfaceRef _s(dp.get(), surface);
22301049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    if (!_s.get()) {
2231737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22321049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
22331049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22341049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    egl_surface_t const * const s = get_surface(surface);
22351049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
223665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (!s->getNativeWindow()) {
2237737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22381049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
22391049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22401049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    uint64_t nextFrameId = 0;
224165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    int ret = native_window_get_next_frame_id(s->getNativeWindow(), &nextFrameId);
22421049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
224365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (ret != 0) {
22441049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        // This should not happen. Return an error that is not in the spec
22451049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        // so it's obvious something is very wrong.
22461049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        ALOGE("eglGetNextFrameId: Unexpected error.");
2247737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
22481049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    }
22491049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22501049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    *frameId = nextFrameId;
22511049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson    return EGL_TRUE;
22521049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson}
22531049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson
22540a61b0c813f5991bf462e36a2314dda062727a10Brian AndersonEGLBoolean eglGetCompositorTimingANDROID(EGLDisplay dpy, EGLSurface surface,
22550a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values)
22560a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson{
22570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    clearError();
22580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    const egl_display_ptr dp = validate_display(dpy);
22600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!dp) {
2261737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
22620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22630a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22640a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    SurfaceRef _s(dp.get(), surface);
22650a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!_s.get()) {
2266737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22670a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22680a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    egl_surface_t const * const s = get_surface(surface);
22700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
227165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (!s->getNativeWindow()) {
2272737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
22730a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22740a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22750a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t* compositeDeadline = nullptr;
22760a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t* compositeInterval = nullptr;
22770a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t* compositeToPresentLatency = nullptr;
22780a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22790a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    for (int i = 0; i < numTimestamps; i++) {
22800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        switch (names[i]) {
22810a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            case EGL_COMPOSITE_DEADLINE_ANDROID:
22820a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                compositeDeadline = &values[i];
22830a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                break;
22840a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            case EGL_COMPOSITE_INTERVAL_ANDROID:
22850a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                compositeInterval = &values[i];
22860a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                break;
22870a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
22880a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                compositeToPresentLatency = &values[i];
22890a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                break;
22900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            default:
2291737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
22920a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        }
22930a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
22940a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
229565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    int ret = native_window_get_compositor_timing(s->getNativeWindow(),
22960a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            compositeDeadline, compositeInterval, compositeToPresentLatency);
22970a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
22980a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    switch (ret) {
229965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian      case 0:
23000a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        return EGL_TRUE;
230165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian      case -ENOSYS:
2302737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
23030a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson      default:
23040a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // This should not happen. Return an error that is not in the spec
23050a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // so it's obvious something is very wrong.
23060a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        ALOGE("eglGetCompositorTiming: Unexpected error.");
2307737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
23080a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
23090a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
23100a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
23110a61b0c813f5991bf462e36a2314dda062727a10Brian AndersonEGLBoolean eglGetCompositorTimingSupportedANDROID(
23120a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        EGLDisplay dpy, EGLSurface surface, EGLint name)
23130a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson{
23140a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    clearError();
23150a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
23160a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    const egl_display_ptr dp = validate_display(dpy);
23170a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!dp) {
2318737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
23190a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
23200a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
23210a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    SurfaceRef _s(dp.get(), surface);
23220a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!_s.get()) {
2323737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
23240a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
23250a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
23260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    egl_surface_t const * const s = get_surface(surface);
23270a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
232865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    ANativeWindow* window = s->getNativeWindow();
23290a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    if (!window) {
2330737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
23310a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
23320a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
23330a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    switch (name) {
23340a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_DEADLINE_ANDROID:
23350a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_INTERVAL_ANDROID:
23360a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
23370a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            return EGL_TRUE;
23380a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        default:
23390a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            return EGL_FALSE;
23400a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
23410a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
23420a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
2343c18be29d01cffbb820bcb22b74916de0023e7857Pablo CeballosEGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
23441049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson        EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps,
2345c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        EGLnsecsANDROID *values)
2346c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos{
2347c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    clearError();
2348c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2349c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    const egl_display_ptr dp = validate_display(dpy);
2350c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!dp) {
2351737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2352c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2353c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2354c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    SurfaceRef _s(dp.get(), surface);
2355c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!_s.get()) {
2356737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2357c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2358c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2359c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    egl_surface_t const * const s = get_surface(surface);
2360c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
236165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (!s->getNativeWindow()) {
2362737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2363c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2364c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2365dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson    nsecs_t* requestedPresentTime = nullptr;
2366c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    nsecs_t* acquireTime = nullptr;
2367f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* latchTime = nullptr;
2368f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* firstRefreshStartTime = nullptr;
2369b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson    nsecs_t* gpuCompositionDoneTime = nullptr;
2370f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* lastRefreshStartTime = nullptr;
2371069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    nsecs_t* displayPresentTime = nullptr;
2372f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson    nsecs_t* dequeueReadyTime = nullptr;
2373c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    nsecs_t* releaseTime = nullptr;
2374c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2375c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    for (int i = 0; i < numTimestamps; i++) {
2376c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        switch (timestamps[i]) {
2377dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson            case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2378dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson                requestedPresentTime = &values[i];
2379c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2380c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2381c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                acquireTime = &values[i];
2382c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2383f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2384f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                latchTime = &values[i];
2385c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2386f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2387f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                firstRefreshStartTime = &values[i];
2388f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                break;
2389f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2390f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                lastRefreshStartTime = &values[i];
2391f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                break;
2392b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson            case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2393b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson                gpuCompositionDoneTime = &values[i];
2394c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2395069b365163470d2736eb6f591c354d208b5da23bBrian Anderson            case EGL_DISPLAY_PRESENT_TIME_ANDROID:
2396069b365163470d2736eb6f591c354d208b5da23bBrian Anderson                displayPresentTime = &values[i];
2397069b365163470d2736eb6f591c354d208b5da23bBrian Anderson                break;
2398f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            case EGL_DEQUEUE_READY_TIME_ANDROID:
2399f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                dequeueReadyTime = &values[i];
2400f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson                break;
2401c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            case EGL_READS_DONE_TIME_ANDROID:
2402c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                releaseTime = &values[i];
2403c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos                break;
2404c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            default:
2405737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian                return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2406c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        }
2407c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2408c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
240965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    int ret = native_window_get_frame_timestamps(s->getNativeWindow(), frameId,
2410f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson            requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime,
2411b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson            lastRefreshStartTime, gpuCompositionDoneTime, displayPresentTime,
24124e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson            dequeueReadyTime, releaseTime);
2413c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2414069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    switch (ret) {
241565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case 0:
2416737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return EGL_TRUE;
241765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case -ENOENT:
2418737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_ACCESS, (EGLBoolean)EGL_FALSE);
241965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case -ENOSYS:
2420737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
242165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        case -EINVAL:
2422737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2423737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        default:
2424737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            // This should not happen. Return an error that is not in the spec
2425737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            // so it's obvious something is very wrong.
2426737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            ALOGE("eglGetFrameTimestamps: Unexpected error.");
2427737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian            return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2428c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2429c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos}
2430c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
24310a61b0c813f5991bf462e36a2314dda062727a10Brian AndersonEGLBoolean eglGetFrameTimestampSupportedANDROID(
24320a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        EGLDisplay dpy, EGLSurface surface, EGLint timestamp)
2433c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos{
2434c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    clearError();
2435c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2436c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    const egl_display_ptr dp = validate_display(dpy);
2437c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!dp) {
2438737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2439c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2440c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2441c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    SurfaceRef _s(dp.get(), surface);
2442c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    if (!_s.get()) {
2443737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2444069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    }
2445069b365163470d2736eb6f591c354d208b5da23bBrian Anderson
2446069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    egl_surface_t const * const s = get_surface(surface);
2447069b365163470d2736eb6f591c354d208b5da23bBrian Anderson
244865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    ANativeWindow* window = s->getNativeWindow();
2449069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    if (!window) {
2450737b896ce81883c5b54cd9be9661680fa8ffba86Mathias Agopian        return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2451c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2452c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos
2453c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    switch (timestamp) {
24540a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_DEADLINE_ANDROID:
24550a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_INTERVAL_ANDROID:
24560a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2457dbd0ea80021cbc61c578385f534f41a33338085bBrian Anderson        case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2458c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2459f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2460f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2461f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2462b04c6f03a2334b03ae0105ec005aeecfa61f4a90Brian Anderson        case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2463f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        case EGL_DEQUEUE_READY_TIME_ANDROID:
2464c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        case EGL_READS_DONE_TIME_ANDROID:
2465c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            return EGL_TRUE;
24666b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
24676b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            int value = 0;
24686b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            window->query(window,
24696b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
24706b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            return value == 0 ? EGL_FALSE : EGL_TRUE;
24716b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        }
2472c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos        default:
2473c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos            return EGL_FALSE;
2474c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos    }
2475c18be29d01cffbb820bcb22b74916de0023e7857Pablo Ceballos}
2476