1 // SwiftShader Software Renderer
3 // Copyright(c) 2005-2013 TransGaming Inc.
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.
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.
18 #include "common/debug.h"
20 #include <EGL/eglext.h>
22 #include <system/graphics.h>
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)
36 mBindToTextureRGB = EGL_FALSE;
37 mBindToTextureRGBA = EGL_FALSE;
39 // Initialize to a high value to lower the preference of formats for which there's no native support
40 mNativeVisualID = 0x7FFFFFFF;
42 switch(renderTargetFormat)
44 case sw::FORMAT_A1R5G5B5:
50 case sw::FORMAT_A2R10G10B10:
56 case sw::FORMAT_A8R8G8B8:
61 mBindToTextureRGBA = EGL_TRUE;
63 mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
65 mNativeVisualID = 2; // Arbitrary; prefer over ABGR
68 case sw::FORMAT_A8B8G8R8:
73 mBindToTextureRGBA = EGL_TRUE;
75 mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
78 case sw::FORMAT_R5G6B5:
84 mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
87 case sw::FORMAT_X8R8G8B8:
92 mBindToTextureRGB = EGL_TRUE;
94 mNativeVisualID = 0x1FF; // HAL_PIXEL_FORMAT_BGRX_8888
96 mNativeVisualID = 1; // Arbitrary; prefer over XBGR
99 case sw::FORMAT_X8B8G8R8:
104 mBindToTextureRGBA = EGL_TRUE;
106 mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
110 UNREACHABLE(renderTargetFormat);
114 mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
116 mColorBufferType = EGL_RGB_BUFFER;
117 mConfigCaveat = EGL_NONE;
119 mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
120 #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
125 switch(depthStencilFormat)
127 case sw::FORMAT_NULL:
131 // case sw::FORMAT_D16_LOCKABLE:
139 // case sw::FORMAT_D15S1:
143 case sw::FORMAT_D24S8:
147 case sw::FORMAT_D24X8:
151 // case sw::FORMAT_D24X4S4:
159 // case sw::FORMAT_D32F_LOCKABLE:
163 // case sw::FORMAT_D24FS8:
168 UNREACHABLE(depthStencilFormat);
172 mMatchNativePixmap = EGL_NONE;
173 mMaxPBufferWidth = 4096;
174 mMaxPBufferHeight = 4096;
175 mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
176 mMaxSwapInterval = maxInterval;
177 mMinSwapInterval = minInterval;
178 mNativeRenderable = EGL_FALSE;
179 mNativeVisualType = 0;
180 mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
181 #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
185 mSampleBuffers = (multiSample > 0) ? 1 : 0;
186 mSamples = multiSample;
187 mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
188 mTransparentType = EGL_NONE;
189 mTransparentRedValue = 0;
190 mTransparentGreenValue = 0;
191 mTransparentBlueValue = 0;
193 mRecordableAndroid = EGL_TRUE;
194 mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE;
197 EGLConfig Config::getHandle() const
199 return (EGLConfig)(size_t)mConfigID;
202 // This ordering determines the config ID
203 bool CompareConfig::operator()(const Config &x, const Config &y) const
205 #define SORT_SMALLER(attribute) \
206 if(x.attribute != y.attribute) \
208 return x.attribute < y.attribute; \
211 META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
212 SORT_SMALLER(mConfigCaveat);
214 META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
215 SORT_SMALLER(mColorBufferType);
217 SORT_SMALLER(mRedSize);
218 SORT_SMALLER(mGreenSize);
219 SORT_SMALLER(mBlueSize);
220 SORT_SMALLER(mAlphaSize);
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 SORT_SMALLER(mNativeVisualID);
233 // Strict ordering requires sorting all non-equal fields above
234 assert(memcmp(&x, &y, sizeof(Config)) == 0);
239 // Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
243 explicit SortConfig(const EGLint *attribList);
245 bool operator()(const Config *x, const Config *y) const;
248 EGLint wantedComponentsSize(const Config *config) const;
257 SortConfig::SortConfig(const EGLint *attribList)
258 : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
260 // [EGL] section 3.4.1 page 24
261 // Sorting rule #3: by larger total number of color bits,
262 // not considering components that are 0 or don't-care.
263 for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
265 if(attr[1] != 0 && attr[1] != EGL_DONT_CARE)
269 case EGL_RED_SIZE: mWantRed = true; break;
270 case EGL_GREEN_SIZE: mWantGreen = true; break;
271 case EGL_BLUE_SIZE: mWantBlue = true; break;
272 case EGL_ALPHA_SIZE: mWantAlpha = true; break;
273 case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
279 EGLint SortConfig::wantedComponentsSize(const Config *config) const
283 if(mWantRed) total += config->mRedSize;
284 if(mWantGreen) total += config->mGreenSize;
285 if(mWantBlue) total += config->mBlueSize;
286 if(mWantAlpha) total += config->mAlphaSize;
287 if(mWantLuminance) total += config->mLuminanceSize;
292 bool SortConfig::operator()(const Config *x, const Config *y) const
294 #define SORT_SMALLER(attribute) \
295 if(x->attribute != y->attribute) \
297 return x->attribute < y->attribute; \
300 META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
301 SORT_SMALLER(mConfigCaveat);
303 META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
304 SORT_SMALLER(mColorBufferType);
306 // By larger total number of color bits, only considering those that are requested to be > 0.
307 EGLint xComponentsSize = wantedComponentsSize(x);
308 EGLint yComponentsSize = wantedComponentsSize(y);
309 if(xComponentsSize != yComponentsSize)
311 return xComponentsSize > yComponentsSize;
314 SORT_SMALLER(mBufferSize);
315 SORT_SMALLER(mSampleBuffers);
316 SORT_SMALLER(mSamples);
317 SORT_SMALLER(mDepthSize);
318 SORT_SMALLER(mStencilSize);
319 SORT_SMALLER(mAlphaMaskSize);
320 SORT_SMALLER(mNativeVisualType);
321 SORT_SMALLER(mConfigID);
328 ConfigSet::ConfigSet()
332 void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
334 Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
339 size_t ConfigSet::size() const
344 bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
346 vector<const Config*> passed;
347 passed.reserve(mSet.size());
349 for(Iterator config = mSet.begin(); config != mSet.end(); config++)
352 const EGLint *attribute = attribList;
354 while(attribute[0] != EGL_NONE)
356 if(attribute[1] != EGL_DONT_CARE)
360 case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribute[1]; break;
361 case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribute[1]; break;
362 case EGL_BLUE_SIZE: match = config->mBlueSize >= attribute[1]; break;
363 case EGL_GREEN_SIZE: match = config->mGreenSize >= attribute[1]; break;
364 case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break;
365 case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break;
366 case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break;
367 case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == attribute[1]; break;
368 case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break;
369 case EGL_LEVEL: match = config->mLevel >= attribute[1]; break;
370 case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break;
371 case EGL_NATIVE_VISUAL_ID: match = config->mNativeVisualID == attribute[1]; break;
372 case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break;
373 case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break;
374 case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break;
375 case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break;
376 case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == attribute[1]; break;
377 case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break;
378 case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break;
379 case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break;
380 case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == attribute[1]; break;
381 case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == attribute[1]; break;
382 case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break;
383 case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break;
384 case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break;
385 case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break;
386 case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == attribute[1]; break;
387 case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
388 case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
389 case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break;
390 case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break;
391 case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break;
392 case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break;
393 case EGL_RECORDABLE_ANDROID: match = config->mRecordableAndroid == attribute[1]; break;
394 case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == attribute[1]; break;
411 passed.push_back(&*config);
417 sort(passed.begin(), passed.end(), SortConfig(attribList));
420 for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
422 configs[index] = passed[index]->getHandle();
429 *numConfig = static_cast<EGLint>(passed.size());
435 const egl::Config *ConfigSet::get(EGLConfig configHandle)
437 for(Iterator config = mSet.begin(); config != mSet.end(); config++)
439 if(config->getHandle() == configHandle)