summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/egl_tests/EGLThreadTest.cpp
blob: 305ccc25f9b966dec11e4773a0dde9f4fe0d2da2 (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
75
76
77
78
79
80
81
82
83
#include "gtest/gtest.h"

#include <EGL/egl.h>
#include <EGL/eglext.h>

typedef EGLAPI EGLDisplay EGLAPIENTRY EGLGetDisplay(EGLNativeDisplayType display_id);
typedef EGLAPI EGLBoolean EGLAPIENTRY EGLInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLAPI EGLContext EGLAPIENTRY EGLGetCurrentContext(void);
typedef EGLAPI EGLSurface EGLAPIENTRY EGLGetCurrentSurface(EGLint readdraw);
typedef EGLAPI EGLBoolean EGLAPIENTRY EGLTerminate(EGLDisplay dpy);

class EGLThreadTest : public testing::Test
{
  public:
    virtual void SetUp() {}
    virtual void TearDown() {}

    EGLGetDisplay *mGetDisplay;
    EGLInitialize *mInitialize;
    EGLGetCurrentContext *mGetCurrentContext;
    EGLGetCurrentSurface *mGetCurrentSurface;

    EGLDisplay mDisplay;

    HMODULE mEGL;
    HMODULE mGLESv2;

    static DWORD WINAPI ThreadingTestEntryPoint(LPVOID thisPointer);

  private:
    void ThreadingTest();
};

DWORD WINAPI EGLThreadTest::ThreadingTestEntryPoint(LPVOID lpParameter)
{
    EGLThreadTest *test = (EGLThreadTest *)lpParameter;
    test->ThreadingTest();
    return 0;
}

void EGLThreadTest::ThreadingTest()
{
    mEGL = LoadLibrary(TEXT("libEGL.dll"));
    mGLESv2 = LoadLibrary(TEXT("libGLESv2.dll"));

    EXPECT_TRUE(mEGL != NULL);
    EXPECT_TRUE(mGLESv2 != NULL);

    mGetDisplay = (EGLGetDisplay *)GetProcAddress(mEGL, "eglGetDisplay");
    mInitialize = (EGLInitialize *)GetProcAddress(mEGL, "eglInitialize");
    mGetCurrentContext = (EGLGetCurrentContext *)GetProcAddress(mEGL, "eglGetCurrentContext");
    mGetCurrentSurface = (EGLGetCurrentSurface *)GetProcAddress(mEGL, "eglGetCurrentSurface");

    EXPECT_TRUE(mGetDisplay != NULL);
    EXPECT_TRUE(mInitialize != NULL);
    EXPECT_TRUE(mGetCurrentContext != NULL);
    EXPECT_TRUE(mGetCurrentSurface != NULL);

    mDisplay = mGetDisplay(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);

    EXPECT_TRUE(mDisplay!= EGL_NO_DISPLAY);

    mInitialize(mDisplay, NULL, NULL);
    mGetCurrentContext();
}

TEST_F(EGLThreadTest, thread_init_crash)
{
    DWORD threadId;
    HANDLE threadHandle = CreateThread(NULL, 0, EGLThreadTest::ThreadingTestEntryPoint, this, 0, &threadId);
    EXPECT_TRUE(threadHandle != NULL);

    // wait for signal from thread
    DWORD waitResult = WaitForSingleObject(threadHandle, 1000);
    EXPECT_EQ(waitResult, WAIT_OBJECT_0);

    // crash, because the TLS value is NULL on main thread
    mGetCurrentSurface(EGL_DRAW);
    mGetCurrentContext();

    auto terminate = (EGLTerminate *)GetProcAddress(mEGL, "eglTerminate");
    terminate(mDisplay);
}