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(EGLNativeDisplayType nativeDisplay,const char * libName,void * eglHandle)31 egl::Error FunctionsEGLDL::initialize(EGLNativeDisplayType nativeDisplay,
32 const char *libName,
33 void *eglHandle)
34 {
35
36 if (eglHandle)
37 {
38 // If the handle is provided, use it.
39 // Caller has already dlopened the vendor library.
40 nativeEGLHandle = eglHandle;
41 }
42
43 if (!nativeEGLHandle)
44 {
45 nativeEGLHandle = dlopen(libName, RTLD_NOW);
46 if (!nativeEGLHandle)
47 {
48 return egl::EglNotInitialized() << "Could not dlopen native EGL: " << dlerror();
49 }
50 }
51
52 mGetProcAddressPtr =
53 reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(dlsym(nativeEGLHandle, "eglGetProcAddress"));
54 if (!mGetProcAddressPtr)
55 {
56 return egl::EglNotInitialized() << "Could not find eglGetProcAddress";
57 }
58
59 return FunctionsEGL::initialize(nativeDisplay);
60 }
61
getProcAddress(const char * name) const62 void *FunctionsEGLDL::getProcAddress(const char *name) const
63 {
64 void *f = reinterpret_cast<void *>(mGetProcAddressPtr(name));
65 if (f)
66 {
67 return f;
68 }
69 return dlsym(nativeEGLHandle, name);
70 }
71
72 } // namespace rx
73