-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
-// Copyright(c) 2005-2013 TransGaming Inc.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+// http://www.apache.org/licenses/LICENSE-2.0
//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
// Config.cpp: Implements the egl::Config class, describing the format, type
// and size for an egl::Surface. Implements EGLConfig and related functionality.
#include "common/debug.h"
#include <EGL/eglext.h>
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
+#include <system/graphics.h>
+#endif
#include <string.h>
#include <algorithm>
+#include <cstring>
#include <vector>
+#include <map>
using namespace std;
namespace egl
{
+
Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
- : mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
+ : mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
{
- mBindToTextureRGB = EGL_FALSE;
- mBindToTextureRGBA = EGL_FALSE;
-
- switch (renderTargetFormat)
- {
- case sw::FORMAT_A1R5G5B5:
- mRedSize = 5;
- mGreenSize = 5;
- mBlueSize = 5;
- mAlphaSize = 1;
- break;
- case sw::FORMAT_A2R10G10B10:
- mRedSize = 10;
- mGreenSize = 10;
- mBlueSize = 10;
- mAlphaSize = 2;
- break;
- case sw::FORMAT_A8R8G8B8:
- mRedSize = 8;
- mGreenSize = 8;
- mBlueSize = 8;
- mAlphaSize = 8;
- mBindToTextureRGBA = EGL_TRUE;
- break;
- case sw::FORMAT_R5G6B5:
- mRedSize = 5;
- mGreenSize = 6;
- mBlueSize = 5;
- mAlphaSize = 0;
- break;
- case sw::FORMAT_X8R8G8B8:
- mRedSize = 8;
- mGreenSize = 8;
- mBlueSize = 8;
- mAlphaSize = 0;
- mBindToTextureRGB = EGL_TRUE;
- break;
- default:
- UNREACHABLE(renderTargetFormat); // Other formats should not be valid
- }
-
- mLuminanceSize = 0;
- mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
- mAlphaMaskSize = 0;
- mColorBufferType = EGL_RGB_BUFFER;
- mConfigCaveat = isSlowConfig() ? EGL_SLOW_CONFIG : EGL_NONE;
- mConfigID = 0;
- mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
-#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
- | EGL_OPENGL_ES3_BIT
-#endif
- ;
+ mBindToTextureRGB = EGL_FALSE;
+ mBindToTextureRGBA = EGL_FALSE;
+
+ // Initialize to a high value to lower the preference of formats for which there's no native support
+ mNativeVisualID = 0x7FFFFFFF;
- switch (depthStencilFormat)
+ switch(renderTargetFormat)
+ {
+ case sw::FORMAT_A1R5G5B5:
+ mRedSize = 5;
+ mGreenSize = 5;
+ mBlueSize = 5;
+ mAlphaSize = 1;
+ break;
+ case sw::FORMAT_A2R10G10B10:
+ mRedSize = 10;
+ mGreenSize = 10;
+ mBlueSize = 10;
+ mAlphaSize = 2;
+ break;
+ case sw::FORMAT_A8R8G8B8:
+ mRedSize = 8;
+ mGreenSize = 8;
+ mBlueSize = 8;
+ mAlphaSize = 8;
+ mBindToTextureRGBA = EGL_TRUE;
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
+ mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
+ #else
+ mNativeVisualID = 2; // Arbitrary; prefer over ABGR
+ #endif
+ break;
+ case sw::FORMAT_A8B8G8R8:
+ mRedSize = 8;
+ mGreenSize = 8;
+ mBlueSize = 8;
+ mAlphaSize = 8;
+ mBindToTextureRGBA = EGL_TRUE;
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
+ mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
+ #endif
+ break;
+ case sw::FORMAT_R5G6B5:
+ mRedSize = 5;
+ mGreenSize = 6;
+ mBlueSize = 5;
+ mAlphaSize = 0;
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
+ mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
+ #endif
+ break;
+ case sw::FORMAT_X8R8G8B8:
+ mRedSize = 8;
+ mGreenSize = 8;
+ mBlueSize = 8;
+ mAlphaSize = 0;
+ mBindToTextureRGB = EGL_TRUE;
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
+ mNativeVisualID = 0x1FF; // HAL_PIXEL_FORMAT_BGRX_8888
+ #else
+ mNativeVisualID = 1; // Arbitrary; prefer over XBGR
+ #endif
+ break;
+ case sw::FORMAT_X8B8G8R8:
+ mRedSize = 8;
+ mGreenSize = 8;
+ mBlueSize = 8;
+ mAlphaSize = 0;
+ mBindToTextureRGB = EGL_TRUE;
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
+ mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
+ #endif
+ break;
+ default:
+ UNREACHABLE(renderTargetFormat);
+ }
+
+ mLuminanceSize = 0;
+ mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
+ mAlphaMaskSize = 0;
+ mColorBufferType = EGL_RGB_BUFFER;
+ mConfigCaveat = EGL_NONE;
+ mConfigID = 0;
+ mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
+
+ switch(depthStencilFormat)
{
case sw::FORMAT_NULL:
mDepthSize = 0;
mStencilSize = 0;
break;
-// case sw::FORMAT_D16_LOCKABLE:
-// mDepthSize = 16;
-// mStencilSize = 0;
-// break;
+// case sw::FORMAT_D16_LOCKABLE:
+// mDepthSize = 16;
+// mStencilSize = 0;
+// break;
case sw::FORMAT_D32:
mDepthSize = 32;
mStencilSize = 0;
mDepthSize = 16;
mStencilSize = 0;
break;
-// case sw::FORMAT_D32F_LOCKABLE:
-// mDepthSize = 32;
-// mStencilSize = 0;
-// break;
-// case sw::FORMAT_D24FS8:
-// mDepthSize = 24;
-// mStencilSize = 8;
-// break;
+// case sw::FORMAT_D32F_LOCKABLE:
+// mDepthSize = 32;
+// mStencilSize = 0;
+// break;
+// case sw::FORMAT_D24FS8:
+// mDepthSize = 24;
+// mStencilSize = 8;
+// break;
default:
UNREACHABLE(depthStencilFormat);
}
- mLevel = 0;
- mMatchNativePixmap = EGL_NONE;
- mMaxPBufferWidth = 4096;
- mMaxPBufferHeight = 4096;
- mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
- mMaxSwapInterval = maxInterval;
- mMinSwapInterval = minInterval;
- mNativeRenderable = EGL_FALSE;
- mNativeVisualID = 0;
- mNativeVisualType = 0;
- mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
-#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
- | EGL_OPENGL_ES3_BIT
-#endif
- ;
- mSampleBuffers = (multiSample > 0) ? 1 : 0;
- mSamples = multiSample;
- mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
- mTransparentType = EGL_NONE;
- mTransparentRedValue = 0;
- mTransparentGreenValue = 0;
- mTransparentBlueValue = 0;
-
- mRecordableAndroid = EGL_TRUE;
+ mLevel = 0;
+ mMatchNativePixmap = EGL_NONE;
+ mMaxPBufferWidth = 4096;
+ mMaxPBufferHeight = 4096;
+ mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
+ mMaxSwapInterval = maxInterval;
+ mMinSwapInterval = minInterval;
+ mNativeRenderable = EGL_FALSE;
+ mNativeVisualType = 0;
+ mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
+ mSampleBuffers = (multiSample > 0) ? 1 : 0;
+ mSamples = multiSample;
+ mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT;
+ mTransparentType = EGL_NONE;
+ mTransparentRedValue = 0;
+ mTransparentGreenValue = 0;
+ mTransparentBlueValue = 0;
+
+ // Although we could support any format as an Android HWComposer compatible config by converting when necessary,
+ // the intent of EGL_ANDROID_framebuffer_target is to prevent any copies or conversions.
mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE;
+ mRecordableAndroid = EGL_TRUE;
}
EGLConfig Config::getHandle() const
{
- return (EGLConfig)(size_t)mConfigID;
-}
-
-bool Config::isSlowConfig() const
-{
- return mRenderTargetFormat != sw::FORMAT_X8R8G8B8 && mRenderTargetFormat != sw::FORMAT_A8R8G8B8;
+ return (EGLConfig)(size_t)mConfigID;
}
// This ordering determines the config ID
bool CompareConfig::operator()(const Config &x, const Config &y) const
{
- #define SORT_SMALLER(attribute) \
- if(x.attribute != y.attribute) \
- { \
- return x.attribute < y.attribute; \
- }
+ #define SORT_SMALLER(attribute) \
+ if(x.attribute != y.attribute) \
+ { \
+ return x.attribute < y.attribute; \
+ }
- META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
- SORT_SMALLER(mConfigCaveat);
+ static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
+ SORT_SMALLER(mConfigCaveat);
- META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
- SORT_SMALLER(mColorBufferType);
+ static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
+ SORT_SMALLER(mColorBufferType);
SORT_SMALLER(mRedSize);
SORT_SMALLER(mGreenSize);
SORT_SMALLER(mBlueSize);
SORT_SMALLER(mAlphaSize);
-
+
SORT_SMALLER(mBufferSize);
- SORT_SMALLER(mSampleBuffers);
- SORT_SMALLER(mSamples);
- SORT_SMALLER(mDepthSize);
- SORT_SMALLER(mStencilSize);
- SORT_SMALLER(mAlphaMaskSize);
- SORT_SMALLER(mNativeVisualType);
+ SORT_SMALLER(mSampleBuffers);
+ SORT_SMALLER(mSamples);
+ SORT_SMALLER(mDepthSize);
+ SORT_SMALLER(mStencilSize);
+ SORT_SMALLER(mAlphaMaskSize);
+ SORT_SMALLER(mNativeVisualType);
+ SORT_SMALLER(mNativeVisualID);
- #undef SORT_SMALLER
+ #undef SORT_SMALLER
// Strict ordering requires sorting all non-equal fields above
assert(memcmp(&x, &y, sizeof(Config)) == 0);
- return false;
+ return false;
}
// Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
class SortConfig
{
public:
- explicit SortConfig(const EGLint *attribList);
+ explicit SortConfig(const EGLint *attribList);
- bool operator()(const Config *x, const Config *y) const;
+ bool operator()(const Config *x, const Config *y) const;
private:
- EGLint wantedComponentsSize(const Config *config) const;
+ EGLint wantedComponentsSize(const Config *config) const;
- bool mWantRed;
- bool mWantGreen;
- bool mWantBlue;
- bool mWantAlpha;
- bool mWantLuminance;
+ bool mWantRed;
+ bool mWantGreen;
+ bool mWantBlue;
+ bool mWantAlpha;
+ bool mWantLuminance;
};
SortConfig::SortConfig(const EGLint *attribList)
- : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
+ : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
{
// [EGL] section 3.4.1 page 24
- // Sorting rule #3: by larger total number of color bits,
+ // Sorting rule #3: by larger total number of color bits,
// not considering components that are 0 or don't-care.
- for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
- {
- if(attr[1] != 0 && attr[1] != EGL_DONT_CARE)
- {
- switch (attr[0])
- {
- case EGL_RED_SIZE: mWantRed = true; break;
- case EGL_GREEN_SIZE: mWantGreen = true; break;
- case EGL_BLUE_SIZE: mWantBlue = true; break;
- case EGL_ALPHA_SIZE: mWantAlpha = true; break;
- case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
- }
- }
- }
+ for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
+ {
+ // When multiple instances of the same attribute are present, last wins.
+ bool isSpecified = attr[1] && attr[1] != EGL_DONT_CARE;
+ switch(attr[0])
+ {
+ case EGL_RED_SIZE: mWantRed = isSpecified; break;
+ case EGL_GREEN_SIZE: mWantGreen = isSpecified; break;
+ case EGL_BLUE_SIZE: mWantBlue = isSpecified; break;
+ case EGL_ALPHA_SIZE: mWantAlpha = isSpecified; break;
+ case EGL_LUMINANCE_SIZE: mWantLuminance = isSpecified; break;
+ }
+ }
}
EGLint SortConfig::wantedComponentsSize(const Config *config) const
{
- EGLint total = 0;
+ EGLint total = 0;
- if(mWantRed) total += config->mRedSize;
- if(mWantGreen) total += config->mGreenSize;
- if(mWantBlue) total += config->mBlueSize;
- if(mWantAlpha) total += config->mAlphaSize;
- if(mWantLuminance) total += config->mLuminanceSize;
+ if(mWantRed) total += config->mRedSize;
+ if(mWantGreen) total += config->mGreenSize;
+ if(mWantBlue) total += config->mBlueSize;
+ if(mWantAlpha) total += config->mAlphaSize;
+ if(mWantLuminance) total += config->mLuminanceSize;
- return total;
+ return total;
}
bool SortConfig::operator()(const Config *x, const Config *y) const
{
- #define SORT_SMALLER(attribute) \
- if(x->attribute != y->attribute) \
- { \
- return x->attribute < y->attribute; \
- }
+ #define SORT_SMALLER(attribute) \
+ if(x->attribute != y->attribute) \
+ { \
+ return x->attribute < y->attribute; \
+ }
- META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
- SORT_SMALLER(mConfigCaveat);
+ static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
+ SORT_SMALLER(mConfigCaveat);
- META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
- SORT_SMALLER(mColorBufferType);
+ static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
+ SORT_SMALLER(mColorBufferType);
// By larger total number of color bits, only considering those that are requested to be > 0.
EGLint xComponentsSize = wantedComponentsSize(x);
return xComponentsSize > yComponentsSize;
}
- SORT_SMALLER(mBufferSize);
- SORT_SMALLER(mSampleBuffers);
- SORT_SMALLER(mSamples);
- SORT_SMALLER(mDepthSize);
- SORT_SMALLER(mStencilSize);
- SORT_SMALLER(mAlphaMaskSize);
- SORT_SMALLER(mNativeVisualType);
- SORT_SMALLER(mConfigID);
+ SORT_SMALLER(mBufferSize);
+ SORT_SMALLER(mSampleBuffers);
+ SORT_SMALLER(mSamples);
+ SORT_SMALLER(mDepthSize);
+ SORT_SMALLER(mStencilSize);
+ SORT_SMALLER(mAlphaMaskSize);
+ SORT_SMALLER(mNativeVisualType);
+ SORT_SMALLER(mConfigID);
- #undef SORT_SMALLER
+ #undef SORT_SMALLER
- return false;
+ return false;
}
ConfigSet::ConfigSet()
void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
{
- Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
-
- mSet.insert(config);
+ Config conformantConfig(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
+ mSet.insert(conformantConfig);
}
size_t ConfigSet::size() const
{
- return mSet.size();
+ return mSet.size();
}
bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
{
- vector<const Config*> passed;
- passed.reserve(mSet.size());
-
- for(Iterator config = mSet.begin(); config != mSet.end(); config++)
- {
- bool match = true;
- const EGLint *attribute = attribList;
+ vector<const Config*> passed;
+ passed.reserve(mSet.size());
+
+ /* Conformance expects for multiple instances of the same attribute that the
+ * last instance `wins`. Reduce the attribute list first to comply with
+ * this.
+ */
+ /* TODO: C++11: unordered_map would be fine here */
+ map<EGLint, EGLint> attribs;
+ const EGLint *attribute = attribList;
+ while (attribute[0] != EGL_NONE)
+ {
+ attribs[attribute[0]] = attribute[1];
+ attribute += 2;
+ }
- while(attribute[0] != EGL_NONE)
- {
- if(attribute[1] != EGL_DONT_CARE)
+ for(Iterator config = mSet.begin(); config != mSet.end(); config++)
+ {
+ bool match = true;
+ bool caveatMatch = (config->mConfigCaveat == EGL_NONE);
+ for (map<EGLint, EGLint>::iterator attribIt = attribs.begin(); attribIt != attribs.end(); attribIt++)
+ {
+ if(attribIt->second != EGL_DONT_CARE)
{
- switch(attribute[0])
+ switch(attribIt->first)
{
- case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribute[1]; break;
- case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribute[1]; break;
- case EGL_BLUE_SIZE: match = config->mBlueSize >= attribute[1]; break;
- case EGL_GREEN_SIZE: match = config->mGreenSize >= attribute[1]; break;
- case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break;
- case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break;
- case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break;
- case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == attribute[1]; break;
- case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break;
- case EGL_LEVEL: match = config->mLevel >= attribute[1]; break;
- case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break;
- case EGL_NATIVE_VISUAL_ID: match = config->mNativeVisualID == attribute[1]; break;
- case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break;
- case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break;
- case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break;
- case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break;
- case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == attribute[1]; break;
- case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break;
- case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break;
- case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break;
- case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == attribute[1]; break;
- case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == attribute[1]; break;
- case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break;
- case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break;
- case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break;
- case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break;
- case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == attribute[1]; break;
- case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
- case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
- case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break;
- case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break;
- case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break;
- case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break;
- case EGL_RECORDABLE_ANDROID: match = config->mRecordableAndroid == attribute[1]; break;
- case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == attribute[1]; break;
+ case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribIt->second; break;
+ case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribIt->second; break;
+ case EGL_BLUE_SIZE: match = config->mBlueSize >= attribIt->second; break;
+ case EGL_GREEN_SIZE: match = config->mGreenSize >= attribIt->second; break;
+ case EGL_RED_SIZE: match = config->mRedSize >= attribIt->second; break;
+ case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribIt->second; break;
+ case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribIt->second; break;
+ case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum)attribIt->second; break;
+ case EGL_CONFIG_ID: match = config->mConfigID == attribIt->second; break;
+ case EGL_LEVEL: match = config->mLevel >= attribIt->second; break;
+ case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean)attribIt->second; break;
+ case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribIt->second; break;
+ case EGL_SAMPLES: match = config->mSamples >= attribIt->second; break;
+ case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribIt->second; break;
+ case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribIt->second) == attribIt->second; break;
+ case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum)attribIt->second; break;
+ case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribIt->second; break;
+ case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribIt->second; break;
+ case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribIt->second; break;
+ case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean)attribIt->second; break;
+ case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean)attribIt->second; break;
+ case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribIt->second; break;
+ case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribIt->second; break;
+ case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribIt->second; break;
+ case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribIt->second; break;
+ case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum)attribIt->second; break;
+ case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribIt->second) == attribIt->second; break;
+ case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
+ case EGL_CONFORMANT: match = (config->mConformant & attribIt->second) == attribIt->second; break;
+ case EGL_RECORDABLE_ANDROID: match = config->mRecordableAndroid == (EGLBoolean)attribIt->second; break;
+ case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == (EGLBoolean)attribIt->second; break;
+
+ // Ignored attributes
+ case EGL_MAX_PBUFFER_WIDTH:
+ case EGL_MAX_PBUFFER_HEIGHT:
+ case EGL_MAX_PBUFFER_PIXELS:
+ case EGL_NATIVE_VISUAL_ID:
+ break;
+
default:
*numConfig = 0;
return false;
}
}
- attribute += 2;
- }
-
- if(match)
- {
- passed.push_back(&*config);
- }
- }
-
- if(configs)
- {
- sort(passed.begin(), passed.end(), SortConfig(attribList));
-
- EGLint index;
- for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
- {
- configs[index] = passed[index]->getHandle();
- }
-
- *numConfig = index;
- }
- else
- {
- *numConfig = static_cast<EGLint>(passed.size());
- }
-
- return true;
+ if(attribIt->first == EGL_CONFIG_CAVEAT)
+ {
+ caveatMatch = match;
+ }
+ }
+
+ if(match && caveatMatch) // We require the caveats to be NONE or the requested flags
+ {
+ passed.push_back(&*config);
+ }
+ }
+
+ if(configs)
+ {
+ sort(passed.begin(), passed.end(), SortConfig(attribList));
+
+ EGLint index;
+ for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
+ {
+ configs[index] = passed[index]->getHandle();
+ }
+
+ *numConfig = index;
+ }
+ else
+ {
+ *numConfig = static_cast<EGLint>(passed.size());
+ }
+
+ return true;
}
const egl::Config *ConfigSet::get(EGLConfig configHandle)
{
- for(Iterator config = mSet.begin(); config != mSet.end(); config++)
- {
- if(config->getHandle() == configHandle)
- {
- return &(*config);
- }
- }
-
- return NULL;
+ for(Iterator config = mSet.begin(); config != mSet.end(); config++)
+ {
+ if(config->getHandle() == configHandle)
+ {
+ return &(*config);
+ }
+ }
+
+ return nullptr;
}
}