xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // FunctionsEGLDL.cpp: Implements the FunctionsEGLDL class.
8 
9 #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
10 
11 #include <dlfcn.h>
12 
13 namespace rx
14 {
15 namespace
16 {
17 // In ideal world, we would want this to be a member of FunctionsEGLDL,
18 // and call dlclose() on it in ~FunctionsEGLDL().
19 // However, some GL implementations are broken and don't allow multiple
20 // load/unload cycles, but only static linking with them.
21 // That's why we dlopen() this handle once and never dlclose() it.
22 // This is consistent with Chromium's CleanupNativeLibraries() code,
23 // referencing crbug.com/250813 and http://www.xfree86.org/4.3.0/DRI11.html
24 void *nativeEGLHandle;
25 }  // anonymous namespace
26 
FunctionsEGLDL()27 FunctionsEGLDL::FunctionsEGLDL() : mGetProcAddressPtr(nullptr) {}
28 
~FunctionsEGLDL()29 FunctionsEGLDL::~FunctionsEGLDL() {}
30 
initialize(EGLAttrib platformType,EGLNativeDisplayType nativeDisplay,const char * libName,void * eglHandle)31 egl::Error FunctionsEGLDL::initialize(EGLAttrib platformType,
32                                       EGLNativeDisplayType nativeDisplay,
33                                       const char *libName,
34                                       void *eglHandle)
35 {
36 
37     if (eglHandle)
38     {
39         // If the handle is provided, use it.
40         // Caller has already dlopened the vendor library.
41         nativeEGLHandle = eglHandle;
42     }
43 
44     if (!nativeEGLHandle)
45     {
46         nativeEGLHandle = dlopen(libName, RTLD_NOW);
47         if (!nativeEGLHandle)
48         {
49             return egl::EglNotInitialized() << "Could not dlopen native EGL: " << dlerror();
50         }
51     }
52 
53     mGetProcAddressPtr =
54         reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(dlsym(nativeEGLHandle, "eglGetProcAddress"));
55     if (!mGetProcAddressPtr)
56     {
57         return egl::EglNotInitialized() << "Could not find eglGetProcAddress";
58     }
59 
60     return FunctionsEGL::initialize(platformType, nativeDisplay);
61 }
62 
getProcAddress(const char * name) const63 void *FunctionsEGLDL::getProcAddress(const char *name) const
64 {
65     void *f = reinterpret_cast<void *>(mGetProcAddressPtr(name));
66     if (f)
67     {
68         return f;
69     }
70     return dlsym(nativeEGLHandle, name);
71 }
72 
73 }  // namespace rx
74