summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
blob: e6ef45d8dda2a7a200ec7cdf5b80108686e32c50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//
// 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