• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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