blob: e6ef45d8dda2a7a200ec7cdf5b80108686e32c50 [file] [log] [blame]
//
// 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 <dlfcn.h>
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<PFNEGLGETPROCADDRESSPROC>(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<void *>(mGetProcAddressPtr(name));
if (f)
{
return f;
}
return dlsym(sNativeLib.handle, name);
}
} // namespace rx