1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // EGLNoConfigContectTest.cpp:
7*8975f5c5SAndroid Build Coastguard Worker // EGL extension EGL_KHR_no_config_context allows a context to be created
8*8975f5c5SAndroid Build Coastguard Worker // without a config specified. This means all surfaces are compatible.
9*8975f5c5SAndroid Build Coastguard Worker // As a result compatibility checks are circumvented.
10*8975f5c5SAndroid Build Coastguard Worker // This test suite creates and verifies creating a configless context
11*8975f5c5SAndroid Build Coastguard Worker // and then verifies simple rendering to ensure compatibility.
12*8975f5c5SAndroid Build Coastguard Worker //
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker #include <gtest/gtest.h>
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker class EGLNoConfigContextTest : public ANGLETest<>
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker public:
EGLNoConfigContextTest()23*8975f5c5SAndroid Build Coastguard Worker EGLNoConfigContextTest() : mDisplay(EGL_NO_DISPLAY), mContext(EGL_NO_CONTEXT) {}
24*8975f5c5SAndroid Build Coastguard Worker
testSetUp()25*8975f5c5SAndroid Build Coastguard Worker void testSetUp() override
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker int clientVersion = GetParam().majorVersion;
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Worker EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
30*8975f5c5SAndroid Build Coastguard Worker mDisplay = eglGetPlatformDisplayEXT(
31*8975f5c5SAndroid Build Coastguard Worker EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
32*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
33*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Worker mExtensionSupported = IsEGLDisplayExtensionEnabled(mDisplay, "EGL_KHR_no_config_context");
36*8975f5c5SAndroid Build Coastguard Worker if (!mExtensionSupported)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker return; // Not supported, don't create context
39*8975f5c5SAndroid Build Coastguard Worker }
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Worker EGLint ctxattrs[] = {EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL_NONE};
42*8975f5c5SAndroid Build Coastguard Worker mContext = eglCreateContext(mDisplay, EGL_NO_CONFIG_KHR, nullptr, ctxattrs);
43*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(mContext != EGL_NO_CONTEXT);
44*8975f5c5SAndroid Build Coastguard Worker }
45*8975f5c5SAndroid Build Coastguard Worker
testTearDown()46*8975f5c5SAndroid Build Coastguard Worker void testTearDown() override
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker if (mDisplay != EGL_NO_DISPLAY)
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker if (mContext != EGL_NO_CONTEXT)
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker eglDestroyContext(mDisplay, mContext);
53*8975f5c5SAndroid Build Coastguard Worker mContext = EGL_NO_CONTEXT;
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker eglTerminate(mDisplay);
56*8975f5c5SAndroid Build Coastguard Worker eglReleaseThread();
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS() << "Error during test TearDown";
59*8975f5c5SAndroid Build Coastguard Worker }
60*8975f5c5SAndroid Build Coastguard Worker
61*8975f5c5SAndroid Build Coastguard Worker EGLDisplay mDisplay = EGL_NO_DISPLAY;
62*8975f5c5SAndroid Build Coastguard Worker EGLContext mContext = EGL_NO_CONTEXT;
63*8975f5c5SAndroid Build Coastguard Worker bool mExtensionSupported = false;
64*8975f5c5SAndroid Build Coastguard Worker };
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker // Check that context has no config.
TEST_P(EGLNoConfigContextTest,QueryConfigID)67*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLNoConfigContextTest, QueryConfigID)
68*8975f5c5SAndroid Build Coastguard Worker {
69*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!mExtensionSupported);
70*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(mDisplay);
71*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(mContext);
72*8975f5c5SAndroid Build Coastguard Worker
73*8975f5c5SAndroid Build Coastguard Worker EGLint configId = -1;
74*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglQueryContext(mDisplay, mContext, EGL_CONFIG_ID, &configId));
75*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(configId == 0);
76*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
77*8975f5c5SAndroid Build Coastguard Worker }
78*8975f5c5SAndroid Build Coastguard Worker
79*8975f5c5SAndroid Build Coastguard Worker // Any surface should be eglMakeCurrent compatible with no-config context.
80*8975f5c5SAndroid Build Coastguard Worker // Do a glClear and glReadPixel to verify rendering.
TEST_P(EGLNoConfigContextTest,RenderCheck)81*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLNoConfigContextTest, RenderCheck)
82*8975f5c5SAndroid Build Coastguard Worker {
83*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!mExtensionSupported);
84*8975f5c5SAndroid Build Coastguard Worker
85*8975f5c5SAndroid Build Coastguard Worker // Get all the configs
86*8975f5c5SAndroid Build Coastguard Worker EGLint count;
87*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &count));
88*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(count > 0);
89*8975f5c5SAndroid Build Coastguard Worker std::vector<EGLConfig> configs(count);
90*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), count, &count));
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker // For each config, create PbufferSurface and do a render check
93*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = EGL_NO_SURFACE;
94*8975f5c5SAndroid Build Coastguard Worker for (auto config : configs)
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker const uint32_t kWidth = 1;
97*8975f5c5SAndroid Build Coastguard Worker const uint32_t kHeight = 1;
98*8975f5c5SAndroid Build Coastguard Worker
99*8975f5c5SAndroid Build Coastguard Worker EGLint configId;
100*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetConfigAttrib(mDisplay, config, EGL_CONFIG_ID, &configId));
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker EGLint surfaceType;
103*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType));
104*8975f5c5SAndroid Build Coastguard Worker EGLint bufferSize;
105*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetConfigAttrib(mDisplay, config, EGL_BUFFER_SIZE, &bufferSize));
106*8975f5c5SAndroid Build Coastguard Worker constexpr int kRGB8BitSize = 24; // RGB8 is 24 bits
107*8975f5c5SAndroid Build Coastguard Worker if (isVulkanRenderer() && bufferSize == kRGB8BitSize &&
108*8975f5c5SAndroid Build Coastguard Worker (surfaceType & EGL_PBUFFER_BIT) != EGL_PBUFFER_BIT)
109*8975f5c5SAndroid Build Coastguard Worker {
110*8975f5c5SAndroid Build Coastguard Worker // Skip this config, since the Vulkan backend doesn't support RGB8 pbuffer surfaces.
111*8975f5c5SAndroid Build Coastguard Worker continue;
112*8975f5c5SAndroid Build Coastguard Worker }
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker EGLint surfattrs[] = {EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_NONE};
115*8975f5c5SAndroid Build Coastguard Worker surface = eglCreatePbufferSurface(mDisplay, config, surfattrs);
116*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(surface != EGL_NO_SURFACE);
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface, surface, mContext));
119*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed with Config: " << configId << '\n';
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker // ClearColor RED
122*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0, 0.0, 0.0, 1.0);
123*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
124*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR() << "glClear failed";
125*8975f5c5SAndroid Build Coastguard Worker
126*8975f5c5SAndroid Build Coastguard Worker if (bufferSize > 32)
127*8975f5c5SAndroid Build Coastguard Worker { // GL_FLOAT configs
128*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR32F_EQ(0, 0, kFloatRed);
129*8975f5c5SAndroid Build Coastguard Worker }
130*8975f5c5SAndroid Build Coastguard Worker else
131*8975f5c5SAndroid Build Coastguard Worker { // GL_UNSIGNED_BYTE configs
132*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker eglDestroySurface(mDisplay, surface);
136*8975f5c5SAndroid Build Coastguard Worker surface = EGL_NO_SURFACE;
137*8975f5c5SAndroid Build Coastguard Worker }
138*8975f5c5SAndroid Build Coastguard Worker }
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLNoConfigContextTest);
141*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(EGLNoConfigContextTest,
142*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_OPENGL()),
143*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_VULKAN()),
144*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES3_OPENGL()),
145*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES3_VULKAN()));
146