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