egl_platform_entries.cpp 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755
  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 "egl_platform_entries.h"
  18. #include <ctype.h>
  19. #include <dlfcn.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <hardware/gralloc1.h>
  23. #include <EGL/egl.h>
  24. #include <EGL/eglext.h>
  25. #include <EGL/eglext_angle.h>
  26. #include <android/hardware_buffer.h>
  27. #include <android-base/strings.h>
  28. #include <graphicsenv/GraphicsEnv.h>
  29. #include <private/android/AHardwareBufferHelpers.h>
  30. #include <cutils/compiler.h>
  31. #include <cutils/properties.h>
  32. #include <log/log.h>
  33. #include <condition_variable>
  34. #include <deque>
  35. #include <mutex>
  36. #include <unordered_map>
  37. #include <string>
  38. #include <thread>
  39. #include "../egl_impl.h"
  40. #include "egl_display.h"
  41. #include "egl_object.h"
  42. #include "egl_layers.h"
  43. #include "egl_tls.h"
  44. #include "egl_trace.h"
  45. using namespace android;
  46. // ----------------------------------------------------------------------------
  47. namespace android {
  48. using nsecs_t = int64_t;
  49. struct extension_map_t {
  50. const char* name;
  51. __eglMustCastToProperFunctionPointerType address;
  52. };
  53. /*
  54. * This is the list of EGL extensions exposed to applications.
  55. *
  56. * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
  57. * wrapper and are always available.
  58. *
  59. * The rest (gExtensionString) depend on support in the EGL driver, and are
  60. * only available if the driver supports them. However, some of these must be
  61. * supported because they are used by the Android system itself; these are
  62. * listed as mandatory below and are required by the CDD. The system *assumes*
  63. * the mandatory extensions are present and may not function properly if some
  64. * are missing.
  65. *
  66. * NOTE: Both strings MUST have a single space as the last character.
  67. */
  68. extern char const * const gBuiltinExtensionString;
  69. extern char const * const gExtensionString;
  70. // clang-format off
  71. // Extensions implemented by the EGL wrapper.
  72. char const * const gBuiltinExtensionString =
  73. "EGL_KHR_get_all_proc_addresses "
  74. "EGL_ANDROID_presentation_time "
  75. "EGL_KHR_swap_buffers_with_damage "
  76. "EGL_ANDROID_get_native_client_buffer "
  77. "EGL_ANDROID_front_buffer_auto_refresh "
  78. "EGL_ANDROID_get_frame_timestamps "
  79. "EGL_EXT_surface_SMPTE2086_metadata "
  80. "EGL_EXT_surface_CTA861_3_metadata "
  81. ;
  82. // Whitelist of extensions exposed to applications if implemented in the vendor driver.
  83. char const * const gExtensionString =
  84. "EGL_KHR_image " // mandatory
  85. "EGL_KHR_image_base " // mandatory
  86. "EGL_EXT_image_gl_colorspace "
  87. "EGL_KHR_image_pixmap "
  88. "EGL_KHR_lock_surface "
  89. "EGL_KHR_gl_colorspace "
  90. "EGL_KHR_gl_texture_2D_image "
  91. "EGL_KHR_gl_texture_3D_image "
  92. "EGL_KHR_gl_texture_cubemap_image "
  93. "EGL_KHR_gl_renderbuffer_image "
  94. "EGL_KHR_reusable_sync "
  95. "EGL_KHR_fence_sync "
  96. "EGL_KHR_create_context "
  97. "EGL_KHR_config_attribs "
  98. "EGL_KHR_surfaceless_context "
  99. "EGL_KHR_stream "
  100. "EGL_KHR_stream_fifo "
  101. "EGL_KHR_stream_producer_eglsurface "
  102. "EGL_KHR_stream_consumer_gltexture "
  103. "EGL_KHR_stream_cross_process_fd "
  104. "EGL_EXT_create_context_robustness "
  105. "EGL_NV_system_time "
  106. "EGL_ANDROID_image_native_buffer " // mandatory
  107. "EGL_KHR_wait_sync " // strongly recommended
  108. "EGL_ANDROID_recordable " // mandatory
  109. "EGL_KHR_partial_update " // strongly recommended
  110. "EGL_EXT_pixel_format_float "
  111. "EGL_EXT_buffer_age " // strongly recommended with partial_update
  112. "EGL_KHR_create_context_no_error "
  113. "EGL_KHR_mutable_render_buffer "
  114. "EGL_EXT_yuv_surface "
  115. "EGL_EXT_protected_content "
  116. "EGL_IMG_context_priority "
  117. "EGL_KHR_no_config_context "
  118. ;
  119. char const * const gClientExtensionString =
  120. "EGL_EXT_client_extensions "
  121. "EGL_KHR_platform_android "
  122. "EGL_ANGLE_platform_angle "
  123. "EGL_ANDROID_GLES_layers";
  124. // clang-format on
  125. // extensions not exposed to applications but used by the ANDROID system
  126. // "EGL_ANDROID_blob_cache " // strongly recommended
  127. // "EGL_IMG_hibernate_process " // optional
  128. // "EGL_ANDROID_native_fence_sync " // strongly recommended
  129. // "EGL_ANDROID_framebuffer_target " // mandatory for HWC 1.1
  130. /*
  131. * EGL Extensions entry-points exposed to 3rd party applications
  132. * (keep in sync with gExtensionString above)
  133. *
  134. */
  135. static const extension_map_t sExtensionMap[] = {
  136. // EGL_KHR_lock_surface
  137. { "eglLockSurfaceKHR",
  138. (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
  139. { "eglUnlockSurfaceKHR",
  140. (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
  141. // EGL_KHR_image, EGL_KHR_image_base
  142. { "eglCreateImageKHR",
  143. (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
  144. { "eglDestroyImageKHR",
  145. (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
  146. // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
  147. { "eglCreateSyncKHR",
  148. (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
  149. { "eglDestroySyncKHR",
  150. (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
  151. { "eglClientWaitSyncKHR",
  152. (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
  153. { "eglSignalSyncKHR",
  154. (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
  155. { "eglGetSyncAttribKHR",
  156. (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
  157. // EGL_NV_system_time
  158. { "eglGetSystemTimeFrequencyNV",
  159. (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
  160. { "eglGetSystemTimeNV",
  161. (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
  162. // EGL_KHR_wait_sync
  163. { "eglWaitSyncKHR",
  164. (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
  165. // EGL_ANDROID_presentation_time
  166. { "eglPresentationTimeANDROID",
  167. (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
  168. // EGL_KHR_swap_buffers_with_damage
  169. { "eglSwapBuffersWithDamageKHR",
  170. (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
  171. // EGL_ANDROID_get_native_client_buffer
  172. { "eglGetNativeClientBufferANDROID",
  173. (__eglMustCastToProperFunctionPointerType)&eglGetNativeClientBufferANDROID },
  174. // EGL_KHR_partial_update
  175. { "eglSetDamageRegionKHR",
  176. (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
  177. { "eglCreateStreamKHR",
  178. (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
  179. { "eglDestroyStreamKHR",
  180. (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
  181. { "eglStreamAttribKHR",
  182. (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
  183. { "eglQueryStreamKHR",
  184. (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
  185. { "eglQueryStreamu64KHR",
  186. (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
  187. { "eglQueryStreamTimeKHR",
  188. (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
  189. { "eglCreateStreamProducerSurfaceKHR",
  190. (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
  191. { "eglStreamConsumerGLTextureExternalKHR",
  192. (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
  193. { "eglStreamConsumerAcquireKHR",
  194. (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
  195. { "eglStreamConsumerReleaseKHR",
  196. (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
  197. { "eglGetStreamFileDescriptorKHR",
  198. (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
  199. { "eglCreateStreamFromFileDescriptorKHR",
  200. (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
  201. // EGL_ANDROID_get_frame_timestamps
  202. { "eglGetNextFrameIdANDROID",
  203. (__eglMustCastToProperFunctionPointerType)&eglGetNextFrameIdANDROID },
  204. { "eglGetCompositorTimingANDROID",
  205. (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingANDROID },
  206. { "eglGetCompositorTimingSupportedANDROID",
  207. (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingSupportedANDROID },
  208. { "eglGetFrameTimestampsANDROID",
  209. (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
  210. { "eglGetFrameTimestampSupportedANDROID",
  211. (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
  212. // EGL_ANDROID_native_fence_sync
  213. { "eglDupNativeFenceFDANDROID",
  214. (__eglMustCastToProperFunctionPointerType)&eglDupNativeFenceFDANDROID },
  215. };
  216. /*
  217. * These extensions entry-points should not be exposed to applications.
  218. * They're used internally by the Android EGL layer.
  219. */
  220. #define FILTER_EXTENSIONS(procname) \
  221. (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") || \
  222. !strcmp((procname), "eglHibernateProcessIMG") || \
  223. !strcmp((procname), "eglAwakenProcessIMG"))
  224. // accesses protected by sExtensionMapMutex
  225. static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtensionMap;
  226. static std::unordered_map<std::string, int> sGLExtensionSlotMap;
  227. static int sGLExtensionSlot = 0;
  228. static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
  229. static void(*findProcAddress(const char* name,
  230. const extension_map_t* map, size_t n))() {
  231. for (uint32_t i=0 ; i<n ; i++) {
  232. if (!strcmp(name, map[i].name)) {
  233. return map[i].address;
  234. }
  235. }
  236. return nullptr;
  237. }
  238. // ----------------------------------------------------------------------------
  239. extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
  240. extern EGLBoolean egl_init_drivers();
  241. extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
  242. extern gl_hooks_t gHooksTrace;
  243. // ----------------------------------------------------------------------------
  244. static inline EGLContext getContext() { return egl_tls_t::getContext(); }
  245. // ----------------------------------------------------------------------------
  246. static EGLDisplay eglGetPlatformDisplayTmpl(EGLenum platform, EGLNativeDisplayType display,
  247. const EGLAttrib* attrib_list) {
  248. if (platform != EGL_PLATFORM_ANDROID_KHR) {
  249. return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
  250. }
  251. uintptr_t index = reinterpret_cast<uintptr_t>(display);
  252. if (index >= NUM_DISPLAYS) {
  253. return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
  254. }
  255. EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display, attrib_list);
  256. return dpy;
  257. }
  258. EGLDisplay eglGetDisplayImpl(EGLNativeDisplayType display) {
  259. return eglGetPlatformDisplayTmpl(EGL_PLATFORM_ANDROID_KHR, display, nullptr);
  260. }
  261. EGLDisplay eglGetPlatformDisplayImpl(EGLenum platform, void* native_display,
  262. const EGLAttrib* attrib_list) {
  263. return eglGetPlatformDisplayTmpl(platform, static_cast<EGLNativeDisplayType>(native_display),
  264. attrib_list);
  265. }
  266. // ----------------------------------------------------------------------------
  267. // Initialization
  268. // ----------------------------------------------------------------------------
  269. EGLBoolean eglInitializeImpl(EGLDisplay dpy, EGLint *major, EGLint *minor)
  270. {
  271. egl_display_ptr dp = get_display(dpy);
  272. if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  273. EGLBoolean res = dp->initialize(major, minor);
  274. return res;
  275. }
  276. EGLBoolean eglTerminateImpl(EGLDisplay dpy)
  277. {
  278. // NOTE: don't unload the drivers b/c some APIs can be called
  279. // after eglTerminate() has been called. eglTerminate() only
  280. // terminates an EGLDisplay, not a EGL itself.
  281. egl_display_ptr dp = get_display(dpy);
  282. if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  283. EGLBoolean res = dp->terminate();
  284. return res;
  285. }
  286. // ----------------------------------------------------------------------------
  287. // configuration
  288. // ----------------------------------------------------------------------------
  289. EGLBoolean eglGetConfigsImpl(EGLDisplay dpy,
  290. EGLConfig *configs,
  291. EGLint config_size, EGLint *num_config)
  292. {
  293. const egl_display_ptr dp = validate_display(dpy);
  294. if (!dp) return EGL_FALSE;
  295. if (num_config==nullptr) {
  296. return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
  297. }
  298. EGLBoolean res = EGL_FALSE;
  299. *num_config = 0;
  300. egl_connection_t* const cnx = &gEGLImpl;
  301. if (cnx->dso) {
  302. res = cnx->egl.eglGetConfigs(
  303. dp->disp.dpy, configs, config_size, num_config);
  304. }
  305. return res;
  306. }
  307. EGLBoolean eglChooseConfigImpl( EGLDisplay dpy, const EGLint *attrib_list,
  308. EGLConfig *configs, EGLint config_size,
  309. EGLint *num_config)
  310. {
  311. const egl_display_ptr dp = validate_display(dpy);
  312. if (!dp) return EGL_FALSE;
  313. if (num_config==nullptr) {
  314. return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
  315. }
  316. EGLBoolean res = EGL_FALSE;
  317. *num_config = 0;
  318. egl_connection_t* const cnx = &gEGLImpl;
  319. if (cnx->dso) {
  320. if (attrib_list) {
  321. char value[PROPERTY_VALUE_MAX];
  322. property_get("debug.egl.force_msaa", value, "false");
  323. if (!strcmp(value, "true")) {
  324. size_t attribCount = 0;
  325. EGLint attrib = attrib_list[0];
  326. // Only enable MSAA if the context is OpenGL ES 2.0 and
  327. // if no caveat is requested
  328. const EGLint *attribRendererable = nullptr;
  329. const EGLint *attribCaveat = nullptr;
  330. // Count the number of attributes and look for
  331. // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
  332. while (attrib != EGL_NONE) {
  333. attrib = attrib_list[attribCount];
  334. switch (attrib) {
  335. case EGL_RENDERABLE_TYPE:
  336. attribRendererable = &attrib_list[attribCount];
  337. break;
  338. case EGL_CONFIG_CAVEAT:
  339. attribCaveat = &attrib_list[attribCount];
  340. break;
  341. default:
  342. break;
  343. }
  344. attribCount++;
  345. }
  346. if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
  347. (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
  348. // Insert 2 extra attributes to force-enable MSAA 4x
  349. EGLint aaAttribs[attribCount + 4];
  350. aaAttribs[0] = EGL_SAMPLE_BUFFERS;
  351. aaAttribs[1] = 1;
  352. aaAttribs[2] = EGL_SAMPLES;
  353. aaAttribs[3] = 4;
  354. memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
  355. EGLint numConfigAA;
  356. EGLBoolean resAA = cnx->egl.eglChooseConfig(
  357. dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
  358. if (resAA == EGL_TRUE && numConfigAA > 0) {
  359. ALOGD("Enabling MSAA 4x");
  360. *num_config = numConfigAA;
  361. return resAA;
  362. }
  363. }
  364. }
  365. }
  366. res = cnx->egl.eglChooseConfig(
  367. dp->disp.dpy, attrib_list, configs, config_size, num_config);
  368. }
  369. return res;
  370. }
  371. EGLBoolean eglGetConfigAttribImpl(EGLDisplay dpy, EGLConfig config,
  372. EGLint attribute, EGLint *value)
  373. {
  374. egl_connection_t* cnx = nullptr;
  375. const egl_display_ptr dp = validate_display_connection(dpy, cnx);
  376. if (!dp) return EGL_FALSE;
  377. return cnx->egl.eglGetConfigAttrib(
  378. dp->disp.dpy, config, attribute, value);
  379. }
  380. // ----------------------------------------------------------------------------
  381. // surfaces
  382. // ----------------------------------------------------------------------------
  383. // Translates EGL color spaces to Android data spaces.
  384. static android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace) {
  385. if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
  386. return HAL_DATASPACE_UNKNOWN;
  387. } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
  388. return HAL_DATASPACE_V0_SRGB;
  389. } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
  390. return HAL_DATASPACE_DISPLAY_P3;
  391. } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT) {
  392. return HAL_DATASPACE_DISPLAY_P3_LINEAR;
  393. } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT) {
  394. return HAL_DATASPACE_DISPLAY_P3;
  395. } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_EXT) {
  396. return HAL_DATASPACE_V0_SCRGB;
  397. } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
  398. return HAL_DATASPACE_V0_SCRGB_LINEAR;
  399. } else if (colorspace == EGL_GL_COLORSPACE_BT2020_LINEAR_EXT) {
  400. return HAL_DATASPACE_BT2020_LINEAR;
  401. } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
  402. return HAL_DATASPACE_BT2020_PQ;
  403. }
  404. return HAL_DATASPACE_UNKNOWN;
  405. }
  406. // Get the colorspace value that should be reported from queries. When the colorspace
  407. // is unknown (no attribute passed), default to reporting LINEAR.
  408. static EGLint getReportedColorSpace(EGLint colorspace) {
  409. return colorspace == EGL_UNKNOWN ? EGL_GL_COLORSPACE_LINEAR_KHR : colorspace;
  410. }
  411. // Returns a list of color spaces understood by the vendor EGL driver.
  412. static std::vector<EGLint> getDriverColorSpaces(egl_display_ptr dp) {
  413. std::vector<EGLint> colorSpaces;
  414. // sRGB and linear are always supported when color space support is present.
  415. colorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
  416. colorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
  417. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_display_p3")) {
  418. colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
  419. }
  420. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_scrgb")) {
  421. colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_EXT);
  422. }
  423. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_scrgb_linear")) {
  424. colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
  425. }
  426. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_bt2020_linear")) {
  427. colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
  428. }
  429. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_bt2020_pq")) {
  430. colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
  431. }
  432. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_display_p3_linear")) {
  433. colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
  434. }
  435. if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_display_p3_passthrough")) {
  436. colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT);
  437. }
  438. return colorSpaces;
  439. }
  440. // Cleans up color space related parameters that the driver does not understand.
  441. // If there is no color space attribute in attrib_list, colorSpace is left
  442. // unmodified.
  443. template <typename AttrType>
  444. static EGLBoolean processAttributes(egl_display_ptr dp, ANativeWindow* window,
  445. const AttrType* attrib_list, EGLint* colorSpace,
  446. std::vector<AttrType>* strippedAttribList) {
  447. for (const AttrType* attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
  448. bool copyAttribute = true;
  449. if (attr[0] == EGL_GL_COLORSPACE_KHR) {
  450. switch (attr[1]) {
  451. case EGL_GL_COLORSPACE_LINEAR_KHR:
  452. case EGL_GL_COLORSPACE_SRGB_KHR:
  453. case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
  454. case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:
  455. case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
  456. case EGL_GL_COLORSPACE_SCRGB_EXT:
  457. case EGL_GL_COLORSPACE_BT2020_LINEAR_EXT:
  458. case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
  459. case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:
  460. // Fail immediately if the driver doesn't have color space support at all.
  461. if (!dp->hasColorSpaceSupport) return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
  462. break;
  463. default:
  464. // BAD_ATTRIBUTE if attr is not any of the EGL_GL_COLORSPACE_*
  465. return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
  466. }
  467. *colorSpace = static_cast<EGLint>(attr[1]);
  468. // Strip the attribute if the driver doesn't understand it.
  469. copyAttribute = false;
  470. std::vector<EGLint> driverColorSpaces = getDriverColorSpaces(dp);
  471. for (auto driverColorSpace : driverColorSpaces) {
  472. if (static_cast<EGLint>(attr[1]) == driverColorSpace) {
  473. copyAttribute = true;
  474. break;
  475. }
  476. }
  477. // If the driver doesn't understand it, we should map sRGB-encoded P3 to
  478. // sRGB rather than just dropping the colorspace on the floor.
  479. // For this format, the driver is expected to apply the sRGB
  480. // transfer function during framebuffer operations.
  481. if (!copyAttribute && attr[1] == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
  482. strippedAttribList->push_back(attr[0]);
  483. strippedAttribList->push_back(EGL_GL_COLORSPACE_SRGB_KHR);
  484. }
  485. }
  486. if (copyAttribute) {
  487. strippedAttribList->push_back(attr[0]);
  488. strippedAttribList->push_back(attr[1]);
  489. }
  490. }
  491. // Terminate the attribute list.
  492. strippedAttribList->push_back(EGL_NONE);
  493. // If the passed color space has wide color gamut, check whether the target native window
  494. // supports wide color.
  495. const bool colorSpaceIsNarrow = *colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
  496. *colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR || *colorSpace == EGL_UNKNOWN;
  497. if (window && !colorSpaceIsNarrow) {
  498. bool windowSupportsWideColor = true;
  499. // Ordinarily we'd put a call to native_window_get_wide_color_support
  500. // at the beginning of the function so that we'll have the
  501. // result when needed elsewhere in the function.
  502. // However, because eglCreateWindowSurface is called by SurfaceFlinger and
  503. // SurfaceFlinger is required to answer the call below we would
  504. // end up in a deadlock situation. By moving the call to only happen
  505. // if the application has specifically asked for wide-color we avoid
  506. // the deadlock with SurfaceFlinger since it will not ask for a
  507. // wide-color surface.
  508. int err = native_window_get_wide_color_support(window, &windowSupportsWideColor);
  509. if (err) {
  510. ALOGE("processAttributes: invalid window (win=%p) "
  511. "failed (%#x) (already connected to another API?)",
  512. window, err);
  513. return setError(EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
  514. }
  515. if (!windowSupportsWideColor) {
  516. // Application has asked for a wide-color colorspace but
  517. // wide-color support isn't available on the display the window is on.
  518. return setError(EGL_BAD_MATCH, EGL_FALSE);
  519. }
  520. }
  521. return true;
  522. }
  523. // Note: This only works for existing GLenum's that are all 32bits.
  524. // If you have 64bit attributes (e.g. pointers) you shouldn't be calling this.
  525. void convertAttribs(const EGLAttrib* attribList, std::vector<EGLint>& newList) {
  526. for (const EGLAttrib* attr = attribList; attr && attr[0] != EGL_NONE; attr += 2) {
  527. newList.push_back(static_cast<EGLint>(attr[0]));
  528. newList.push_back(static_cast<EGLint>(attr[1]));
  529. }
  530. newList.push_back(EGL_NONE);
  531. }
  532. // Gets the native pixel format corrsponding to the passed EGLConfig.
  533. void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
  534. android_pixel_format* format) {
  535. // Set the native window's buffers format to match what this config requests.
  536. // Whether to use sRGB gamma is not part of the EGLconfig, but is part
  537. // of our native format. So if sRGB gamma is requested, we have to
  538. // modify the EGLconfig's format before setting the native window's
  539. // format.
  540. EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
  541. cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType);
  542. EGLint a = 0;
  543. EGLint r, g, b;
  544. r = g = b = 0;
  545. cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r);
  546. cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
  547. cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b);
  548. cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
  549. EGLint colorDepth = r + g + b;
  550. // Today, the driver only understands sRGB and linear on 888X
  551. // formats. Strip other colorspaces from the attribute list and
  552. // only use them to set the dataspace via
  553. // native_window_set_buffers_dataspace
  554. // if pixel format is RGBX 8888
  555. // TBD: Can test for future extensions that indicate that driver
  556. // handles requested color space and we can let it through.
  557. // allow SRGB and LINEAR. All others need to be stripped.
  558. // else if 565, 4444
  559. // TBD: Can we assume these are supported if 8888 is?
  560. // else if FP16 or 1010102
  561. // strip colorspace from attribs.
  562. // endif
  563. if (a == 0) {
  564. if (colorDepth <= 16) {
  565. *format = HAL_PIXEL_FORMAT_RGB_565;
  566. } else {
  567. if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
  568. if (colorDepth > 24) {
  569. *format = HAL_PIXEL_FORMAT_RGBA_1010102;
  570. } else {
  571. *format = HAL_PIXEL_FORMAT_RGBX_8888;
  572. }
  573. } else {
  574. *format = HAL_PIXEL_FORMAT_RGBA_FP16;
  575. }
  576. }
  577. } else {
  578. if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
  579. if (colorDepth > 24) {
  580. *format = HAL_PIXEL_FORMAT_RGBA_1010102;
  581. } else {
  582. *format = HAL_PIXEL_FORMAT_RGBA_8888;
  583. }
  584. } else {
  585. *format = HAL_PIXEL_FORMAT_RGBA_FP16;
  586. }
  587. }
  588. }
  589. EGLBoolean sendSurfaceMetadata(egl_surface_t* s) {
  590. android_smpte2086_metadata smpteMetadata;
  591. if (s->getSmpte2086Metadata(smpteMetadata)) {
  592. int err =
  593. native_window_set_buffers_smpte2086_metadata(s->getNativeWindow(), &smpteMetadata);
  594. s->resetSmpte2086Metadata();
  595. if (err != 0) {
  596. ALOGE("error setting native window smpte2086 metadata: %s (%d)", strerror(-err), err);
  597. return EGL_FALSE;
  598. }
  599. }
  600. android_cta861_3_metadata cta8613Metadata;
  601. if (s->getCta8613Metadata(cta8613Metadata)) {
  602. int err =
  603. native_window_set_buffers_cta861_3_metadata(s->getNativeWindow(), &cta8613Metadata);
  604. s->resetCta8613Metadata();
  605. if (err != 0) {
  606. ALOGE("error setting native window CTS 861.3 metadata: %s (%d)", strerror(-err), err);
  607. return EGL_FALSE;
  608. }
  609. }
  610. return EGL_TRUE;
  611. }
  612. template <typename AttrType, typename CreateFuncType>
  613. EGLSurface eglCreateWindowSurfaceTmpl(egl_display_ptr dp, egl_connection_t* cnx, EGLConfig config,
  614. ANativeWindow* window, const AttrType* attrib_list,
  615. CreateFuncType createWindowSurfaceFunc) {
  616. const AttrType* origAttribList = attrib_list;
  617. if (!window) {
  618. return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  619. }
  620. int value = 0;
  621. window->query(window, NATIVE_WINDOW_IS_VALID, &value);
  622. if (!value) {
  623. return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  624. }
  625. // NOTE: When using Vulkan backend, the Vulkan runtime makes all the
  626. // native_window_* calls, so don't do them here.
  627. if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
  628. int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
  629. if (result < 0) {
  630. ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
  631. "failed (%#x) (already connected to another API?)",
  632. window, result);
  633. return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
  634. }
  635. }
  636. EGLDisplay iDpy = dp->disp.dpy;
  637. android_pixel_format format;
  638. getNativePixelFormat(iDpy, cnx, config, &format);
  639. // now select correct colorspace and dataspace based on user's attribute list
  640. EGLint colorSpace = EGL_UNKNOWN;
  641. std::vector<AttrType> strippedAttribList;
  642. if (!processAttributes<AttrType>(dp, window, attrib_list, &colorSpace, &strippedAttribList)) {
  643. ALOGE("error invalid colorspace: %d", colorSpace);
  644. if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
  645. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  646. }
  647. return EGL_NO_SURFACE;
  648. }
  649. attrib_list = strippedAttribList.data();
  650. if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
  651. int err = native_window_set_buffers_format(window, format);
  652. if (err != 0) {
  653. ALOGE("error setting native window pixel format: %s (%d)", strerror(-err), err);
  654. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  655. return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  656. }
  657. android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
  658. // Set dataSpace even if it could be HAL_DATASPACE_UNKNOWN.
  659. // HAL_DATASPACE_UNKNOWN is the default value, but it may have changed
  660. // at this point.
  661. err = native_window_set_buffers_data_space(window, dataSpace);
  662. if (err != 0) {
  663. ALOGE("error setting native window pixel dataSpace: %s (%d)", strerror(-err), err);
  664. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  665. return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  666. }
  667. }
  668. // the EGL spec requires that a new EGLSurface default to swap interval
  669. // 1, so explicitly set that on the window here.
  670. window->setSwapInterval(window, 1);
  671. EGLSurface surface = createWindowSurfaceFunc(iDpy, config, window, attrib_list);
  672. if (surface != EGL_NO_SURFACE) {
  673. egl_surface_t* s = new egl_surface_t(dp.get(), config, window, surface,
  674. getReportedColorSpace(colorSpace), cnx);
  675. return s;
  676. }
  677. // EGLSurface creation failed
  678. if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
  679. native_window_set_buffers_format(window, 0);
  680. native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
  681. }
  682. return EGL_NO_SURFACE;
  683. }
  684. typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config,
  685. NativeWindowType window,
  686. const EGLint* attrib_list);
  687. typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(
  688. EGLDisplay dpy, EGLConfig config, void* native_window, const EGLAttrib* attrib_list);
  689. EGLSurface eglCreateWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, NativeWindowType window,
  690. const EGLint* attrib_list) {
  691. egl_connection_t* cnx = NULL;
  692. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  693. if (dp) {
  694. return eglCreateWindowSurfaceTmpl<
  695. EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config, window, attrib_list,
  696. cnx->egl.eglCreateWindowSurface);
  697. }
  698. return EGL_NO_SURFACE;
  699. }
  700. EGLSurface eglCreatePlatformWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, void* native_window,
  701. const EGLAttrib* attrib_list) {
  702. egl_connection_t* cnx = NULL;
  703. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  704. if (dp) {
  705. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  706. if (cnx->egl.eglCreatePlatformWindowSurface) {
  707. return eglCreateWindowSurfaceTmpl<EGLAttrib, PFNEGLCREATEPLATFORMWINDOWSURFACEPROC>(
  708. dp, cnx, config, static_cast<ANativeWindow*>(native_window), attrib_list,
  709. cnx->egl.eglCreatePlatformWindowSurface);
  710. }
  711. // driver doesn't support native function, return EGL_BAD_DISPLAY
  712. ALOGE("Driver indicates EGL 1.5 support, but does not have "
  713. "eglCreatePlatformWindowSurface");
  714. return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
  715. }
  716. std::vector<EGLint> convertedAttribs;
  717. convertAttribs(attrib_list, convertedAttribs);
  718. if (cnx->egl.eglCreatePlatformWindowSurfaceEXT) {
  719. return eglCreateWindowSurfaceTmpl<EGLint, PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>(
  720. dp, cnx, config, static_cast<ANativeWindow*>(native_window),
  721. convertedAttribs.data(), cnx->egl.eglCreatePlatformWindowSurfaceEXT);
  722. } else {
  723. return eglCreateWindowSurfaceTmpl<
  724. EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config,
  725. static_cast<ANativeWindow*>(
  726. native_window),
  727. convertedAttribs.data(),
  728. cnx->egl.eglCreateWindowSurface);
  729. }
  730. }
  731. return EGL_NO_SURFACE;
  732. }
  733. EGLSurface eglCreatePlatformPixmapSurfaceImpl(EGLDisplay dpy, EGLConfig /*config*/,
  734. void* /*native_pixmap*/,
  735. const EGLAttrib* /*attrib_list*/) {
  736. // Per EGL_KHR_platform_android:
  737. // It is not valid to call eglCreatePlatformPixmapSurface with a <dpy> that
  738. // belongs to the Android platform. Any such call fails and generates
  739. // an EGL_BAD_PARAMETER error.
  740. egl_connection_t* cnx = NULL;
  741. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  742. if (dp) {
  743. return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
  744. }
  745. return EGL_NO_SURFACE;
  746. }
  747. EGLSurface eglCreatePixmapSurfaceImpl(EGLDisplay dpy, EGLConfig /*config*/,
  748. NativePixmapType /*pixmap*/, const EGLint* /*attrib_list*/) {
  749. egl_connection_t* cnx = nullptr;
  750. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  751. if (dp) {
  752. return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
  753. }
  754. return EGL_NO_SURFACE;
  755. }
  756. EGLSurface eglCreatePbufferSurfaceImpl(EGLDisplay dpy, EGLConfig config,
  757. const EGLint* attrib_list) {
  758. egl_connection_t* cnx = nullptr;
  759. egl_display_ptr dp = validate_display_connection(dpy, cnx);
  760. if (dp) {
  761. EGLDisplay iDpy = dp->disp.dpy;
  762. android_pixel_format format;
  763. getNativePixelFormat(iDpy, cnx, config, &format);
  764. // Select correct colorspace based on user's attribute list
  765. EGLint colorSpace = EGL_UNKNOWN;
  766. std::vector<EGLint> strippedAttribList;
  767. if (!processAttributes(dp, nullptr, attrib_list, &colorSpace, &strippedAttribList)) {
  768. ALOGE("error invalid colorspace: %d", colorSpace);
  769. return EGL_NO_SURFACE;
  770. }
  771. attrib_list = strippedAttribList.data();
  772. EGLSurface surface = cnx->egl.eglCreatePbufferSurface(dp->disp.dpy, config, attrib_list);
  773. if (surface != EGL_NO_SURFACE) {
  774. egl_surface_t* s = new egl_surface_t(dp.get(), config, nullptr, surface,
  775. getReportedColorSpace(colorSpace), cnx);
  776. return s;
  777. }
  778. }
  779. return EGL_NO_SURFACE;
  780. }
  781. EGLBoolean eglDestroySurfaceImpl(EGLDisplay dpy, EGLSurface surface) {
  782. const egl_display_ptr dp = validate_display(dpy);
  783. if (!dp) return EGL_FALSE;
  784. SurfaceRef _s(dp.get(), surface);
  785. if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  786. egl_surface_t* const s = get_surface(surface);
  787. EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
  788. if (result == EGL_TRUE) {
  789. _s.terminate();
  790. }
  791. return result;
  792. }
  793. EGLBoolean eglQuerySurfaceImpl(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
  794. EGLint* value) {
  795. const egl_display_ptr dp = validate_display(dpy);
  796. if (!dp) return EGL_FALSE;
  797. SurfaceRef _s(dp.get(), surface);
  798. if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  799. egl_surface_t const* const s = get_surface(surface);
  800. if (s->getColorSpaceAttribute(attribute, value)) {
  801. return EGL_TRUE;
  802. } else if (s->getSmpte2086Attribute(attribute, value)) {
  803. return EGL_TRUE;
  804. } else if (s->getCta8613Attribute(attribute, value)) {
  805. return EGL_TRUE;
  806. }
  807. return s->cnx->egl.eglQuerySurface(dp->disp.dpy, s->surface, attribute, value);
  808. }
  809. void EGLAPI eglBeginFrameImpl(EGLDisplay dpy, EGLSurface surface) {
  810. const egl_display_ptr dp = validate_display(dpy);
  811. if (!dp) {
  812. return;
  813. }
  814. SurfaceRef _s(dp.get(), surface);
  815. if (!_s.get()) {
  816. setError(EGL_BAD_SURFACE, EGL_FALSE);
  817. }
  818. }
  819. // ----------------------------------------------------------------------------
  820. // Contexts
  821. // ----------------------------------------------------------------------------
  822. EGLContext eglCreateContextImpl(EGLDisplay dpy, EGLConfig config,
  823. EGLContext share_list, const EGLint *attrib_list)
  824. {
  825. egl_connection_t* cnx = nullptr;
  826. const egl_display_ptr dp = validate_display_connection(dpy, cnx);
  827. if (dp) {
  828. if (share_list != EGL_NO_CONTEXT) {
  829. if (!ContextRef(dp.get(), share_list).get()) {
  830. return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
  831. }
  832. egl_context_t* const c = get_context(share_list);
  833. share_list = c->context;
  834. }
  835. // b/111083885 - If we are presenting EGL 1.4 interface to apps
  836. // error out on robust access attributes that are invalid
  837. // in EGL 1.4 as the driver may be fine with them but dEQP expects
  838. // tests to fail according to spec.
  839. if (attrib_list && (cnx->driverVersion < EGL_MAKE_VERSION(1, 5, 0))) {
  840. const EGLint* attrib_ptr = attrib_list;
  841. while (*attrib_ptr != EGL_NONE) {
  842. GLint attr = *attrib_ptr++;
  843. GLint value = *attrib_ptr++;
  844. if (attr == EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR) {
  845. // We are GL ES context with EGL 1.4, this is an invalid
  846. // attribute
  847. return setError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
  848. }
  849. };
  850. }
  851. EGLContext context = cnx->egl.eglCreateContext(
  852. dp->disp.dpy, config, share_list, attrib_list);
  853. if (context != EGL_NO_CONTEXT) {
  854. // figure out if it's a GLESv1 or GLESv2
  855. int version = 0;
  856. if (attrib_list) {
  857. while (*attrib_list != EGL_NONE) {
  858. GLint attr = *attrib_list++;
  859. GLint value = *attrib_list++;
  860. if (attr == EGL_CONTEXT_CLIENT_VERSION) {
  861. if (value == 1) {
  862. version = egl_connection_t::GLESv1_INDEX;
  863. } else if (value == 2 || value == 3) {
  864. version = egl_connection_t::GLESv2_INDEX;
  865. }
  866. }
  867. };
  868. }
  869. egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
  870. version);
  871. return c;
  872. }
  873. }
  874. return EGL_NO_CONTEXT;
  875. }
  876. EGLBoolean eglDestroyContextImpl(EGLDisplay dpy, EGLContext ctx)
  877. {
  878. const egl_display_ptr dp = validate_display(dpy);
  879. if (!dp)
  880. return EGL_FALSE;
  881. ContextRef _c(dp.get(), ctx);
  882. if (!_c.get())
  883. return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
  884. egl_context_t * const c = get_context(ctx);
  885. EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
  886. if (result == EGL_TRUE) {
  887. _c.terminate();
  888. }
  889. return result;
  890. }
  891. EGLBoolean eglMakeCurrentImpl( EGLDisplay dpy, EGLSurface draw,
  892. EGLSurface read, EGLContext ctx)
  893. {
  894. egl_display_ptr dp = validate_display(dpy);
  895. if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  896. // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
  897. // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
  898. // a valid but uninitialized display.
  899. if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
  900. (draw != EGL_NO_SURFACE) ) {
  901. if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
  902. }
  903. // get a reference to the object passed in
  904. ContextRef _c(dp.get(), ctx);
  905. SurfaceRef _d(dp.get(), draw);
  906. SurfaceRef _r(dp.get(), read);
  907. // validate the context (if not EGL_NO_CONTEXT)
  908. if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
  909. // EGL_NO_CONTEXT is valid
  910. return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
  911. }
  912. // these are the underlying implementation's object
  913. EGLContext impl_ctx = EGL_NO_CONTEXT;
  914. EGLSurface impl_draw = EGL_NO_SURFACE;
  915. EGLSurface impl_read = EGL_NO_SURFACE;
  916. // these are our objects structs passed in
  917. egl_context_t * c = nullptr;
  918. egl_surface_t const * d = nullptr;
  919. egl_surface_t const * r = nullptr;
  920. // these are the current objects structs
  921. egl_context_t * cur_c = get_context(getContext());
  922. if (ctx != EGL_NO_CONTEXT) {
  923. c = get_context(ctx);
  924. impl_ctx = c->context;
  925. } else {
  926. // no context given, use the implementation of the current context
  927. if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
  928. // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
  929. return setError(EGL_BAD_MATCH, (EGLBoolean)EGL_FALSE);
  930. }
  931. if (cur_c == nullptr) {
  932. // no current context
  933. // not an error, there is just no current context.
  934. return EGL_TRUE;
  935. }
  936. }
  937. // retrieve the underlying implementation's draw EGLSurface
  938. if (draw != EGL_NO_SURFACE) {
  939. if (!_d.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  940. d = get_surface(draw);
  941. impl_draw = d->surface;
  942. }
  943. // retrieve the underlying implementation's read EGLSurface
  944. if (read != EGL_NO_SURFACE) {
  945. if (!_r.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  946. r = get_surface(read);
  947. impl_read = r->surface;
  948. }
  949. EGLBoolean result = dp->makeCurrent(c, cur_c,
  950. draw, read, ctx,
  951. impl_draw, impl_read, impl_ctx);
  952. if (result == EGL_TRUE) {
  953. if (c) {
  954. setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
  955. egl_tls_t::setContext(ctx);
  956. _c.acquire();
  957. _r.acquire();
  958. _d.acquire();
  959. } else {
  960. setGLHooksThreadSpecific(&gHooksNoContext);
  961. egl_tls_t::setContext(EGL_NO_CONTEXT);
  962. }
  963. } else {
  964. // this will ALOGE the error
  965. egl_connection_t* const cnx = &gEGLImpl;
  966. result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
  967. }
  968. return result;
  969. }
  970. EGLBoolean eglQueryContextImpl( EGLDisplay dpy, EGLContext ctx,
  971. EGLint attribute, EGLint *value)
  972. {
  973. const egl_display_ptr dp = validate_display(dpy);
  974. if (!dp) return EGL_FALSE;
  975. ContextRef _c(dp.get(), ctx);
  976. if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
  977. egl_context_t * const c = get_context(ctx);
  978. return c->cnx->egl.eglQueryContext(
  979. dp->disp.dpy, c->context, attribute, value);
  980. }
  981. EGLContext eglGetCurrentContextImpl(void)
  982. {
  983. // could be called before eglInitialize(), but we wouldn't have a context
  984. // then, and this function would correctly return EGL_NO_CONTEXT.
  985. EGLContext ctx = getContext();
  986. return ctx;
  987. }
  988. EGLSurface eglGetCurrentSurfaceImpl(EGLint readdraw)
  989. {
  990. // could be called before eglInitialize(), but we wouldn't have a context
  991. // then, and this function would correctly return EGL_NO_SURFACE.
  992. EGLContext ctx = getContext();
  993. if (ctx) {
  994. egl_context_t const * const c = get_context(ctx);
  995. if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
  996. switch (readdraw) {
  997. case EGL_READ: return c->read;
  998. case EGL_DRAW: return c->draw;
  999. default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
  1000. }
  1001. }
  1002. return EGL_NO_SURFACE;
  1003. }
  1004. EGLDisplay eglGetCurrentDisplayImpl(void)
  1005. {
  1006. // could be called before eglInitialize(), but we wouldn't have a context
  1007. // then, and this function would correctly return EGL_NO_DISPLAY.
  1008. EGLContext ctx = getContext();
  1009. if (ctx) {
  1010. egl_context_t const * const c = get_context(ctx);
  1011. if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
  1012. return c->dpy;
  1013. }
  1014. return EGL_NO_DISPLAY;
  1015. }
  1016. EGLBoolean eglWaitGLImpl(void)
  1017. {
  1018. egl_connection_t* const cnx = &gEGLImpl;
  1019. if (!cnx->dso)
  1020. return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
  1021. return cnx->egl.eglWaitGL();
  1022. }
  1023. EGLBoolean eglWaitNativeImpl(EGLint engine)
  1024. {
  1025. egl_connection_t* const cnx = &gEGLImpl;
  1026. if (!cnx->dso)
  1027. return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
  1028. return cnx->egl.eglWaitNative(engine);
  1029. }
  1030. EGLint eglGetErrorImpl(void)
  1031. {
  1032. EGLint err = EGL_SUCCESS;
  1033. egl_connection_t* const cnx = &gEGLImpl;
  1034. if (cnx->dso) {
  1035. err = cnx->egl.eglGetError();
  1036. }
  1037. if (err == EGL_SUCCESS) {
  1038. err = egl_tls_t::getError();
  1039. }
  1040. return err;
  1041. }
  1042. static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
  1043. const char* procname) {
  1044. const egl_connection_t* cnx = &gEGLImpl;
  1045. void* proc = nullptr;
  1046. proc = dlsym(cnx->libEgl, procname);
  1047. if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
  1048. proc = dlsym(cnx->libGles2, procname);
  1049. if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
  1050. proc = dlsym(cnx->libGles1, procname);
  1051. if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
  1052. return nullptr;
  1053. }
  1054. __eglMustCastToProperFunctionPointerType eglGetProcAddressImpl(const char *procname)
  1055. {
  1056. if (FILTER_EXTENSIONS(procname)) {
  1057. return nullptr;
  1058. }
  1059. __eglMustCastToProperFunctionPointerType addr;
  1060. addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
  1061. if (addr) return addr;
  1062. addr = findBuiltinWrapper(procname);
  1063. if (addr) return addr;
  1064. // this protects accesses to sGLExtensionMap, sGLExtensionSlot, and sGLExtensionSlotMap
  1065. pthread_mutex_lock(&sExtensionMapMutex);
  1066. /*
  1067. * Since eglGetProcAddress() is not associated to anything, it needs
  1068. * to return a function pointer that "works" regardless of what
  1069. * the current context is.
  1070. *
  1071. * For this reason, we return a "forwarder", a small stub that takes
  1072. * care of calling the function associated with the context
  1073. * currently bound.
  1074. *
  1075. * We first look for extensions we've already resolved, if we're seeing
  1076. * this extension for the first time, we go through all our
  1077. * implementations and call eglGetProcAddress() and record the
  1078. * result in the appropriate implementation hooks and return the
  1079. * address of the forwarder corresponding to that hook set.
  1080. *
  1081. */
  1082. const std::string name(procname);
  1083. auto& extensionMap = sGLExtensionMap;
  1084. auto& extensionSlotMap = sGLExtensionSlotMap;
  1085. egl_connection_t* const cnx = &gEGLImpl;
  1086. LayerLoader& layer_loader(LayerLoader::getInstance());
  1087. // See if we've already looked up this extension
  1088. auto pos = extensionMap.find(name);
  1089. addr = (pos != extensionMap.end()) ? pos->second : nullptr;
  1090. if (!addr) {
  1091. // This is the first time we've looked this function up
  1092. // Ensure we have room to track it
  1093. const int slot = sGLExtensionSlot;
  1094. if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) {
  1095. if (cnx->dso && cnx->egl.eglGetProcAddress) {
  1096. // Extensions are independent of the bound context
  1097. addr = cnx->egl.eglGetProcAddress(procname);
  1098. if (addr) {
  1099. // purposefully track the bottom of the stack in extensionMap
  1100. extensionMap[name] = addr;
  1101. // Apply layers
  1102. addr = layer_loader.ApplyLayers(procname, addr);
  1103. // Track the top most entry point return the extension forwarder
  1104. cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
  1105. cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr;
  1106. addr = gExtensionForwarders[slot];
  1107. // Remember the slot for this extension
  1108. extensionSlotMap[name] = slot;
  1109. // Increment the global extension index
  1110. sGLExtensionSlot++;
  1111. }
  1112. }
  1113. } else {
  1114. // The extension forwarder has a fixed number of slots
  1115. ALOGE("no more slots for eglGetProcAddress(\"%s\")", procname);
  1116. }
  1117. } else {
  1118. // We tracked an address, so we've seen this func before
  1119. // Look up the slot for this extension
  1120. auto slot_pos = extensionSlotMap.find(name);
  1121. int ext_slot = (slot_pos != extensionSlotMap.end()) ? slot_pos->second : -1;
  1122. if (ext_slot < 0) {
  1123. // Something has gone wrong, this should not happen
  1124. ALOGE("No extension slot found for %s", procname);
  1125. return nullptr;
  1126. }
  1127. // We tracked the bottom of the stack, so re-apply layers since
  1128. // more layers might have been enabled
  1129. addr = layer_loader.ApplyLayers(procname, addr);
  1130. // Track the top most entry point and return the extension forwarder
  1131. cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[ext_slot] =
  1132. cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[ext_slot] = addr;
  1133. addr = gExtensionForwarders[ext_slot];
  1134. }
  1135. pthread_mutex_unlock(&sExtensionMapMutex);
  1136. return addr;
  1137. }
  1138. class FrameCompletionThread {
  1139. public:
  1140. static void queueSync(EGLSyncKHR sync) {
  1141. static FrameCompletionThread thread;
  1142. char name[64];
  1143. std::lock_guard<std::mutex> lock(thread.mMutex);
  1144. snprintf(name, sizeof(name), "kicked off frame %u", (unsigned int)thread.mFramesQueued);
  1145. ATRACE_NAME(name);
  1146. thread.mQueue.push_back(sync);
  1147. thread.mCondition.notify_one();
  1148. thread.mFramesQueued++;
  1149. ATRACE_INT("GPU Frames Outstanding", int32_t(thread.mQueue.size()));
  1150. }
  1151. private:
  1152. FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {
  1153. std::thread thread(&FrameCompletionThread::loop, this);
  1154. thread.detach();
  1155. }
  1156. #pragma clang diagnostic push
  1157. #pragma clang diagnostic ignored "-Wmissing-noreturn"
  1158. void loop() {
  1159. while (true) {
  1160. threadLoop();
  1161. }
  1162. }
  1163. #pragma clang diagnostic pop
  1164. void threadLoop() {
  1165. EGLSyncKHR sync;
  1166. uint32_t frameNum;
  1167. {
  1168. std::unique_lock<std::mutex> lock(mMutex);
  1169. while (mQueue.empty()) {
  1170. mCondition.wait(lock);
  1171. }
  1172. sync = mQueue[0];
  1173. frameNum = mFramesCompleted;
  1174. }
  1175. EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  1176. {
  1177. char name[64];
  1178. snprintf(name, sizeof(name), "waiting for frame %u", (unsigned int)frameNum);
  1179. ATRACE_NAME(name);
  1180. EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
  1181. if (result == EGL_FALSE) {
  1182. ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
  1183. } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
  1184. ALOGE("FrameCompletion: timeout waiting for fence");
  1185. }
  1186. eglDestroySyncKHR(dpy, sync);
  1187. }
  1188. {
  1189. std::lock_guard<std::mutex> lock(mMutex);
  1190. mQueue.pop_front();
  1191. mFramesCompleted++;
  1192. ATRACE_INT("GPU Frames Outstanding", int32_t(mQueue.size()));
  1193. }
  1194. }
  1195. uint32_t mFramesQueued;
  1196. uint32_t mFramesCompleted;
  1197. std::deque<EGLSyncKHR> mQueue;
  1198. std::condition_variable mCondition;
  1199. std::mutex mMutex;
  1200. };
  1201. EGLBoolean eglSwapBuffersWithDamageKHRImpl(EGLDisplay dpy, EGLSurface draw,
  1202. EGLint *rects, EGLint n_rects)
  1203. {
  1204. const egl_display_ptr dp = validate_display(dpy);
  1205. if (!dp) return EGL_FALSE;
  1206. SurfaceRef _s(dp.get(), draw);
  1207. if (!_s.get())
  1208. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1209. egl_surface_t* const s = get_surface(draw);
  1210. if (CC_UNLIKELY(dp->traceGpuCompletion)) {
  1211. EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
  1212. if (sync != EGL_NO_SYNC_KHR) {
  1213. FrameCompletionThread::queueSync(sync);
  1214. }
  1215. }
  1216. if (CC_UNLIKELY(dp->finishOnSwap)) {
  1217. uint32_t pixel;
  1218. egl_context_t * const c = get_context( egl_tls_t::getContext() );
  1219. if (c) {
  1220. // glReadPixels() ensures that the frame is complete
  1221. s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
  1222. GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
  1223. }
  1224. }
  1225. if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
  1226. if (!sendSurfaceMetadata(s)) {
  1227. native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
  1228. return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
  1229. }
  1230. }
  1231. if (n_rects == 0) {
  1232. return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
  1233. }
  1234. std::vector<android_native_rect_t> androidRects((size_t)n_rects);
  1235. for (int r = 0; r < n_rects; ++r) {
  1236. int offset = r * 4;
  1237. int x = rects[offset];
  1238. int y = rects[offset + 1];
  1239. int width = rects[offset + 2];
  1240. int height = rects[offset + 3];
  1241. android_native_rect_t androidRect;
  1242. androidRect.left = x;
  1243. androidRect.top = y + height;
  1244. androidRect.right = x + width;
  1245. androidRect.bottom = y;
  1246. androidRects.push_back(androidRect);
  1247. }
  1248. if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
  1249. native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(),
  1250. androidRects.size());
  1251. }
  1252. if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
  1253. return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
  1254. rects, n_rects);
  1255. } else {
  1256. return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
  1257. }
  1258. }
  1259. EGLBoolean eglSwapBuffersImpl(EGLDisplay dpy, EGLSurface surface)
  1260. {
  1261. return eglSwapBuffersWithDamageKHRImpl(dpy, surface, nullptr, 0);
  1262. }
  1263. EGLBoolean eglCopyBuffersImpl( EGLDisplay dpy, EGLSurface surface,
  1264. NativePixmapType target)
  1265. {
  1266. const egl_display_ptr dp = validate_display(dpy);
  1267. if (!dp) return EGL_FALSE;
  1268. SurfaceRef _s(dp.get(), surface);
  1269. if (!_s.get())
  1270. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1271. egl_surface_t const * const s = get_surface(surface);
  1272. return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
  1273. }
  1274. const char* eglQueryStringImpl(EGLDisplay dpy, EGLint name)
  1275. {
  1276. if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
  1277. // Return list of client extensions
  1278. return gClientExtensionString;
  1279. }
  1280. const egl_display_ptr dp = validate_display(dpy);
  1281. if (!dp) return (const char *) nullptr;
  1282. switch (name) {
  1283. case EGL_VENDOR:
  1284. return dp->getVendorString();
  1285. case EGL_VERSION:
  1286. return dp->getVersionString();
  1287. case EGL_EXTENSIONS:
  1288. return dp->getExtensionString();
  1289. case EGL_CLIENT_APIS:
  1290. return dp->getClientApiString();
  1291. default:
  1292. break;
  1293. }
  1294. return setError(EGL_BAD_PARAMETER, (const char *)nullptr);
  1295. }
  1296. EGLAPI const char* eglQueryStringImplementationANDROIDImpl(EGLDisplay dpy, EGLint name)
  1297. {
  1298. const egl_display_ptr dp = validate_display(dpy);
  1299. if (!dp) return (const char *) nullptr;
  1300. switch (name) {
  1301. case EGL_VENDOR:
  1302. return dp->disp.queryString.vendor;
  1303. case EGL_VERSION:
  1304. return dp->disp.queryString.version;
  1305. case EGL_EXTENSIONS:
  1306. return dp->disp.queryString.extensions;
  1307. case EGL_CLIENT_APIS:
  1308. return dp->disp.queryString.clientApi;
  1309. default:
  1310. break;
  1311. }
  1312. return setError(EGL_BAD_PARAMETER, (const char *)nullptr);
  1313. }
  1314. // ----------------------------------------------------------------------------
  1315. // EGL 1.1
  1316. // ----------------------------------------------------------------------------
  1317. EGLBoolean eglSurfaceAttribImpl(
  1318. EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
  1319. {
  1320. const egl_display_ptr dp = validate_display(dpy);
  1321. if (!dp) return EGL_FALSE;
  1322. SurfaceRef _s(dp.get(), surface);
  1323. if (!_s.get())
  1324. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1325. egl_surface_t * const s = get_surface(surface);
  1326. if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
  1327. if (!s->getNativeWindow()) {
  1328. setError(EGL_BAD_SURFACE, EGL_FALSE);
  1329. }
  1330. int err = native_window_set_auto_refresh(s->getNativeWindow(), value != 0);
  1331. return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1332. }
  1333. if (attribute == EGL_TIMESTAMPS_ANDROID) {
  1334. if (!s->getNativeWindow()) {
  1335. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1336. }
  1337. int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0);
  1338. return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1339. }
  1340. if (s->setSmpte2086Attribute(attribute, value)) {
  1341. return EGL_TRUE;
  1342. } else if (s->setCta8613Attribute(attribute, value)) {
  1343. return EGL_TRUE;
  1344. } else if (s->cnx->egl.eglSurfaceAttrib) {
  1345. return s->cnx->egl.eglSurfaceAttrib(
  1346. dp->disp.dpy, s->surface, attribute, value);
  1347. }
  1348. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1349. }
  1350. EGLBoolean eglBindTexImageImpl(
  1351. EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  1352. {
  1353. const egl_display_ptr dp = validate_display(dpy);
  1354. if (!dp) return EGL_FALSE;
  1355. SurfaceRef _s(dp.get(), surface);
  1356. if (!_s.get())
  1357. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1358. egl_surface_t const * const s = get_surface(surface);
  1359. if (s->cnx->egl.eglBindTexImage) {
  1360. return s->cnx->egl.eglBindTexImage(
  1361. dp->disp.dpy, s->surface, buffer);
  1362. }
  1363. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1364. }
  1365. EGLBoolean eglReleaseTexImageImpl(
  1366. EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  1367. {
  1368. const egl_display_ptr dp = validate_display(dpy);
  1369. if (!dp) return EGL_FALSE;
  1370. SurfaceRef _s(dp.get(), surface);
  1371. if (!_s.get())
  1372. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1373. egl_surface_t const * const s = get_surface(surface);
  1374. if (s->cnx->egl.eglReleaseTexImage) {
  1375. return s->cnx->egl.eglReleaseTexImage(
  1376. dp->disp.dpy, s->surface, buffer);
  1377. }
  1378. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1379. }
  1380. EGLBoolean eglSwapIntervalImpl(EGLDisplay dpy, EGLint interval)
  1381. {
  1382. const egl_display_ptr dp = validate_display(dpy);
  1383. if (!dp) return EGL_FALSE;
  1384. EGLBoolean res = EGL_TRUE;
  1385. egl_connection_t* const cnx = &gEGLImpl;
  1386. if (cnx->dso && cnx->egl.eglSwapInterval) {
  1387. res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
  1388. }
  1389. return res;
  1390. }
  1391. // ----------------------------------------------------------------------------
  1392. // EGL 1.2
  1393. // ----------------------------------------------------------------------------
  1394. EGLBoolean eglWaitClientImpl(void)
  1395. {
  1396. egl_connection_t* const cnx = &gEGLImpl;
  1397. if (!cnx->dso)
  1398. return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
  1399. EGLBoolean res;
  1400. if (cnx->egl.eglWaitClient) {
  1401. res = cnx->egl.eglWaitClient();
  1402. } else {
  1403. res = cnx->egl.eglWaitGL();
  1404. }
  1405. return res;
  1406. }
  1407. EGLBoolean eglBindAPIImpl(EGLenum api)
  1408. {
  1409. // bind this API on all EGLs
  1410. EGLBoolean res = EGL_TRUE;
  1411. egl_connection_t* const cnx = &gEGLImpl;
  1412. if (cnx->dso && cnx->egl.eglBindAPI) {
  1413. res = cnx->egl.eglBindAPI(api);
  1414. }
  1415. return res;
  1416. }
  1417. EGLenum eglQueryAPIImpl(void)
  1418. {
  1419. egl_connection_t* const cnx = &gEGLImpl;
  1420. if (cnx->dso && cnx->egl.eglQueryAPI) {
  1421. return cnx->egl.eglQueryAPI();
  1422. }
  1423. // or, it can only be OpenGL ES
  1424. return EGL_OPENGL_ES_API;
  1425. }
  1426. EGLBoolean eglReleaseThreadImpl(void)
  1427. {
  1428. egl_connection_t* const cnx = &gEGLImpl;
  1429. if (cnx->dso && cnx->egl.eglReleaseThread) {
  1430. cnx->egl.eglReleaseThread();
  1431. }
  1432. // If there is context bound to the thread, release it
  1433. egl_display_t::loseCurrent(get_context(getContext()));
  1434. egl_tls_t::clearTLS();
  1435. return EGL_TRUE;
  1436. }
  1437. EGLSurface eglCreatePbufferFromClientBufferImpl(
  1438. EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
  1439. EGLConfig config, const EGLint *attrib_list)
  1440. {
  1441. egl_connection_t* cnx = nullptr;
  1442. const egl_display_ptr dp = validate_display_connection(dpy, cnx);
  1443. if (!dp) return EGL_FALSE;
  1444. if (cnx->egl.eglCreatePbufferFromClientBuffer) {
  1445. return cnx->egl.eglCreatePbufferFromClientBuffer(
  1446. dp->disp.dpy, buftype, buffer, config, attrib_list);
  1447. }
  1448. return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
  1449. }
  1450. // ----------------------------------------------------------------------------
  1451. // EGL_EGLEXT_VERSION 3
  1452. // ----------------------------------------------------------------------------
  1453. EGLBoolean eglLockSurfaceKHRImpl(EGLDisplay dpy, EGLSurface surface,
  1454. const EGLint *attrib_list)
  1455. {
  1456. const egl_display_ptr dp = validate_display(dpy);
  1457. if (!dp) return EGL_FALSE;
  1458. SurfaceRef _s(dp.get(), surface);
  1459. if (!_s.get())
  1460. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1461. egl_surface_t const * const s = get_surface(surface);
  1462. if (s->cnx->egl.eglLockSurfaceKHR) {
  1463. return s->cnx->egl.eglLockSurfaceKHR(
  1464. dp->disp.dpy, s->surface, attrib_list);
  1465. }
  1466. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  1467. }
  1468. EGLBoolean eglUnlockSurfaceKHRImpl(EGLDisplay dpy, EGLSurface surface)
  1469. {
  1470. const egl_display_ptr dp = validate_display(dpy);
  1471. if (!dp) return EGL_FALSE;
  1472. SurfaceRef _s(dp.get(), surface);
  1473. if (!_s.get())
  1474. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  1475. egl_surface_t const * const s = get_surface(surface);
  1476. if (s->cnx->egl.eglUnlockSurfaceKHR) {
  1477. return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
  1478. }
  1479. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  1480. }
  1481. // Note: EGLImageKHR and EGLImage are the same thing so no need
  1482. // to templatize that.
  1483. template <typename AttrType, typename FuncType>
  1484. EGLImageKHR eglCreateImageTmpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1485. EGLClientBuffer buffer, const AttrType* attrib_list,
  1486. FuncType eglCreateImageFunc) {
  1487. const egl_display_ptr dp = validate_display(dpy);
  1488. if (!dp) return EGL_NO_IMAGE_KHR;
  1489. std::vector<AttrType> strippedAttribs;
  1490. if (needsAndroidPEglMitigation()) {
  1491. // Mitigation for Android P vendor partitions: eglImageCreateKHR should accept
  1492. // EGL_GL_COLORSPACE_LINEAR_KHR, EGL_GL_COLORSPACE_SRGB_KHR and
  1493. // EGL_GL_COLORSPACE_DEFAULT_EXT if EGL_EXT_image_gl_colorspace is supported,
  1494. // but some drivers don't like the DEFAULT value and generate an error.
  1495. for (const AttrType *attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
  1496. if (attr[0] == EGL_GL_COLORSPACE_KHR &&
  1497. dp->haveExtension("EGL_EXT_image_gl_colorspace")) {
  1498. if (attr[1] != EGL_GL_COLORSPACE_LINEAR_KHR &&
  1499. attr[1] != EGL_GL_COLORSPACE_SRGB_KHR) {
  1500. continue;
  1501. }
  1502. }
  1503. strippedAttribs.push_back(attr[0]);
  1504. strippedAttribs.push_back(attr[1]);
  1505. }
  1506. strippedAttribs.push_back(EGL_NONE);
  1507. }
  1508. ContextRef _c(dp.get(), ctx);
  1509. egl_context_t* const c = _c.get();
  1510. EGLImageKHR result = EGL_NO_IMAGE_KHR;
  1511. egl_connection_t* const cnx = &gEGLImpl;
  1512. if (cnx->dso && eglCreateImageFunc) {
  1513. result = eglCreateImageFunc(dp->disp.dpy, c ? c->context : EGL_NO_CONTEXT, target, buffer,
  1514. needsAndroidPEglMitigation() ? strippedAttribs.data() : attrib_list);
  1515. }
  1516. return result;
  1517. }
  1518. typedef EGLImage(EGLAPIENTRYP PFNEGLCREATEIMAGE)(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1519. EGLClientBuffer buffer,
  1520. const EGLAttrib* attrib_list);
  1521. EGLImageKHR eglCreateImageKHRImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1522. EGLClientBuffer buffer, const EGLint* attrib_list) {
  1523. return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
  1524. attrib_list,
  1525. gEGLImpl.egl.eglCreateImageKHR);
  1526. }
  1527. EGLImage eglCreateImageImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
  1528. const EGLAttrib* attrib_list) {
  1529. egl_connection_t* const cnx = &gEGLImpl;
  1530. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1531. if (cnx->egl.eglCreateImage) {
  1532. return eglCreateImageTmpl<EGLAttrib, PFNEGLCREATEIMAGE>(dpy, ctx, target, buffer,
  1533. attrib_list,
  1534. cnx->egl.eglCreateImage);
  1535. }
  1536. // driver doesn't support native function, return EGL_BAD_DISPLAY
  1537. ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateImage");
  1538. return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE);
  1539. }
  1540. std::vector<EGLint> convertedAttribs;
  1541. convertAttribs(attrib_list, convertedAttribs);
  1542. return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
  1543. convertedAttribs.data(),
  1544. gEGLImpl.egl.eglCreateImageKHR);
  1545. }
  1546. EGLBoolean eglDestroyImageTmpl(EGLDisplay dpy, EGLImageKHR img,
  1547. PFNEGLDESTROYIMAGEKHRPROC destroyImageFunc) {
  1548. const egl_display_ptr dp = validate_display(dpy);
  1549. if (!dp) return EGL_FALSE;
  1550. EGLBoolean result = EGL_FALSE;
  1551. egl_connection_t* const cnx = &gEGLImpl;
  1552. if (cnx->dso && destroyImageFunc) {
  1553. result = destroyImageFunc(dp->disp.dpy, img);
  1554. }
  1555. return result;
  1556. }
  1557. EGLBoolean eglDestroyImageKHRImpl(EGLDisplay dpy, EGLImageKHR img) {
  1558. return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
  1559. }
  1560. EGLBoolean eglDestroyImageImpl(EGLDisplay dpy, EGLImageKHR img) {
  1561. egl_connection_t* const cnx = &gEGLImpl;
  1562. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1563. if (cnx->egl.eglDestroyImage) {
  1564. return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImage);
  1565. }
  1566. // driver doesn't support native function, return EGL_BAD_DISPLAY
  1567. ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroyImage");
  1568. return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  1569. }
  1570. return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
  1571. }
  1572. // ----------------------------------------------------------------------------
  1573. // EGL_EGLEXT_VERSION 5
  1574. // ----------------------------------------------------------------------------
  1575. // NOTE: EGLSyncKHR and EGLSync are identical, no need to templatize
  1576. template <typename AttrType, typename FuncType>
  1577. EGLSyncKHR eglCreateSyncTmpl(EGLDisplay dpy, EGLenum type, const AttrType* attrib_list,
  1578. FuncType eglCreateSyncFunc) {
  1579. const egl_display_ptr dp = validate_display(dpy);
  1580. if (!dp) return EGL_NO_SYNC_KHR;
  1581. egl_connection_t* const cnx = &gEGLImpl;
  1582. EGLSyncKHR result = EGL_NO_SYNC_KHR;
  1583. if (cnx->dso && eglCreateSyncFunc) {
  1584. result = eglCreateSyncFunc(dp->disp.dpy, type, attrib_list);
  1585. }
  1586. return result;
  1587. }
  1588. typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATESYNC)(EGLDisplay dpy, EGLenum type,
  1589. const EGLAttrib* attrib_list);
  1590. EGLSyncKHR eglCreateSyncKHRImpl(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
  1591. return eglCreateSyncTmpl<EGLint, PFNEGLCREATESYNCKHRPROC>(dpy, type, attrib_list,
  1592. gEGLImpl.egl.eglCreateSyncKHR);
  1593. }
  1594. EGLSync eglCreateSyncImpl(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) {
  1595. egl_connection_t* const cnx = &gEGLImpl;
  1596. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1597. if (cnx->egl.eglCreateSync) {
  1598. return eglCreateSyncTmpl<EGLAttrib, PFNEGLCREATESYNC>(dpy, type, attrib_list,
  1599. cnx->egl.eglCreateSync);
  1600. }
  1601. // driver doesn't support native function, return EGL_BAD_DISPLAY
  1602. ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateSync");
  1603. return setError(EGL_BAD_DISPLAY, EGL_NO_SYNC);
  1604. }
  1605. std::vector<EGLint> convertedAttribs;
  1606. convertAttribs(attrib_list, convertedAttribs);
  1607. return eglCreateSyncTmpl<EGLint, PFNEGLCREATESYNCKHRPROC>(dpy, type, convertedAttribs.data(),
  1608. cnx->egl.eglCreateSyncKHR);
  1609. }
  1610. EGLBoolean eglDestroySyncTmpl(EGLDisplay dpy, EGLSyncKHR sync,
  1611. PFNEGLDESTROYSYNCKHRPROC eglDestroySyncFunc) {
  1612. const egl_display_ptr dp = validate_display(dpy);
  1613. if (!dp) return EGL_FALSE;
  1614. EGLBoolean result = EGL_FALSE;
  1615. egl_connection_t* const cnx = &gEGLImpl;
  1616. if (cnx->dso && eglDestroySyncFunc) {
  1617. result = eglDestroySyncFunc(dp->disp.dpy, sync);
  1618. }
  1619. return result;
  1620. }
  1621. EGLBoolean eglDestroySyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync) {
  1622. return eglDestroySyncTmpl(dpy, sync, gEGLImpl.egl.eglDestroySyncKHR);
  1623. }
  1624. EGLBoolean eglDestroySyncImpl(EGLDisplay dpy, EGLSyncKHR sync) {
  1625. egl_connection_t* const cnx = &gEGLImpl;
  1626. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1627. if (cnx->egl.eglDestroySync) {
  1628. return eglDestroySyncTmpl(dpy, sync, cnx->egl.eglDestroySync);
  1629. }
  1630. ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroySync");
  1631. return setError(EGL_BAD_DISPLAY, EGL_FALSE);
  1632. }
  1633. return eglDestroySyncTmpl(dpy, sync, cnx->egl.eglDestroySyncKHR);
  1634. }
  1635. EGLBoolean eglSignalSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
  1636. const egl_display_ptr dp = validate_display(dpy);
  1637. if (!dp) return EGL_FALSE;
  1638. EGLBoolean result = EGL_FALSE;
  1639. egl_connection_t* const cnx = &gEGLImpl;
  1640. if (cnx->dso && gEGLImpl.egl.eglSignalSyncKHR) {
  1641. result = gEGLImpl.egl.eglSignalSyncKHR(dp->disp.dpy, sync, mode);
  1642. }
  1643. return result;
  1644. }
  1645. EGLint eglClientWaitSyncTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout,
  1646. PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncFunc) {
  1647. const egl_display_ptr dp = validate_display(dpy);
  1648. if (!dp) return EGL_FALSE;
  1649. EGLint result = EGL_FALSE;
  1650. egl_connection_t* const cnx = &gEGLImpl;
  1651. if (cnx->dso && eglClientWaitSyncFunc) {
  1652. result = eglClientWaitSyncFunc(dp->disp.dpy, sync, flags, timeout);
  1653. }
  1654. return result;
  1655. }
  1656. EGLint eglClientWaitSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
  1657. egl_connection_t* const cnx = &gEGLImpl;
  1658. return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSyncKHR);
  1659. }
  1660. EGLint eglClientWaitSyncImpl(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTimeKHR timeout) {
  1661. egl_connection_t* const cnx = &gEGLImpl;
  1662. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1663. if (cnx->egl.eglClientWaitSync) {
  1664. return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSync);
  1665. }
  1666. ALOGE("Driver indicates EGL 1.5 support, but does not have eglClientWaitSync");
  1667. return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
  1668. }
  1669. return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSyncKHR);
  1670. }
  1671. template <typename AttrType, typename FuncType>
  1672. EGLBoolean eglGetSyncAttribTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, AttrType* value,
  1673. FuncType eglGetSyncAttribFunc) {
  1674. const egl_display_ptr dp = validate_display(dpy);
  1675. if (!dp) return EGL_FALSE;
  1676. EGLBoolean result = EGL_FALSE;
  1677. egl_connection_t* const cnx = &gEGLImpl;
  1678. if (cnx->dso && eglGetSyncAttribFunc) {
  1679. result = eglGetSyncAttribFunc(dp->disp.dpy, sync, attribute, value);
  1680. }
  1681. return result;
  1682. }
  1683. typedef EGLBoolean(EGLAPIENTRYP PFNEGLGETSYNCATTRIB)(EGLDisplay dpy, EGLSync sync, EGLint attribute,
  1684. EGLAttrib* value);
  1685. EGLBoolean eglGetSyncAttribImpl(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) {
  1686. egl_connection_t* const cnx = &gEGLImpl;
  1687. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1688. if (cnx->egl.eglGetSyncAttrib) {
  1689. return eglGetSyncAttribTmpl<EGLAttrib, PFNEGLGETSYNCATTRIB>(dpy, sync, attribute, value,
  1690. cnx->egl.eglGetSyncAttrib);
  1691. }
  1692. ALOGE("Driver indicates EGL 1.5 support, but does not have eglGetSyncAttrib");
  1693. return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
  1694. }
  1695. // Fallback to KHR, ask for EGLint attribute and cast back to EGLAttrib
  1696. EGLint attribValue;
  1697. EGLBoolean ret =
  1698. eglGetSyncAttribTmpl<EGLint, PFNEGLGETSYNCATTRIBKHRPROC>(dpy, sync, attribute,
  1699. &attribValue,
  1700. gEGLImpl.egl
  1701. .eglGetSyncAttribKHR);
  1702. if (ret) {
  1703. *value = static_cast<EGLAttrib>(attribValue);
  1704. }
  1705. return ret;
  1706. }
  1707. EGLBoolean eglGetSyncAttribKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute,
  1708. EGLint* value) {
  1709. return eglGetSyncAttribTmpl<EGLint, PFNEGLGETSYNCATTRIBKHRPROC>(dpy, sync, attribute, value,
  1710. gEGLImpl.egl
  1711. .eglGetSyncAttribKHR);
  1712. }
  1713. EGLStreamKHR eglCreateStreamKHRImpl(EGLDisplay dpy, const EGLint *attrib_list)
  1714. {
  1715. const egl_display_ptr dp = validate_display(dpy);
  1716. if (!dp) return EGL_NO_STREAM_KHR;
  1717. EGLStreamKHR result = EGL_NO_STREAM_KHR;
  1718. egl_connection_t* const cnx = &gEGLImpl;
  1719. if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
  1720. result = cnx->egl.eglCreateStreamKHR(
  1721. dp->disp.dpy, attrib_list);
  1722. }
  1723. return result;
  1724. }
  1725. EGLBoolean eglDestroyStreamKHRImpl(EGLDisplay dpy, EGLStreamKHR stream)
  1726. {
  1727. const egl_display_ptr dp = validate_display(dpy);
  1728. if (!dp) return EGL_FALSE;
  1729. EGLBoolean result = EGL_FALSE;
  1730. egl_connection_t* const cnx = &gEGLImpl;
  1731. if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
  1732. result = cnx->egl.eglDestroyStreamKHR(
  1733. dp->disp.dpy, stream);
  1734. }
  1735. return result;
  1736. }
  1737. EGLBoolean eglStreamAttribKHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
  1738. EGLenum attribute, EGLint value)
  1739. {
  1740. const egl_display_ptr dp = validate_display(dpy);
  1741. if (!dp) return EGL_FALSE;
  1742. EGLBoolean result = EGL_FALSE;
  1743. egl_connection_t* const cnx = &gEGLImpl;
  1744. if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
  1745. result = cnx->egl.eglStreamAttribKHR(
  1746. dp->disp.dpy, stream, attribute, value);
  1747. }
  1748. return result;
  1749. }
  1750. EGLBoolean eglQueryStreamKHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
  1751. EGLenum attribute, EGLint *value)
  1752. {
  1753. const egl_display_ptr dp = validate_display(dpy);
  1754. if (!dp) return EGL_FALSE;
  1755. EGLBoolean result = EGL_FALSE;
  1756. egl_connection_t* const cnx = &gEGLImpl;
  1757. if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
  1758. result = cnx->egl.eglQueryStreamKHR(
  1759. dp->disp.dpy, stream, attribute, value);
  1760. }
  1761. return result;
  1762. }
  1763. EGLBoolean eglQueryStreamu64KHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
  1764. EGLenum attribute, EGLuint64KHR *value)
  1765. {
  1766. const egl_display_ptr dp = validate_display(dpy);
  1767. if (!dp) return EGL_FALSE;
  1768. EGLBoolean result = EGL_FALSE;
  1769. egl_connection_t* const cnx = &gEGLImpl;
  1770. if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
  1771. result = cnx->egl.eglQueryStreamu64KHR(
  1772. dp->disp.dpy, stream, attribute, value);
  1773. }
  1774. return result;
  1775. }
  1776. EGLBoolean eglQueryStreamTimeKHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
  1777. EGLenum attribute, EGLTimeKHR *value)
  1778. {
  1779. const egl_display_ptr dp = validate_display(dpy);
  1780. if (!dp) return EGL_FALSE;
  1781. EGLBoolean result = EGL_FALSE;
  1782. egl_connection_t* const cnx = &gEGLImpl;
  1783. if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
  1784. result = cnx->egl.eglQueryStreamTimeKHR(
  1785. dp->disp.dpy, stream, attribute, value);
  1786. }
  1787. return result;
  1788. }
  1789. EGLSurface eglCreateStreamProducerSurfaceKHRImpl(EGLDisplay dpy, EGLConfig config,
  1790. EGLStreamKHR stream, const EGLint *attrib_list)
  1791. {
  1792. egl_display_ptr dp = validate_display(dpy);
  1793. if (!dp) return EGL_NO_SURFACE;
  1794. egl_connection_t* const cnx = &gEGLImpl;
  1795. if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
  1796. EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
  1797. dp->disp.dpy, config, stream, attrib_list);
  1798. if (surface != EGL_NO_SURFACE) {
  1799. egl_surface_t* s = new egl_surface_t(dp.get(), config, nullptr, surface,
  1800. EGL_GL_COLORSPACE_LINEAR_KHR, cnx);
  1801. return s;
  1802. }
  1803. }
  1804. return EGL_NO_SURFACE;
  1805. }
  1806. EGLBoolean eglStreamConsumerGLTextureExternalKHRImpl(EGLDisplay dpy,
  1807. EGLStreamKHR stream)
  1808. {
  1809. const egl_display_ptr dp = validate_display(dpy);
  1810. if (!dp) return EGL_FALSE;
  1811. EGLBoolean result = EGL_FALSE;
  1812. egl_connection_t* const cnx = &gEGLImpl;
  1813. if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
  1814. result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
  1815. dp->disp.dpy, stream);
  1816. }
  1817. return result;
  1818. }
  1819. EGLBoolean eglStreamConsumerAcquireKHRImpl(EGLDisplay dpy,
  1820. EGLStreamKHR stream)
  1821. {
  1822. const egl_display_ptr dp = validate_display(dpy);
  1823. if (!dp) return EGL_FALSE;
  1824. EGLBoolean result = EGL_FALSE;
  1825. egl_connection_t* const cnx = &gEGLImpl;
  1826. if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
  1827. result = cnx->egl.eglStreamConsumerAcquireKHR(
  1828. dp->disp.dpy, stream);
  1829. }
  1830. return result;
  1831. }
  1832. EGLBoolean eglStreamConsumerReleaseKHRImpl(EGLDisplay dpy,
  1833. EGLStreamKHR stream)
  1834. {
  1835. const egl_display_ptr dp = validate_display(dpy);
  1836. if (!dp) return EGL_FALSE;
  1837. EGLBoolean result = EGL_FALSE;
  1838. egl_connection_t* const cnx = &gEGLImpl;
  1839. if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
  1840. result = cnx->egl.eglStreamConsumerReleaseKHR(
  1841. dp->disp.dpy, stream);
  1842. }
  1843. return result;
  1844. }
  1845. EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHRImpl(
  1846. EGLDisplay dpy, EGLStreamKHR stream)
  1847. {
  1848. const egl_display_ptr dp = validate_display(dpy);
  1849. if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
  1850. EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
  1851. egl_connection_t* const cnx = &gEGLImpl;
  1852. if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
  1853. result = cnx->egl.eglGetStreamFileDescriptorKHR(
  1854. dp->disp.dpy, stream);
  1855. }
  1856. return result;
  1857. }
  1858. EGLStreamKHR eglCreateStreamFromFileDescriptorKHRImpl(
  1859. EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
  1860. {
  1861. const egl_display_ptr dp = validate_display(dpy);
  1862. if (!dp) return EGL_NO_STREAM_KHR;
  1863. EGLStreamKHR result = EGL_NO_STREAM_KHR;
  1864. egl_connection_t* const cnx = &gEGLImpl;
  1865. if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
  1866. result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
  1867. dp->disp.dpy, file_descriptor);
  1868. }
  1869. return result;
  1870. }
  1871. // ----------------------------------------------------------------------------
  1872. // EGL_EGLEXT_VERSION 15
  1873. // ----------------------------------------------------------------------------
  1874. // Need to template function type because return type is different
  1875. template <typename ReturnType, typename FuncType>
  1876. ReturnType eglWaitSyncTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags,
  1877. FuncType eglWaitSyncFunc) {
  1878. const egl_display_ptr dp = validate_display(dpy);
  1879. if (!dp) return EGL_FALSE;
  1880. ReturnType result = EGL_FALSE;
  1881. egl_connection_t* const cnx = &gEGLImpl;
  1882. if (cnx->dso && eglWaitSyncFunc) {
  1883. result = eglWaitSyncFunc(dp->disp.dpy, sync, flags);
  1884. }
  1885. return result;
  1886. }
  1887. typedef EGLBoolean(EGLAPIENTRYP PFNEGLWAITSYNC)(EGLDisplay dpy, EGLSync sync, EGLint flags);
  1888. EGLint eglWaitSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
  1889. egl_connection_t* const cnx = &gEGLImpl;
  1890. return eglWaitSyncTmpl<EGLint, PFNEGLWAITSYNCKHRPROC>(dpy, sync, flags,
  1891. cnx->egl.eglWaitSyncKHR);
  1892. }
  1893. EGLBoolean eglWaitSyncImpl(EGLDisplay dpy, EGLSync sync, EGLint flags) {
  1894. egl_connection_t* const cnx = &gEGLImpl;
  1895. if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
  1896. if (cnx->egl.eglWaitSync) {
  1897. return eglWaitSyncTmpl<EGLBoolean, PFNEGLWAITSYNC>(dpy, sync, flags,
  1898. cnx->egl.eglWaitSync);
  1899. }
  1900. return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
  1901. }
  1902. return static_cast<EGLBoolean>(
  1903. eglWaitSyncTmpl<EGLint, PFNEGLWAITSYNCKHRPROC>(dpy, sync, flags,
  1904. cnx->egl.eglWaitSyncKHR));
  1905. }
  1906. // ----------------------------------------------------------------------------
  1907. // ANDROID extensions
  1908. // ----------------------------------------------------------------------------
  1909. EGLint eglDupNativeFenceFDANDROIDImpl(EGLDisplay dpy, EGLSyncKHR sync)
  1910. {
  1911. const egl_display_ptr dp = validate_display(dpy);
  1912. if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
  1913. EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
  1914. egl_connection_t* const cnx = &gEGLImpl;
  1915. if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
  1916. result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
  1917. }
  1918. return result;
  1919. }
  1920. EGLBoolean eglPresentationTimeANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
  1921. EGLnsecsANDROID time)
  1922. {
  1923. const egl_display_ptr dp = validate_display(dpy);
  1924. if (!dp) {
  1925. return EGL_FALSE;
  1926. }
  1927. SurfaceRef _s(dp.get(), surface);
  1928. if (!_s.get()) {
  1929. setError(EGL_BAD_SURFACE, EGL_FALSE);
  1930. return EGL_FALSE;
  1931. }
  1932. egl_surface_t const * const s = get_surface(surface);
  1933. native_window_set_buffers_timestamp(s->getNativeWindow(), time);
  1934. return EGL_TRUE;
  1935. }
  1936. EGLClientBuffer eglGetNativeClientBufferANDROIDImpl(const AHardwareBuffer *buffer) {
  1937. // AHardwareBuffer_to_ANativeWindowBuffer is a platform-only symbol and thus
  1938. // this function cannot be implemented when this libEGL is built for
  1939. // vendors.
  1940. #ifndef __ANDROID_VNDK__
  1941. if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer) nullptr);
  1942. return const_cast<ANativeWindowBuffer *>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
  1943. #else
  1944. return setError(EGL_BAD_PARAMETER, (EGLClientBuffer) nullptr);
  1945. #endif
  1946. }
  1947. // ----------------------------------------------------------------------------
  1948. // NVIDIA extensions
  1949. // ----------------------------------------------------------------------------
  1950. EGLuint64NV eglGetSystemTimeFrequencyNVImpl()
  1951. {
  1952. EGLuint64NV ret = 0;
  1953. egl_connection_t* const cnx = &gEGLImpl;
  1954. if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
  1955. return cnx->egl.eglGetSystemTimeFrequencyNV();
  1956. }
  1957. return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
  1958. }
  1959. EGLuint64NV eglGetSystemTimeNVImpl()
  1960. {
  1961. EGLuint64NV ret = 0;
  1962. egl_connection_t* const cnx = &gEGLImpl;
  1963. if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
  1964. return cnx->egl.eglGetSystemTimeNV();
  1965. }
  1966. return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
  1967. }
  1968. // ----------------------------------------------------------------------------
  1969. // Partial update extension
  1970. // ----------------------------------------------------------------------------
  1971. EGLBoolean eglSetDamageRegionKHRImpl(EGLDisplay dpy, EGLSurface surface,
  1972. EGLint *rects, EGLint n_rects)
  1973. {
  1974. const egl_display_ptr dp = validate_display(dpy);
  1975. if (!dp) {
  1976. setError(EGL_BAD_DISPLAY, EGL_FALSE);
  1977. return EGL_FALSE;
  1978. }
  1979. SurfaceRef _s(dp.get(), surface);
  1980. if (!_s.get()) {
  1981. setError(EGL_BAD_SURFACE, EGL_FALSE);
  1982. return EGL_FALSE;
  1983. }
  1984. egl_surface_t const * const s = get_surface(surface);
  1985. if (s->cnx->egl.eglSetDamageRegionKHR) {
  1986. return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
  1987. rects, n_rects);
  1988. }
  1989. return EGL_FALSE;
  1990. }
  1991. EGLBoolean eglGetNextFrameIdANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
  1992. EGLuint64KHR *frameId) {
  1993. const egl_display_ptr dp = validate_display(dpy);
  1994. if (!dp) {
  1995. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  1996. }
  1997. SurfaceRef _s(dp.get(), surface);
  1998. if (!_s.get()) {
  1999. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2000. }
  2001. egl_surface_t const * const s = get_surface(surface);
  2002. if (!s->getNativeWindow()) {
  2003. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2004. }
  2005. uint64_t nextFrameId = 0;
  2006. int ret = native_window_get_next_frame_id(s->getNativeWindow(), &nextFrameId);
  2007. if (ret != 0) {
  2008. // This should not happen. Return an error that is not in the spec
  2009. // so it's obvious something is very wrong.
  2010. ALOGE("eglGetNextFrameId: Unexpected error.");
  2011. return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
  2012. }
  2013. *frameId = nextFrameId;
  2014. return EGL_TRUE;
  2015. }
  2016. EGLBoolean eglGetCompositorTimingANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
  2017. EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values)
  2018. {
  2019. const egl_display_ptr dp = validate_display(dpy);
  2020. if (!dp) {
  2021. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  2022. }
  2023. SurfaceRef _s(dp.get(), surface);
  2024. if (!_s.get()) {
  2025. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2026. }
  2027. egl_surface_t const * const s = get_surface(surface);
  2028. if (!s->getNativeWindow()) {
  2029. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2030. }
  2031. nsecs_t* compositeDeadline = nullptr;
  2032. nsecs_t* compositeInterval = nullptr;
  2033. nsecs_t* compositeToPresentLatency = nullptr;
  2034. for (int i = 0; i < numTimestamps; i++) {
  2035. switch (names[i]) {
  2036. case EGL_COMPOSITE_DEADLINE_ANDROID:
  2037. compositeDeadline = &values[i];
  2038. break;
  2039. case EGL_COMPOSITE_INTERVAL_ANDROID:
  2040. compositeInterval = &values[i];
  2041. break;
  2042. case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
  2043. compositeToPresentLatency = &values[i];
  2044. break;
  2045. default:
  2046. return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
  2047. }
  2048. }
  2049. int ret = native_window_get_compositor_timing(s->getNativeWindow(),
  2050. compositeDeadline, compositeInterval, compositeToPresentLatency);
  2051. switch (ret) {
  2052. case 0:
  2053. return EGL_TRUE;
  2054. case -ENOSYS:
  2055. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2056. default:
  2057. // This should not happen. Return an error that is not in the spec
  2058. // so it's obvious something is very wrong.
  2059. ALOGE("eglGetCompositorTiming: Unexpected error.");
  2060. return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
  2061. }
  2062. }
  2063. EGLBoolean eglGetCompositorTimingSupportedANDROIDImpl(
  2064. EGLDisplay dpy, EGLSurface surface, EGLint name)
  2065. {
  2066. const egl_display_ptr dp = validate_display(dpy);
  2067. if (!dp) {
  2068. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  2069. }
  2070. SurfaceRef _s(dp.get(), surface);
  2071. if (!_s.get()) {
  2072. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2073. }
  2074. egl_surface_t const * const s = get_surface(surface);
  2075. ANativeWindow* window = s->getNativeWindow();
  2076. if (!window) {
  2077. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2078. }
  2079. switch (name) {
  2080. case EGL_COMPOSITE_DEADLINE_ANDROID:
  2081. case EGL_COMPOSITE_INTERVAL_ANDROID:
  2082. case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
  2083. return EGL_TRUE;
  2084. default:
  2085. return EGL_FALSE;
  2086. }
  2087. }
  2088. EGLBoolean eglGetFrameTimestampsANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
  2089. EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps,
  2090. EGLnsecsANDROID *values)
  2091. {
  2092. const egl_display_ptr dp = validate_display(dpy);
  2093. if (!dp) {
  2094. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  2095. }
  2096. SurfaceRef _s(dp.get(), surface);
  2097. if (!_s.get()) {
  2098. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2099. }
  2100. egl_surface_t const * const s = get_surface(surface);
  2101. if (!s->getNativeWindow()) {
  2102. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2103. }
  2104. nsecs_t* requestedPresentTime = nullptr;
  2105. nsecs_t* acquireTime = nullptr;
  2106. nsecs_t* latchTime = nullptr;
  2107. nsecs_t* firstRefreshStartTime = nullptr;
  2108. nsecs_t* gpuCompositionDoneTime = nullptr;
  2109. nsecs_t* lastRefreshStartTime = nullptr;
  2110. nsecs_t* displayPresentTime = nullptr;
  2111. nsecs_t* dequeueReadyTime = nullptr;
  2112. nsecs_t* releaseTime = nullptr;
  2113. for (int i = 0; i < numTimestamps; i++) {
  2114. switch (timestamps[i]) {
  2115. case EGL_REQUESTED_PRESENT_TIME_ANDROID:
  2116. requestedPresentTime = &values[i];
  2117. break;
  2118. case EGL_RENDERING_COMPLETE_TIME_ANDROID:
  2119. acquireTime = &values[i];
  2120. break;
  2121. case EGL_COMPOSITION_LATCH_TIME_ANDROID:
  2122. latchTime = &values[i];
  2123. break;
  2124. case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
  2125. firstRefreshStartTime = &values[i];
  2126. break;
  2127. case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
  2128. lastRefreshStartTime = &values[i];
  2129. break;
  2130. case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
  2131. gpuCompositionDoneTime = &values[i];
  2132. break;
  2133. case EGL_DISPLAY_PRESENT_TIME_ANDROID:
  2134. displayPresentTime = &values[i];
  2135. break;
  2136. case EGL_DEQUEUE_READY_TIME_ANDROID:
  2137. dequeueReadyTime = &values[i];
  2138. break;
  2139. case EGL_READS_DONE_TIME_ANDROID:
  2140. releaseTime = &values[i];
  2141. break;
  2142. default:
  2143. return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
  2144. }
  2145. }
  2146. int ret = native_window_get_frame_timestamps(s->getNativeWindow(), frameId,
  2147. requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime,
  2148. lastRefreshStartTime, gpuCompositionDoneTime, displayPresentTime,
  2149. dequeueReadyTime, releaseTime);
  2150. switch (ret) {
  2151. case 0:
  2152. return EGL_TRUE;
  2153. case -ENOENT:
  2154. return setError(EGL_BAD_ACCESS, (EGLBoolean)EGL_FALSE);
  2155. case -ENOSYS:
  2156. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2157. case -EINVAL:
  2158. return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
  2159. default:
  2160. // This should not happen. Return an error that is not in the spec
  2161. // so it's obvious something is very wrong.
  2162. ALOGE("eglGetFrameTimestamps: Unexpected error.");
  2163. return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
  2164. }
  2165. }
  2166. EGLBoolean eglGetFrameTimestampSupportedANDROIDImpl(
  2167. EGLDisplay dpy, EGLSurface surface, EGLint timestamp)
  2168. {
  2169. const egl_display_ptr dp = validate_display(dpy);
  2170. if (!dp) {
  2171. return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
  2172. }
  2173. SurfaceRef _s(dp.get(), surface);
  2174. if (!_s.get()) {
  2175. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2176. }
  2177. egl_surface_t const * const s = get_surface(surface);
  2178. ANativeWindow* window = s->getNativeWindow();
  2179. if (!window) {
  2180. return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
  2181. }
  2182. switch (timestamp) {
  2183. case EGL_COMPOSITE_DEADLINE_ANDROID:
  2184. case EGL_COMPOSITE_INTERVAL_ANDROID:
  2185. case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
  2186. case EGL_REQUESTED_PRESENT_TIME_ANDROID:
  2187. case EGL_RENDERING_COMPLETE_TIME_ANDROID:
  2188. case EGL_COMPOSITION_LATCH_TIME_ANDROID:
  2189. case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
  2190. case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
  2191. case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
  2192. case EGL_DEQUEUE_READY_TIME_ANDROID:
  2193. case EGL_READS_DONE_TIME_ANDROID:
  2194. return EGL_TRUE;
  2195. case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
  2196. int value = 0;
  2197. window->query(window,
  2198. NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
  2199. return value == 0 ? EGL_FALSE : EGL_TRUE;
  2200. }
  2201. default:
  2202. return EGL_FALSE;
  2203. }
  2204. }
  2205. const GLubyte * glGetStringImpl(GLenum name) {
  2206. const GLubyte * ret = egl_get_string_for_current_context(name);
  2207. if (ret == NULL) {
  2208. gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
  2209. if(_c) ret = _c->glGetString(name);
  2210. }
  2211. return ret;
  2212. }
  2213. const GLubyte * glGetStringiImpl(GLenum name, GLuint index) {
  2214. const GLubyte * ret = egl_get_string_for_current_context(name, index);
  2215. if (ret == NULL) {
  2216. gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
  2217. if(_c) ret = _c->glGetStringi(name, index);
  2218. }
  2219. return ret;
  2220. }
  2221. void glGetBooleanvImpl(GLenum pname, GLboolean * data) {
  2222. if (pname == GL_NUM_EXTENSIONS) {
  2223. int num_exts = egl_get_num_extensions_for_current_context();
  2224. if (num_exts >= 0) {
  2225. *data = num_exts > 0 ? GL_TRUE : GL_FALSE;
  2226. return;
  2227. }
  2228. }
  2229. gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
  2230. if (_c) _c->glGetBooleanv(pname, data);
  2231. }
  2232. void glGetFloatvImpl(GLenum pname, GLfloat * data) {
  2233. if (pname == GL_NUM_EXTENSIONS) {
  2234. int num_exts = egl_get_num_extensions_for_current_context();
  2235. if (num_exts >= 0) {
  2236. *data = (GLfloat)num_exts;
  2237. return;
  2238. }
  2239. }
  2240. gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
  2241. if (_c) _c->glGetFloatv(pname, data);
  2242. }
  2243. void glGetIntegervImpl(GLenum pname, GLint * data) {
  2244. if (pname == GL_NUM_EXTENSIONS) {
  2245. int num_exts = egl_get_num_extensions_for_current_context();
  2246. if (num_exts >= 0) {
  2247. *data = (GLint)num_exts;
  2248. return;
  2249. }
  2250. }
  2251. gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
  2252. if (_c) _c->glGetIntegerv(pname, data);
  2253. }
  2254. void glGetInteger64vImpl(GLenum pname, GLint64 * data) {
  2255. if (pname == GL_NUM_EXTENSIONS) {
  2256. int num_exts = egl_get_num_extensions_for_current_context();
  2257. if (num_exts >= 0) {
  2258. *data = (GLint64)num_exts;
  2259. return;
  2260. }
  2261. }
  2262. gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
  2263. if (_c) _c->glGetInteger64v(pname, data);
  2264. }
  2265. struct implementation_map_t {
  2266. const char* name;
  2267. EGLFuncPointer address;
  2268. };
  2269. static const implementation_map_t sPlatformImplMap[] = {
  2270. // clang-format off
  2271. { "eglGetDisplay", (EGLFuncPointer)&eglGetDisplayImpl },
  2272. { "eglGetPlatformDisplay", (EGLFuncPointer)&eglGetPlatformDisplayImpl },
  2273. { "eglInitialize", (EGLFuncPointer)&eglInitializeImpl },
  2274. { "eglTerminate", (EGLFuncPointer)&eglTerminateImpl },
  2275. { "eglGetConfigs", (EGLFuncPointer)&eglGetConfigsImpl },
  2276. { "eglChooseConfig", (EGLFuncPointer)&eglChooseConfigImpl },
  2277. { "eglGetConfigAttrib", (EGLFuncPointer)&eglGetConfigAttribImpl },
  2278. { "eglCreateWindowSurface", (EGLFuncPointer)&eglCreateWindowSurfaceImpl },
  2279. { "eglCreatePixmapSurface", (EGLFuncPointer)&eglCreatePixmapSurfaceImpl },
  2280. { "eglCreatePlatformWindowSurface", (EGLFuncPointer)&eglCreatePlatformWindowSurfaceImpl },
  2281. { "eglCreatePlatformPixmapSurface", (EGLFuncPointer)&eglCreatePlatformPixmapSurfaceImpl },
  2282. { "eglCreatePbufferSurface", (EGLFuncPointer)&eglCreatePbufferSurfaceImpl },
  2283. { "eglDestroySurface", (EGLFuncPointer)&eglDestroySurfaceImpl },
  2284. { "eglQuerySurface", (EGLFuncPointer)&eglQuerySurfaceImpl },
  2285. { "eglBeginFrame", (EGLFuncPointer)&eglBeginFrameImpl },
  2286. { "eglCreateContext", (EGLFuncPointer)&eglCreateContextImpl },
  2287. { "eglDestroyContext", (EGLFuncPointer)&eglDestroyContextImpl },
  2288. { "eglMakeCurrent", (EGLFuncPointer)&eglMakeCurrentImpl },
  2289. { "eglQueryContext", (EGLFuncPointer)&eglQueryContextImpl },
  2290. { "eglGetCurrentContext", (EGLFuncPointer)&eglGetCurrentContextImpl },
  2291. { "eglGetCurrentSurface", (EGLFuncPointer)&eglGetCurrentSurfaceImpl },
  2292. { "eglGetCurrentDisplay", (EGLFuncPointer)&eglGetCurrentDisplayImpl },
  2293. { "eglWaitGL", (EGLFuncPointer)&eglWaitGLImpl },
  2294. { "eglWaitNative", (EGLFuncPointer)&eglWaitNativeImpl },
  2295. { "eglGetError", (EGLFuncPointer)&eglGetErrorImpl },
  2296. { "eglSwapBuffersWithDamageKHR", (EGLFuncPointer)&eglSwapBuffersWithDamageKHRImpl },
  2297. { "eglGetProcAddress", (EGLFuncPointer)&eglGetProcAddressImpl },
  2298. { "eglSwapBuffers", (EGLFuncPointer)&eglSwapBuffersImpl },
  2299. { "eglCopyBuffers", (EGLFuncPointer)&eglCopyBuffersImpl },
  2300. { "eglQueryString", (EGLFuncPointer)&eglQueryStringImpl },
  2301. { "eglQueryStringImplementationANDROID", (EGLFuncPointer)&eglQueryStringImplementationANDROIDImpl },
  2302. { "eglSurfaceAttrib", (EGLFuncPointer)&eglSurfaceAttribImpl },
  2303. { "eglBindTexImage", (EGLFuncPointer)&eglBindTexImageImpl },
  2304. { "eglReleaseTexImage", (EGLFuncPointer)&eglReleaseTexImageImpl },
  2305. { "eglSwapInterval", (EGLFuncPointer)&eglSwapIntervalImpl },
  2306. { "eglWaitClient", (EGLFuncPointer)&eglWaitClientImpl },
  2307. { "eglBindAPI", (EGLFuncPointer)&eglBindAPIImpl },
  2308. { "eglQueryAPI", (EGLFuncPointer)&eglQueryAPIImpl },
  2309. { "eglReleaseThread", (EGLFuncPointer)&eglReleaseThreadImpl },
  2310. { "eglCreatePbufferFromClientBuffer", (EGLFuncPointer)&eglCreatePbufferFromClientBufferImpl },
  2311. { "eglLockSurfaceKHR", (EGLFuncPointer)&eglLockSurfaceKHRImpl },
  2312. { "eglUnlockSurfaceKHR", (EGLFuncPointer)&eglUnlockSurfaceKHRImpl },
  2313. { "eglCreateImageKHR", (EGLFuncPointer)&eglCreateImageKHRImpl },
  2314. { "eglDestroyImageKHR", (EGLFuncPointer)&eglDestroyImageKHRImpl },
  2315. { "eglCreateImage", (EGLFuncPointer)&eglCreateImageImpl },
  2316. { "eglDestroyImage", (EGLFuncPointer)&eglDestroyImageImpl },
  2317. { "eglCreateSync", (EGLFuncPointer)&eglCreateSyncImpl },
  2318. { "eglDestroySync", (EGLFuncPointer)&eglDestroySyncImpl },
  2319. { "eglClientWaitSync", (EGLFuncPointer)&eglClientWaitSyncImpl },
  2320. { "eglGetSyncAttrib", (EGLFuncPointer)&eglGetSyncAttribImpl },
  2321. { "eglCreateSyncKHR", (EGLFuncPointer)&eglCreateSyncKHRImpl },
  2322. { "eglDestroySyncKHR", (EGLFuncPointer)&eglDestroySyncKHRImpl },
  2323. { "eglSignalSyncKHR", (EGLFuncPointer)&eglSignalSyncKHRImpl },
  2324. { "eglClientWaitSyncKHR", (EGLFuncPointer)&eglClientWaitSyncKHRImpl },
  2325. { "eglGetSyncAttribKHR", (EGLFuncPointer)&eglGetSyncAttribKHRImpl },
  2326. { "eglCreateStreamKHR", (EGLFuncPointer)&eglCreateStreamKHRImpl },
  2327. { "eglDestroyStreamKHR", (EGLFuncPointer)&eglDestroyStreamKHRImpl },
  2328. { "eglStreamAttribKHR", (EGLFuncPointer)&eglStreamAttribKHRImpl },
  2329. { "eglQueryStreamKHR", (EGLFuncPointer)&eglQueryStreamKHRImpl },
  2330. { "eglQueryStreamu64KHR", (EGLFuncPointer)&eglQueryStreamu64KHRImpl },
  2331. { "eglQueryStreamTimeKHR", (EGLFuncPointer)&eglQueryStreamTimeKHRImpl },
  2332. { "eglCreateStreamProducerSurfaceKHR", (EGLFuncPointer)&eglCreateStreamProducerSurfaceKHRImpl },
  2333. { "eglStreamConsumerGLTextureExternalKHR", (EGLFuncPointer)&eglStreamConsumerGLTextureExternalKHRImpl },
  2334. { "eglStreamConsumerAcquireKHR", (EGLFuncPointer)&eglStreamConsumerAcquireKHRImpl },
  2335. { "eglStreamConsumerReleaseKHR", (EGLFuncPointer)&eglStreamConsumerReleaseKHRImpl },
  2336. { "eglGetStreamFileDescriptorKHR", (EGLFuncPointer)&eglGetStreamFileDescriptorKHRImpl },
  2337. { "eglCreateStreamFromFileDescriptorKHR", (EGLFuncPointer)&eglCreateStreamFromFileDescriptorKHRImpl },
  2338. { "eglWaitSync", (EGLFuncPointer)&eglWaitSyncImpl },
  2339. { "eglWaitSyncKHR", (EGLFuncPointer)&eglWaitSyncKHRImpl },
  2340. { "eglDupNativeFenceFDANDROID", (EGLFuncPointer)&eglDupNativeFenceFDANDROIDImpl },
  2341. { "eglPresentationTimeANDROID", (EGLFuncPointer)&eglPresentationTimeANDROIDImpl },
  2342. { "eglGetNativeClientBufferANDROID", (EGLFuncPointer)&eglGetNativeClientBufferANDROIDImpl },
  2343. { "eglGetSystemTimeFrequencyNV", (EGLFuncPointer)&eglGetSystemTimeFrequencyNVImpl },
  2344. { "eglGetSystemTimeNV", (EGLFuncPointer)&eglGetSystemTimeNVImpl },
  2345. { "eglSetDamageRegionKHR", (EGLFuncPointer)&eglSetDamageRegionKHRImpl },
  2346. { "eglGetNextFrameIdANDROID", (EGLFuncPointer)&eglGetNextFrameIdANDROIDImpl },
  2347. { "eglGetCompositorTimingANDROID", (EGLFuncPointer)&eglGetCompositorTimingANDROIDImpl },
  2348. { "eglGetCompositorTimingSupportedANDROID", (EGLFuncPointer)&eglGetCompositorTimingSupportedANDROIDImpl },
  2349. { "eglGetFrameTimestampsANDROID", (EGLFuncPointer)&eglGetFrameTimestampsANDROIDImpl },
  2350. { "eglGetFrameTimestampSupportedANDROID", (EGLFuncPointer)&eglGetFrameTimestampSupportedANDROIDImpl },
  2351. { "glGetString", (EGLFuncPointer)&glGetStringImpl },
  2352. { "glGetStringi", (EGLFuncPointer)&glGetStringiImpl },
  2353. { "glGetBooleanv", (EGLFuncPointer)&glGetBooleanvImpl },
  2354. { "glGetFloatv", (EGLFuncPointer)&glGetFloatvImpl },
  2355. { "glGetIntegerv", (EGLFuncPointer)&glGetIntegervImpl },
  2356. { "glGetInteger64v", (EGLFuncPointer)&glGetInteger64vImpl },
  2357. // clang-format on
  2358. };
  2359. EGLFuncPointer FindPlatformImplAddr(const char* name)
  2360. {
  2361. static const bool DEBUG = false;
  2362. if (name == nullptr) {
  2363. ALOGV("FindPlatformImplAddr called with null name");
  2364. return nullptr;
  2365. }
  2366. for (int i = 0; i < NELEM(sPlatformImplMap); i++) {
  2367. if (sPlatformImplMap[i].name == nullptr) {
  2368. ALOGV("FindPlatformImplAddr found nullptr for sPlatformImplMap[%i].name (%s)", i, name);
  2369. return nullptr;
  2370. }
  2371. if (!strcmp(name, sPlatformImplMap[i].name)) {
  2372. ALOGV("FindPlatformImplAddr found %llu for sPlatformImplMap[%i].address (%s)", (unsigned long long)sPlatformImplMap[i].address, i, name);
  2373. return sPlatformImplMap[i].address;
  2374. }
  2375. }
  2376. ALOGV("FindPlatformImplAddr did not find an entry for %s", name);
  2377. return nullptr;
  2378. }
  2379. } // namespace android