John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 1 | // SwiftShader Software Renderer |
| 2 | // |
John Bauman | d4ae863 | 2014-05-06 16:18:33 -0400 | [diff] [blame] | 3 | // Copyright(c) 2005-2013 TransGaming Inc. |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 4 | // |
| 5 | // All rights reserved. No part of this software may be copied, distributed, transmitted, |
| 6 | // transcribed, stored in a retrieval system, translated into any human or computer |
| 7 | // language by any means, or disclosed to third parties without the explicit written |
| 8 | // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express |
| 9 | // or implied, including but not limited to any patent rights, are granted to you. |
| 10 | // |
| 11 | |
| 12 | // Config.cpp: Implements the egl::Config class, describing the format, type |
| 13 | // and size for an egl::Surface. Implements EGLConfig and related functionality. |
| 14 | // [EGL 1.4] section 3.4 page 15. |
| 15 | |
| 16 | #include "Config.h" |
| 17 | |
| 18 | #include "common/debug.h" |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 19 | |
Nicolas Capens | f4fea7f | 2014-11-25 13:31:46 -0500 | [diff] [blame] | 20 | #include <EGL/eglext.h> |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 21 | #ifdef __ANDROID__ |
| 22 | #include <system/graphics.h> |
| 23 | #endif |
Nicolas Capens | f4fea7f | 2014-11-25 13:31:46 -0500 | [diff] [blame] | 24 | |
Nicolas Capens | b77b877 | 2015-10-30 13:50:31 -0400 | [diff] [blame] | 25 | #include <string.h> |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 26 | #include <algorithm> |
| 27 | #include <vector> |
| 28 | |
| 29 | using namespace std; |
| 30 | |
| 31 | namespace egl |
| 32 | { |
Nicolas Capens | 8b4ea00 | 2015-10-01 01:09:27 -0400 | [diff] [blame] | 33 | Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample) |
| 34 | : mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 35 | { |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 36 | mBindToTextureRGB = EGL_FALSE; |
| 37 | mBindToTextureRGBA = EGL_FALSE; |
| 38 | |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 39 | mNativeVisualID = 0; |
| 40 | |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 41 | switch(renderTargetFormat) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 42 | { |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 43 | case sw::FORMAT_A1R5G5B5: |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 44 | mRedSize = 5; |
| 45 | mGreenSize = 5; |
| 46 | mBlueSize = 5; |
| 47 | mAlphaSize = 1; |
| 48 | break; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 49 | case sw::FORMAT_A2R10G10B10: |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 50 | mRedSize = 10; |
| 51 | mGreenSize = 10; |
| 52 | mBlueSize = 10; |
| 53 | mAlphaSize = 2; |
| 54 | break; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 55 | case sw::FORMAT_A8R8G8B8: |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 56 | mRedSize = 8; |
| 57 | mGreenSize = 8; |
| 58 | mBlueSize = 8; |
| 59 | mAlphaSize = 8; |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 60 | mBindToTextureRGBA = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 61 | #ifdef __ANDROID__ |
| 62 | mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888; |
| 63 | #endif |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 64 | break; |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 65 | case sw::FORMAT_A8B8G8R8: |
| 66 | mRedSize = 8; |
| 67 | mGreenSize = 8; |
| 68 | mBlueSize = 8; |
| 69 | mAlphaSize = 8; |
| 70 | mBindToTextureRGBA = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 71 | #ifdef __ANDROID__ |
| 72 | mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888; |
| 73 | #endif |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 74 | break; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 75 | case sw::FORMAT_R5G6B5: |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 76 | mRedSize = 5; |
| 77 | mGreenSize = 6; |
| 78 | mBlueSize = 5; |
| 79 | mAlphaSize = 0; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 80 | #ifdef __ANDROID__ |
| 81 | mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565; |
| 82 | #endif |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 83 | break; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 84 | case sw::FORMAT_X8R8G8B8: |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 85 | mRedSize = 8; |
| 86 | mGreenSize = 8; |
| 87 | mBlueSize = 8; |
| 88 | mAlphaSize = 0; |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 89 | mBindToTextureRGB = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 90 | #ifdef __ANDROID__ |
| 91 | mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888; |
| 92 | #endif |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 93 | break; |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 94 | case sw::FORMAT_X8B8G8R8: |
| 95 | mRedSize = 8; |
| 96 | mGreenSize = 8; |
| 97 | mBlueSize = 8; |
| 98 | mAlphaSize = 0; |
| 99 | mBindToTextureRGBA = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame^] | 100 | #ifdef __ANDROID__ |
| 101 | mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888; |
| 102 | #endif |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 103 | break; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 104 | default: |
Nicolas Capens | 3713cd4 | 2015-06-22 10:41:54 -0400 | [diff] [blame] | 105 | UNREACHABLE(renderTargetFormat); // Other formats should not be valid |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | mLuminanceSize = 0; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 109 | mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 110 | mAlphaMaskSize = 0; |
| 111 | mColorBufferType = EGL_RGB_BUFFER; |
Nicolas Capens | 3533125 | 2014-11-24 17:36:19 -0500 | [diff] [blame] | 112 | mConfigCaveat = isSlowConfig() ? EGL_SLOW_CONFIG : EGL_NONE; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 113 | mConfigID = 0; |
Alexis Hetu | 83d0e98 | 2015-07-02 14:17:00 -0400 | [diff] [blame] | 114 | mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT |
| 115 | #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android |
| 116 | | EGL_OPENGL_ES3_BIT |
| 117 | #endif |
| 118 | ; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 119 | |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 120 | switch(depthStencilFormat) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 121 | { |
| 122 | case sw::FORMAT_NULL: |
| 123 | mDepthSize = 0; |
| 124 | mStencilSize = 0; |
| 125 | break; |
| 126 | // case sw::FORMAT_D16_LOCKABLE: |
| 127 | // mDepthSize = 16; |
| 128 | // mStencilSize = 0; |
| 129 | // break; |
| 130 | case sw::FORMAT_D32: |
| 131 | mDepthSize = 32; |
| 132 | mStencilSize = 0; |
| 133 | break; |
| 134 | // case sw::FORMAT_D15S1: |
| 135 | // mDepthSize = 15; |
| 136 | // mStencilSize = 1; |
| 137 | // break; |
| 138 | case sw::FORMAT_D24S8: |
| 139 | mDepthSize = 24; |
| 140 | mStencilSize = 8; |
| 141 | break; |
| 142 | case sw::FORMAT_D24X8: |
| 143 | mDepthSize = 24; |
| 144 | mStencilSize = 0; |
| 145 | break; |
| 146 | // case sw::FORMAT_D24X4S4: |
| 147 | // mDepthSize = 24; |
| 148 | // mStencilSize = 4; |
| 149 | // break; |
| 150 | case sw::FORMAT_D16: |
| 151 | mDepthSize = 16; |
| 152 | mStencilSize = 0; |
| 153 | break; |
| 154 | // case sw::FORMAT_D32F_LOCKABLE: |
| 155 | // mDepthSize = 32; |
| 156 | // mStencilSize = 0; |
| 157 | // break; |
| 158 | // case sw::FORMAT_D24FS8: |
| 159 | // mDepthSize = 24; |
| 160 | // mStencilSize = 8; |
| 161 | // break; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 162 | default: |
Nicolas Capens | 3713cd4 | 2015-06-22 10:41:54 -0400 | [diff] [blame] | 163 | UNREACHABLE(depthStencilFormat); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 164 | } |
| 165 | |
| 166 | mLevel = 0; |
| 167 | mMatchNativePixmap = EGL_NONE; |
| 168 | mMaxPBufferWidth = 4096; |
| 169 | mMaxPBufferHeight = 4096; |
| 170 | mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight; |
| 171 | mMaxSwapInterval = maxInterval; |
| 172 | mMinSwapInterval = minInterval; |
| 173 | mNativeRenderable = EGL_FALSE; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 174 | mNativeVisualType = 0; |
Alexis Hetu | 83d0e98 | 2015-07-02 14:17:00 -0400 | [diff] [blame] | 175 | mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT |
| 176 | #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android |
| 177 | | EGL_OPENGL_ES3_BIT |
| 178 | #endif |
| 179 | ; |
Nicolas Capens | b602f0d | 2015-09-01 01:38:00 -0400 | [diff] [blame] | 180 | mSampleBuffers = (multiSample > 0) ? 1 : 0; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 181 | mSamples = multiSample; |
| 182 | mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; |
| 183 | mTransparentType = EGL_NONE; |
| 184 | mTransparentRedValue = 0; |
| 185 | mTransparentGreenValue = 0; |
| 186 | mTransparentBlueValue = 0; |
Nicolas Capens | 9a74a0e | 2015-08-12 16:36:52 -0400 | [diff] [blame] | 187 | |
| 188 | mRecordableAndroid = EGL_TRUE; |
Nicolas Capens | b77b877 | 2015-10-30 13:50:31 -0400 | [diff] [blame] | 189 | mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | EGLConfig Config::getHandle() const |
| 193 | { |
| 194 | return (EGLConfig)(size_t)mConfigID; |
| 195 | } |
| 196 | |
Nicolas Capens | 3533125 | 2014-11-24 17:36:19 -0500 | [diff] [blame] | 197 | bool Config::isSlowConfig() const |
| 198 | { |
Nicolas Capens | 688b0ad | 2014-12-04 14:41:38 -0500 | [diff] [blame] | 199 | return mRenderTargetFormat != sw::FORMAT_X8R8G8B8 && mRenderTargetFormat != sw::FORMAT_A8R8G8B8; |
Nicolas Capens | 3533125 | 2014-11-24 17:36:19 -0500 | [diff] [blame] | 200 | } |
| 201 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 202 | // This ordering determines the config ID |
| 203 | bool CompareConfig::operator()(const Config &x, const Config &y) const |
| 204 | { |
| 205 | #define SORT_SMALLER(attribute) \ |
| 206 | if(x.attribute != y.attribute) \ |
| 207 | { \ |
| 208 | return x.attribute < y.attribute; \ |
| 209 | } |
| 210 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 211 | META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); |
| 212 | SORT_SMALLER(mConfigCaveat); |
| 213 | |
| 214 | META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER); |
| 215 | SORT_SMALLER(mColorBufferType); |
| 216 | |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 217 | SORT_SMALLER(mRedSize); |
| 218 | SORT_SMALLER(mGreenSize); |
| 219 | SORT_SMALLER(mBlueSize); |
| 220 | SORT_SMALLER(mAlphaSize); |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 221 | |
| 222 | SORT_SMALLER(mBufferSize); |
| 223 | SORT_SMALLER(mSampleBuffers); |
| 224 | SORT_SMALLER(mSamples); |
| 225 | SORT_SMALLER(mDepthSize); |
| 226 | SORT_SMALLER(mStencilSize); |
| 227 | SORT_SMALLER(mAlphaMaskSize); |
| 228 | SORT_SMALLER(mNativeVisualType); |
| 229 | |
| 230 | #undef SORT_SMALLER |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 231 | |
| 232 | // Strict ordering requires sorting all non-equal fields above |
| 233 | assert(memcmp(&x, &y, sizeof(Config)) == 0); |
| 234 | |
| 235 | return false; |
| 236 | } |
| 237 | |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 238 | // Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24. |
| 239 | class SortConfig |
| 240 | { |
| 241 | public: |
| 242 | explicit SortConfig(const EGLint *attribList); |
| 243 | |
| 244 | bool operator()(const Config *x, const Config *y) const; |
| 245 | |
| 246 | private: |
| 247 | EGLint wantedComponentsSize(const Config *config) const; |
| 248 | |
| 249 | bool mWantRed; |
| 250 | bool mWantGreen; |
| 251 | bool mWantBlue; |
| 252 | bool mWantAlpha; |
| 253 | bool mWantLuminance; |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 254 | }; |
| 255 | |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 256 | SortConfig::SortConfig(const EGLint *attribList) |
| 257 | : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false) |
| 258 | { |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 259 | // [EGL] section 3.4.1 page 24 |
| 260 | // Sorting rule #3: by larger total number of color bits, |
| 261 | // not considering components that are 0 or don't-care. |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 262 | for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2) |
| 263 | { |
| 264 | if(attr[1] != 0 && attr[1] != EGL_DONT_CARE) |
| 265 | { |
| 266 | switch (attr[0]) |
| 267 | { |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 268 | case EGL_RED_SIZE: mWantRed = true; break; |
| 269 | case EGL_GREEN_SIZE: mWantGreen = true; break; |
| 270 | case EGL_BLUE_SIZE: mWantBlue = true; break; |
| 271 | case EGL_ALPHA_SIZE: mWantAlpha = true; break; |
| 272 | case EGL_LUMINANCE_SIZE: mWantLuminance = true; break; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 273 | } |
| 274 | } |
| 275 | } |
| 276 | } |
| 277 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 278 | EGLint SortConfig::wantedComponentsSize(const Config *config) const |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 279 | { |
| 280 | EGLint total = 0; |
| 281 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 282 | 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 287 | |
| 288 | return total; |
| 289 | } |
| 290 | |
| 291 | bool SortConfig::operator()(const Config *x, const Config *y) const |
| 292 | { |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 293 | #define SORT_SMALLER(attribute) \ |
| 294 | if(x->attribute != y->attribute) \ |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 295 | { \ |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 296 | return x->attribute < y->attribute; \ |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 297 | } |
| 298 | |
| 299 | META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 300 | SORT_SMALLER(mConfigCaveat); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 301 | |
| 302 | META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER); |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 303 | SORT_SMALLER(mColorBufferType); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 304 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 305 | // 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 312 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 313 | 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 321 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 322 | #undef SORT_SMALLER |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 323 | |
| 324 | return false; |
| 325 | } |
| 326 | |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 327 | ConfigSet::ConfigSet() |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 328 | { |
| 329 | } |
| 330 | |
Nicolas Capens | 8b4ea00 | 2015-10-01 01:09:27 -0400 | [diff] [blame] | 331 | void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 332 | { |
Nicolas Capens | 8b4ea00 | 2015-10-01 01:09:27 -0400 | [diff] [blame] | 333 | Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 334 | |
| 335 | mSet.insert(config); |
| 336 | } |
| 337 | |
| 338 | size_t ConfigSet::size() const |
| 339 | { |
| 340 | return mSet.size(); |
| 341 | } |
| 342 | |
| 343 | bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig) |
| 344 | { |
| 345 | vector<const Config*> passed; |
| 346 | passed.reserve(mSet.size()); |
| 347 | |
| 348 | for(Iterator config = mSet.begin(); config != mSet.end(); config++) |
| 349 | { |
| 350 | bool match = true; |
| 351 | const EGLint *attribute = attribList; |
| 352 | |
| 353 | while(attribute[0] != EGL_NONE) |
| 354 | { |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 355 | if(attribute[1] != EGL_DONT_CARE) |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 356 | { |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 357 | switch(attribute[0]) |
| 358 | { |
| 359 | case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribute[1]; break; |
| 360 | case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribute[1]; break; |
| 361 | case EGL_BLUE_SIZE: match = config->mBlueSize >= attribute[1]; break; |
| 362 | case EGL_GREEN_SIZE: match = config->mGreenSize >= attribute[1]; break; |
| 363 | case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break; |
| 364 | case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break; |
| 365 | case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break; |
| 366 | case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == attribute[1]; break; |
| 367 | case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break; |
| 368 | case EGL_LEVEL: match = config->mLevel >= attribute[1]; break; |
| 369 | case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break; |
| 370 | case EGL_NATIVE_VISUAL_ID: match = config->mNativeVisualID == attribute[1]; break; |
| 371 | case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break; |
| 372 | case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break; |
| 373 | case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break; |
| 374 | case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break; |
| 375 | case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == attribute[1]; break; |
| 376 | case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break; |
| 377 | case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break; |
| 378 | case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break; |
| 379 | case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == attribute[1]; break; |
| 380 | case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == attribute[1]; break; |
| 381 | case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break; |
| 382 | case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break; |
| 383 | case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break; |
| 384 | case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break; |
| 385 | case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == attribute[1]; break; |
| 386 | case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break; |
| 387 | case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break; |
| 388 | case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break; |
| 389 | case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break; |
| 390 | case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break; |
| 391 | case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break; |
Nicolas Capens | 9a74a0e | 2015-08-12 16:36:52 -0400 | [diff] [blame] | 392 | case EGL_RECORDABLE_ANDROID: match = config->mRecordableAndroid == attribute[1]; break; |
| 393 | case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == attribute[1]; break; |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 394 | default: |
Nicolas Capens | 0c19ed8 | 2015-08-12 17:21:06 -0400 | [diff] [blame] | 395 | *numConfig = 0; |
| 396 | return false; |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 397 | } |
| 398 | |
| 399 | if(!match) |
| 400 | { |
| 401 | break; |
| 402 | } |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 403 | } |
| 404 | |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 405 | attribute += 2; |
| 406 | } |
| 407 | |
| 408 | if(match) |
| 409 | { |
| 410 | passed.push_back(&*config); |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | if(configs) |
| 415 | { |
| 416 | sort(passed.begin(), passed.end(), SortConfig(attribList)); |
| 417 | |
| 418 | EGLint index; |
| 419 | for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++) |
| 420 | { |
| 421 | configs[index] = passed[index]->getHandle(); |
| 422 | } |
| 423 | |
| 424 | *numConfig = index; |
| 425 | } |
| 426 | else |
| 427 | { |
Alexis Hetu | 617a5d5 | 2014-11-13 10:56:20 -0500 | [diff] [blame] | 428 | *numConfig = static_cast<EGLint>(passed.size()); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 429 | } |
| 430 | |
| 431 | return true; |
| 432 | } |
| 433 | |
| 434 | const egl::Config *ConfigSet::get(EGLConfig configHandle) |
| 435 | { |
| 436 | for(Iterator config = mSet.begin(); config != mSet.end(); config++) |
| 437 | { |
| 438 | if(config->getHandle() == configHandle) |
| 439 | { |
| 440 | return &(*config); |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | return NULL; |
| 445 | } |
| 446 | } |