blob: 1af92290170464546976eaba3994758849c9daf6 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman66b8ab22014-05-06 15:57:45 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
John Bauman66b8ab22014-05-06 15:57:45 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman66b8ab22014-05-06 15:57:45 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
John Bauman66b8ab22014-05-06 15:57:45 -040014
15// Config.cpp: Implements the egl::Config class, describing the format, type
16// and size for an egl::Surface. Implements EGLConfig and related functionality.
17// [EGL 1.4] section 3.4 page 15.
18
19#include "Config.h"
20
21#include "common/debug.h"
John Bauman66b8ab22014-05-06 15:57:45 -040022
Nicolas Capensf4fea7f2014-11-25 13:31:46 -050023#include <EGL/eglext.h>
Stephen Whitee6ab01f2019-04-04 14:31:25 -040024#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
Nicolas Capensb3c0c732015-10-30 14:05:23 -040025#include <system/graphics.h>
26#endif
Nicolas Capensf4fea7f2014-11-25 13:31:46 -050027
Nicolas Capensb77b8772015-10-30 13:50:31 -040028#include <string.h>
John Bauman66b8ab22014-05-06 15:57:45 -040029#include <algorithm>
Anthony Vallee-Dubois13241c62015-08-17 14:12:32 -040030#include <cstring>
John Bauman66b8ab22014-05-06 15:57:45 -040031#include <vector>
Chris Forbes787e3d52018-08-31 18:26:20 -070032#include <map>
John Bauman66b8ab22014-05-06 15:57:45 -040033
34using namespace std;
35
36namespace egl
37{
Nicolas Capens216980a2017-01-02 16:21:39 -050038
Nicolas Capensc8fcfd82018-01-11 12:53:57 -050039Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
Nicolas Capens81c28572017-03-13 15:08:39 -040040 : mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
John Bauman66b8ab22014-05-06 15:57:45 -040041{
Nicolas Capens0bac2852016-05-07 06:09:58 -040042 mBindToTextureRGB = EGL_FALSE;
43 mBindToTextureRGBA = EGL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -040044
Nicolas Capensf59ad062015-11-13 12:39:21 -050045 // Initialize to a high value to lower the preference of formats for which there's no native support
Nicolas Capens0bac2852016-05-07 06:09:58 -040046 mNativeVisualID = 0x7FFFFFFF;
Nicolas Capensb3c0c732015-10-30 14:05:23 -040047
Nicolas Capens0bac2852016-05-07 06:09:58 -040048 switch(renderTargetFormat)
49 {
50 case sw::FORMAT_A1R5G5B5:
51 mRedSize = 5;
52 mGreenSize = 5;
53 mBlueSize = 5;
54 mAlphaSize = 1;
55 break;
56 case sw::FORMAT_A2R10G10B10:
57 mRedSize = 10;
58 mGreenSize = 10;
59 mBlueSize = 10;
60 mAlphaSize = 2;
61 break;
62 case sw::FORMAT_A8R8G8B8:
63 mRedSize = 8;
64 mGreenSize = 8;
65 mBlueSize = 8;
66 mAlphaSize = 8;
67 mBindToTextureRGBA = EGL_TRUE;
Stephen Whitee6ab01f2019-04-04 14:31:25 -040068 #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
Nicolas Capensb3c0c732015-10-30 14:05:23 -040069 mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
Nicolas Capensf59ad062015-11-13 12:39:21 -050070 #else
71 mNativeVisualID = 2; // Arbitrary; prefer over ABGR
Nicolas Capensb3c0c732015-10-30 14:05:23 -040072 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040073 break;
Nicolas Capens5716cf02015-10-30 13:54:24 -040074 case sw::FORMAT_A8B8G8R8:
Nicolas Capens0bac2852016-05-07 06:09:58 -040075 mRedSize = 8;
76 mGreenSize = 8;
77 mBlueSize = 8;
78 mAlphaSize = 8;
79 mBindToTextureRGBA = EGL_TRUE;
Stephen Whitee6ab01f2019-04-04 14:31:25 -040080 #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
Nicolas Capensb3c0c732015-10-30 14:05:23 -040081 mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
82 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040083 break;
84 case sw::FORMAT_R5G6B5:
85 mRedSize = 5;
86 mGreenSize = 6;
87 mBlueSize = 5;
88 mAlphaSize = 0;
Stephen Whitee6ab01f2019-04-04 14:31:25 -040089 #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
Nicolas Capensb3c0c732015-10-30 14:05:23 -040090 mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
91 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040092 break;
93 case sw::FORMAT_X8R8G8B8:
94 mRedSize = 8;
95 mGreenSize = 8;
96 mBlueSize = 8;
97 mAlphaSize = 0;
98 mBindToTextureRGB = EGL_TRUE;
Stephen Whitee6ab01f2019-04-04 14:31:25 -040099 #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
Nicolas Capensf59ad062015-11-13 12:39:21 -0500100 mNativeVisualID = 0x1FF; // HAL_PIXEL_FORMAT_BGRX_8888
101 #else
102 mNativeVisualID = 1; // Arbitrary; prefer over XBGR
Nicolas Capensb3c0c732015-10-30 14:05:23 -0400103 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400104 break;
Nicolas Capens5716cf02015-10-30 13:54:24 -0400105 case sw::FORMAT_X8B8G8R8:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400106 mRedSize = 8;
107 mGreenSize = 8;
108 mBlueSize = 8;
109 mAlphaSize = 0;
110 mBindToTextureRGB = EGL_TRUE;
Stephen Whitee6ab01f2019-04-04 14:31:25 -0400111 #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
Nicolas Capensb3c0c732015-10-30 14:05:23 -0400112 mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
113 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400114 break;
115 default:
116 UNREACHABLE(renderTargetFormat);
117 }
John Bauman66b8ab22014-05-06 15:57:45 -0400118
Nicolas Capens0bac2852016-05-07 06:09:58 -0400119 mLuminanceSize = 0;
120 mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
121 mAlphaMaskSize = 0;
122 mColorBufferType = EGL_RGB_BUFFER;
Nicolas Capensc8fcfd82018-01-11 12:53:57 -0500123 mConfigCaveat = EGL_NONE;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400124 mConfigID = 0;
Nicolas Capensc8fcfd82018-01-11 12:53:57 -0500125 mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
John Bauman66b8ab22014-05-06 15:57:45 -0400126
Nicolas Capens5716cf02015-10-30 13:54:24 -0400127 switch(depthStencilFormat)
John Bauman66b8ab22014-05-06 15:57:45 -0400128 {
129 case sw::FORMAT_NULL:
130 mDepthSize = 0;
131 mStencilSize = 0;
132 break;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400133// case sw::FORMAT_D16_LOCKABLE:
134// mDepthSize = 16;
135// mStencilSize = 0;
136// break;
John Bauman66b8ab22014-05-06 15:57:45 -0400137 case sw::FORMAT_D32:
138 mDepthSize = 32;
139 mStencilSize = 0;
140 break;
141// case sw::FORMAT_D15S1:
142// mDepthSize = 15;
143// mStencilSize = 1;
144// break;
145 case sw::FORMAT_D24S8:
146 mDepthSize = 24;
147 mStencilSize = 8;
148 break;
149 case sw::FORMAT_D24X8:
150 mDepthSize = 24;
151 mStencilSize = 0;
152 break;
153// case sw::FORMAT_D24X4S4:
154// mDepthSize = 24;
155// mStencilSize = 4;
156// break;
157 case sw::FORMAT_D16:
158 mDepthSize = 16;
159 mStencilSize = 0;
160 break;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400161// case sw::FORMAT_D32F_LOCKABLE:
162// mDepthSize = 32;
163// mStencilSize = 0;
164// break;
165// case sw::FORMAT_D24FS8:
166// mDepthSize = 24;
167// mStencilSize = 8;
168// break;
Nicolas Capens101e4f02015-06-03 14:54:38 -0400169 default:
Nicolas Capens3713cd42015-06-22 10:41:54 -0400170 UNREACHABLE(depthStencilFormat);
John Bauman66b8ab22014-05-06 15:57:45 -0400171 }
172
Nicolas Capens0bac2852016-05-07 06:09:58 -0400173 mLevel = 0;
174 mMatchNativePixmap = EGL_NONE;
175 mMaxPBufferWidth = 4096;
176 mMaxPBufferHeight = 4096;
177 mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
178 mMaxSwapInterval = maxInterval;
179 mMinSwapInterval = minInterval;
180 mNativeRenderable = EGL_FALSE;
181 mNativeVisualType = 0;
Nicolas Capensc8fcfd82018-01-11 12:53:57 -0500182 mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400183 mSampleBuffers = (multiSample > 0) ? 1 : 0;
184 mSamples = multiSample;
Nicolas Capensc8eedeb2018-04-12 12:50:21 -0400185 mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400186 mTransparentType = EGL_NONE;
187 mTransparentRedValue = 0;
188 mTransparentGreenValue = 0;
189 mTransparentBlueValue = 0;
Nicolas Capens9a74a0e2015-08-12 16:36:52 -0400190
Nicolas Capens81c28572017-03-13 15:08:39 -0400191 // Although we could support any format as an Android HWComposer compatible config by converting when necessary,
192 // the intent of EGL_ANDROID_framebuffer_target is to prevent any copies or conversions.
Nicolas Capensb77b8772015-10-30 13:50:31 -0400193 mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE;
Nicolas Capens81c28572017-03-13 15:08:39 -0400194 mRecordableAndroid = EGL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -0400195}
196
197EGLConfig Config::getHandle() const
198{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400199 return (EGLConfig)(size_t)mConfigID;
John Bauman66b8ab22014-05-06 15:57:45 -0400200}
201
Nicolas Capense2b31f22015-05-31 01:38:47 -0400202// This ordering determines the config ID
203bool CompareConfig::operator()(const Config &x, const Config &y) const
204{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400205 #define SORT_SMALLER(attribute) \
206 if(x.attribute != y.attribute) \
207 { \
208 return x.attribute < y.attribute; \
209 }
Nicolas Capense2b31f22015-05-31 01:38:47 -0400210
Nicolas Capensa26bade2016-05-27 13:19:49 -0400211 static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400212 SORT_SMALLER(mConfigCaveat);
Nicolas Capense2b31f22015-05-31 01:38:47 -0400213
Nicolas Capensa26bade2016-05-27 13:19:49 -0400214 static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400215 SORT_SMALLER(mColorBufferType);
Nicolas Capense2b31f22015-05-31 01:38:47 -0400216
Nicolas Capens101e4f02015-06-03 14:54:38 -0400217 SORT_SMALLER(mRedSize);
218 SORT_SMALLER(mGreenSize);
219 SORT_SMALLER(mBlueSize);
220 SORT_SMALLER(mAlphaSize);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400221
Nicolas Capense2b31f22015-05-31 01:38:47 -0400222 SORT_SMALLER(mBufferSize);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400223 SORT_SMALLER(mSampleBuffers);
224 SORT_SMALLER(mSamples);
225 SORT_SMALLER(mDepthSize);
226 SORT_SMALLER(mStencilSize);
227 SORT_SMALLER(mAlphaMaskSize);
228 SORT_SMALLER(mNativeVisualType);
Nicolas Capensf59ad062015-11-13 12:39:21 -0500229 SORT_SMALLER(mNativeVisualID);
Nicolas Capense2b31f22015-05-31 01:38:47 -0400230
Nicolas Capens0bac2852016-05-07 06:09:58 -0400231 #undef SORT_SMALLER
Nicolas Capense2b31f22015-05-31 01:38:47 -0400232
233 // Strict ordering requires sorting all non-equal fields above
234 assert(memcmp(&x, &y, sizeof(Config)) == 0);
235
Nicolas Capens0bac2852016-05-07 06:09:58 -0400236 return false;
Nicolas Capense2b31f22015-05-31 01:38:47 -0400237}
238
Nicolas Capens101e4f02015-06-03 14:54:38 -0400239// Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
240class SortConfig
241{
242public:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400243 explicit SortConfig(const EGLint *attribList);
Nicolas Capens101e4f02015-06-03 14:54:38 -0400244
Nicolas Capens0bac2852016-05-07 06:09:58 -0400245 bool operator()(const Config *x, const Config *y) const;
Nicolas Capens101e4f02015-06-03 14:54:38 -0400246
247private:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400248 EGLint wantedComponentsSize(const Config *config) const;
Nicolas Capens101e4f02015-06-03 14:54:38 -0400249
Nicolas Capens0bac2852016-05-07 06:09:58 -0400250 bool mWantRed;
251 bool mWantGreen;
252 bool mWantBlue;
253 bool mWantAlpha;
254 bool mWantLuminance;
Nicolas Capense2b31f22015-05-31 01:38:47 -0400255};
256
John Bauman66b8ab22014-05-06 15:57:45 -0400257SortConfig::SortConfig(const EGLint *attribList)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400258 : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
John Bauman66b8ab22014-05-06 15:57:45 -0400259{
Nicolas Capense2b31f22015-05-31 01:38:47 -0400260 // [EGL] section 3.4.1 page 24
Nicolas Capens0bac2852016-05-07 06:09:58 -0400261 // Sorting rule #3: by larger total number of color bits,
Nicolas Capense2b31f22015-05-31 01:38:47 -0400262 // not considering components that are 0 or don't-care.
Nicolas Capens0bac2852016-05-07 06:09:58 -0400263 for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
264 {
Chris Forbes787e3d52018-08-31 18:26:20 -0700265 // When multiple instances of the same attribute are present, last wins.
266 bool isSpecified = attr[1] && attr[1] != EGL_DONT_CARE;
267 switch(attr[0])
Nicolas Capens0bac2852016-05-07 06:09:58 -0400268 {
Chris Forbes787e3d52018-08-31 18:26:20 -0700269 case EGL_RED_SIZE: mWantRed = isSpecified; break;
270 case EGL_GREEN_SIZE: mWantGreen = isSpecified; break;
271 case EGL_BLUE_SIZE: mWantBlue = isSpecified; break;
272 case EGL_ALPHA_SIZE: mWantAlpha = isSpecified; break;
273 case EGL_LUMINANCE_SIZE: mWantLuminance = isSpecified; break;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400274 }
275 }
John Bauman66b8ab22014-05-06 15:57:45 -0400276}
277
Nicolas Capense2b31f22015-05-31 01:38:47 -0400278EGLint SortConfig::wantedComponentsSize(const Config *config) const
John Bauman66b8ab22014-05-06 15:57:45 -0400279{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400280 EGLint total = 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400281
Nicolas Capens0bac2852016-05-07 06:09:58 -0400282 if(mWantRed) total += config->mRedSize;
283 if(mWantGreen) total += config->mGreenSize;
284 if(mWantBlue) total += config->mBlueSize;
285 if(mWantAlpha) total += config->mAlphaSize;
286 if(mWantLuminance) total += config->mLuminanceSize;
John Bauman66b8ab22014-05-06 15:57:45 -0400287
Nicolas Capens0bac2852016-05-07 06:09:58 -0400288 return total;
John Bauman66b8ab22014-05-06 15:57:45 -0400289}
290
291bool SortConfig::operator()(const Config *x, const Config *y) const
292{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400293 #define SORT_SMALLER(attribute) \
294 if(x->attribute != y->attribute) \
295 { \
296 return x->attribute < y->attribute; \
297 }
John Bauman66b8ab22014-05-06 15:57:45 -0400298
Nicolas Capensa26bade2016-05-27 13:19:49 -0400299 static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400300 SORT_SMALLER(mConfigCaveat);
John Bauman66b8ab22014-05-06 15:57:45 -0400301
Nicolas Capensa26bade2016-05-27 13:19:49 -0400302 static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400303 SORT_SMALLER(mColorBufferType);
John Bauman66b8ab22014-05-06 15:57:45 -0400304
Nicolas Capense2b31f22015-05-31 01:38:47 -0400305 // By larger total number of color bits, only considering those that are requested to be > 0.
306 EGLint xComponentsSize = wantedComponentsSize(x);
307 EGLint yComponentsSize = wantedComponentsSize(y);
308 if(xComponentsSize != yComponentsSize)
309 {
310 return xComponentsSize > yComponentsSize;
311 }
John Bauman66b8ab22014-05-06 15:57:45 -0400312
Nicolas Capens0bac2852016-05-07 06:09:58 -0400313 SORT_SMALLER(mBufferSize);
314 SORT_SMALLER(mSampleBuffers);
315 SORT_SMALLER(mSamples);
316 SORT_SMALLER(mDepthSize);
317 SORT_SMALLER(mStencilSize);
318 SORT_SMALLER(mAlphaMaskSize);
319 SORT_SMALLER(mNativeVisualType);
320 SORT_SMALLER(mConfigID);
John Bauman66b8ab22014-05-06 15:57:45 -0400321
Nicolas Capens0bac2852016-05-07 06:09:58 -0400322 #undef SORT_SMALLER
John Bauman66b8ab22014-05-06 15:57:45 -0400323
Nicolas Capens0bac2852016-05-07 06:09:58 -0400324 return false;
John Bauman66b8ab22014-05-06 15:57:45 -0400325}
326
John Bauman66b8ab22014-05-06 15:57:45 -0400327ConfigSet::ConfigSet()
John Bauman66b8ab22014-05-06 15:57:45 -0400328{
329}
330
Nicolas Capens8b4ea002015-10-01 01:09:27 -0400331void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
John Bauman66b8ab22014-05-06 15:57:45 -0400332{
Nicolas Capensc8fcfd82018-01-11 12:53:57 -0500333 Config conformantConfig(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
Nicolas Capens216980a2017-01-02 16:21:39 -0500334 mSet.insert(conformantConfig);
John Bauman66b8ab22014-05-06 15:57:45 -0400335}
336
337size_t ConfigSet::size() const
338{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400339 return mSet.size();
John Bauman66b8ab22014-05-06 15:57:45 -0400340}
341
342bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
343{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400344 vector<const Config*> passed;
345 passed.reserve(mSet.size());
John Bauman66b8ab22014-05-06 15:57:45 -0400346
Chris Forbes787e3d52018-08-31 18:26:20 -0700347 /* Conformance expects for multiple instances of the same attribute that the
348 * last instance `wins`. Reduce the attribute list first to comply with
349 * this.
350 */
351 /* TODO: C++11: unordered_map would be fine here */
352 map<EGLint, EGLint> attribs;
353 const EGLint *attribute = attribList;
354 while (attribute[0] != EGL_NONE)
355 {
356 attribs[attribute[0]] = attribute[1];
357 attribute += 2;
358 }
359
Nicolas Capens0bac2852016-05-07 06:09:58 -0400360 for(Iterator config = mSet.begin(); config != mSet.end(); config++)
361 {
362 bool match = true;
Nicolas Capens216980a2017-01-02 16:21:39 -0500363 bool caveatMatch = (config->mConfigCaveat == EGL_NONE);
Chris Forbes787e3d52018-08-31 18:26:20 -0700364 for (map<EGLint, EGLint>::iterator attribIt = attribs.begin(); attribIt != attribs.end(); attribIt++)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400365 {
Chris Forbes787e3d52018-08-31 18:26:20 -0700366 if(attribIt->second != EGL_DONT_CARE)
Nicolas Capens101e4f02015-06-03 14:54:38 -0400367 {
Chris Forbes787e3d52018-08-31 18:26:20 -0700368 switch(attribIt->first)
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400369 {
Chris Forbes787e3d52018-08-31 18:26:20 -0700370 case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribIt->second; break;
371 case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribIt->second; break;
372 case EGL_BLUE_SIZE: match = config->mBlueSize >= attribIt->second; break;
373 case EGL_GREEN_SIZE: match = config->mGreenSize >= attribIt->second; break;
374 case EGL_RED_SIZE: match = config->mRedSize >= attribIt->second; break;
375 case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribIt->second; break;
376 case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribIt->second; break;
377 case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum)attribIt->second; break;
378 case EGL_CONFIG_ID: match = config->mConfigID == attribIt->second; break;
379 case EGL_LEVEL: match = config->mLevel >= attribIt->second; break;
380 case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean)attribIt->second; break;
381 case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribIt->second; break;
382 case EGL_SAMPLES: match = config->mSamples >= attribIt->second; break;
383 case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribIt->second; break;
384 case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribIt->second) == attribIt->second; break;
385 case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum)attribIt->second; break;
386 case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribIt->second; break;
387 case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribIt->second; break;
388 case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribIt->second; break;
389 case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean)attribIt->second; break;
390 case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean)attribIt->second; break;
391 case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribIt->second; break;
392 case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribIt->second; break;
393 case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribIt->second; break;
394 case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribIt->second; break;
395 case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum)attribIt->second; break;
396 case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribIt->second) == attribIt->second; break;
397 case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
398 case EGL_CONFORMANT: match = (config->mConformant & attribIt->second) == attribIt->second; break;
399 case EGL_RECORDABLE_ANDROID: match = config->mRecordableAndroid == (EGLBoolean)attribIt->second; break;
400 case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == (EGLBoolean)attribIt->second; break;
Nicolas Capense76163e2018-04-18 14:46:17 -0400401
402 // Ignored attributes
403 case EGL_MAX_PBUFFER_WIDTH:
404 case EGL_MAX_PBUFFER_HEIGHT:
405 case EGL_MAX_PBUFFER_PIXELS:
406 case EGL_NATIVE_VISUAL_ID:
407 break;
408
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400409 default:
Nicolas Capens0c19ed82015-08-12 17:21:06 -0400410 *numConfig = 0;
411 return false;
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400412 }
413
414 if(!match)
415 {
416 break;
417 }
Nicolas Capens101e4f02015-06-03 14:54:38 -0400418 }
419
Chris Forbes787e3d52018-08-31 18:26:20 -0700420 if(attribIt->first == EGL_CONFIG_CAVEAT)
Nicolas Capens216980a2017-01-02 16:21:39 -0500421 {
422 caveatMatch = match;
423 }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400424 }
John Bauman66b8ab22014-05-06 15:57:45 -0400425
Nicolas Capens216980a2017-01-02 16:21:39 -0500426 if(match && caveatMatch) // We require the caveats to be NONE or the requested flags
Nicolas Capens0bac2852016-05-07 06:09:58 -0400427 {
428 passed.push_back(&*config);
429 }
430 }
John Bauman66b8ab22014-05-06 15:57:45 -0400431
Nicolas Capens0bac2852016-05-07 06:09:58 -0400432 if(configs)
433 {
434 sort(passed.begin(), passed.end(), SortConfig(attribList));
John Bauman66b8ab22014-05-06 15:57:45 -0400435
Nicolas Capens0bac2852016-05-07 06:09:58 -0400436 EGLint index;
437 for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
438 {
439 configs[index] = passed[index]->getHandle();
440 }
John Bauman66b8ab22014-05-06 15:57:45 -0400441
Nicolas Capens0bac2852016-05-07 06:09:58 -0400442 *numConfig = index;
443 }
444 else
445 {
446 *numConfig = static_cast<EGLint>(passed.size());
447 }
John Bauman66b8ab22014-05-06 15:57:45 -0400448
Nicolas Capens0bac2852016-05-07 06:09:58 -0400449 return true;
John Bauman66b8ab22014-05-06 15:57:45 -0400450}
451
452const egl::Config *ConfigSet::get(EGLConfig configHandle)
453{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400454 for(Iterator config = mSet.begin(); config != mSet.end(); config++)
455 {
456 if(config->getHandle() == configHandle)
457 {
458 return &(*config);
459 }
460 }
John Bauman66b8ab22014-05-06 15:57:45 -0400461
Nicolas Capens0bac2852016-05-07 06:09:58 -0400462 return nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400463}
464}