blob: d78d3db0666ffba93be2b7d748aa62154a970c1d [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>
Nicolas Capensb3c0c732015-10-30 14:05:23 -040024#ifdef __ANDROID__
25#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>
32
33using namespace std;
34
35namespace egl
36{
Nicolas Capens8b4ea002015-10-01 01:09:27 -040037Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
Nicolas Capens0bac2852016-05-07 06:09:58 -040038 : mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
John Bauman66b8ab22014-05-06 15:57:45 -040039{
Nicolas Capens0bac2852016-05-07 06:09:58 -040040 mBindToTextureRGB = EGL_FALSE;
41 mBindToTextureRGBA = EGL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -040042
Nicolas Capensf59ad062015-11-13 12:39:21 -050043 // 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 -040044 mNativeVisualID = 0x7FFFFFFF;
Nicolas Capensb3c0c732015-10-30 14:05:23 -040045
Nicolas Capens0bac2852016-05-07 06:09:58 -040046 switch(renderTargetFormat)
47 {
48 case sw::FORMAT_A1R5G5B5:
49 mRedSize = 5;
50 mGreenSize = 5;
51 mBlueSize = 5;
52 mAlphaSize = 1;
53 break;
54 case sw::FORMAT_A2R10G10B10:
55 mRedSize = 10;
56 mGreenSize = 10;
57 mBlueSize = 10;
58 mAlphaSize = 2;
59 break;
60 case sw::FORMAT_A8R8G8B8:
61 mRedSize = 8;
62 mGreenSize = 8;
63 mBlueSize = 8;
64 mAlphaSize = 8;
65 mBindToTextureRGBA = EGL_TRUE;
66 #ifdef __ANDROID__
Nicolas Capensb3c0c732015-10-30 14:05:23 -040067 mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
Nicolas Capensf59ad062015-11-13 12:39:21 -050068 #else
69 mNativeVisualID = 2; // Arbitrary; prefer over ABGR
Nicolas Capensb3c0c732015-10-30 14:05:23 -040070 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040071 break;
Nicolas Capens5716cf02015-10-30 13:54:24 -040072 case sw::FORMAT_A8B8G8R8:
Nicolas Capens0bac2852016-05-07 06:09:58 -040073 mRedSize = 8;
74 mGreenSize = 8;
75 mBlueSize = 8;
76 mAlphaSize = 8;
77 mBindToTextureRGBA = EGL_TRUE;
Nicolas Capensb3c0c732015-10-30 14:05:23 -040078 #ifdef __ANDROID__
79 mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
80 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040081 break;
82 case sw::FORMAT_R5G6B5:
83 mRedSize = 5;
84 mGreenSize = 6;
85 mBlueSize = 5;
86 mAlphaSize = 0;
87 #ifdef __ANDROID__
Nicolas Capensb3c0c732015-10-30 14:05:23 -040088 mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
89 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040090 break;
91 case sw::FORMAT_X8R8G8B8:
92 mRedSize = 8;
93 mGreenSize = 8;
94 mBlueSize = 8;
95 mAlphaSize = 0;
96 mBindToTextureRGB = EGL_TRUE;
Nicolas Capensb3c0c732015-10-30 14:05:23 -040097 #ifdef __ANDROID__
Nicolas Capensf59ad062015-11-13 12:39:21 -050098 mNativeVisualID = 0x1FF; // HAL_PIXEL_FORMAT_BGRX_8888
99 #else
100 mNativeVisualID = 1; // Arbitrary; prefer over XBGR
Nicolas Capensb3c0c732015-10-30 14:05:23 -0400101 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400102 break;
Nicolas Capens5716cf02015-10-30 13:54:24 -0400103 case sw::FORMAT_X8B8G8R8:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400104 mRedSize = 8;
105 mGreenSize = 8;
106 mBlueSize = 8;
107 mAlphaSize = 0;
108 mBindToTextureRGB = EGL_TRUE;
Nicolas Capensb3c0c732015-10-30 14:05:23 -0400109 #ifdef __ANDROID__
110 mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
111 #endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400112 break;
113 default:
114 UNREACHABLE(renderTargetFormat);
115 }
John Bauman66b8ab22014-05-06 15:57:45 -0400116
Nicolas Capens0bac2852016-05-07 06:09:58 -0400117 mLuminanceSize = 0;
118 mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
119 mAlphaMaskSize = 0;
120 mColorBufferType = EGL_RGB_BUFFER;
121 mConfigCaveat = EGL_NONE;
122 mConfigID = 0;
123 mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
Alexis Hetu83d0e982015-07-02 14:17:00 -0400124#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
Nicolas Capens0bac2852016-05-07 06:09:58 -0400125 | EGL_OPENGL_ES3_BIT
Alexis Hetu83d0e982015-07-02 14:17:00 -0400126#endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400127 ;
John Bauman66b8ab22014-05-06 15:57:45 -0400128
Nicolas Capens5716cf02015-10-30 13:54:24 -0400129 switch(depthStencilFormat)
John Bauman66b8ab22014-05-06 15:57:45 -0400130 {
131 case sw::FORMAT_NULL:
132 mDepthSize = 0;
133 mStencilSize = 0;
134 break;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400135// case sw::FORMAT_D16_LOCKABLE:
136// mDepthSize = 16;
137// mStencilSize = 0;
138// break;
John Bauman66b8ab22014-05-06 15:57:45 -0400139 case sw::FORMAT_D32:
140 mDepthSize = 32;
141 mStencilSize = 0;
142 break;
143// case sw::FORMAT_D15S1:
144// mDepthSize = 15;
145// mStencilSize = 1;
146// break;
147 case sw::FORMAT_D24S8:
148 mDepthSize = 24;
149 mStencilSize = 8;
150 break;
151 case sw::FORMAT_D24X8:
152 mDepthSize = 24;
153 mStencilSize = 0;
154 break;
155// case sw::FORMAT_D24X4S4:
156// mDepthSize = 24;
157// mStencilSize = 4;
158// break;
159 case sw::FORMAT_D16:
160 mDepthSize = 16;
161 mStencilSize = 0;
162 break;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400163// case sw::FORMAT_D32F_LOCKABLE:
164// mDepthSize = 32;
165// mStencilSize = 0;
166// break;
167// case sw::FORMAT_D24FS8:
168// mDepthSize = 24;
169// mStencilSize = 8;
170// break;
Nicolas Capens101e4f02015-06-03 14:54:38 -0400171 default:
Nicolas Capens3713cd42015-06-22 10:41:54 -0400172 UNREACHABLE(depthStencilFormat);
John Bauman66b8ab22014-05-06 15:57:45 -0400173 }
174
Nicolas Capens0bac2852016-05-07 06:09:58 -0400175 mLevel = 0;
176 mMatchNativePixmap = EGL_NONE;
177 mMaxPBufferWidth = 4096;
178 mMaxPBufferHeight = 4096;
179 mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
180 mMaxSwapInterval = maxInterval;
181 mMinSwapInterval = minInterval;
182 mNativeRenderable = EGL_FALSE;
183 mNativeVisualType = 0;
184 mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
Alexis Hetu83d0e982015-07-02 14:17:00 -0400185#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
Nicolas Capens0bac2852016-05-07 06:09:58 -0400186 | EGL_OPENGL_ES3_BIT
Alexis Hetu83d0e982015-07-02 14:17:00 -0400187#endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400188 ;
189 mSampleBuffers = (multiSample > 0) ? 1 : 0;
190 mSamples = multiSample;
191 mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
192 mTransparentType = EGL_NONE;
193 mTransparentRedValue = 0;
194 mTransparentGreenValue = 0;
195 mTransparentBlueValue = 0;
Nicolas Capens9a74a0e2015-08-12 16:36:52 -0400196
197 mRecordableAndroid = EGL_TRUE;
Nicolas Capensb77b8772015-10-30 13:50:31 -0400198 mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -0400199}
200
201EGLConfig Config::getHandle() const
202{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400203 return (EGLConfig)(size_t)mConfigID;
John Bauman66b8ab22014-05-06 15:57:45 -0400204}
205
Nicolas Capense2b31f22015-05-31 01:38:47 -0400206// This ordering determines the config ID
207bool CompareConfig::operator()(const Config &x, const Config &y) const
208{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400209 #define SORT_SMALLER(attribute) \
210 if(x.attribute != y.attribute) \
211 { \
212 return x.attribute < y.attribute; \
213 }
Nicolas Capense2b31f22015-05-31 01:38:47 -0400214
Nicolas Capensa26bade2016-05-27 13:19:49 -0400215 static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400216 SORT_SMALLER(mConfigCaveat);
Nicolas Capense2b31f22015-05-31 01:38:47 -0400217
Nicolas Capensa26bade2016-05-27 13:19:49 -0400218 static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400219 SORT_SMALLER(mColorBufferType);
Nicolas Capense2b31f22015-05-31 01:38:47 -0400220
Nicolas Capens101e4f02015-06-03 14:54:38 -0400221 SORT_SMALLER(mRedSize);
222 SORT_SMALLER(mGreenSize);
223 SORT_SMALLER(mBlueSize);
224 SORT_SMALLER(mAlphaSize);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400225
Nicolas Capense2b31f22015-05-31 01:38:47 -0400226 SORT_SMALLER(mBufferSize);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400227 SORT_SMALLER(mSampleBuffers);
228 SORT_SMALLER(mSamples);
229 SORT_SMALLER(mDepthSize);
230 SORT_SMALLER(mStencilSize);
231 SORT_SMALLER(mAlphaMaskSize);
232 SORT_SMALLER(mNativeVisualType);
Nicolas Capensf59ad062015-11-13 12:39:21 -0500233 SORT_SMALLER(mNativeVisualID);
Nicolas Capense2b31f22015-05-31 01:38:47 -0400234
Nicolas Capens0bac2852016-05-07 06:09:58 -0400235 #undef SORT_SMALLER
Nicolas Capense2b31f22015-05-31 01:38:47 -0400236
237 // Strict ordering requires sorting all non-equal fields above
238 assert(memcmp(&x, &y, sizeof(Config)) == 0);
239
Nicolas Capens0bac2852016-05-07 06:09:58 -0400240 return false;
Nicolas Capense2b31f22015-05-31 01:38:47 -0400241}
242
Nicolas Capens101e4f02015-06-03 14:54:38 -0400243// Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
244class SortConfig
245{
246public:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400247 explicit SortConfig(const EGLint *attribList);
Nicolas Capens101e4f02015-06-03 14:54:38 -0400248
Nicolas Capens0bac2852016-05-07 06:09:58 -0400249 bool operator()(const Config *x, const Config *y) const;
Nicolas Capens101e4f02015-06-03 14:54:38 -0400250
251private:
Nicolas Capens0bac2852016-05-07 06:09:58 -0400252 EGLint wantedComponentsSize(const Config *config) const;
Nicolas Capens101e4f02015-06-03 14:54:38 -0400253
Nicolas Capens0bac2852016-05-07 06:09:58 -0400254 bool mWantRed;
255 bool mWantGreen;
256 bool mWantBlue;
257 bool mWantAlpha;
258 bool mWantLuminance;
Nicolas Capense2b31f22015-05-31 01:38:47 -0400259};
260
John Bauman66b8ab22014-05-06 15:57:45 -0400261SortConfig::SortConfig(const EGLint *attribList)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400262 : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
John Bauman66b8ab22014-05-06 15:57:45 -0400263{
Nicolas Capense2b31f22015-05-31 01:38:47 -0400264 // [EGL] section 3.4.1 page 24
Nicolas Capens0bac2852016-05-07 06:09:58 -0400265 // Sorting rule #3: by larger total number of color bits,
Nicolas Capense2b31f22015-05-31 01:38:47 -0400266 // not considering components that are 0 or don't-care.
Nicolas Capens0bac2852016-05-07 06:09:58 -0400267 for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
268 {
269 if(attr[1] != 0 && attr[1] != EGL_DONT_CARE)
270 {
271 switch(attr[0])
272 {
273 case EGL_RED_SIZE: mWantRed = true; break;
274 case EGL_GREEN_SIZE: mWantGreen = true; break;
275 case EGL_BLUE_SIZE: mWantBlue = true; break;
276 case EGL_ALPHA_SIZE: mWantAlpha = true; break;
277 case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
278 }
279 }
280 }
John Bauman66b8ab22014-05-06 15:57:45 -0400281}
282
Nicolas Capense2b31f22015-05-31 01:38:47 -0400283EGLint SortConfig::wantedComponentsSize(const Config *config) const
John Bauman66b8ab22014-05-06 15:57:45 -0400284{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400285 EGLint total = 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400286
Nicolas Capens0bac2852016-05-07 06:09:58 -0400287 if(mWantRed) total += config->mRedSize;
288 if(mWantGreen) total += config->mGreenSize;
289 if(mWantBlue) total += config->mBlueSize;
290 if(mWantAlpha) total += config->mAlphaSize;
291 if(mWantLuminance) total += config->mLuminanceSize;
John Bauman66b8ab22014-05-06 15:57:45 -0400292
Nicolas Capens0bac2852016-05-07 06:09:58 -0400293 return total;
John Bauman66b8ab22014-05-06 15:57:45 -0400294}
295
296bool SortConfig::operator()(const Config *x, const Config *y) const
297{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400298 #define SORT_SMALLER(attribute) \
299 if(x->attribute != y->attribute) \
300 { \
301 return x->attribute < y->attribute; \
302 }
John Bauman66b8ab22014-05-06 15:57:45 -0400303
Nicolas Capensa26bade2016-05-27 13:19:49 -0400304 static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400305 SORT_SMALLER(mConfigCaveat);
John Bauman66b8ab22014-05-06 15:57:45 -0400306
Nicolas Capensa26bade2016-05-27 13:19:49 -0400307 static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400308 SORT_SMALLER(mColorBufferType);
John Bauman66b8ab22014-05-06 15:57:45 -0400309
Nicolas Capense2b31f22015-05-31 01:38:47 -0400310 // By larger total number of color bits, only considering those that are requested to be > 0.
311 EGLint xComponentsSize = wantedComponentsSize(x);
312 EGLint yComponentsSize = wantedComponentsSize(y);
313 if(xComponentsSize != yComponentsSize)
314 {
315 return xComponentsSize > yComponentsSize;
316 }
John Bauman66b8ab22014-05-06 15:57:45 -0400317
Nicolas Capens0bac2852016-05-07 06:09:58 -0400318 SORT_SMALLER(mBufferSize);
319 SORT_SMALLER(mSampleBuffers);
320 SORT_SMALLER(mSamples);
321 SORT_SMALLER(mDepthSize);
322 SORT_SMALLER(mStencilSize);
323 SORT_SMALLER(mAlphaMaskSize);
324 SORT_SMALLER(mNativeVisualType);
325 SORT_SMALLER(mConfigID);
John Bauman66b8ab22014-05-06 15:57:45 -0400326
Nicolas Capens0bac2852016-05-07 06:09:58 -0400327 #undef SORT_SMALLER
John Bauman66b8ab22014-05-06 15:57:45 -0400328
Nicolas Capens0bac2852016-05-07 06:09:58 -0400329 return false;
John Bauman66b8ab22014-05-06 15:57:45 -0400330}
331
John Bauman66b8ab22014-05-06 15:57:45 -0400332ConfigSet::ConfigSet()
John Bauman66b8ab22014-05-06 15:57:45 -0400333{
334}
335
Nicolas Capens8b4ea002015-10-01 01:09:27 -0400336void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
John Bauman66b8ab22014-05-06 15:57:45 -0400337{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400338 Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
John Bauman66b8ab22014-05-06 15:57:45 -0400339
Nicolas Capens0bac2852016-05-07 06:09:58 -0400340 mSet.insert(config);
John Bauman66b8ab22014-05-06 15:57:45 -0400341}
342
343size_t ConfigSet::size() const
344{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400345 return mSet.size();
John Bauman66b8ab22014-05-06 15:57:45 -0400346}
347
348bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
349{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400350 vector<const Config*> passed;
351 passed.reserve(mSet.size());
John Bauman66b8ab22014-05-06 15:57:45 -0400352
Nicolas Capens0bac2852016-05-07 06:09:58 -0400353 for(Iterator config = mSet.begin(); config != mSet.end(); config++)
354 {
355 bool match = true;
356 const EGLint *attribute = attribList;
John Bauman66b8ab22014-05-06 15:57:45 -0400357
Nicolas Capens0bac2852016-05-07 06:09:58 -0400358 while(attribute[0] != EGL_NONE)
359 {
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400360 if(attribute[1] != EGL_DONT_CARE)
Nicolas Capens101e4f02015-06-03 14:54:38 -0400361 {
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400362 switch(attribute[0])
363 {
Nicolas Capens5d961882016-01-01 23:18:14 -0500364 case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribute[1]; break;
365 case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribute[1]; break;
366 case EGL_BLUE_SIZE: match = config->mBlueSize >= attribute[1]; break;
367 case EGL_GREEN_SIZE: match = config->mGreenSize >= attribute[1]; break;
368 case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break;
369 case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break;
370 case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break;
371 case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum)attribute[1]; break;
372 case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break;
373 case EGL_LEVEL: match = config->mLevel >= attribute[1]; break;
374 case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean)attribute[1]; break;
375 case EGL_NATIVE_VISUAL_ID: match = config->mNativeVisualID == attribute[1]; break;
376 case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break;
377 case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break;
378 case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break;
379 case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break;
380 case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum)attribute[1]; break;
381 case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break;
382 case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break;
383 case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break;
384 case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean)attribute[1]; break;
385 case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean)attribute[1]; break;
386 case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break;
387 case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break;
388 case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break;
389 case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break;
390 case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum)attribute[1]; break;
391 case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
392 case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
393 case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break;
394 case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break;
395 case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break;
396 case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break;
397 case EGL_RECORDABLE_ANDROID: match = config->mRecordableAndroid == (EGLBoolean)attribute[1]; break;
398 case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == (EGLBoolean)attribute[1]; break;
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400399 default:
Nicolas Capens0c19ed82015-08-12 17:21:06 -0400400 *numConfig = 0;
401 return false;
Nicolas Capensfc02cfc2015-06-04 08:59:09 -0400402 }
403
404 if(!match)
405 {
406 break;
407 }
Nicolas Capens101e4f02015-06-03 14:54:38 -0400408 }
409
Nicolas Capens0bac2852016-05-07 06:09:58 -0400410 attribute += 2;
411 }
John Bauman66b8ab22014-05-06 15:57:45 -0400412
Nicolas Capens0bac2852016-05-07 06:09:58 -0400413 if(match)
414 {
415 passed.push_back(&*config);
416 }
417 }
John Bauman66b8ab22014-05-06 15:57:45 -0400418
Nicolas Capens0bac2852016-05-07 06:09:58 -0400419 if(configs)
420 {
421 sort(passed.begin(), passed.end(), SortConfig(attribList));
John Bauman66b8ab22014-05-06 15:57:45 -0400422
Nicolas Capens0bac2852016-05-07 06:09:58 -0400423 EGLint index;
424 for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
425 {
426 configs[index] = passed[index]->getHandle();
427 }
John Bauman66b8ab22014-05-06 15:57:45 -0400428
Nicolas Capens0bac2852016-05-07 06:09:58 -0400429 *numConfig = index;
430 }
431 else
432 {
433 *numConfig = static_cast<EGLint>(passed.size());
434 }
John Bauman66b8ab22014-05-06 15:57:45 -0400435
Nicolas Capens0bac2852016-05-07 06:09:58 -0400436 return true;
John Bauman66b8ab22014-05-06 15:57:45 -0400437}
438
439const egl::Config *ConfigSet::get(EGLConfig configHandle)
440{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400441 for(Iterator config = mSet.begin(); config != mSet.end(); config++)
442 {
443 if(config->getHandle() == configHandle)
444 {
445 return &(*config);
446 }
447 }
John Bauman66b8ab22014-05-06 15:57:45 -0400448
Nicolas Capens0bac2852016-05-07 06:09:58 -0400449 return nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400450}
451}