Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLSurfacelessContextTest.cpp
1693 views
1
//
2
// Copyright 2017 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
// EGLSurfacelessContextTest.cpp:
8
// Tests for the EGL_KHR_surfaceless_context and GL_OES_surfaceless_context
9
10
#include <gtest/gtest.h>
11
12
#include "test_utils/ANGLETest.h"
13
#include "test_utils/angle_test_configs.h"
14
#include "test_utils/gl_raii.h"
15
16
using namespace angle;
17
18
namespace
19
{
20
21
class EGLSurfacelessContextTest : public ANGLETest
22
{
23
public:
24
EGLSurfacelessContextTest() : mDisplay(0) {}
25
26
void testSetUp() override
27
{
28
EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
29
mDisplay = eglGetPlatformDisplayEXT(
30
EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
31
ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
32
33
ASSERT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
34
35
int nConfigs = 0;
36
ASSERT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs));
37
ASSERT_TRUE(nConfigs != 0);
38
39
int nReturnedConfigs = 0;
40
std::vector<EGLConfig> configs(nConfigs);
41
ASSERT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), nConfigs, &nReturnedConfigs));
42
ASSERT_TRUE(nConfigs == nReturnedConfigs);
43
44
for (auto config : configs)
45
{
46
EGLint surfaceType;
47
eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
48
if (surfaceType & EGL_PBUFFER_BIT)
49
{
50
mConfig = config;
51
mSupportsPbuffers = true;
52
break;
53
}
54
}
55
56
if (!mConfig)
57
{
58
mConfig = configs[0];
59
}
60
61
ASSERT_NE(nullptr, mConfig);
62
}
63
64
void testTearDown() override
65
{
66
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
67
68
if (mContext != EGL_NO_CONTEXT)
69
{
70
eglDestroyContext(mDisplay, mContext);
71
}
72
73
if (mPbuffer != EGL_NO_SURFACE)
74
{
75
eglDestroySurface(mDisplay, mPbuffer);
76
}
77
78
eglTerminate(mDisplay);
79
}
80
81
protected:
82
EGLContext createContext()
83
{
84
const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
85
86
mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, contextAttribs);
87
EXPECT_TRUE(mContext != EGL_NO_CONTEXT);
88
return mContext;
89
}
90
91
EGLSurface createPbuffer(int width, int height)
92
{
93
if (!mSupportsPbuffers)
94
{
95
return EGL_NO_SURFACE;
96
}
97
98
const EGLint pbufferAttribs[] = {
99
EGL_WIDTH, 500, EGL_HEIGHT, 500, EGL_NONE,
100
};
101
mPbuffer = eglCreatePbufferSurface(mDisplay, mConfig, pbufferAttribs);
102
EXPECT_TRUE(mPbuffer != EGL_NO_SURFACE);
103
return mPbuffer;
104
}
105
106
void createFramebuffer(GLFramebuffer *fbo, GLTexture *tex) const
107
{
108
glBindFramebuffer(GL_FRAMEBUFFER, fbo->get());
109
110
glBindTexture(GL_TEXTURE_2D, tex->get());
111
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 500, 500, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
112
113
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->get(), 0);
114
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
115
}
116
117
bool checkExtension(bool verbose = true) const
118
{
119
if (!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_KHR_surfaceless_context"))
120
{
121
if (verbose)
122
{
123
std::cout << "Test skipped because EGL_KHR_surfaceless_context is not available."
124
<< std::endl;
125
}
126
return false;
127
}
128
return true;
129
}
130
131
EGLContext mContext = EGL_NO_CONTEXT;
132
EGLSurface mPbuffer = EGL_NO_SURFACE;
133
bool mSupportsPbuffers = false;
134
EGLConfig mConfig = 0;
135
EGLDisplay mDisplay = EGL_NO_DISPLAY;
136
};
137
138
// Test surfaceless MakeCurrent returns the correct value.
139
TEST_P(EGLSurfacelessContextTest, MakeCurrentSurfaceless)
140
{
141
EGLContext context = createContext();
142
143
if (eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context))
144
{
145
ASSERT_TRUE(checkExtension(false));
146
}
147
else
148
{
149
// The extension allows EGL_BAD_MATCH with the extension too, but ANGLE
150
// shouldn't do that.
151
ASSERT_FALSE(checkExtension(false));
152
}
153
}
154
155
// Test that the scissor and viewport are set correctly
156
TEST_P(EGLSurfacelessContextTest, DefaultScissorAndViewport)
157
{
158
if (!checkExtension())
159
{
160
return;
161
}
162
163
EGLContext context = createContext();
164
ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
165
166
GLint scissor[4] = {1, 2, 3, 4};
167
glGetIntegerv(GL_SCISSOR_BOX, scissor);
168
ASSERT_GL_NO_ERROR();
169
ASSERT_EQ(0, scissor[0]);
170
ASSERT_EQ(0, scissor[1]);
171
ASSERT_EQ(0, scissor[2]);
172
ASSERT_EQ(0, scissor[3]);
173
174
GLint viewport[4] = {1, 2, 3, 4};
175
glGetIntegerv(GL_VIEWPORT, viewport);
176
ASSERT_GL_NO_ERROR();
177
ASSERT_EQ(0, viewport[0]);
178
ASSERT_EQ(0, viewport[1]);
179
ASSERT_EQ(0, viewport[2]);
180
ASSERT_EQ(0, viewport[3]);
181
}
182
183
// Test the CheckFramebufferStatus returns the correct value.
184
TEST_P(EGLSurfacelessContextTest, CheckFramebufferStatus)
185
{
186
if (!checkExtension())
187
{
188
return;
189
}
190
191
EGLContext context = createContext();
192
ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
193
194
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_UNDEFINED_OES, glCheckFramebufferStatus(GL_FRAMEBUFFER));
195
196
GLFramebuffer fbo;
197
GLTexture tex;
198
createFramebuffer(&fbo, &tex);
199
glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
200
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
201
}
202
203
// Test that clearing and readpixels work when done in an FBO.
204
TEST_P(EGLSurfacelessContextTest, ClearReadPixelsInFBO)
205
{
206
if (!checkExtension())
207
{
208
return;
209
}
210
211
EGLContext context = createContext();
212
ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
213
214
GLFramebuffer fbo;
215
GLTexture tex;
216
createFramebuffer(&fbo, &tex);
217
glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
218
219
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
220
glClear(GL_COLOR_BUFFER_BIT);
221
ASSERT_GL_NO_ERROR();
222
223
EXPECT_PIXEL_COLOR_EQ(250, 250, GLColor::red);
224
ASSERT_GL_NO_ERROR();
225
}
226
227
// Test clear+readpixels in an FBO in surfaceless and in the default FBO in a pbuffer
228
TEST_P(EGLSurfacelessContextTest, Switcheroo)
229
{
230
ANGLE_SKIP_TEST_IF(!checkExtension());
231
ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);
232
233
// Fails on NVIDIA Shield TV (http://anglebug.com/4924)
234
ANGLE_SKIP_TEST_IF(IsAndroid() && IsNVIDIA());
235
236
EGLContext context = createContext();
237
EGLSurface pbuffer = createPbuffer(500, 500);
238
239
// We need to make the context current to do the one time setup of the FBO
240
ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
241
GLFramebuffer fbo;
242
GLTexture tex;
243
createFramebuffer(&fbo, &tex);
244
glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
245
246
for (int i = 0; i < 4; ++i)
247
{
248
// Clear to red in the FBO in surfaceless mode
249
ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
250
251
glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
252
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
253
glClear(GL_COLOR_BUFFER_BIT);
254
ASSERT_GL_NO_ERROR();
255
256
EXPECT_PIXEL_COLOR_EQ(250, 250, GLColor::red);
257
ASSERT_GL_NO_ERROR();
258
259
// Clear to green in the pbuffer
260
ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, pbuffer, pbuffer, context));
261
262
glBindFramebuffer(GL_FRAMEBUFFER, 0);
263
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
264
glClear(GL_COLOR_BUFFER_BIT);
265
ASSERT_GL_NO_ERROR();
266
267
EXPECT_PIXEL_COLOR_EQ(250, 250, GLColor::green);
268
ASSERT_GL_NO_ERROR();
269
}
270
}
271
272
} // anonymous namespace
273
274
ANGLE_INSTANTIATE_TEST(EGLSurfacelessContextTest,
275
WithNoFixture(ES2_D3D9()),
276
WithNoFixture(ES2_D3D11()),
277
WithNoFixture(ES2_METAL()),
278
WithNoFixture(ES2_OPENGL()),
279
WithNoFixture(ES2_OPENGLES()),
280
WithNoFixture(ES2_VULKAN()));
281
282