1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // FunctionsEGL.cpp: Implements the FunctionsEGL class.
8
9 #include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
10
11 #include <algorithm>
12
13 #include "common/platform.h"
14 #include "common/string_utils.h"
15 #include "libANGLE/renderer/driver_utils.h"
16 #include "libANGLE/renderer/gl/FunctionsGL.h"
17 #include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
18
19 namespace
20 {
21
22 template <typename T>
SetPtr(T * dst,void * src)23 bool SetPtr(T *dst, void *src)
24 {
25 if (src)
26 {
27 *dst = reinterpret_cast<T>(src);
28 return true;
29 }
30 return false;
31 }
32
IsValidPlatformTypeForPlatformDisplayConnection(EGLAttrib platformType)33 bool IsValidPlatformTypeForPlatformDisplayConnection(EGLAttrib platformType)
34 {
35 switch (platformType)
36 {
37 case EGL_PLATFORM_SURFACELESS_MESA:
38 return true;
39 default:
40 break;
41 }
42 return false;
43 }
44
45 } // namespace
46
47 namespace rx
48 {
49
50 struct FunctionsEGL::EGLDispatchTable
51 {
EGLDispatchTablerx::FunctionsEGL::EGLDispatchTable52 EGLDispatchTable()
53 : bindAPIPtr(nullptr),
54 chooseConfigPtr(nullptr),
55 createContextPtr(nullptr),
56 createPbufferSurfacePtr(nullptr),
57 createWindowSurfacePtr(nullptr),
58 destroyContextPtr(nullptr),
59 destroySurfacePtr(nullptr),
60 getConfigAttribPtr(nullptr),
61 getConfigsPtr(nullptr),
62 getCurrentSurfacePtr(nullptr),
63 getDisplayPtr(nullptr),
64 getErrorPtr(nullptr),
65 initializePtr(nullptr),
66 makeCurrentPtr(nullptr),
67 queryStringPtr(nullptr),
68 querySurfacePtr(nullptr),
69 swapBuffersPtr(nullptr),
70 terminatePtr(nullptr),
71
72 bindTexImagePtr(nullptr),
73 releaseTexImagePtr(nullptr),
74 surfaceAttribPtr(nullptr),
75 swapIntervalPtr(nullptr),
76
77 getCurrentContextPtr(nullptr),
78
79 createImageKHRPtr(nullptr),
80 destroyImageKHRPtr(nullptr),
81
82 createSyncKHRPtr(nullptr),
83 destroySyncKHRPtr(nullptr),
84 clientWaitSyncKHRPtr(nullptr),
85 getSyncAttribKHRPtr(nullptr),
86
87 waitSyncKHRPtr(nullptr),
88
89 swapBuffersWithDamageKHRPtr(nullptr),
90
91 presentationTimeANDROIDPtr(nullptr),
92
93 setBlobCacheFuncsANDROIDPtr(nullptr),
94
95 getCompositorTimingSupportedANDROIDPtr(nullptr),
96 getCompositorTimingANDROIDPtr(nullptr),
97 getNextFrameIdANDROIDPtr(nullptr),
98 getFrameTimestampSupportedANDROIDPtr(nullptr),
99 getFrameTimestampsANDROIDPtr(nullptr),
100
101 dupNativeFenceFDANDROIDPtr(nullptr),
102
103 queryDmaBufFormatsEXTPtr(nullptr),
104 queryDmaBufModifiersEXTPtr(nullptr),
105
106 queryDeviceAttribEXTPtr(nullptr),
107 queryDeviceStringEXTPtr(nullptr),
108 queryDisplayAttribEXTPtr(nullptr)
109 {}
110
111 // 1.0
112 PFNEGLBINDAPIPROC bindAPIPtr;
113 PFNEGLCHOOSECONFIGPROC chooseConfigPtr;
114 PFNEGLCREATECONTEXTPROC createContextPtr;
115 PFNEGLCREATEPBUFFERSURFACEPROC createPbufferSurfacePtr;
116 PFNEGLCREATEWINDOWSURFACEPROC createWindowSurfacePtr;
117 PFNEGLDESTROYCONTEXTPROC destroyContextPtr;
118 PFNEGLDESTROYSURFACEPROC destroySurfacePtr;
119 PFNEGLGETCONFIGATTRIBPROC getConfigAttribPtr;
120 PFNEGLGETCONFIGSPROC getConfigsPtr;
121 PFNEGLGETCURRENTSURFACEPROC getCurrentSurfacePtr;
122 PFNEGLGETDISPLAYPROC getDisplayPtr;
123 PFNEGLGETERRORPROC getErrorPtr;
124 PFNEGLINITIALIZEPROC initializePtr;
125 PFNEGLMAKECURRENTPROC makeCurrentPtr;
126 PFNEGLQUERYSTRINGPROC queryStringPtr;
127 PFNEGLQUERYSURFACEPROC querySurfacePtr;
128 PFNEGLSWAPBUFFERSPROC swapBuffersPtr;
129 PFNEGLTERMINATEPROC terminatePtr;
130
131 // 1.1
132 PFNEGLBINDTEXIMAGEPROC bindTexImagePtr;
133 PFNEGLRELEASETEXIMAGEPROC releaseTexImagePtr;
134 PFNEGLSURFACEATTRIBPROC surfaceAttribPtr;
135 PFNEGLSWAPINTERVALPROC swapIntervalPtr;
136
137 // 1.4
138 PFNEGLGETCURRENTCONTEXTPROC getCurrentContextPtr;
139
140 // EGL_KHR_image
141 PFNEGLCREATEIMAGEKHRPROC createImageKHRPtr;
142 PFNEGLDESTROYIMAGEKHRPROC destroyImageKHRPtr;
143
144 // EGL_KHR_fence_sync
145 PFNEGLCREATESYNCKHRPROC createSyncKHRPtr;
146 PFNEGLDESTROYSYNCKHRPROC destroySyncKHRPtr;
147 PFNEGLCLIENTWAITSYNCKHRPROC clientWaitSyncKHRPtr;
148 PFNEGLGETSYNCATTRIBKHRPROC getSyncAttribKHRPtr;
149
150 // EGL_KHR_wait_sync
151 PFNEGLWAITSYNCKHRPROC waitSyncKHRPtr;
152
153 // EGL_KHR_swap_buffers_with_damage
154 PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC swapBuffersWithDamageKHRPtr;
155
156 // EGL_ANDROID_presentation_time
157 PFNEGLPRESENTATIONTIMEANDROIDPROC presentationTimeANDROIDPtr;
158
159 // EGL_ANDROID_blob_cache
160 PFNEGLSETBLOBCACHEFUNCSANDROIDPROC setBlobCacheFuncsANDROIDPtr;
161
162 // EGL_ANDROID_get_frame_timestamps
163 PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC getCompositorTimingSupportedANDROIDPtr;
164 PFNEGLGETCOMPOSITORTIMINGANDROIDPROC getCompositorTimingANDROIDPtr;
165 PFNEGLGETNEXTFRAMEIDANDROIDPROC getNextFrameIdANDROIDPtr;
166 PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC getFrameTimestampSupportedANDROIDPtr;
167 PFNEGLGETFRAMETIMESTAMPSANDROIDPROC getFrameTimestampsANDROIDPtr;
168
169 // EGL_ANDROID_native_fence_sync
170 PFNEGLDUPNATIVEFENCEFDANDROIDPROC dupNativeFenceFDANDROIDPtr;
171
172 // EGL_EXT_image_dma_buf_import_modifiers
173 PFNEGLQUERYDMABUFFORMATSEXTPROC queryDmaBufFormatsEXTPtr;
174 PFNEGLQUERYDMABUFMODIFIERSEXTPROC queryDmaBufModifiersEXTPtr;
175
176 // EGL_EXT_device_query
177 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXTPtr;
178 PFNEGLQUERYDEVICESTRINGEXTPROC queryDeviceStringEXTPtr;
179 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXTPtr;
180 };
181
FunctionsEGL()182 FunctionsEGL::FunctionsEGL()
183 : majorVersion(0), minorVersion(0), mFnPtrs(new EGLDispatchTable()), mEGLDisplay(EGL_NO_DISPLAY)
184 {}
185
~FunctionsEGL()186 FunctionsEGL::~FunctionsEGL()
187 {
188 SafeDelete(mFnPtrs);
189 }
190
initialize(EGLAttrib platformType,EGLNativeDisplayType nativeDisplay)191 egl::Error FunctionsEGL::initialize(EGLAttrib platformType, EGLNativeDisplayType nativeDisplay)
192 {
193 #define ANGLE_GET_PROC_OR_WARNING(MEMBER, NAME) \
194 do \
195 { \
196 if (!SetPtr(MEMBER, getProcAddress(#NAME))) \
197 { \
198 WARN() << "Could not load EGL entry point " #NAME; \
199 } \
200 } while (0)
201 #define ANGLE_GET_PROC_OR_ERROR(MEMBER, NAME) \
202 do \
203 { \
204 if (!SetPtr(MEMBER, getProcAddress(#NAME))) \
205 { \
206 return egl::EglNotInitialized() << "Could not load EGL entry point " #NAME; \
207 } \
208 } while (0)
209
210 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindAPIPtr, eglBindAPI);
211 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->chooseConfigPtr, eglChooseConfig);
212 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createContextPtr, eglCreateContext);
213 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createPbufferSurfacePtr, eglCreatePbufferSurface);
214 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createWindowSurfacePtr, eglCreateWindowSurface);
215 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroyContextPtr, eglDestroyContext);
216 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySurfacePtr, eglDestroySurface);
217 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getConfigAttribPtr, eglGetConfigAttrib);
218 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getConfigsPtr, eglGetConfigs);
219 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getCurrentSurfacePtr, eglGetCurrentSurface);
220 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getDisplayPtr, eglGetDisplay);
221 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getErrorPtr, eglGetError);
222 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->initializePtr, eglInitialize);
223 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->makeCurrentPtr, eglMakeCurrent);
224 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->queryStringPtr, eglQueryString);
225 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->querySurfacePtr, eglQuerySurface);
226 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapBuffersPtr, eglSwapBuffers);
227 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->terminatePtr, eglTerminate);
228
229 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindTexImagePtr, eglBindTexImage);
230 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->releaseTexImagePtr, eglReleaseTexImage);
231 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->surfaceAttribPtr, eglSurfaceAttrib);
232 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalPtr, eglSwapInterval);
233
234 if (IsValidPlatformTypeForPlatformDisplayConnection(platformType))
235 {
236 mEGLDisplay = getPlatformDisplay(platformType, nativeDisplay);
237 }
238 else
239 {
240 mEGLDisplay = mFnPtrs->getDisplayPtr(nativeDisplay);
241 }
242
243 if (mEGLDisplay != EGL_NO_DISPLAY)
244 {
245 if (mFnPtrs->initializePtr(mEGLDisplay, &majorVersion, &minorVersion) != EGL_TRUE)
246 {
247 return egl::Error(mFnPtrs->getErrorPtr(), "Failed to initialize system egl");
248 }
249 }
250 else
251 {
252 // If no display was available, try to fallback to the first available
253 // native device object's display.
254 mEGLDisplay = getNativeDisplay(&majorVersion, &minorVersion);
255 if (mEGLDisplay == EGL_NO_DISPLAY)
256 {
257 return egl::EglNotInitialized() << "Failed to get system egl display";
258 }
259 }
260 if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 4))
261 {
262 return egl::EglNotInitialized() << "Unsupported EGL version (require at least 1.4).";
263 }
264 if (mFnPtrs->bindAPIPtr(EGL_OPENGL_ES_API) != EGL_TRUE)
265 {
266 return egl::Error(mFnPtrs->getErrorPtr(), "Failed to bind API in system egl");
267 }
268
269 vendorString = queryString(EGL_VENDOR);
270 versionString = queryString(EGL_VERSION);
271
272 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getCurrentContextPtr, eglGetCurrentContext);
273
274 const char *extensions = queryString(EGL_EXTENSIONS);
275 if (!extensions)
276 {
277 return egl::Error(mFnPtrs->getErrorPtr(), "Failed to query extensions in system egl");
278 }
279 angle::SplitStringAlongWhitespace(extensions, &mExtensions);
280
281 if (hasExtension("EGL_KHR_image_base"))
282 {
283 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createImageKHRPtr, eglCreateImageKHR);
284 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroyImageKHRPtr, eglDestroyImageKHR);
285 }
286 if (hasExtension("EGL_KHR_fence_sync"))
287 {
288 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createSyncKHRPtr, eglCreateSyncKHR);
289 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySyncKHRPtr, eglDestroySyncKHR);
290 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->clientWaitSyncKHRPtr, eglClientWaitSyncKHR);
291 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getSyncAttribKHRPtr, eglGetSyncAttribKHR);
292 }
293 if (hasExtension("EGL_KHR_wait_sync"))
294 {
295 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->waitSyncKHRPtr, eglWaitSyncKHR);
296 }
297
298 if (hasExtension("EGL_KHR_swap_buffers_with_damage"))
299 {
300 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapBuffersWithDamageKHRPtr, eglSwapBuffersWithDamageKHR);
301 }
302
303 if (hasExtension("EGL_ANDROID_presentation_time"))
304 {
305 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->presentationTimeANDROIDPtr, eglPresentationTimeANDROID);
306 }
307
308 if (hasExtension("EGL_ANDROID_blob_cache"))
309 {
310 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->setBlobCacheFuncsANDROIDPtr, eglSetBlobCacheFuncsANDROID);
311 }
312
313 if (hasExtension("EGL_ANDROID_get_frame_timestamps"))
314 {
315 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getCompositorTimingSupportedANDROIDPtr,
316 eglGetCompositorTimingSupportedANDROID);
317 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getCompositorTimingANDROIDPtr,
318 eglGetCompositorTimingANDROID);
319 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getNextFrameIdANDROIDPtr, eglGetNextFrameIdANDROID);
320 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getFrameTimestampSupportedANDROIDPtr,
321 eglGetFrameTimestampSupportedANDROID);
322 ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getFrameTimestampsANDROIDPtr,
323 eglGetFrameTimestampsANDROID);
324 }
325
326 // The native fence sync extension is a bit complicated. It's reported as present for ChromeOS,
327 // but Android currently doesn't report this extension even when it's present, and older devices
328 // may export a useless wrapper function. See crbug.com/775707 for details. In short, if the
329 // symbol is present and we're on Android N or newer, assume that it's usable even if the
330 // extension wasn't reported.
331 if (hasExtension("EGL_ANDROID_native_fence_sync") || GetAndroidSDKVersion() >= 24)
332 {
333 // Don't error trying to load this entry point.
334 if (SetPtr(&mFnPtrs->dupNativeFenceFDANDROIDPtr,
335 getProcAddress("eglDupNativeFenceFDANDROID")) &&
336 !hasExtension("EGL_ANDROID_native_fence_sync"))
337 {
338 mExtensions.push_back("EGL_ANDROID_native_fence_sync");
339 }
340 }
341
342 if (hasExtension("EGL_EXT_image_dma_buf_import_modifiers"))
343 {
344 // https://anglebug.com/7664
345 // Some drivers, notably older versions of ANGLE, announce this extension without
346 // implementing the following functions. DisplayEGL checks for this case and disables the
347 // extension.
348 ANGLE_GET_PROC_OR_WARNING(&mFnPtrs->queryDmaBufFormatsEXTPtr, eglQueryDmaBufFormatsEXT);
349 ANGLE_GET_PROC_OR_WARNING(&mFnPtrs->queryDmaBufModifiersEXTPtr, eglQueryDmaBufModifiersEXT);
350 }
351
352 // EGL_EXT_device_query is only advertised in extension string in the
353 // no-display case, see getNativeDisplay().
354 if (SetPtr(&mFnPtrs->queryDeviceAttribEXTPtr, getProcAddress("eglQueryDeviceAttribEXT")) &&
355 SetPtr(&mFnPtrs->queryDeviceStringEXTPtr, getProcAddress("eglQueryDeviceStringEXT")) &&
356 SetPtr(&mFnPtrs->queryDisplayAttribEXTPtr, getProcAddress("eglQueryDisplayAttribEXT")))
357 {
358 mExtensions.push_back("EGL_EXT_device_query");
359 }
360
361 #undef ANGLE_GET_PROC_OR_ERROR
362
363 return egl::NoError();
364 }
365
terminate()366 egl::Error FunctionsEGL::terminate()
367 {
368 if (mFnPtrs->terminatePtr == nullptr || mFnPtrs->terminatePtr(mEGLDisplay) == EGL_TRUE)
369 {
370 mEGLDisplay = nullptr;
371 return egl::NoError();
372 }
373 return egl::Error(mFnPtrs->getErrorPtr());
374 }
375
getPlatformDisplay(EGLAttrib platformType,EGLNativeDisplayType nativeDisplay)376 EGLDisplay FunctionsEGL::getPlatformDisplay(EGLAttrib platformType,
377 EGLNativeDisplayType nativeDisplay)
378 {
379 // As in getNativeDisplay(), querying EGL_EXTENSIONS string and loading it into the mExtensions
380 // vector will at this point retrieve the client extensions since mEGLDisplay is still
381 // EGL_NO_DISPLAY. This is desired, and mExtensions will later be reinitialized with the display
382 // extensions once the display is created and initialized.
383 const char *extensions = queryString(EGL_EXTENSIONS);
384 if (!extensions)
385 {
386 return EGL_NO_DISPLAY;
387 }
388 angle::SplitStringAlongWhitespace(extensions, &mExtensions);
389
390 PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplayEXTPtr;
391 if (!hasExtension("EGL_EXT_platform_base") ||
392 !SetPtr(&getPlatformDisplayEXTPtr, getProcAddress("eglGetPlatformDisplayEXT")))
393 {
394 return EGL_NO_DISPLAY;
395 }
396
397 ASSERT(IsValidPlatformTypeForPlatformDisplayConnection(platformType));
398 switch (platformType)
399 {
400 case EGL_PLATFORM_SURFACELESS_MESA:
401 if (!hasExtension("EGL_MESA_platform_surfaceless"))
402 return EGL_NO_DISPLAY;
403 break;
404 default:
405 UNREACHABLE();
406 return EGL_NO_DISPLAY;
407 }
408
409 return getPlatformDisplayEXTPtr(static_cast<EGLenum>(platformType),
410 reinterpret_cast<void *>(nativeDisplay), nullptr);
411 }
412
getNativeDisplay(int * major,int * minor)413 EGLDisplay FunctionsEGL::getNativeDisplay(int *major, int *minor)
414 {
415 // We haven't queried extensions yet since some platforms require a display
416 // to do so. We'll query them now since we need some for this fallback, and
417 // then re-query them again later once we have the display.
418 const char *extensions = queryString(EGL_EXTENSIONS);
419 if (!extensions)
420 {
421 return EGL_NO_DISPLAY;
422 }
423 angle::SplitStringAlongWhitespace(extensions, &mExtensions);
424
425 // This fallback mechanism makes use of:
426 // - EGL_EXT_device_enumeration or EGL_EXT_device_base for eglQueryDevicesEXT
427 // - EGL_EXT_platform_base for eglGetPlatformDisplayEXT
428 // - EGL_EXT_platform_device for EGL_PLATFORM_DEVICE_EXT
429 PFNEGLQUERYDEVICESEXTPROC queryDevices;
430 PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay;
431 bool hasQueryDevicesEXT =
432 hasExtension("EGL_EXT_device_enumeration") || hasExtension("EGL_EXT_device_base");
433 bool hasPlatformBaseEXT = hasExtension("EGL_EXT_platform_base");
434 bool hasPlatformDeviceEXT = hasExtension("EGL_EXT_platform_device");
435 if (!hasQueryDevicesEXT || !hasPlatformBaseEXT || !hasPlatformDeviceEXT)
436 {
437 return EGL_NO_DISPLAY;
438 }
439 if (!SetPtr(&queryDevices, getProcAddress("eglQueryDevicesEXT")) ||
440 !SetPtr(&getPlatformDisplay, getProcAddress("eglGetPlatformDisplayEXT")))
441 {
442 return EGL_NO_DISPLAY;
443 }
444
445 // Get a list of native device objects.
446 const EGLint kMaxDevices = 32;
447 EGLDeviceEXT eglDevices[kMaxDevices];
448 EGLint numDevices = 0;
449 if (!queryDevices(kMaxDevices, eglDevices, &numDevices))
450 {
451 return EGL_NO_DISPLAY;
452 }
453
454 // Look for the first native device that gives us a valid display.
455 for (EGLint i = 0; i < numDevices; i++)
456 {
457 EGLDisplay display = getPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, eglDevices[i], nullptr);
458 if (mFnPtrs->getErrorPtr() != EGL_SUCCESS)
459 {
460 continue;
461 }
462 if (mFnPtrs->initializePtr(display, major, minor) == EGL_TRUE)
463 {
464 return display;
465 }
466 }
467
468 return EGL_NO_DISPLAY;
469 }
470
471 class FunctionsGLEGL : public FunctionsGL
472 {
473 public:
FunctionsGLEGL(const FunctionsEGL & egl)474 FunctionsGLEGL(const FunctionsEGL &egl) : mEGL(egl) {}
475
~FunctionsGLEGL()476 ~FunctionsGLEGL() override {}
477
478 private:
loadProcAddress(const std::string & function) const479 void *loadProcAddress(const std::string &function) const override
480 {
481 return mEGL.getProcAddress(function.c_str());
482 }
483
484 const FunctionsEGL &mEGL;
485 };
486
makeFunctionsGL(void) const487 FunctionsGL *FunctionsEGL::makeFunctionsGL(void) const
488 {
489 return new FunctionsGLEGL(*this);
490 }
491
hasExtension(const char * extension) const492 bool FunctionsEGL::hasExtension(const char *extension) const
493 {
494 return std::find(mExtensions.begin(), mExtensions.end(), extension) != mExtensions.end();
495 }
496
hasDmaBufImportModifierFunctions() const497 bool FunctionsEGL::hasDmaBufImportModifierFunctions() const
498 {
499 return mFnPtrs->queryDmaBufFormatsEXTPtr != nullptr &&
500 mFnPtrs->queryDmaBufModifiersEXTPtr != nullptr;
501 }
502
getDisplay() const503 EGLDisplay FunctionsEGL::getDisplay() const
504 {
505 return mEGLDisplay;
506 }
507
getError() const508 EGLint FunctionsEGL::getError() const
509 {
510 return mFnPtrs->getErrorPtr();
511 }
512
chooseConfig(EGLint const * attribList,EGLConfig * configs,EGLint configSize,EGLint * numConfig) const513 EGLBoolean FunctionsEGL::chooseConfig(EGLint const *attribList,
514 EGLConfig *configs,
515 EGLint configSize,
516 EGLint *numConfig) const
517 {
518 return mFnPtrs->chooseConfigPtr(mEGLDisplay, attribList, configs, configSize, numConfig);
519 }
520
getConfigs(EGLConfig * configs,EGLint config_size,EGLint * num_config) const521 EGLBoolean FunctionsEGL::getConfigs(EGLConfig *configs,
522 EGLint config_size,
523 EGLint *num_config) const
524 {
525 return mFnPtrs->getConfigsPtr(mEGLDisplay, configs, config_size, num_config);
526 }
527
getConfigAttrib(EGLConfig config,EGLint attribute,EGLint * value) const528 EGLBoolean FunctionsEGL::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) const
529 {
530 return mFnPtrs->getConfigAttribPtr(mEGLDisplay, config, attribute, value);
531 }
532
getCurrentSurface(EGLint readdraw) const533 EGLSurface FunctionsEGL::getCurrentSurface(EGLint readdraw) const
534 {
535 return mFnPtrs->getCurrentSurfacePtr(readdraw);
536 }
537
createContext(EGLConfig config,EGLContext share_context,EGLint const * attrib_list) const538 EGLContext FunctionsEGL::createContext(EGLConfig config,
539 EGLContext share_context,
540 EGLint const *attrib_list) const
541 {
542 return mFnPtrs->createContextPtr(mEGLDisplay, config, share_context, attrib_list);
543 }
544
createPbufferSurface(EGLConfig config,const EGLint * attrib_list) const545 EGLSurface FunctionsEGL::createPbufferSurface(EGLConfig config, const EGLint *attrib_list) const
546 {
547 return mFnPtrs->createPbufferSurfacePtr(mEGLDisplay, config, attrib_list);
548 }
549
createWindowSurface(EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list) const550 EGLSurface FunctionsEGL::createWindowSurface(EGLConfig config,
551 EGLNativeWindowType win,
552 const EGLint *attrib_list) const
553 {
554 return mFnPtrs->createWindowSurfacePtr(mEGLDisplay, config, win, attrib_list);
555 }
556
destroyContext(EGLContext context) const557 EGLBoolean FunctionsEGL::destroyContext(EGLContext context) const
558 {
559 return mFnPtrs->destroyContextPtr(mEGLDisplay, context);
560 }
561
destroySurface(EGLSurface surface) const562 EGLBoolean FunctionsEGL::destroySurface(EGLSurface surface) const
563 {
564 return mFnPtrs->destroySurfacePtr(mEGLDisplay, surface);
565 }
566
makeCurrent(EGLSurface surface,EGLContext context) const567 EGLBoolean FunctionsEGL::makeCurrent(EGLSurface surface, EGLContext context) const
568 {
569 return mFnPtrs->makeCurrentPtr(mEGLDisplay, surface, surface, context);
570 }
571
queryString(EGLint name) const572 char const *FunctionsEGL::queryString(EGLint name) const
573 {
574 return mFnPtrs->queryStringPtr(mEGLDisplay, name);
575 }
576
querySurface(EGLSurface surface,EGLint attribute,EGLint * value) const577 EGLBoolean FunctionsEGL::querySurface(EGLSurface surface, EGLint attribute, EGLint *value) const
578 {
579 return mFnPtrs->querySurfacePtr(mEGLDisplay, surface, attribute, value);
580 }
581
swapBuffers(EGLSurface surface) const582 EGLBoolean FunctionsEGL::swapBuffers(EGLSurface surface) const
583 {
584 return mFnPtrs->swapBuffersPtr(mEGLDisplay, surface);
585 }
586
bindTexImage(EGLSurface surface,EGLint buffer) const587 EGLBoolean FunctionsEGL::bindTexImage(EGLSurface surface, EGLint buffer) const
588 {
589 return mFnPtrs->bindTexImagePtr(mEGLDisplay, surface, buffer);
590 }
591
releaseTexImage(EGLSurface surface,EGLint buffer) const592 EGLBoolean FunctionsEGL::releaseTexImage(EGLSurface surface, EGLint buffer) const
593 {
594 return mFnPtrs->releaseTexImagePtr(mEGLDisplay, surface, buffer);
595 }
596
surfaceAttrib(EGLSurface surface,EGLint attribute,EGLint value) const597 EGLBoolean FunctionsEGL::surfaceAttrib(EGLSurface surface, EGLint attribute, EGLint value) const
598 {
599 return mFnPtrs->surfaceAttribPtr(mEGLDisplay, surface, attribute, value);
600 }
601
swapInterval(EGLint interval) const602 EGLBoolean FunctionsEGL::swapInterval(EGLint interval) const
603 {
604 return mFnPtrs->swapIntervalPtr(mEGLDisplay, interval);
605 }
606
getCurrentContext() const607 EGLContext FunctionsEGL::getCurrentContext() const
608 {
609 return mFnPtrs->getCurrentContextPtr();
610 }
611
createImageKHR(EGLContext context,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list) const612 EGLImageKHR FunctionsEGL::createImageKHR(EGLContext context,
613 EGLenum target,
614 EGLClientBuffer buffer,
615 const EGLint *attrib_list) const
616 {
617 return mFnPtrs->createImageKHRPtr(mEGLDisplay, context, target, buffer, attrib_list);
618 }
619
destroyImageKHR(EGLImageKHR image) const620 EGLBoolean FunctionsEGL::destroyImageKHR(EGLImageKHR image) const
621 {
622 return mFnPtrs->destroyImageKHRPtr(mEGLDisplay, image);
623 }
624
createSyncKHR(EGLenum type,const EGLint * attrib_list) const625 EGLSyncKHR FunctionsEGL::createSyncKHR(EGLenum type, const EGLint *attrib_list) const
626 {
627 return mFnPtrs->createSyncKHRPtr(mEGLDisplay, type, attrib_list);
628 }
629
destroySyncKHR(EGLSyncKHR sync) const630 EGLBoolean FunctionsEGL::destroySyncKHR(EGLSyncKHR sync) const
631 {
632 return mFnPtrs->destroySyncKHRPtr(mEGLDisplay, sync);
633 }
634
clientWaitSyncKHR(EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout) const635 EGLint FunctionsEGL::clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) const
636 {
637 return mFnPtrs->clientWaitSyncKHRPtr(mEGLDisplay, sync, flags, timeout);
638 }
639
getSyncAttribKHR(EGLSyncKHR sync,EGLint attribute,EGLint * value) const640 EGLBoolean FunctionsEGL::getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value) const
641 {
642 return mFnPtrs->getSyncAttribKHRPtr(mEGLDisplay, sync, attribute, value);
643 }
644
waitSyncKHR(EGLSyncKHR sync,EGLint flags) const645 EGLint FunctionsEGL::waitSyncKHR(EGLSyncKHR sync, EGLint flags) const
646 {
647 return mFnPtrs->waitSyncKHRPtr(mEGLDisplay, sync, flags);
648 }
649
swapBuffersWithDamageKHR(EGLSurface surface,const EGLint * rects,EGLint n_rects) const650 EGLBoolean FunctionsEGL::swapBuffersWithDamageKHR(EGLSurface surface,
651 const EGLint *rects,
652 EGLint n_rects) const
653 {
654 return mFnPtrs->swapBuffersWithDamageKHRPtr(mEGLDisplay, surface, rects, n_rects);
655 }
656
presentationTimeANDROID(EGLSurface surface,EGLnsecsANDROID time) const657 EGLBoolean FunctionsEGL::presentationTimeANDROID(EGLSurface surface, EGLnsecsANDROID time) const
658 {
659 return mFnPtrs->presentationTimeANDROIDPtr(mEGLDisplay, surface, time);
660 }
661
setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set,EGLGetBlobFuncANDROID get) const662 void FunctionsEGL::setBlobCacheFuncsANDROID(EGLSetBlobFuncANDROID set,
663 EGLGetBlobFuncANDROID get) const
664 {
665 return mFnPtrs->setBlobCacheFuncsANDROIDPtr(mEGLDisplay, set, get);
666 }
667
getCompositorTimingSupportedANDROID(EGLSurface surface,EGLint name) const668 EGLBoolean FunctionsEGL::getCompositorTimingSupportedANDROID(EGLSurface surface, EGLint name) const
669 {
670 return mFnPtrs->getCompositorTimingSupportedANDROIDPtr(mEGLDisplay, surface, name);
671 }
672
getCompositorTimingANDROID(EGLSurface surface,EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const673 EGLBoolean FunctionsEGL::getCompositorTimingANDROID(EGLSurface surface,
674 EGLint numTimestamps,
675 const EGLint *names,
676 EGLnsecsANDROID *values) const
677 {
678 return mFnPtrs->getCompositorTimingANDROIDPtr(mEGLDisplay, surface, numTimestamps, names,
679 values);
680 }
681
getNextFrameIdANDROID(EGLSurface surface,EGLuint64KHR * frameId) const682 EGLBoolean FunctionsEGL::getNextFrameIdANDROID(EGLSurface surface, EGLuint64KHR *frameId) const
683 {
684 return mFnPtrs->getNextFrameIdANDROIDPtr(mEGLDisplay, surface, frameId);
685 }
686
getFrameTimestampSupportedANDROID(EGLSurface surface,EGLint timestamp) const687 EGLBoolean FunctionsEGL::getFrameTimestampSupportedANDROID(EGLSurface surface,
688 EGLint timestamp) const
689 {
690 return mFnPtrs->getFrameTimestampSupportedANDROIDPtr(mEGLDisplay, surface, timestamp);
691 }
692
getFrameTimestampsANDROID(EGLSurface surface,EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const693 EGLBoolean FunctionsEGL::getFrameTimestampsANDROID(EGLSurface surface,
694 EGLuint64KHR frameId,
695 EGLint numTimestamps,
696 const EGLint *timestamps,
697 EGLnsecsANDROID *values) const
698 {
699 return mFnPtrs->getFrameTimestampsANDROIDPtr(mEGLDisplay, surface, frameId, numTimestamps,
700 timestamps, values);
701 }
702
dupNativeFenceFDANDROID(EGLSync sync) const703 EGLint FunctionsEGL::dupNativeFenceFDANDROID(EGLSync sync) const
704 {
705 return mFnPtrs->dupNativeFenceFDANDROIDPtr(mEGLDisplay, sync);
706 }
707
queryDmaBufFormatsEXT(EGLint maxFormats,EGLint * formats,EGLint * numFormats) const708 EGLint FunctionsEGL::queryDmaBufFormatsEXT(EGLint maxFormats,
709 EGLint *formats,
710 EGLint *numFormats) const
711 {
712 return mFnPtrs->queryDmaBufFormatsEXTPtr(mEGLDisplay, maxFormats, formats, numFormats);
713 }
714
queryDmaBufModifiersEXT(EGLint format,EGLint maxModifiers,EGLuint64KHR * modifiers,EGLBoolean * externalOnly,EGLint * numModifiers) const715 EGLint FunctionsEGL::queryDmaBufModifiersEXT(EGLint format,
716 EGLint maxModifiers,
717 EGLuint64KHR *modifiers,
718 EGLBoolean *externalOnly,
719 EGLint *numModifiers) const
720 {
721 return mFnPtrs->queryDmaBufModifiersEXTPtr(mEGLDisplay, format, maxModifiers, modifiers,
722 externalOnly, numModifiers);
723 }
724
queryDeviceAttribEXT(EGLDeviceEXT device,EGLint attribute,EGLAttrib * value) const725 EGLBoolean FunctionsEGL::queryDeviceAttribEXT(EGLDeviceEXT device,
726 EGLint attribute,
727 EGLAttrib *value) const
728 {
729 return mFnPtrs->queryDeviceAttribEXTPtr(device, attribute, value);
730 }
731
queryDeviceStringEXT(EGLDeviceEXT device,EGLint name) const732 const char *FunctionsEGL::queryDeviceStringEXT(EGLDeviceEXT device, EGLint name) const
733 {
734 return mFnPtrs->queryDeviceStringEXTPtr(device, name);
735 }
736
queryDisplayAttribEXT(EGLint attribute,EGLAttrib * value) const737 EGLBoolean FunctionsEGL::queryDisplayAttribEXT(EGLint attribute, EGLAttrib *value) const
738 {
739 return mFnPtrs->queryDisplayAttribEXTPtr(mEGLDisplay, attribute, value);
740 }
741
742 } // namespace rx
743