Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 2 | // |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 3 | // 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 6 | // |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 8 | // |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 9 | // 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 14 | |
| 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 22 | |
Nicolas Capens | f4fea7f | 2014-11-25 13:31:46 -0500 | [diff] [blame] | 23 | #include <EGL/eglext.h> |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 24 | #ifdef __ANDROID__ |
| 25 | #include <system/graphics.h> |
| 26 | #endif |
Nicolas Capens | f4fea7f | 2014-11-25 13:31:46 -0500 | [diff] [blame] | 27 | |
Nicolas Capens | b77b877 | 2015-10-30 13:50:31 -0400 | [diff] [blame] | 28 | #include <string.h> |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 29 | #include <algorithm> |
Anthony Vallee-Dubois | 13241c6 | 2015-08-17 14:12:32 -0400 | [diff] [blame] | 30 | #include <cstring> |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 31 | #include <vector> |
| 32 | |
| 33 | using namespace std; |
| 34 | |
| 35 | namespace egl |
| 36 | { |
Nicolas Capens | 8b4ea00 | 2015-10-01 01:09:27 -0400 | [diff] [blame] | 37 | Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample) |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 38 | : mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 39 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 40 | mBindToTextureRGB = EGL_FALSE; |
| 41 | mBindToTextureRGBA = EGL_FALSE; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 42 | |
Nicolas Capens | f59ad06 | 2015-11-13 12:39:21 -0500 | [diff] [blame] | 43 | // Initialize to a high value to lower the preference of formats for which there's no native support |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 44 | mNativeVisualID = 0x7FFFFFFF; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 45 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 46 | 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 Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 67 | mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888; |
Nicolas Capens | f59ad06 | 2015-11-13 12:39:21 -0500 | [diff] [blame] | 68 | #else |
| 69 | mNativeVisualID = 2; // Arbitrary; prefer over ABGR |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 70 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 71 | break; |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 72 | case sw::FORMAT_A8B8G8R8: |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 73 | mRedSize = 8; |
| 74 | mGreenSize = 8; |
| 75 | mBlueSize = 8; |
| 76 | mAlphaSize = 8; |
| 77 | mBindToTextureRGBA = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 78 | #ifdef __ANDROID__ |
| 79 | mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888; |
| 80 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 81 | break; |
| 82 | case sw::FORMAT_R5G6B5: |
| 83 | mRedSize = 5; |
| 84 | mGreenSize = 6; |
| 85 | mBlueSize = 5; |
| 86 | mAlphaSize = 0; |
| 87 | #ifdef __ANDROID__ |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 88 | mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565; |
| 89 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 90 | break; |
| 91 | case sw::FORMAT_X8R8G8B8: |
| 92 | mRedSize = 8; |
| 93 | mGreenSize = 8; |
| 94 | mBlueSize = 8; |
| 95 | mAlphaSize = 0; |
| 96 | mBindToTextureRGB = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 97 | #ifdef __ANDROID__ |
Nicolas Capens | f59ad06 | 2015-11-13 12:39:21 -0500 | [diff] [blame] | 98 | mNativeVisualID = 0x1FF; // HAL_PIXEL_FORMAT_BGRX_8888 |
| 99 | #else |
| 100 | mNativeVisualID = 1; // Arbitrary; prefer over XBGR |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 101 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 102 | break; |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 103 | case sw::FORMAT_X8B8G8R8: |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 104 | mRedSize = 8; |
| 105 | mGreenSize = 8; |
| 106 | mBlueSize = 8; |
| 107 | mAlphaSize = 0; |
| 108 | mBindToTextureRGB = EGL_TRUE; |
Nicolas Capens | b3c0c73 | 2015-10-30 14:05:23 -0400 | [diff] [blame] | 109 | #ifdef __ANDROID__ |
| 110 | mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888; |
| 111 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 112 | break; |
| 113 | default: |
| 114 | UNREACHABLE(renderTargetFormat); |
| 115 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 116 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 117 | 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 Hetu | 83d0e98 | 2015-07-02 14:17:00 -0400 | [diff] [blame] | 124 | #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 125 | | EGL_OPENGL_ES3_BIT |
Alexis Hetu | 83d0e98 | 2015-07-02 14:17:00 -0400 | [diff] [blame] | 126 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 127 | ; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 128 | |
Nicolas Capens | 5716cf0 | 2015-10-30 13:54:24 -0400 | [diff] [blame] | 129 | switch(depthStencilFormat) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 130 | { |
| 131 | case sw::FORMAT_NULL: |
| 132 | mDepthSize = 0; |
| 133 | mStencilSize = 0; |
| 134 | break; |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 135 | // case sw::FORMAT_D16_LOCKABLE: |
| 136 | // mDepthSize = 16; |
| 137 | // mStencilSize = 0; |
| 138 | // break; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 139 | 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 Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 163 | // 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 Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 171 | default: |
Nicolas Capens | 3713cd4 | 2015-06-22 10:41:54 -0400 | [diff] [blame] | 172 | UNREACHABLE(depthStencilFormat); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 173 | } |
| 174 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 175 | 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 Hetu | 83d0e98 | 2015-07-02 14:17:00 -0400 | [diff] [blame] | 185 | #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 186 | | EGL_OPENGL_ES3_BIT |
Alexis Hetu | 83d0e98 | 2015-07-02 14:17:00 -0400 | [diff] [blame] | 187 | #endif |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 188 | ; |
| 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 Capens | 9a74a0e | 2015-08-12 16:36:52 -0400 | [diff] [blame] | 196 | |
| 197 | mRecordableAndroid = EGL_TRUE; |
Nicolas Capens | b77b877 | 2015-10-30 13:50:31 -0400 | [diff] [blame] | 198 | mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | EGLConfig Config::getHandle() const |
| 202 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 203 | return (EGLConfig)(size_t)mConfigID; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 204 | } |
| 205 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 206 | // This ordering determines the config ID |
| 207 | bool CompareConfig::operator()(const Config &x, const Config &y) const |
| 208 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 209 | #define SORT_SMALLER(attribute) \ |
| 210 | if(x.attribute != y.attribute) \ |
| 211 | { \ |
| 212 | return x.attribute < y.attribute; \ |
| 213 | } |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 214 | |
Nicolas Capens | a26bade | 2016-05-27 13:19:49 -0400 | [diff] [blame] | 215 | static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, ""); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 216 | SORT_SMALLER(mConfigCaveat); |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 217 | |
Nicolas Capens | a26bade | 2016-05-27 13:19:49 -0400 | [diff] [blame] | 218 | static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, ""); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 219 | SORT_SMALLER(mColorBufferType); |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 220 | |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 221 | SORT_SMALLER(mRedSize); |
| 222 | SORT_SMALLER(mGreenSize); |
| 223 | SORT_SMALLER(mBlueSize); |
| 224 | SORT_SMALLER(mAlphaSize); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 225 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 226 | SORT_SMALLER(mBufferSize); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 227 | SORT_SMALLER(mSampleBuffers); |
| 228 | SORT_SMALLER(mSamples); |
| 229 | SORT_SMALLER(mDepthSize); |
| 230 | SORT_SMALLER(mStencilSize); |
| 231 | SORT_SMALLER(mAlphaMaskSize); |
| 232 | SORT_SMALLER(mNativeVisualType); |
Nicolas Capens | f59ad06 | 2015-11-13 12:39:21 -0500 | [diff] [blame] | 233 | SORT_SMALLER(mNativeVisualID); |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 234 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 235 | #undef SORT_SMALLER |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 236 | |
| 237 | // Strict ordering requires sorting all non-equal fields above |
| 238 | assert(memcmp(&x, &y, sizeof(Config)) == 0); |
| 239 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 240 | return false; |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 241 | } |
| 242 | |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 243 | // Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24. |
| 244 | class SortConfig |
| 245 | { |
| 246 | public: |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 247 | explicit SortConfig(const EGLint *attribList); |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 248 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 249 | bool operator()(const Config *x, const Config *y) const; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 250 | |
| 251 | private: |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 252 | EGLint wantedComponentsSize(const Config *config) const; |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 253 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 254 | bool mWantRed; |
| 255 | bool mWantGreen; |
| 256 | bool mWantBlue; |
| 257 | bool mWantAlpha; |
| 258 | bool mWantLuminance; |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 259 | }; |
| 260 | |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 261 | SortConfig::SortConfig(const EGLint *attribList) |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 262 | : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false) |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 263 | { |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 264 | // [EGL] section 3.4.1 page 24 |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 265 | // Sorting rule #3: by larger total number of color bits, |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 266 | // not considering components that are 0 or don't-care. |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 267 | 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 281 | } |
| 282 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 283 | EGLint SortConfig::wantedComponentsSize(const Config *config) const |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 284 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 285 | EGLint total = 0; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 286 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 287 | 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 292 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 293 | return total; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 294 | } |
| 295 | |
| 296 | bool SortConfig::operator()(const Config *x, const Config *y) const |
| 297 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 298 | #define SORT_SMALLER(attribute) \ |
| 299 | if(x->attribute != y->attribute) \ |
| 300 | { \ |
| 301 | return x->attribute < y->attribute; \ |
| 302 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 303 | |
Nicolas Capens | a26bade | 2016-05-27 13:19:49 -0400 | [diff] [blame] | 304 | static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, ""); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 305 | SORT_SMALLER(mConfigCaveat); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 306 | |
Nicolas Capens | a26bade | 2016-05-27 13:19:49 -0400 | [diff] [blame] | 307 | static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, ""); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 308 | SORT_SMALLER(mColorBufferType); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 309 | |
Nicolas Capens | e2b31f2 | 2015-05-31 01:38:47 -0400 | [diff] [blame] | 310 | // 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 317 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 318 | 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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 326 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 327 | #undef SORT_SMALLER |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 328 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 329 | return false; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 330 | } |
| 331 | |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 332 | ConfigSet::ConfigSet() |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 333 | { |
| 334 | } |
| 335 | |
Nicolas Capens | 8b4ea00 | 2015-10-01 01:09:27 -0400 | [diff] [blame] | 336 | 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] | 337 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 338 | Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 339 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 340 | mSet.insert(config); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 341 | } |
| 342 | |
| 343 | size_t ConfigSet::size() const |
| 344 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 345 | return mSet.size(); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 346 | } |
| 347 | |
| 348 | bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig) |
| 349 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 350 | vector<const Config*> passed; |
| 351 | passed.reserve(mSet.size()); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 352 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 353 | for(Iterator config = mSet.begin(); config != mSet.end(); config++) |
| 354 | { |
| 355 | bool match = true; |
| 356 | const EGLint *attribute = attribList; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 357 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 358 | while(attribute[0] != EGL_NONE) |
| 359 | { |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 360 | if(attribute[1] != EGL_DONT_CARE) |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 361 | { |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 362 | switch(attribute[0]) |
| 363 | { |
Nicolas Capens | 5d96188 | 2016-01-01 23:18:14 -0500 | [diff] [blame] | 364 | 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 Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 399 | default: |
Nicolas Capens | 0c19ed8 | 2015-08-12 17:21:06 -0400 | [diff] [blame] | 400 | *numConfig = 0; |
| 401 | return false; |
Nicolas Capens | fc02cfc | 2015-06-04 08:59:09 -0400 | [diff] [blame] | 402 | } |
| 403 | |
| 404 | if(!match) |
| 405 | { |
| 406 | break; |
| 407 | } |
Nicolas Capens | 101e4f0 | 2015-06-03 14:54:38 -0400 | [diff] [blame] | 408 | } |
| 409 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 410 | attribute += 2; |
| 411 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 412 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 413 | if(match) |
| 414 | { |
| 415 | passed.push_back(&*config); |
| 416 | } |
| 417 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 418 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 419 | if(configs) |
| 420 | { |
| 421 | sort(passed.begin(), passed.end(), SortConfig(attribList)); |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 422 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 423 | EGLint index; |
| 424 | for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++) |
| 425 | { |
| 426 | configs[index] = passed[index]->getHandle(); |
| 427 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 428 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 429 | *numConfig = index; |
| 430 | } |
| 431 | else |
| 432 | { |
| 433 | *numConfig = static_cast<EGLint>(passed.size()); |
| 434 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 435 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 436 | return true; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 437 | } |
| 438 | |
| 439 | const egl::Config *ConfigSet::get(EGLConfig configHandle) |
| 440 | { |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 441 | for(Iterator config = mSet.begin(); config != mSet.end(); config++) |
| 442 | { |
| 443 | if(config->getHandle() == configHandle) |
| 444 | { |
| 445 | return &(*config); |
| 446 | } |
| 447 | } |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 448 | |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 449 | return nullptr; |
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 450 | } |
| 451 | } |