eglApi.cpp 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897
  1. /*
  2. ** Copyright 2007, The Android Open Source Project
  3. **
  4. ** Licensed under the Apache License, Version 2.0 (the "License");
  5. ** you may not use this file except in compliance with the License.
  6. ** You may obtain a copy of the License at
  7. **
  8. ** http://www.apache.org/licenses/LICENSE-2.0
  9. **
  10. ** Unless required by applicable law or agreed to in writing, software
  11. ** distributed under the License is distributed on an "AS IS" BASIS,
  12. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. ** See the License for the specific language governing permissions and
  14. ** limitations under the License.
  15. */
  16. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  17. #include <dlfcn.h>
  18. #include <ctype.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <hardware/gralloc.h>
  22. #include <system/window.h>
  23. #include <EGL/egl.h>
  24. #include <EGL/eglext.h>
  25. #include <cutils/log.h>
  26. #include <cutils/atomic.h>
  27. #include <cutils/compiler.h>
  28. #include <cutils/properties.h>
  29. #include <cutils/memory.h>
  30. #include <utils/KeyedVector.h>
  31. #include <utils/SortedVector.h>
  32. #include <utils/String8.h>
  33. #include <utils/Trace.h>
  34. #include "../egl_impl.h"
  35. #include "../glestrace.h"
  36. #include "../hooks.h"
  37. #include "egl_display.h"
  38. #include "egl_object.h"
  39. #include "egl_tls.h"
  40. #include "egldefs.h"
  41. using namespace android;
  42. // This extension has not been ratified yet, so can't be shipped.
  43. // Implementation is incomplete and untested.
  44. #define ENABLE_EGL_KHR_GL_COLORSPACE 0
  45. // ----------------------------------------------------------------------------
  46. namespace android {
  47. struct extention_map_t {
  48. const char* name;
  49. __eglMustCastToProperFunctionPointerType address;
  50. };
  51. /*
  52. * This is the list of EGL extensions exposed to applications.
  53. *
  54. * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
  55. * wrapper and are always available.
  56. *
  57. * The rest (gExtensionString) depend on support in the EGL driver, and are
  58. * only available if the driver supports them. However, some of these must be
  59. * supported because they are used by the Android system itself; these are
  60. * listd as mandatory below and are required by the CDD. The system *assumes*
  61. * the mandatory extensions are present and may not function properly if some
  62. * are missing.
  63. *
  64. * NOTE: Both strings MUST have a single space as the last character.
  65. */
  66. extern char const * const gBuiltinExtensionString =
  67. "EGL_KHR_get_all_proc_addresses "
  68. "EGL_ANDROID_presentation_time "
  69. "EGL_KHR_swap_buffers_with_damage "
  70. ;
  71. extern char const * const gExtensionString =
  72. "EGL_KHR_image " // mandatory
  73. "EGL_KHR_image_base " // mandatory
  74. "EGL_KHR_image_pixmap "
  75. "EGL_KHR_lock_surface "
  76. #if (ENABLE_EGL_KHR_GL_COLORSPACE != 0)
  77. "EGL_KHR_gl_colorspace "
  78. #endif
  79. "EGL_KHR_gl_texture_2D_image "
  80. "EGL_KHR_gl_texture_3D_image "
  81. "EGL_KHR_gl_texture_cubemap_image "
  82. "EGL_KHR_gl_renderbuffer_image "
  83. "EGL_KHR_reusable_sync "
  84. "EGL_KHR_fence_sync "
  85. "EGL_KHR_create_context "
  86. "EGL_KHR_config_attribs "
  87. "EGL_KHR_surfaceless_context "
  88. "EGL_KHR_stream "
  89. "EGL_KHR_stream_fifo "
  90. "EGL_KHR_stream_producer_eglsurface "
  91. "EGL_KHR_stream_consumer_gltexture "
  92. "EGL_KHR_stream_cross_process_fd "
  93. "EGL_EXT_create_context_robustness "
  94. "EGL_NV_system_time "
  95. "EGL_ANDROID_image_native_buffer " // mandatory
  96. "EGL_KHR_wait_sync " // strongly recommended
  97. "EGL_ANDROID_recordable " // mandatory
  98. "EGL_KHR_partial_update " // strongly recommended
  99. "EGL_EXT_buffer_age " // strongly recommended with partial_update
  100. "EGL_KHR_create_context_no_error "
  101. ;
  102. // extensions not exposed to applications but used by the ANDROID system
  103. // "EGL_ANDROID_blob_cache " // strongly recommended
  104. // "EGL_IMG_hibernate_process " // optional
  105. // "EGL_ANDROID_native_fence_sync " // strongly recommended
  106. // "EGL_ANDROID_framebuffer_target " // mandatory for HWC 1.1
  107. // "EGL_ANDROID_image_crop " // optional
  108. /*
  109. * EGL Extensions entry-points exposed to 3rd party applications
  110. * (keep in sync with gExtensionString above)
  111. *
  112. */
  113. static const extention_map_t sExtensionMap[] = {
  114. // EGL_KHR_lock_surface
  115. { "eglLockSurfaceKHR",
  116. (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
  117. { "eglUnlockSurfaceKHR",
  118. (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
  119. // EGL_KHR_image, EGL_KHR_image_base
  120. { "eglCreateImageKHR",
  121. (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
  122. { "eglDestroyImageKHR",
  123. (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
  124. // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
  125. { "eglCreateSyncKHR",
  126. (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
  127. { "eglDestroySyncKHR",
  128. (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
  129. { "eglClientWaitSyncKHR",
  130. (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
  131. { "eglSignalSyncKHR",
  132. (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
  133. { "eglGetSyncAttribKHR",
  134. (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
  135. // EGL_NV_system_time
  136. { "eglGetSystemTimeFrequencyNV",
  137. (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
  138. { "eglGetSystemTimeNV",
  139. (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
  140. // EGL_KHR_wait_sync
  141. { "eglWaitSyncKHR",
  142. (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
  143. // EGL_ANDROID_presentation_time
  144. { "eglPresentationTimeANDROID",
  145. (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
  146. // EGL_KHR_swap_buffers_with_damage
  147. { "eglSwapBuffersWithDamageKHR",
  148. (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
  149. // EGL_KHR_partial_update
  150. { "eglSetDamageRegionKHR",
  151. (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
  152. { "eglCreateStreamKHR",
  153. (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
  154. { "eglDestroyStreamKHR",
  155. (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
  156. { "eglStreamAttribKHR",
  157. (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
  158. { "eglQueryStreamKHR",
  159. (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
  160. { "eglQueryStreamu64KHR",
  161. (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
  162. { "eglQueryStreamTimeKHR",
  163. (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
  164. { "eglCreateStreamProducerSurfaceKHR",
  165. (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
  166. { "eglStreamConsumerGLTextureExternalKHR",
  167. (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
  168. { "eglStreamConsumerAcquireKHR",
  169. (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
  170. { "eglStreamConsumerReleaseKHR",
  171. (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
  172. { "eglGetStreamFileDescriptorKHR",
  173. (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
  174. { "eglCreateStreamFromFileDescriptorKHR",
  175. (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
  176. };
  177. /*
  178. * These extensions entry-points should not be exposed to applications.
  179. * They're used internally by the Android EGL layer.
  180. */
  181. #define FILTER_EXTENSIONS(procname) \
  182. (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") || \
  183. !strcmp((procname), "eglHibernateProcessIMG") || \
  184. !strcmp((procname), "eglAwakenProcessIMG") || \
  185. !strcmp((procname), "eglDupNativeFenceFDANDROID"))
  186. // accesses protected by sExtensionMapMutex
  187. static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
  188. static int sGLExtentionSlot = 0;
  189. static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
  190. static void(*findProcAddress(const char* name,
  191. const extention_map_t* map, size_t n))() {
  192. for (uint32_t i=0 ; i<n ; i++) {
  193. if (!strcmp(name, map[i].name)) {
  194. return map[i].address;
  195. }
  196. }
  197. return NULL;
  198. }
  199. // ----------------------------------------------------------------------------
  200. extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
  201. extern EGLBoolean egl_init_drivers();
  202. extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
  203. extern int getEGLDebugLevel();
  204. extern void setEGLDebugLevel(int level);
  205. extern gl_hooks_t gHooksTrace;
  206. } // namespace android;
  207. // ----------------------------------------------------------------------------
  208. static inline void clearError() { egl_tls_t::clearError(); }
  209. static inline EGLContext getContext() { return egl_tls_t::getContext(); }
  210. // ----------------------------------------------------------------------------
  211. EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
  212. {
  213. clearError();
  214. uintptr_t index = reinterpret_cast<uintptr_t>(display);
  215. if (index >= NUM_DISPLAYS) {
  216. return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
  217. }
  218. if (egl_init_drivers() == EGL_FALSE) {
  219. return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
  220. }
  221. EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
  222. return dpy;
  223. }
  224. // ----------------------------------------------------------------------------
  225. // Initialization
  226. // ----------------------------------------------------------------------------
  227. EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
  228. {
  229. clearError();
  230. egl_display_ptr dp = get_display(dpy);
  231. if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  232. EGLBoolean res = dp->initialize(major, minor);
  233. return res;
  234. }
  235. EGLBoolean eglTerminate(EGLDisplay dpy)
  236. {
  237. // NOTE: don't unload the drivers b/c some APIs can be called
  238. // after eglTerminate() has been called. eglTerminate() only
  239. // terminates an EGLDisplay, not a EGL itself.
  240. clearError();
  241. egl_display_ptr dp = get_display(dpy);
  242. if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  243. EGLBoolean res = dp->terminate();
  244. return res;
  245. }
  246. // ----------------------------------------------------------------------------
  247. // configuration
  248. // ----------------------------------------------------------------------------
  249. EGLBoolean eglGetConfigs( EGLDisplay dpy,
  250. EGLConfig *configs,
  251. EGLint config_size, EGLint *num_config)
  252. {
  253. clearError();
  254. const egl_display_ptr dp = validate_display(dpy);
  255. if (!dp) return EGL_FALSE;
  256. if (num_config==0) {
  257. return setError(EGL_BAD_PARAMETER, EGL_FALSE);
  258. }
  259. EGLBoolean res = EGL_FALSE;
  260. *num_config = 0;
  261. egl_connection_t* const cnx = &gEGLImpl;
  262. if (cnx->dso) {
  263. res = cnx->egl.eglGetConfigs(
  264. dp->disp.dpy, configs, config_size, num_config);
  265. }
  266. return res;
  267. }
  268. EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
  269. EGLConfig *configs, EGLint config_size,
  270. EGLint *num_config)
  271. {
  272. clearError();
  273. const egl_display_ptr dp = validate_display(dpy);
  274. if (!dp) return EGL_FALSE;
  275. if (num_config==0) {
  276. return setError(EGL_BAD_PARAMETER, EGL_FALSE);
  277. }
  278. EGLBoolean res = EGL_FALSE;
  279. *num_config = 0;
  280. egl_connection_t* const cnx = &gEGLImpl;
  281. if (cnx->dso) {
  282. if (attrib_list) {
  283. char value[PROPERTY_VALUE_MAX];
  284. property_get("debug.egl.force_msaa", value, "false");
  285. if (!strcmp(value, "true")) {
  286. size_t attribCount = 0;
  287. EGLint attrib = attrib_list[0];
  288. // Only enable MSAA if the context is OpenGL ES 2.0 and
  289. // if no caveat is requested
  290. const EGLint *attribRendererable = NULL;
  291. const EGLint *attribCaveat = NULL;
  292. // Count the number of attributes and look for
  293. // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
  294. while (attrib != EGL_NONE) {
  295. attrib = attrib_list[attribCount];
  296. switch (attrib) {
  297. case EGL_RENDERABLE_TYPE:
  298. attribRendererable = &attrib_list[attribCount];
  299. break;
  300. case EGL_CONFIG_CAVEAT:
  301. attribCaveat = &attrib_list[attribCount];
  302. break;
  303. }
  304. attribCount++;
  305. }
  306. if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
  307. (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
  308. // Insert 2 extra attributes to force-enable MSAA 4x
  309. EGLint aaAttribs[attribCount + 4];
  310. aaAttribs[0] = EGL_SAMPLE_BUFFERS;
  311. aaAttribs[1] = 1;
  312. aaAttribs[2] = EGL_SAMPLES;
  313. aaAttribs[3] = 4;
  314. memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
  315. EGLint numConfigAA;
  316. EGLBoolean resAA = cnx->egl.eglChooseConfig(
  317. dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
  318. if (resAA == EGL_TRUE && numConfigAA > 0) {
  319. ALOGD("Enabling MSAA 4x");
  320. *num_config = numConfigAA;
  321. return resAA;
  322. }
  323. }
  324. }
  325. }
  326. res = cnx->egl.eglChooseConfig(
  327. dp->disp.dpy, attrib_list, configs, config_size, num_config);
  328. }
  329. return res;
  330. }
  331. EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
  332. EGLint attribute, EGLint *value)
  333. {
  334. clearError();
  335. egl_connection_t* cnx = NULL;
  336. const egl_display_ptr dp = validate_display_connection(dpy, cnx);
  337. if (!dp) return EGL_FALSE;
  338. return cnx->egl.eglGetConfigAttrib(
  339. dp->disp.dpy, config, attribute, value);
  340. }
  341. // ----------------------------------------------------------------------------
  342. // surfaces
  343. // ----------------------------------------------------------------------------
  344. // The EGL_KHR_gl_colorspace spec hasn't been ratified yet, so these haven't
  345. // been added to the Khronos egl.h.
  346. #define EGL_GL_COLORSPACE_KHR EGL_VG_COLORSPACE
  347. #define EGL_GL_COLORSPACE_SRGB_KHR EGL_VG_COLORSPACE_sRGB
  348. #define EGL_GL_COLORSPACE_LINEAR_KHR EGL_VG_COLORSPACE_LINEAR
  349. // Turn linear formats into corresponding sRGB formats when colorspace is
  350. // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
  351. // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
  352. // the modification isn't possible, the original dataSpace is returned.
  353. static android_dataspace modifyBufferDataspace( android_dataspace dataSpace,
  354. EGLint colorspace) {
  355. if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
  356. return HAL_DATASPACE_SRGB_LINEAR;
  357. } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
  358. return HAL_DATASPACE_SRGB;
  359. }
  360. return dataSpace;
  361. }
  362. EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
  363. NativeWindowType window,
  364. const EGLint *attrib_list)
  365. {
  366. clearError();
  367. egl_connection_t* cnx = NULL;
  368. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  369. if (dp) {
  370. EGLDisplay iDpy = dp->disp.dpy;
  371. int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
  372. if (result != OK) {
  373. ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
  374. "failed (%#x) (already connected to another API?)",
  375. window, result);
  376. return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
  377. }
  378. // Set the native window's buffers format to match what this config requests.
  379. // Whether to use sRGB gamma is not part of the EGLconfig, but is part
  380. // of our native format. So if sRGB gamma is requested, we have to
  381. // modify the EGLconfig's format before setting the native window's
  382. // format.
  383. EGLint format;
  384. android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
  385. #if WORKAROUND_BUG_10194508
  386. if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
  387. &format)) {
  388. ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
  389. eglGetError());
  390. format = 0;
  391. }
  392. #else
  393. EGLint a = 0;
  394. cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
  395. if (a > 0) {
  396. // alpha-channel requested, there's really only one suitable format
  397. if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
  398. &format)) {
  399. ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
  400. eglGetError());
  401. format = HAL_PIXEL_FORMAT_RGBA_8888;
  402. }
  403. } else {
  404. EGLint r, g, b;
  405. r = g = b = 0;
  406. cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE, &r);
  407. cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g);
  408. cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE, &b);
  409. EGLint colorDepth = r + g + b;
  410. if (colorDepth <= 16) {
  411. format = HAL_PIXEL_FORMAT_RGB_565;
  412. } else {
  413. format = HAL_PIXEL_FORMAT_RGBX_8888;
  414. }
  415. }
  416. #endif
  417. // now select a corresponding sRGB format if needed
  418. if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
  419. for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
  420. if (*attr == EGL_GL_COLORSPACE_KHR) {
  421. if (ENABLE_EGL_KHR_GL_COLORSPACE) {
  422. dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
  423. } else {
  424. // Normally we'd pass through unhandled attributes to
  425. // the driver. But in case the driver implements this
  426. // extension but we're disabling it, we want to prevent
  427. // it getting through -- support will be broken without
  428. // our help.
  429. ALOGE("sRGB window surfaces not supported");
  430. return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
  431. }
  432. }
  433. }
  434. }
  435. if (format != 0) {
  436. int err = native_window_set_buffers_format(window, format);
  437. if (err != 0) {
  438. ALOGE("error setting native window pixel format: %s (%d)",
  439. strerror(-err), err);
  440. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  441. return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  442. }
  443. }
  444. if (dataSpace != 0) {
  445. int err = native_window_set_buffers_data_space(window, dataSpace);
  446. if (err != 0) {
  447. ALOGE("error setting native window pixel dataSpace: %s (%d)",
  448. strerror(-err), err);
  449. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  450. return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  451. }
  452. }
  453. // the EGL spec requires that a new EGLSurface default to swap interval
  454. // 1, so explicitly set that on the window here.
  455. ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
  456. anw->setSwapInterval(anw, 1);
  457. EGLSurface surface = cnx->egl.eglCreateWindowSurface(
  458. iDpy, config, window, attrib_list);
  459. if (surface != EGL_NO_SURFACE) {
  460. egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
  461. surface, cnx);
  462. return s;
  463. }
  464. // EGLSurface creation failed
  465. native_window_set_buffers_format(window, 0);
  466. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  467. }
  468. return EGL_NO_SURFACE;
  469. }
  470. EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config,
  471. NativePixmapType pixmap,
  472. const EGLint *attrib_list)
  473. {
  474. clearError();
  475. egl_connection_t* cnx = NULL;
  476. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  477. if (dp) {
  478. EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
  479. dp->disp.dpy, config, pixmap, attrib_list);
  480. if (surface != EGL_NO_SURFACE) {
  481. egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
  482. surface, cnx);
  483. return s;
  484. }
  485. }
  486. return EGL_NO_SURFACE;
  487. }
  488. EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
  489. const EGLint *attrib_list)
  490. {
  491. clearError();
  492. egl_connection_t* cnx = NULL;
  493. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  494. if (dp) {
  495. EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
  496. dp->disp.dpy, config, attrib_list);
  497. if (surface != EGL_NO_SURFACE) {
  498. egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
  499. surface, cnx);
  500. return s;
  501. }
  502. }
  503. return EGL_NO_SURFACE;
  504. }
  505. EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
  506. {
  507. clearError();
  508. const egl_display_ptr dp = validate_display(dpy);
  509. if (!dp) return EGL_FALSE;
  510. SurfaceRef _s(dp.get(), surface);
  511. if (!_s.get())
  512. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  513. egl_surface_t * const s = get_surface(surface);
  514. EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
  515. if (result == EGL_TRUE) {
  516. _s.terminate();
  517. }
  518. return result;
  519. }
  520. EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
  521. EGLint attribute, EGLint *value)
  522. {
  523. clearError();
  524. const egl_display_ptr dp = validate_display(dpy);
  525. if (!dp) return EGL_FALSE;
  526. SurfaceRef _s(dp.get(), surface);
  527. if (!_s.get())
  528. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  529. egl_surface_t const * const s = get_surface(surface);
  530. return s->cnx->egl.eglQuerySurface(
  531. dp->disp.dpy, s->surface, attribute, value);
  532. }
  533. void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
  534. ATRACE_CALL();
  535. clearError();
  536. const egl_display_ptr dp = validate_display(dpy);
  537. if (!dp) {
  538. return;
  539. }
  540. SurfaceRef _s(dp.get(), surface);
  541. if (!_s.get()) {
  542. setError(EGL_BAD_SURFACE, EGL_FALSE);
  543. return;
  544. }
  545. }
  546. // ----------------------------------------------------------------------------
  547. // Contexts
  548. // ----------------------------------------------------------------------------
  549. EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
  550. EGLContext share_list, const EGLint *attrib_list)
  551. {
  552. clearError();
  553. egl_connection_t* cnx = NULL;
  554. const egl_display_ptr dp = validate_display_connection(dpy, cnx);
  555. if (dp) {
  556. if (share_list != EGL_NO_CONTEXT) {
  557. if (!ContextRef(dp.get(), share_list).get()) {
  558. return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
  559. }
  560. egl_context_t* const c = get_context(share_list);
  561. share_list = c->context;
  562. }
  563. EGLContext context = cnx->egl.eglCreateContext(
  564. dp->disp.dpy, config, share_list, attrib_list);
  565. if (context != EGL_NO_CONTEXT) {
  566. // figure out if it's a GLESv1 or GLESv2
  567. int version = 0;
  568. if (attrib_list) {
  569. while (*attrib_list != EGL_NONE) {
  570. GLint attr = *attrib_list++;
  571. GLint value = *attrib_list++;
  572. if (attr == EGL_CONTEXT_CLIENT_VERSION) {
  573. if (value == 1) {
  574. version = egl_connection_t::GLESv1_INDEX;
  575. } else if (value == 2 || value == 3) {
  576. version = egl_connection_t::GLESv2_INDEX;
  577. }
  578. }
  579. };
  580. }
  581. egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
  582. version);
  583. #if EGL_TRACE
  584. if (getEGLDebugLevel() > 0)
  585. GLTrace_eglCreateContext(version, c);
  586. #endif
  587. return c;
  588. }
  589. }
  590. return EGL_NO_CONTEXT;
  591. }
  592. EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
  593. {
  594. clearError();
  595. const egl_display_ptr dp = validate_display(dpy);
  596. if (!dp)
  597. return EGL_FALSE;
  598. ContextRef _c(dp.get(), ctx);
  599. if (!_c.get())
  600. return setError(EGL_BAD_CONTEXT, EGL_FALSE);
  601. egl_context_t * const c = get_context(ctx);
  602. EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
  603. if (result == EGL_TRUE) {
  604. _c.terminate();
  605. }
  606. return result;
  607. }
  608. EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
  609. EGLSurface read, EGLContext ctx)
  610. {
  611. clearError();
  612. egl_display_ptr dp = validate_display(dpy);
  613. if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  614. // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
  615. // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
  616. // a valid but uninitialized display.
  617. if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
  618. (draw != EGL_NO_SURFACE) ) {
  619. if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
  620. }
  621. // get a reference to the object passed in
  622. ContextRef _c(dp.get(), ctx);
  623. SurfaceRef _d(dp.get(), draw);
  624. SurfaceRef _r(dp.get(), read);
  625. // validate the context (if not EGL_NO_CONTEXT)
  626. if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
  627. // EGL_NO_CONTEXT is valid
  628. return setError(EGL_BAD_CONTEXT, EGL_FALSE);
  629. }
  630. // these are the underlying implementation's object
  631. EGLContext impl_ctx = EGL_NO_CONTEXT;
  632. EGLSurface impl_draw = EGL_NO_SURFACE;
  633. EGLSurface impl_read = EGL_NO_SURFACE;
  634. // these are our objects structs passed in
  635. egl_context_t * c = NULL;
  636. egl_surface_t const * d = NULL;
  637. egl_surface_t const * r = NULL;
  638. // these are the current objects structs
  639. egl_context_t * cur_c = get_context(getContext());
  640. if (ctx != EGL_NO_CONTEXT) {
  641. c = get_context(ctx);
  642. impl_ctx = c->context;
  643. } else {
  644. // no context given, use the implementation of the current context
  645. if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
  646. // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
  647. return setError(EGL_BAD_MATCH, EGL_FALSE);
  648. }
  649. if (cur_c == NULL) {
  650. // no current context
  651. // not an error, there is just no current context.
  652. return EGL_TRUE;
  653. }
  654. }
  655. // retrieve the underlying implementation's draw EGLSurface
  656. if (draw != EGL_NO_SURFACE) {
  657. if (!_d.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
  658. d = get_surface(draw);
  659. impl_draw = d->surface;
  660. }
  661. // retrieve the underlying implementation's read EGLSurface
  662. if (read != EGL_NO_SURFACE) {
  663. if (!_r.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
  664. r = get_surface(read);
  665. impl_read = r->surface;
  666. }
  667. EGLBoolean result = dp->makeCurrent(c, cur_c,
  668. draw, read, ctx,
  669. impl_draw, impl_read, impl_ctx);
  670. if (result == EGL_TRUE) {
  671. if (c) {
  672. setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
  673. egl_tls_t::setContext(ctx);
  674. #if EGL_TRACE
  675. if (getEGLDebugLevel() > 0)
  676. GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx);
  677. #endif
  678. _c.acquire();
  679. _r.acquire();
  680. _d.acquire();
  681. } else {
  682. setGLHooksThreadSpecific(&gHooksNoContext);
  683. egl_tls_t::setContext(EGL_NO_CONTEXT);
  684. }
  685. } else {
  686. // this will ALOGE the error
  687. egl_connection_t* const cnx = &gEGLImpl;
  688. result = setError(cnx->egl.eglGetError(), EGL_FALSE);
  689. }
  690. return result;
  691. }
  692. EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
  693. EGLint attribute, EGLint *value)
  694. {
  695. clearError();
  696. const egl_display_ptr dp = validate_display(dpy);
  697. if (!dp) return EGL_FALSE;
  698. ContextRef _c(dp.get(), ctx);
  699. if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
  700. egl_context_t * const c = get_context(ctx);
  701. return c->cnx->egl.eglQueryContext(
  702. dp->disp.dpy, c->context, attribute, value);
  703. }
  704. EGLContext eglGetCurrentContext(void)
  705. {
  706. // could be called before eglInitialize(), but we wouldn't have a context
  707. // then, and this function would correctly return EGL_NO_CONTEXT.
  708. clearError();
  709. EGLContext ctx = getContext();
  710. return ctx;
  711. }
  712. EGLSurface eglGetCurrentSurface(EGLint readdraw)
  713. {
  714. // could be called before eglInitialize(), but we wouldn't have a context
  715. // then, and this function would correctly return EGL_NO_SURFACE.
  716. clearError();
  717. EGLContext ctx = getContext();
  718. if (ctx) {
  719. egl_context_t const * const c = get_context(ctx);
  720. if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
  721. switch (readdraw) {
  722. case EGL_READ: return c->read;
  723. case EGL_DRAW: return c->draw;
  724. default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
  725. }
  726. }
  727. return EGL_NO_SURFACE;
  728. }
  729. EGLDisplay eglGetCurrentDisplay(void)
  730. {
  731. // could be called before eglInitialize(), but we wouldn't have a context
  732. // then, and this function would correctly return EGL_NO_DISPLAY.
  733. clearError();
  734. EGLContext ctx = getContext();
  735. if (ctx) {
  736. egl_context_t const * const c = get_context(ctx);
  737. if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
  738. return c->dpy;
  739. }
  740. return EGL_NO_DISPLAY;
  741. }
  742. EGLBoolean eglWaitGL(void)
  743. {
  744. clearError();
  745. egl_connection_t* const cnx = &gEGLImpl;
  746. if (!cnx->dso)
  747. return setError(EGL_BAD_CONTEXT, EGL_FALSE);
  748. return cnx->egl.eglWaitGL();
  749. }
  750. EGLBoolean eglWaitNative(EGLint engine)
  751. {
  752. clearError();
  753. egl_connection_t* const cnx = &gEGLImpl;
  754. if (!cnx->dso)
  755. return setError(EGL_BAD_CONTEXT, EGL_FALSE);
  756. return cnx->egl.eglWaitNative(engine);
  757. }
  758. EGLint eglGetError(void)
  759. {
  760. EGLint err = EGL_SUCCESS;
  761. egl_connection_t* const cnx = &gEGLImpl;
  762. if (cnx->dso) {
  763. err = cnx->egl.eglGetError();
  764. }
  765. if (err == EGL_SUCCESS) {
  766. err = egl_tls_t::getError();
  767. }
  768. return err;
  769. }
  770. static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
  771. const char* procname) {
  772. const egl_connection_t* cnx = &gEGLImpl;
  773. void* proc = NULL;
  774. proc = dlsym(cnx->libEgl, procname);
  775. if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
  776. proc = dlsym(cnx->libGles2, procname);
  777. if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
  778. proc = dlsym(cnx->libGles1, procname);
  779. if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
  780. return NULL;
  781. }
  782. __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
  783. {
  784. // eglGetProcAddress() could be the very first function called
  785. // in which case we must make sure we've initialized ourselves, this
  786. // happens the first time egl_get_display() is called.
  787. clearError();
  788. if (egl_init_drivers() == EGL_FALSE) {
  789. setError(EGL_BAD_PARAMETER, NULL);
  790. return NULL;
  791. }
  792. if (FILTER_EXTENSIONS(procname)) {
  793. return NULL;
  794. }
  795. __eglMustCastToProperFunctionPointerType addr;
  796. addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
  797. if (addr) return addr;
  798. addr = findBuiltinWrapper(procname);
  799. if (addr) return addr;
  800. // this protects accesses to sGLExtentionMap and sGLExtentionSlot
  801. pthread_mutex_lock(&sExtensionMapMutex);
  802. /*
  803. * Since eglGetProcAddress() is not associated to anything, it needs
  804. * to return a function pointer that "works" regardless of what
  805. * the current context is.
  806. *
  807. * For this reason, we return a "forwarder", a small stub that takes
  808. * care of calling the function associated with the context
  809. * currently bound.
  810. *
  811. * We first look for extensions we've already resolved, if we're seeing
  812. * this extension for the first time, we go through all our
  813. * implementations and call eglGetProcAddress() and record the
  814. * result in the appropriate implementation hooks and return the
  815. * address of the forwarder corresponding to that hook set.
  816. *
  817. */
  818. const String8 name(procname);
  819. addr = sGLExtentionMap.valueFor(name);
  820. const int slot = sGLExtentionSlot;
  821. ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
  822. "no more slots for eglGetProcAddress(\"%s\")",
  823. procname);
  824. #if EGL_TRACE
  825. gl_hooks_t *debugHooks = GLTrace_getGLHooks();
  826. #endif
  827. if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
  828. bool found = false;
  829. egl_connection_t* const cnx = &gEGLImpl;
  830. if (cnx->dso && cnx->egl.eglGetProcAddress) {
  831. // Extensions are independent of the bound context
  832. addr =
  833. cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
  834. cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
  835. #if EGL_TRACE
  836. debugHooks->ext.extensions[slot] =
  837. gHooksTrace.ext.extensions[slot] =
  838. #endif
  839. cnx->egl.eglGetProcAddress(procname);
  840. if (addr) found = true;
  841. }
  842. if (found) {
  843. addr = gExtensionForwarders[slot];
  844. sGLExtentionMap.add(name, addr);
  845. sGLExtentionSlot++;
  846. }
  847. }
  848. pthread_mutex_unlock(&sExtensionMapMutex);
  849. return addr;
  850. }
  851. class FrameCompletionThread : public Thread {
  852. public:
  853. static void queueSync(EGLSyncKHR sync) {
  854. static sp<FrameCompletionThread> thread(new FrameCompletionThread);
  855. static bool running = false;
  856. if (!running) {
  857. thread->run("GPUFrameCompletion");
  858. running = true;
  859. }
  860. {
  861. Mutex::Autolock lock(thread->mMutex);
  862. ScopedTrace st(ATRACE_TAG, String8::format("kicked off frame %d",
  863. thread->mFramesQueued).string());
  864. thread->mQueue.push_back(sync);
  865. thread->mCondition.signal();
  866. thread->mFramesQueued++;
  867. ATRACE_INT("GPU Frames Outstanding", thread->mQueue.size());
  868. }
  869. }
  870. private:
  871. FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {}
  872. virtual bool threadLoop() {
  873. EGLSyncKHR sync;
  874. uint32_t frameNum;
  875. {
  876. Mutex::Autolock lock(mMutex);
  877. while (mQueue.isEmpty()) {
  878. mCondition.wait(mMutex);
  879. }
  880. sync = mQueue[0];
  881. frameNum = mFramesCompleted;
  882. }
  883. EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  884. {
  885. ScopedTrace st(ATRACE_TAG, String8::format("waiting for frame %d",
  886. frameNum).string());
  887. EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
  888. if (result == EGL_FALSE) {
  889. ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
  890. } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
  891. ALOGE("FrameCompletion: timeout waiting for fence");
  892. }
  893. eglDestroySyncKHR(dpy, sync);
  894. }
  895. {
  896. Mutex::Autolock lock(mMutex);
  897. mQueue.removeAt(0);
  898. mFramesCompleted++;
  899. ATRACE_INT("GPU Frames Outstanding", mQueue.size());
  900. }
  901. return true;
  902. }
  903. uint32_t mFramesQueued;
  904. uint32_t mFramesCompleted;
  905. Vector<EGLSyncKHR> mQueue;
  906. Condition mCondition;
  907. Mutex mMutex;
  908. };
  909. EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
  910. EGLint *rects, EGLint n_rects)
  911. {
  912. ATRACE_CALL();
  913. clearError();
  914. const egl_display_ptr dp = validate_display(dpy);
  915. if (!dp) return EGL_FALSE;
  916. SurfaceRef _s(dp.get(), draw);
  917. if (!_s.get())
  918. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  919. #if EGL_TRACE
  920. gl_hooks_t const *trace_hooks = getGLTraceThreadSpecific();
  921. if (getEGLDebugLevel() > 0) {
  922. if (trace_hooks == NULL) {
  923. if (GLTrace_start() < 0) {
  924. ALOGE("Disabling Tracer for OpenGL ES");
  925. setEGLDebugLevel(0);
  926. } else {
  927. // switch over to the trace version of hooks
  928. EGLContext ctx = egl_tls_t::getContext();
  929. egl_context_t * const c = get_context(ctx);
  930. if (c) {
  931. setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
  932. GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx);
  933. }
  934. }
  935. }
  936. GLTrace_eglSwapBuffers(dpy, draw);
  937. } else if (trace_hooks != NULL) {
  938. // tracing is now disabled, so switch back to the non trace version
  939. EGLContext ctx = egl_tls_t::getContext();
  940. egl_context_t * const c = get_context(ctx);
  941. if (c) setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
  942. GLTrace_stop();
  943. }
  944. #endif
  945. egl_surface_t const * const s = get_surface(draw);
  946. if (CC_UNLIKELY(dp->traceGpuCompletion)) {
  947. EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
  948. if (sync != EGL_NO_SYNC_KHR) {
  949. FrameCompletionThread::queueSync(sync);
  950. }
  951. }
  952. if (CC_UNLIKELY(dp->finishOnSwap)) {
  953. uint32_t pixel;
  954. egl_context_t * const c = get_context( egl_tls_t::getContext() );
  955. if (c) {
  956. // glReadPixels() ensures that the frame is complete
  957. s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
  958. GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
  959. }
  960. }
  961. if (n_rects == 0) {
  962. return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
  963. }
  964. Vector<android_native_rect_t> androidRects;
  965. for (int r = 0; r < n_rects; ++r) {
  966. int offset = r * 4;
  967. int x = rects[offset];
  968. int y = rects[offset + 1];
  969. int width = rects[offset + 2];
  970. int height = rects[offset + 3];
  971. android_native_rect_t androidRect;
  972. androidRect.left = x;
  973. androidRect.top = y + height;
  974. androidRect.right = x + width;
  975. androidRect.bottom = y;
  976. androidRects.push_back(androidRect);
  977. }
  978. native_window_set_surface_damage(s->win.get(), androidRects.array(),
  979. androidRects.size());
  980. if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
  981. return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
  982. rects, n_rects);
  983. } else {
  984. return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
  985. }
  986. }
  987. EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  988. {
  989. return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
  990. }
  991. EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface,
  992. NativePixmapType target)
  993. {
  994. clearError();
  995. const egl_display_ptr dp = validate_display(dpy);
  996. if (!dp) return EGL_FALSE;
  997. SurfaceRef _s(dp.get(), surface);
  998. if (!_s.get())
  999. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1000. egl_surface_t const * const s = get_surface(surface);
  1001. return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
  1002. }
  1003. const char* eglQueryString(EGLDisplay dpy, EGLint name)
  1004. {
  1005. clearError();
  1006. const egl_display_ptr dp = validate_display(dpy);
  1007. if (!dp) return (const char *) NULL;
  1008. switch (name) {
  1009. case EGL_VENDOR:
  1010. return dp->getVendorString();
  1011. case EGL_VERSION:
  1012. return dp->getVersionString();
  1013. case EGL_EXTENSIONS:
  1014. return dp->getExtensionString();
  1015. case EGL_CLIENT_APIS:
  1016. return dp->getClientApiString();
  1017. }
  1018. return setError(EGL_BAD_PARAMETER, (const char *)0);
  1019. }
  1020. EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
  1021. {
  1022. clearError();
  1023. const egl_display_ptr dp = validate_display(dpy);
  1024. if (!dp) return (const char *) NULL;
  1025. switch (name) {
  1026. case EGL_VENDOR:
  1027. return dp->disp.queryString.vendor;
  1028. case EGL_VERSION:
  1029. return dp->disp.queryString.version;
  1030. case EGL_EXTENSIONS:
  1031. return dp->disp.queryString.extensions;
  1032. case EGL_CLIENT_APIS:
  1033. return dp->disp.queryString.clientApi;
  1034. }
  1035. return setError(EGL_BAD_PARAMETER, (const char *)0);
  1036. }
  1037. // ----------------------------------------------------------------------------
  1038. // EGL 1.1
  1039. // ----------------------------------------------------------------------------
  1040. EGLBoolean eglSurfaceAttrib(
  1041. EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
  1042. {
  1043. clearError();
  1044. const egl_display_ptr dp = validate_display(dpy);
  1045. if (!dp) return EGL_FALSE;
  1046. SurfaceRef _s(dp.get(), surface);
  1047. if (!_s.get())
  1048. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1049. egl_surface_t const * const s = get_surface(surface);
  1050. if (s->cnx->egl.eglSurfaceAttrib) {
  1051. return s->cnx->egl.eglSurfaceAttrib(
  1052. dp->disp.dpy, s->surface, attribute, value);
  1053. }
  1054. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1055. }
  1056. EGLBoolean eglBindTexImage(
  1057. EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  1058. {
  1059. clearError();
  1060. const egl_display_ptr dp = validate_display(dpy);
  1061. if (!dp) return EGL_FALSE;
  1062. SurfaceRef _s(dp.get(), surface);
  1063. if (!_s.get())
  1064. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1065. egl_surface_t const * const s = get_surface(surface);
  1066. if (s->cnx->egl.eglBindTexImage) {
  1067. return s->cnx->egl.eglBindTexImage(
  1068. dp->disp.dpy, s->surface, buffer);
  1069. }
  1070. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1071. }
  1072. EGLBoolean eglReleaseTexImage(
  1073. EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  1074. {
  1075. clearError();
  1076. const egl_display_ptr dp = validate_display(dpy);
  1077. if (!dp) return EGL_FALSE;
  1078. SurfaceRef _s(dp.get(), surface);
  1079. if (!_s.get())
  1080. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1081. egl_surface_t const * const s = get_surface(surface);
  1082. if (s->cnx->egl.eglReleaseTexImage) {
  1083. return s->cnx->egl.eglReleaseTexImage(
  1084. dp->disp.dpy, s->surface, buffer);
  1085. }
  1086. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1087. }
  1088. EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
  1089. {
  1090. clearError();
  1091. const egl_display_ptr dp = validate_display(dpy);
  1092. if (!dp) return EGL_FALSE;
  1093. EGLBoolean res = EGL_TRUE;
  1094. egl_connection_t* const cnx = &gEGLImpl;
  1095. if (cnx->dso && cnx->egl.eglSwapInterval) {
  1096. res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
  1097. }
  1098. return res;
  1099. }
  1100. // ----------------------------------------------------------------------------
  1101. // EGL 1.2
  1102. // ----------------------------------------------------------------------------
  1103. EGLBoolean eglWaitClient(void)
  1104. {
  1105. clearError();
  1106. egl_connection_t* const cnx = &gEGLImpl;
  1107. if (!cnx->dso)
  1108. return setError(EGL_BAD_CONTEXT, EGL_FALSE);
  1109. EGLBoolean res;
  1110. if (cnx->egl.eglWaitClient) {
  1111. res = cnx->egl.eglWaitClient();
  1112. } else {
  1113. res = cnx->egl.eglWaitGL();
  1114. }
  1115. return res;
  1116. }
  1117. EGLBoolean eglBindAPI(EGLenum api)
  1118. {
  1119. clearError();
  1120. if (egl_init_drivers() == EGL_FALSE) {
  1121. return setError(EGL_BAD_PARAMETER, EGL_FALSE);
  1122. }
  1123. // bind this API on all EGLs
  1124. EGLBoolean res = EGL_TRUE;
  1125. egl_connection_t* const cnx = &gEGLImpl;
  1126. if (cnx->dso && cnx->egl.eglBindAPI) {
  1127. res = cnx->egl.eglBindAPI(api);
  1128. }
  1129. return res;
  1130. }
  1131. EGLenum eglQueryAPI(void)
  1132. {
  1133. clearError();
  1134. if (egl_init_drivers() == EGL_FALSE) {
  1135. return setError(EGL_BAD_PARAMETER, EGL_FALSE);
  1136. }
  1137. egl_connection_t* const cnx = &gEGLImpl;
  1138. if (cnx->dso && cnx->egl.eglQueryAPI) {
  1139. return cnx->egl.eglQueryAPI();
  1140. }
  1141. // or, it can only be OpenGL ES
  1142. return EGL_OPENGL_ES_API;
  1143. }
  1144. EGLBoolean eglReleaseThread(void)
  1145. {
  1146. clearError();
  1147. #if EGL_TRACE
  1148. if (getEGLDebugLevel() > 0)
  1149. GLTrace_eglReleaseThread();
  1150. #endif
  1151. // If there is context bound to the thread, release it
  1152. egl_display_t::loseCurrent(get_context(getContext()));
  1153. egl_connection_t* const cnx = &gEGLImpl;
  1154. if (cnx->dso && cnx->egl.eglReleaseThread) {
  1155. cnx->egl.eglReleaseThread();
  1156. }
  1157. egl_tls_t::clearTLS();
  1158. return EGL_TRUE;
  1159. }
  1160. EGLSurface eglCreatePbufferFromClientBuffer(
  1161. EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
  1162. EGLConfig config, const EGLint *attrib_list)
  1163. {
  1164. clearError();
  1165. egl_connection_t* cnx = NULL;
  1166. const egl_display_ptr dp = validate_display_connection(dpy, cnx);
  1167. if (!dp) return EGL_FALSE;
  1168. if (cnx->egl.eglCreatePbufferFromClientBuffer) {
  1169. return cnx->egl.eglCreatePbufferFromClientBuffer(
  1170. dp->disp.dpy, buftype, buffer, config, attrib_list);
  1171. }
  1172. return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
  1173. }
  1174. // ----------------------------------------------------------------------------
  1175. // EGL_EGLEXT_VERSION 3
  1176. // ----------------------------------------------------------------------------
  1177. EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
  1178. const EGLint *attrib_list)
  1179. {
  1180. clearError();
  1181. const egl_display_ptr dp = validate_display(dpy);
  1182. if (!dp) return EGL_FALSE;
  1183. SurfaceRef _s(dp.get(), surface);
  1184. if (!_s.get())
  1185. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1186. egl_surface_t const * const s = get_surface(surface);
  1187. if (s->cnx->egl.eglLockSurfaceKHR) {
  1188. return s->cnx->egl.eglLockSurfaceKHR(
  1189. dp->disp.dpy, s->surface, attrib_list);
  1190. }
  1191. return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  1192. }
  1193. EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
  1194. {
  1195. clearError();
  1196. const egl_display_ptr dp = validate_display(dpy);
  1197. if (!dp) return EGL_FALSE;
  1198. SurfaceRef _s(dp.get(), surface);
  1199. if (!_s.get())
  1200. return setError(EGL_BAD_SURFACE, EGL_FALSE);
  1201. egl_surface_t const * const s = get_surface(surface);
  1202. if (s->cnx->egl.eglUnlockSurfaceKHR) {
  1203. return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
  1204. }
  1205. return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  1206. }
  1207. EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1208. EGLClientBuffer buffer, const EGLint *attrib_list)
  1209. {
  1210. clearError();
  1211. const egl_display_ptr dp = validate_display(dpy);
  1212. if (!dp) return EGL_NO_IMAGE_KHR;
  1213. ContextRef _c(dp.get(), ctx);
  1214. egl_context_t * const c = _c.get();
  1215. EGLImageKHR result = EGL_NO_IMAGE_KHR;
  1216. egl_connection_t* const cnx = &gEGLImpl;
  1217. if (cnx->dso && cnx->egl.eglCreateImageKHR) {
  1218. result = cnx->egl.eglCreateImageKHR(
  1219. dp->disp.dpy,
  1220. c ? c->context : EGL_NO_CONTEXT,
  1221. target, buffer, attrib_list);
  1222. }
  1223. return result;
  1224. }
  1225. EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
  1226. {
  1227. clearError();
  1228. const egl_display_ptr dp = validate_display(dpy);
  1229. if (!dp) return EGL_FALSE;
  1230. EGLBoolean result = EGL_FALSE;
  1231. egl_connection_t* const cnx = &gEGLImpl;
  1232. if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
  1233. result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
  1234. }
  1235. return result;
  1236. }
  1237. // ----------------------------------------------------------------------------
  1238. // EGL_EGLEXT_VERSION 5
  1239. // ----------------------------------------------------------------------------
  1240. EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
  1241. {
  1242. clearError();
  1243. const egl_display_ptr dp = validate_display(dpy);
  1244. if (!dp) return EGL_NO_SYNC_KHR;
  1245. EGLSyncKHR result = EGL_NO_SYNC_KHR;
  1246. egl_connection_t* const cnx = &gEGLImpl;
  1247. if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
  1248. result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
  1249. }
  1250. return result;
  1251. }
  1252. EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
  1253. {
  1254. clearError();
  1255. const egl_display_ptr dp = validate_display(dpy);
  1256. if (!dp) return EGL_FALSE;
  1257. EGLBoolean result = EGL_FALSE;
  1258. egl_connection_t* const cnx = &gEGLImpl;
  1259. if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
  1260. result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
  1261. }
  1262. return result;
  1263. }
  1264. EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
  1265. clearError();
  1266. const egl_display_ptr dp = validate_display(dpy);
  1267. if (!dp) return EGL_FALSE;
  1268. EGLBoolean result = EGL_FALSE;
  1269. egl_connection_t* const cnx = &gEGLImpl;
  1270. if (cnx->dso && cnx->egl.eglSignalSyncKHR) {
  1271. result = cnx->egl.eglSignalSyncKHR(
  1272. dp->disp.dpy, sync, mode);
  1273. }
  1274. return result;
  1275. }
  1276. EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
  1277. EGLint flags, EGLTimeKHR timeout)
  1278. {
  1279. clearError();
  1280. const egl_display_ptr dp = validate_display(dpy);
  1281. if (!dp) return EGL_FALSE;
  1282. EGLBoolean result = EGL_FALSE;
  1283. egl_connection_t* const cnx = &gEGLImpl;
  1284. if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
  1285. result = cnx->egl.eglClientWaitSyncKHR(
  1286. dp->disp.dpy, sync, flags, timeout);
  1287. }
  1288. return result;
  1289. }
  1290. EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
  1291. EGLint attribute, EGLint *value)
  1292. {
  1293. clearError();
  1294. const egl_display_ptr dp = validate_display(dpy);
  1295. if (!dp) return EGL_FALSE;
  1296. EGLBoolean result = EGL_FALSE;
  1297. egl_connection_t* const cnx = &gEGLImpl;
  1298. if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
  1299. result = cnx->egl.eglGetSyncAttribKHR(
  1300. dp->disp.dpy, sync, attribute, value);
  1301. }
  1302. return result;
  1303. }
  1304. EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
  1305. {
  1306. clearError();
  1307. const egl_display_ptr dp = validate_display(dpy);
  1308. if (!dp) return EGL_NO_STREAM_KHR;
  1309. EGLStreamKHR result = EGL_NO_STREAM_KHR;
  1310. egl_connection_t* const cnx = &gEGLImpl;
  1311. if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
  1312. result = cnx->egl.eglCreateStreamKHR(
  1313. dp->disp.dpy, attrib_list);
  1314. }
  1315. return result;
  1316. }
  1317. EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
  1318. {
  1319. clearError();
  1320. const egl_display_ptr dp = validate_display(dpy);
  1321. if (!dp) return EGL_FALSE;
  1322. EGLBoolean result = EGL_FALSE;
  1323. egl_connection_t* const cnx = &gEGLImpl;
  1324. if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
  1325. result = cnx->egl.eglDestroyStreamKHR(
  1326. dp->disp.dpy, stream);
  1327. }
  1328. return result;
  1329. }
  1330. EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
  1331. EGLenum attribute, EGLint value)
  1332. {
  1333. clearError();
  1334. const egl_display_ptr dp = validate_display(dpy);
  1335. if (!dp) return EGL_FALSE;
  1336. EGLBoolean result = EGL_FALSE;
  1337. egl_connection_t* const cnx = &gEGLImpl;
  1338. if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
  1339. result = cnx->egl.eglStreamAttribKHR(
  1340. dp->disp.dpy, stream, attribute, value);
  1341. }
  1342. return result;
  1343. }
  1344. EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
  1345. EGLenum attribute, EGLint *value)
  1346. {
  1347. clearError();
  1348. const egl_display_ptr dp = validate_display(dpy);
  1349. if (!dp) return EGL_FALSE;
  1350. EGLBoolean result = EGL_FALSE;
  1351. egl_connection_t* const cnx = &gEGLImpl;
  1352. if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
  1353. result = cnx->egl.eglQueryStreamKHR(
  1354. dp->disp.dpy, stream, attribute, value);
  1355. }
  1356. return result;
  1357. }
  1358. EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
  1359. EGLenum attribute, EGLuint64KHR *value)
  1360. {
  1361. clearError();
  1362. const egl_display_ptr dp = validate_display(dpy);
  1363. if (!dp) return EGL_FALSE;
  1364. EGLBoolean result = EGL_FALSE;
  1365. egl_connection_t* const cnx = &gEGLImpl;
  1366. if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
  1367. result = cnx->egl.eglQueryStreamu64KHR(
  1368. dp->disp.dpy, stream, attribute, value);
  1369. }
  1370. return result;
  1371. }
  1372. EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
  1373. EGLenum attribute, EGLTimeKHR *value)
  1374. {
  1375. clearError();
  1376. const egl_display_ptr dp = validate_display(dpy);
  1377. if (!dp) return EGL_FALSE;
  1378. EGLBoolean result = EGL_FALSE;
  1379. egl_connection_t* const cnx = &gEGLImpl;
  1380. if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
  1381. result = cnx->egl.eglQueryStreamTimeKHR(
  1382. dp->disp.dpy, stream, attribute, value);
  1383. }
  1384. return result;
  1385. }
  1386. EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
  1387. EGLStreamKHR stream, const EGLint *attrib_list)
  1388. {
  1389. clearError();
  1390. egl_display_ptr dp = validate_display(dpy);
  1391. if (!dp) return EGL_NO_SURFACE;
  1392. egl_connection_t* const cnx = &gEGLImpl;
  1393. if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
  1394. EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
  1395. dp->disp.dpy, config, stream, attrib_list);
  1396. if (surface != EGL_NO_SURFACE) {
  1397. egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
  1398. surface, cnx);
  1399. return s;
  1400. }
  1401. }
  1402. return EGL_NO_SURFACE;
  1403. }
  1404. EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
  1405. EGLStreamKHR stream)
  1406. {
  1407. clearError();
  1408. const egl_display_ptr dp = validate_display(dpy);
  1409. if (!dp) return EGL_FALSE;
  1410. EGLBoolean result = EGL_FALSE;
  1411. egl_connection_t* const cnx = &gEGLImpl;
  1412. if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
  1413. result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
  1414. dp->disp.dpy, stream);
  1415. }
  1416. return result;
  1417. }
  1418. EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
  1419. EGLStreamKHR stream)
  1420. {
  1421. clearError();
  1422. const egl_display_ptr dp = validate_display(dpy);
  1423. if (!dp) return EGL_FALSE;
  1424. EGLBoolean result = EGL_FALSE;
  1425. egl_connection_t* const cnx = &gEGLImpl;
  1426. if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
  1427. result = cnx->egl.eglStreamConsumerAcquireKHR(
  1428. dp->disp.dpy, stream);
  1429. }
  1430. return result;
  1431. }
  1432. EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
  1433. EGLStreamKHR stream)
  1434. {
  1435. clearError();
  1436. const egl_display_ptr dp = validate_display(dpy);
  1437. if (!dp) return EGL_FALSE;
  1438. EGLBoolean result = EGL_FALSE;
  1439. egl_connection_t* const cnx = &gEGLImpl;
  1440. if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
  1441. result = cnx->egl.eglStreamConsumerReleaseKHR(
  1442. dp->disp.dpy, stream);
  1443. }
  1444. return result;
  1445. }
  1446. EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
  1447. EGLDisplay dpy, EGLStreamKHR stream)
  1448. {
  1449. clearError();
  1450. const egl_display_ptr dp = validate_display(dpy);
  1451. if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
  1452. EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
  1453. egl_connection_t* const cnx = &gEGLImpl;
  1454. if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
  1455. result = cnx->egl.eglGetStreamFileDescriptorKHR(
  1456. dp->disp.dpy, stream);
  1457. }
  1458. return result;
  1459. }
  1460. EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
  1461. EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
  1462. {
  1463. clearError();
  1464. const egl_display_ptr dp = validate_display(dpy);
  1465. if (!dp) return EGL_NO_STREAM_KHR;
  1466. EGLStreamKHR result = EGL_NO_STREAM_KHR;
  1467. egl_connection_t* const cnx = &gEGLImpl;
  1468. if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
  1469. result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
  1470. dp->disp.dpy, file_descriptor);
  1471. }
  1472. return result;
  1473. }
  1474. // ----------------------------------------------------------------------------
  1475. // EGL_EGLEXT_VERSION 15
  1476. // ----------------------------------------------------------------------------
  1477. EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
  1478. clearError();
  1479. const egl_display_ptr dp = validate_display(dpy);
  1480. if (!dp) return EGL_FALSE;
  1481. EGLint result = EGL_FALSE;
  1482. egl_connection_t* const cnx = &gEGLImpl;
  1483. if (cnx->dso && cnx->egl.eglWaitSyncKHR) {
  1484. result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags);
  1485. }
  1486. return result;
  1487. }
  1488. // ----------------------------------------------------------------------------
  1489. // ANDROID extensions
  1490. // ----------------------------------------------------------------------------
  1491. EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
  1492. {
  1493. clearError();
  1494. const egl_display_ptr dp = validate_display(dpy);
  1495. if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
  1496. EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
  1497. egl_connection_t* const cnx = &gEGLImpl;
  1498. if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
  1499. result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
  1500. }
  1501. return result;
  1502. }
  1503. EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
  1504. EGLnsecsANDROID time)
  1505. {
  1506. clearError();
  1507. const egl_display_ptr dp = validate_display(dpy);
  1508. if (!dp) {
  1509. return EGL_FALSE;
  1510. }
  1511. SurfaceRef _s(dp.get(), surface);
  1512. if (!_s.get()) {
  1513. setError(EGL_BAD_SURFACE, EGL_FALSE);
  1514. return EGL_FALSE;
  1515. }
  1516. egl_surface_t const * const s = get_surface(surface);
  1517. native_window_set_buffers_timestamp(s->win.get(), time);
  1518. return EGL_TRUE;
  1519. }
  1520. // ----------------------------------------------------------------------------
  1521. // NVIDIA extensions
  1522. // ----------------------------------------------------------------------------
  1523. EGLuint64NV eglGetSystemTimeFrequencyNV()
  1524. {
  1525. clearError();
  1526. if (egl_init_drivers() == EGL_FALSE) {
  1527. return setError(EGL_BAD_PARAMETER, EGL_FALSE);
  1528. }
  1529. EGLuint64NV ret = 0;
  1530. egl_connection_t* const cnx = &gEGLImpl;
  1531. if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
  1532. return cnx->egl.eglGetSystemTimeFrequencyNV();
  1533. }
  1534. return setErrorQuiet(EGL_BAD_DISPLAY, 0);
  1535. }
  1536. EGLuint64NV eglGetSystemTimeNV()
  1537. {
  1538. clearError();
  1539. if (egl_init_drivers() == EGL_FALSE) {
  1540. return setError(EGL_BAD_PARAMETER, EGL_FALSE);
  1541. }
  1542. EGLuint64NV ret = 0;
  1543. egl_connection_t* const cnx = &gEGLImpl;
  1544. if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
  1545. return cnx->egl.eglGetSystemTimeNV();
  1546. }
  1547. return setErrorQuiet(EGL_BAD_DISPLAY, 0);
  1548. }
  1549. // ----------------------------------------------------------------------------
  1550. // Partial update extension
  1551. // ----------------------------------------------------------------------------
  1552. EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
  1553. EGLint *rects, EGLint n_rects)
  1554. {
  1555. clearError();
  1556. const egl_display_ptr dp = validate_display(dpy);
  1557. if (!dp) {
  1558. setError(EGL_BAD_DISPLAY, EGL_FALSE);
  1559. return EGL_FALSE;
  1560. }
  1561. SurfaceRef _s(dp.get(), surface);
  1562. if (!_s.get()) {
  1563. setError(EGL_BAD_SURFACE, EGL_FALSE);
  1564. return EGL_FALSE;
  1565. }
  1566. egl_surface_t const * const s = get_surface(surface);
  1567. if (s->cnx->egl.eglSetDamageRegionKHR) {
  1568. return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
  1569. rects, n_rects);
  1570. }
  1571. return EGL_FALSE;
  1572. }