xref: /aosp_15_r20/external/angle/src/libANGLE/Config_unittest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 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 
7*8975f5c5SAndroid Build Coastguard Worker #include "gmock/gmock.h"
8*8975f5c5SAndroid Build Coastguard Worker #include "gtest/gtest.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/AttributeMap.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Config.h"
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker // Create a generic, valid EGL config that can be modified to test sorting and
14*8975f5c5SAndroid Build Coastguard Worker // filtering routines
GenerateGenericConfig()15*8975f5c5SAndroid Build Coastguard Worker static egl::Config GenerateGenericConfig()
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker     egl::Config config;
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker     config.bufferSize          = 24;
20*8975f5c5SAndroid Build Coastguard Worker     config.redSize             = 8;
21*8975f5c5SAndroid Build Coastguard Worker     config.greenSize           = 8;
22*8975f5c5SAndroid Build Coastguard Worker     config.blueSize            = 8;
23*8975f5c5SAndroid Build Coastguard Worker     config.luminanceSize       = 0;
24*8975f5c5SAndroid Build Coastguard Worker     config.alphaSize           = 8;
25*8975f5c5SAndroid Build Coastguard Worker     config.alphaMaskSize       = 0;
26*8975f5c5SAndroid Build Coastguard Worker     config.bindToTextureRGB    = EGL_TRUE;
27*8975f5c5SAndroid Build Coastguard Worker     config.bindToTextureRGBA   = EGL_TRUE;
28*8975f5c5SAndroid Build Coastguard Worker     config.colorBufferType     = EGL_RGB_BUFFER;
29*8975f5c5SAndroid Build Coastguard Worker     config.configCaveat        = EGL_NONE;
30*8975f5c5SAndroid Build Coastguard Worker     config.configID            = 0;
31*8975f5c5SAndroid Build Coastguard Worker     config.conformant          = EGL_OPENGL_ES2_BIT;
32*8975f5c5SAndroid Build Coastguard Worker     config.depthSize           = 24;
33*8975f5c5SAndroid Build Coastguard Worker     config.level               = 0;
34*8975f5c5SAndroid Build Coastguard Worker     config.matchNativePixmap   = EGL_NONE;
35*8975f5c5SAndroid Build Coastguard Worker     config.maxPBufferWidth     = 1024;
36*8975f5c5SAndroid Build Coastguard Worker     config.maxPBufferHeight    = 1024;
37*8975f5c5SAndroid Build Coastguard Worker     config.maxPBufferPixels    = config.maxPBufferWidth * config.maxPBufferWidth;
38*8975f5c5SAndroid Build Coastguard Worker     config.maxSwapInterval     = 0;
39*8975f5c5SAndroid Build Coastguard Worker     config.minSwapInterval     = 4;
40*8975f5c5SAndroid Build Coastguard Worker     config.nativeRenderable    = EGL_OPENGL_ES2_BIT;
41*8975f5c5SAndroid Build Coastguard Worker     config.nativeVisualID      = 0;
42*8975f5c5SAndroid Build Coastguard Worker     config.nativeVisualType    = 0;
43*8975f5c5SAndroid Build Coastguard Worker     config.renderableType      = EGL_FALSE;
44*8975f5c5SAndroid Build Coastguard Worker     config.sampleBuffers       = 0;
45*8975f5c5SAndroid Build Coastguard Worker     config.samples             = 0;
46*8975f5c5SAndroid Build Coastguard Worker     config.stencilSize         = 8;
47*8975f5c5SAndroid Build Coastguard Worker     config.surfaceType         = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
48*8975f5c5SAndroid Build Coastguard Worker     config.transparentType     = EGL_NONE;
49*8975f5c5SAndroid Build Coastguard Worker     config.transparentRedValue = 0;
50*8975f5c5SAndroid Build Coastguard Worker     config.transparentGreenValue = 0;
51*8975f5c5SAndroid Build Coastguard Worker     config.transparentBlueValue  = 0;
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     return config;
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker 
GenerateUniqueConfigs(size_t count)56*8975f5c5SAndroid Build Coastguard Worker static std::vector<egl::Config> GenerateUniqueConfigs(size_t count)
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker     std::vector<egl::Config> configs;
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < count; i++)
61*8975f5c5SAndroid Build Coastguard Worker     {
62*8975f5c5SAndroid Build Coastguard Worker         egl::Config config = GenerateGenericConfig();
63*8975f5c5SAndroid Build Coastguard Worker         config.samples     = static_cast<EGLint>(i);
64*8975f5c5SAndroid Build Coastguard Worker         configs.push_back(config);
65*8975f5c5SAndroid Build Coastguard Worker     }
66*8975f5c5SAndroid Build Coastguard Worker 
67*8975f5c5SAndroid Build Coastguard Worker     return configs;
68*8975f5c5SAndroid Build Coastguard Worker }
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker // Add unique configs to a ConfigSet and expect that the size of the
71*8975f5c5SAndroid Build Coastguard Worker // set is equal to the number of configs added.
TEST(ConfigSetTest,Size)72*8975f5c5SAndroid Build Coastguard Worker TEST(ConfigSetTest, Size)
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker     egl::ConfigSet set;
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker     std::vector<egl::Config> uniqueConfigs = GenerateUniqueConfigs(16);
77*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < uniqueConfigs.size(); i++)
78*8975f5c5SAndroid Build Coastguard Worker     {
79*8975f5c5SAndroid Build Coastguard Worker         set.add(uniqueConfigs[i]);
80*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(set.size(), i + 1);
81*8975f5c5SAndroid Build Coastguard Worker     }
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker // [EGL 1.5] section 3.4:
85*8975f5c5SAndroid Build Coastguard Worker // EGL_CONFIG_ID is a unique integer identifying different EGLConfigs. Configuration IDs
86*8975f5c5SAndroid Build Coastguard Worker // must be small positive integers starting at 1 and ID assignment should be compact;
87*8975f5c5SAndroid Build Coastguard Worker // that is, if there are N EGLConfigs defined by the EGL implementation, their
88*8975f5c5SAndroid Build Coastguard Worker // configuration IDs should be in the range [1, N].
TEST(ConfigSetTest,IDs)89*8975f5c5SAndroid Build Coastguard Worker TEST(ConfigSetTest, IDs)
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker     egl::ConfigSet set;
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker     std::set<EGLint> ids;
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     std::vector<egl::Config> uniqueConfigs = GenerateUniqueConfigs(16);
96*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < uniqueConfigs.size(); i++)
97*8975f5c5SAndroid Build Coastguard Worker     {
98*8975f5c5SAndroid Build Coastguard Worker         EGLint id = set.add(uniqueConfigs[i]);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker         // Check that the config that was inserted has the ID that was returned
101*8975f5c5SAndroid Build Coastguard Worker         // by ConfigSet::add
102*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(id, set.get(id).configID);
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker         ids.insert(id);
105*8975f5c5SAndroid Build Coastguard Worker     }
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker     // Verify configCount unique IDs
108*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(ids.size(), set.size());
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     // Check that there are no gaps and the IDs are in the range [1, N].
111*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(*std::min_element(ids.begin(), ids.end()), 1);
112*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(*std::max_element(ids.begin(), ids.end()), static_cast<EGLint>(set.size()));
113*8975f5c5SAndroid Build Coastguard Worker }
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker // Test case to verify filtering of egl::ConfigSet based on bit size attributes
116*8975f5c5SAndroid Build Coastguard Worker // (e.g., EGL_RED_SIZE, EGL_GREEN_SIZE, etc.). The test generates configurations
117*8975f5c5SAndroid Build Coastguard Worker // with varying bit sizes for each attribute, filters by the attribute, and
118*8975f5c5SAndroid Build Coastguard Worker // checks that the number of filtered results matches the expected count.
TEST(ConfigSetTest,FilteringBitSizes)119*8975f5c5SAndroid Build Coastguard Worker TEST(ConfigSetTest, FilteringBitSizes)
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker     egl::ConfigSet set;
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     struct VariableConfigBitSize
124*8975f5c5SAndroid Build Coastguard Worker     {
125*8975f5c5SAndroid Build Coastguard Worker         EGLint Name;
126*8975f5c5SAndroid Build Coastguard Worker         EGLint(egl::Config::*ConfigMember);
127*8975f5c5SAndroid Build Coastguard Worker     };
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     VariableConfigBitSize testMembers[] = {
130*8975f5c5SAndroid Build Coastguard Worker         {EGL_RED_SIZE, &egl::Config::redSize},     {EGL_GREEN_SIZE, &egl::Config::greenSize},
131*8975f5c5SAndroid Build Coastguard Worker         {EGL_BLUE_SIZE, &egl::Config::blueSize},   {EGL_ALPHA_SIZE, &egl::Config::alphaSize},
132*8975f5c5SAndroid Build Coastguard Worker         {EGL_DEPTH_SIZE, &egl::Config::depthSize}, {EGL_STENCIL_SIZE, &egl::Config::stencilSize},
133*8975f5c5SAndroid Build Coastguard Worker     };
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     // Generate configsPerType configs with varying bit sizes of each type
136*8975f5c5SAndroid Build Coastguard Worker     size_t configsPerType = 4;
137*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < ArraySize(testMembers); i++)
138*8975f5c5SAndroid Build Coastguard Worker     {
139*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < configsPerType; j++)
140*8975f5c5SAndroid Build Coastguard Worker         {
141*8975f5c5SAndroid Build Coastguard Worker             egl::Config config = GenerateGenericConfig();
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker             // Set all the other tested members of this config to 0
144*8975f5c5SAndroid Build Coastguard Worker             for (size_t k = 0; k < ArraySize(testMembers); k++)
145*8975f5c5SAndroid Build Coastguard Worker             {
146*8975f5c5SAndroid Build Coastguard Worker                 config.*(testMembers[k].ConfigMember) = 0;
147*8975f5c5SAndroid Build Coastguard Worker             }
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker             // Set the tested member of this config to i so it ranges from
150*8975f5c5SAndroid Build Coastguard Worker             // [1, configsPerType]
151*8975f5c5SAndroid Build Coastguard Worker             config.*(testMembers[i].ConfigMember) = static_cast<EGLint>(j) + 1;
152*8975f5c5SAndroid Build Coastguard Worker 
153*8975f5c5SAndroid Build Coastguard Worker             set.add(config);
154*8975f5c5SAndroid Build Coastguard Worker         }
155*8975f5c5SAndroid Build Coastguard Worker     }
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker     // for each tested member, filter by it's type and verify that the correct number
158*8975f5c5SAndroid Build Coastguard Worker     // of results are returned
159*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < ArraySize(testMembers); i++)
160*8975f5c5SAndroid Build Coastguard Worker     {
161*8975f5c5SAndroid Build Coastguard Worker         // Start with a filter of 1 to not grab the other members
162*8975f5c5SAndroid Build Coastguard Worker         for (EGLint j = 0; j < static_cast<EGLint>(configsPerType); j++)
163*8975f5c5SAndroid Build Coastguard Worker         {
164*8975f5c5SAndroid Build Coastguard Worker             egl::AttributeMap filter;
165*8975f5c5SAndroid Build Coastguard Worker             filter.insert(testMembers[i].Name, j + 1);
166*8975f5c5SAndroid Build Coastguard Worker 
167*8975f5c5SAndroid Build Coastguard Worker             std::vector<const egl::Config *> filteredConfigs = set.filter(filter);
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(filteredConfigs.size(), configsPerType - j);
170*8975f5c5SAndroid Build Coastguard Worker         }
171*8975f5c5SAndroid Build Coastguard Worker     }
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker 
174*8975f5c5SAndroid Build Coastguard Worker // Verify the sorting, [EGL 1.5] section 3.4.1.2 pg 30:
175*8975f5c5SAndroid Build Coastguard Worker // [configs are sorted] by larger total number of color bits (for an RGB
176*8975f5c5SAndroid Build Coastguard Worker // color buffer this is the sum of EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE,
177*8975f5c5SAndroid Build Coastguard Worker // and EGL_ALPHA_SIZE; for a luminance color buffer, the sum of EGL_LUMINANCE_SIZE
178*8975f5c5SAndroid Build Coastguard Worker // and EGL_ALPHA_SIZE).If the requested number of bits in attrib list for a
179*8975f5c5SAndroid Build Coastguard Worker // particular color component is 0 or EGL_DONT_CARE, then the number of bits
180*8975f5c5SAndroid Build Coastguard Worker // for that component is not considered.
TEST(ConfigSetTest,SortingBitSizes)181*8975f5c5SAndroid Build Coastguard Worker TEST(ConfigSetTest, SortingBitSizes)
182*8975f5c5SAndroid Build Coastguard Worker {
183*8975f5c5SAndroid Build Coastguard Worker     egl::ConfigSet set;
184*8975f5c5SAndroid Build Coastguard Worker     size_t testConfigCount = 64;
185*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < testConfigCount; i++)
186*8975f5c5SAndroid Build Coastguard Worker     {
187*8975f5c5SAndroid Build Coastguard Worker         egl::Config config = GenerateGenericConfig();
188*8975f5c5SAndroid Build Coastguard Worker 
189*8975f5c5SAndroid Build Coastguard Worker         // Give random-ish bit sizes to the config
190*8975f5c5SAndroid Build Coastguard Worker         config.redSize   = (i * 2) % 3;
191*8975f5c5SAndroid Build Coastguard Worker         config.greenSize = (i + 5) % 7;
192*8975f5c5SAndroid Build Coastguard Worker         config.blueSize  = (i + 7) % 11;
193*8975f5c5SAndroid Build Coastguard Worker         config.alphaSize = (i + 13) % 17;
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker         set.add(config);
196*8975f5c5SAndroid Build Coastguard Worker     }
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker     egl::AttributeMap greaterThan1BitFilter;
199*8975f5c5SAndroid Build Coastguard Worker     greaterThan1BitFilter.insert(EGL_RED_SIZE, 1);
200*8975f5c5SAndroid Build Coastguard Worker     greaterThan1BitFilter.insert(EGL_GREEN_SIZE, 1);
201*8975f5c5SAndroid Build Coastguard Worker     greaterThan1BitFilter.insert(EGL_BLUE_SIZE, 1);
202*8975f5c5SAndroid Build Coastguard Worker     greaterThan1BitFilter.insert(EGL_ALPHA_SIZE, 1);
203*8975f5c5SAndroid Build Coastguard Worker 
204*8975f5c5SAndroid Build Coastguard Worker     std::vector<const egl::Config *> filteredConfigs = set.filter(greaterThan1BitFilter);
205*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 1; i < filteredConfigs.size(); i++)
206*8975f5c5SAndroid Build Coastguard Worker     {
207*8975f5c5SAndroid Build Coastguard Worker         const egl::Config &prevConfig = *filteredConfigs[i - 1];
208*8975f5c5SAndroid Build Coastguard Worker         size_t prevBitCount =
209*8975f5c5SAndroid Build Coastguard Worker             prevConfig.redSize + prevConfig.greenSize + prevConfig.blueSize + prevConfig.alphaSize;
210*8975f5c5SAndroid Build Coastguard Worker 
211*8975f5c5SAndroid Build Coastguard Worker         const egl::Config &curConfig = *filteredConfigs[i];
212*8975f5c5SAndroid Build Coastguard Worker         size_t curBitCount =
213*8975f5c5SAndroid Build Coastguard Worker             curConfig.redSize + curConfig.greenSize + curConfig.blueSize + curConfig.alphaSize;
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GE(prevBitCount, curBitCount);
216*8975f5c5SAndroid Build Coastguard Worker     }
217*8975f5c5SAndroid Build Coastguard Worker }
218