// // Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // FunctionsEGLDL.cpp: Implements the FunctionsEGLDL class. #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h" #include namespace rx { DynamicLib::DynamicLib() : handle(nullptr) { } DynamicLib::~DynamicLib() { if (handle) { dlclose(handle); handle = nullptr; } } // Due to a bug in Mesa (or maybe libdl) it's not possible to close and re-open libEGL.so // an arbitrary number of times. End2end tests would die after a couple hundred tests. // So we use a static object with a destructor to close the library when the program exits. // TODO(fjhenigman) File a bug and put a link here. DynamicLib FunctionsEGLDL::sNativeLib; FunctionsEGLDL::FunctionsEGLDL() : mGetProcAddressPtr(nullptr) { } FunctionsEGLDL::~FunctionsEGLDL() { } egl::Error FunctionsEGLDL::initialize(EGLNativeDisplayType nativeDisplay, const char *libName) { if (!sNativeLib.handle) { sNativeLib.handle = dlopen(libName, RTLD_NOW); if (!sNativeLib.handle) { return egl::Error(EGL_NOT_INITIALIZED, "Could not dlopen native EGL: %s", dlerror()); } } mGetProcAddressPtr = reinterpret_cast(dlsym(sNativeLib.handle, "eglGetProcAddress")); if (!mGetProcAddressPtr) { return egl::Error(EGL_NOT_INITIALIZED, "Could not find eglGetProcAddress"); } return FunctionsEGL::initialize(nativeDisplay); } void *FunctionsEGLDL::getProcAddress(const char *name) const { void *f = reinterpret_cast(mGetProcAddressPtr(name)); if (f) { return f; } return dlsym(sNativeLib.handle, name); } } // namespace rx