Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/libANGLE/Config.cpp
1693 views
1
//
2
// Copyright 2002 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
// Config.cpp: Implements the egl::Config class, describing the format, type
8
// and size for an egl::Surface. Implements EGLConfig and related functionality.
9
// [EGL 1.5] section 3.4 page 19.
10
11
#include "libANGLE/Config.h"
12
#include "libANGLE/AttributeMap.h"
13
14
#include <algorithm>
15
#include <vector>
16
17
#include <EGL/eglext.h>
18
#include "angle_gl.h"
19
20
#include "common/debug.h"
21
22
namespace egl
23
{
24
25
Config::Config()
26
: renderTargetFormat(GL_NONE),
27
depthStencilFormat(GL_NONE),
28
bufferSize(0),
29
redSize(0),
30
greenSize(0),
31
blueSize(0),
32
luminanceSize(0),
33
alphaSize(0),
34
alphaMaskSize(0),
35
bindToTextureRGB(EGL_FALSE),
36
bindToTextureRGBA(EGL_FALSE),
37
bindToTextureTarget(EGL_TEXTURE_2D),
38
colorBufferType(EGL_RGB_BUFFER),
39
configCaveat(EGL_NONE),
40
configID(0),
41
conformant(0),
42
depthSize(0),
43
level(0),
44
matchNativePixmap(EGL_FALSE),
45
maxPBufferWidth(0),
46
maxPBufferHeight(0),
47
maxPBufferPixels(0),
48
maxSwapInterval(0),
49
minSwapInterval(0),
50
nativeRenderable(EGL_FALSE),
51
nativeVisualID(0),
52
nativeVisualType(0),
53
renderableType(0),
54
sampleBuffers(0),
55
samples(0),
56
stencilSize(0),
57
surfaceType(0),
58
transparentType(EGL_NONE),
59
transparentRedValue(0),
60
transparentGreenValue(0),
61
transparentBlueValue(0),
62
optimalOrientation(0),
63
colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
64
recordable(EGL_FALSE),
65
framebufferTarget(EGL_FALSE), // TODO: http://anglebug.com/4208
66
yInverted(EGL_FALSE)
67
{}
68
69
Config::~Config() {}
70
71
Config::Config(const Config &other) = default;
72
73
Config &Config::operator=(const Config &other) = default;
74
75
ConfigSet::ConfigSet() = default;
76
77
ConfigSet::ConfigSet(const ConfigSet &other) = default;
78
79
ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default;
80
81
ConfigSet::~ConfigSet() = default;
82
83
EGLint ConfigSet::add(const Config &config)
84
{
85
// Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
86
EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;
87
88
Config copyConfig(config);
89
copyConfig.configID = id;
90
mConfigs.insert(std::make_pair(id, copyConfig));
91
92
return id;
93
}
94
95
const Config &ConfigSet::get(EGLint id) const
96
{
97
ASSERT(mConfigs.find(id) != mConfigs.end());
98
return mConfigs.find(id)->second;
99
}
100
101
void ConfigSet::clear()
102
{
103
mConfigs.clear();
104
}
105
106
size_t ConfigSet::size() const
107
{
108
return mConfigs.size();
109
}
110
111
bool ConfigSet::contains(const Config *config) const
112
{
113
for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
114
{
115
const Config &item = i->second;
116
if (config == &item)
117
{
118
return true;
119
}
120
}
121
122
return false;
123
}
124
125
// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5]
126
// section 3.4.1.2 page 28.
127
class ConfigSorter
128
{
129
public:
130
explicit ConfigSorter(const AttributeMap &attributeMap)
131
: mWantRed(false),
132
mWantGreen(false),
133
mWantBlue(false),
134
mWantAlpha(false),
135
mWantLuminance(false)
136
{
137
scanForWantedComponents(attributeMap);
138
}
139
140
bool operator()(const Config *x, const Config *y) const { return (*this)(*x, *y); }
141
142
bool operator()(const Config &x, const Config &y) const
143
{
144
#define SORT(attribute) \
145
do \
146
{ \
147
if (x.attribute != y.attribute) \
148
return x.attribute < y.attribute; \
149
} while (0)
150
151
static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG,
152
"Unexpected EGL enum value.");
153
SORT(configCaveat);
154
155
static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
156
"Unexpected order of EGL enums.");
157
SORT(colorComponentType);
158
159
static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
160
SORT(colorBufferType);
161
162
// By larger total number of color bits, only considering those that are requested to be >
163
// 0.
164
EGLint xComponentsSize = wantedComponentsSize(x);
165
EGLint yComponentsSize = wantedComponentsSize(y);
166
if (xComponentsSize != yComponentsSize)
167
{
168
return xComponentsSize > yComponentsSize;
169
}
170
171
SORT(bufferSize);
172
SORT(sampleBuffers);
173
SORT(samples);
174
SORT(depthSize);
175
SORT(stencilSize);
176
SORT(alphaMaskSize);
177
SORT(nativeVisualType);
178
SORT(configID);
179
180
#undef SORT
181
182
return false;
183
}
184
185
private:
186
static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component)
187
{
188
// [EGL 1.5] section 3.4.1.2 page 30
189
// Sorting rule #3: by larger total number of color bits, not considering
190
// components that are 0 or don't-care.
191
EGLAttrib value = attributeMap.get(component, 0);
192
return value != 0 && value != EGL_DONT_CARE;
193
}
194
195
void scanForWantedComponents(const AttributeMap &attributeMap)
196
{
197
mWantRed = wantsComponent(attributeMap, EGL_RED_SIZE);
198
mWantGreen = wantsComponent(attributeMap, EGL_GREEN_SIZE);
199
mWantBlue = wantsComponent(attributeMap, EGL_BLUE_SIZE);
200
mWantAlpha = wantsComponent(attributeMap, EGL_ALPHA_SIZE);
201
mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE);
202
}
203
204
EGLint wantedComponentsSize(const Config &config) const
205
{
206
EGLint total = 0;
207
208
if (mWantRed)
209
total += config.redSize;
210
if (mWantGreen)
211
total += config.greenSize;
212
if (mWantBlue)
213
total += config.blueSize;
214
if (mWantAlpha)
215
total += config.alphaSize;
216
if (mWantLuminance)
217
total += config.luminanceSize;
218
219
return total;
220
}
221
222
bool mWantRed;
223
bool mWantGreen;
224
bool mWantBlue;
225
bool mWantAlpha;
226
bool mWantLuminance;
227
};
228
229
std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap) const
230
{
231
std::vector<const Config *> result;
232
result.reserve(mConfigs.size());
233
234
for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
235
{
236
const Config &config = configIter->second;
237
bool match = true;
238
239
for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
240
{
241
EGLAttrib attributeKey = attribIter->first;
242
EGLAttrib attributeValue = attribIter->second;
243
244
if (attributeValue == EGL_DONT_CARE)
245
{
246
continue;
247
}
248
249
switch (attributeKey)
250
{
251
case EGL_BUFFER_SIZE:
252
match = config.bufferSize >= attributeValue;
253
break;
254
case EGL_ALPHA_SIZE:
255
match = config.alphaSize >= attributeValue;
256
break;
257
case EGL_BLUE_SIZE:
258
match = config.blueSize >= attributeValue;
259
break;
260
case EGL_GREEN_SIZE:
261
match = config.greenSize >= attributeValue;
262
break;
263
case EGL_RED_SIZE:
264
match = config.redSize >= attributeValue;
265
break;
266
case EGL_DEPTH_SIZE:
267
match = config.depthSize >= attributeValue;
268
break;
269
case EGL_STENCIL_SIZE:
270
match = config.stencilSize >= attributeValue;
271
break;
272
case EGL_CONFIG_CAVEAT:
273
match = config.configCaveat == static_cast<EGLenum>(attributeValue);
274
break;
275
case EGL_CONFIG_ID:
276
match = config.configID == attributeValue;
277
break;
278
case EGL_LEVEL:
279
match = config.level == attributeValue;
280
break;
281
case EGL_NATIVE_RENDERABLE:
282
match = config.nativeRenderable == static_cast<EGLBoolean>(attributeValue);
283
break;
284
case EGL_NATIVE_VISUAL_TYPE:
285
match = config.nativeVisualType == attributeValue;
286
break;
287
case EGL_SAMPLES:
288
match = config.samples >= attributeValue;
289
break;
290
case EGL_SAMPLE_BUFFERS:
291
match = config.sampleBuffers >= attributeValue;
292
break;
293
case EGL_SURFACE_TYPE:
294
match = (config.surfaceType & attributeValue) == attributeValue;
295
break;
296
case EGL_TRANSPARENT_TYPE:
297
match = config.transparentType == static_cast<EGLenum>(attributeValue);
298
break;
299
case EGL_TRANSPARENT_BLUE_VALUE:
300
if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
301
{
302
match = config.transparentBlueValue == attributeValue;
303
}
304
break;
305
case EGL_TRANSPARENT_GREEN_VALUE:
306
if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
307
{
308
match = config.transparentGreenValue == attributeValue;
309
}
310
break;
311
case EGL_TRANSPARENT_RED_VALUE:
312
if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
313
{
314
match = config.transparentRedValue == attributeValue;
315
}
316
break;
317
case EGL_BIND_TO_TEXTURE_RGB:
318
match = config.bindToTextureRGB == static_cast<EGLBoolean>(attributeValue);
319
break;
320
case EGL_BIND_TO_TEXTURE_RGBA:
321
match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue);
322
break;
323
case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
324
match = config.bindToTextureTarget == static_cast<EGLenum>(attributeValue);
325
break;
326
case EGL_MIN_SWAP_INTERVAL:
327
match = config.minSwapInterval == attributeValue;
328
break;
329
case EGL_MAX_SWAP_INTERVAL:
330
match = config.maxSwapInterval == attributeValue;
331
break;
332
case EGL_LUMINANCE_SIZE:
333
match = config.luminanceSize >= attributeValue;
334
break;
335
case EGL_ALPHA_MASK_SIZE:
336
match = config.alphaMaskSize >= attributeValue;
337
break;
338
case EGL_COLOR_BUFFER_TYPE:
339
match = config.colorBufferType == static_cast<EGLenum>(attributeValue);
340
break;
341
case EGL_RENDERABLE_TYPE:
342
match = (config.renderableType & attributeValue) == attributeValue;
343
break;
344
case EGL_MATCH_NATIVE_PIXMAP:
345
match = false;
346
UNIMPLEMENTED();
347
break;
348
case EGL_CONFORMANT:
349
match = (config.conformant & attributeValue) == attributeValue;
350
break;
351
case EGL_MAX_PBUFFER_WIDTH:
352
match = config.maxPBufferWidth >= attributeValue;
353
break;
354
case EGL_MAX_PBUFFER_HEIGHT:
355
match = config.maxPBufferHeight >= attributeValue;
356
break;
357
case EGL_MAX_PBUFFER_PIXELS:
358
match = config.maxPBufferPixels >= attributeValue;
359
break;
360
case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
361
match = config.optimalOrientation == attributeValue;
362
break;
363
case EGL_COLOR_COMPONENT_TYPE_EXT:
364
match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
365
break;
366
case EGL_RECORDABLE_ANDROID:
367
match = config.recordable == static_cast<EGLBoolean>(attributeValue);
368
break;
369
case EGL_FRAMEBUFFER_TARGET_ANDROID:
370
match = config.framebufferTarget == static_cast<EGLBoolean>(attributeValue);
371
break;
372
case EGL_Y_INVERTED_NOK:
373
match = config.yInverted == static_cast<EGLBoolean>(attributeValue);
374
break;
375
default:
376
UNREACHABLE();
377
}
378
379
if (!match)
380
{
381
break;
382
}
383
}
384
385
if (match)
386
{
387
result.push_back(&config);
388
}
389
}
390
391
// Sort the result
392
std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));
393
394
return result;
395
}
396
397
ConfigSet::ConfigMap::iterator ConfigSet::begin()
398
{
399
return mConfigs.begin();
400
}
401
402
ConfigSet::ConfigMap::iterator ConfigSet::end()
403
{
404
return mConfigs.end();
405
}
406
} // namespace egl
407
408