summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/Config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/Config.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/Config.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/Config.cpp b/gfx/angle/src/libANGLE/Config.cpp
new file mode 100755
index 000000000..822518ef6
--- /dev/null
+++ b/gfx/angle/src/libANGLE/Config.cpp
@@ -0,0 +1,279 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Config.cpp: Implements the egl::Config class, describing the format, type
+// and size for an egl::Surface. Implements EGLConfig and related functionality.
+// [EGL 1.5] section 3.4 page 19.
+
+#include "libANGLE/Config.h"
+#include "libANGLE/AttributeMap.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "angle_gl.h"
+#include <EGL/eglext.h>
+
+#include "common/debug.h"
+
+namespace egl
+{
+
+Config::Config()
+ : renderTargetFormat(GL_NONE),
+ depthStencilFormat(GL_NONE),
+ bufferSize(0),
+ redSize(0),
+ greenSize(0),
+ blueSize(0),
+ luminanceSize(0),
+ alphaSize(0),
+ alphaMaskSize(0),
+ bindToTextureRGB(EGL_FALSE),
+ bindToTextureRGBA(EGL_FALSE),
+ colorBufferType(EGL_NONE),
+ configCaveat(EGL_NONE),
+ configID(0),
+ conformant(0),
+ depthSize(0),
+ level(0),
+ matchNativePixmap(EGL_FALSE),
+ maxPBufferWidth(0),
+ maxPBufferHeight(0),
+ maxPBufferPixels(0),
+ maxSwapInterval(0),
+ minSwapInterval(0),
+ nativeRenderable(EGL_FALSE),
+ nativeVisualID(0),
+ nativeVisualType(0),
+ renderableType(0),
+ sampleBuffers(0),
+ samples(0),
+ stencilSize(0),
+ surfaceType(0),
+ transparentType(EGL_NONE),
+ transparentRedValue(0),
+ transparentGreenValue(0),
+ transparentBlueValue(0),
+ optimalOrientation(0)
+{
+}
+
+EGLint ConfigSet::add(const Config &config)
+{
+ // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
+ EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;
+
+ Config copyConfig(config);
+ copyConfig.configID = id;
+ mConfigs.insert(std::make_pair(id, copyConfig));
+
+ return id;
+}
+
+const Config &ConfigSet::get(EGLint id) const
+{
+ ASSERT(mConfigs.find(id) != mConfigs.end());
+ return mConfigs.find(id)->second;
+}
+
+void ConfigSet::clear()
+{
+ mConfigs.clear();
+}
+
+size_t ConfigSet::size() const
+{
+ return mConfigs.size();
+}
+
+bool ConfigSet::contains(const Config *config) const
+{
+ for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
+ {
+ const Config &item = i->second;
+ if (config == &item)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5] section 3.4.1.2 page 28.
+class ConfigSorter
+{
+ public:
+ explicit ConfigSorter(const AttributeMap &attributeMap)
+ : mWantRed(false),
+ mWantGreen(false),
+ mWantBlue(false),
+ mWantAlpha(false),
+ mWantLuminance(false)
+ {
+ scanForWantedComponents(attributeMap);
+ }
+
+ bool operator()(const Config *x, const Config *y) const
+ {
+ return (*this)(*x, *y);
+ }
+
+ bool operator()(const Config &x, const Config &y) const
+ {
+ #define SORT(attribute) \
+ if (x.attribute != y.attribute) \
+ { \
+ return x.attribute < y.attribute; \
+ }
+
+ static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "Unexpected EGL enum value.");
+ SORT(configCaveat);
+
+ static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
+ SORT(colorBufferType);
+
+ // By larger total number of color bits, only considering those that are requested to be > 0.
+ EGLint xComponentsSize = wantedComponentsSize(x);
+ EGLint yComponentsSize = wantedComponentsSize(y);
+ if (xComponentsSize != yComponentsSize)
+ {
+ return xComponentsSize > yComponentsSize;
+ }
+
+ SORT(bufferSize);
+ SORT(sampleBuffers);
+ SORT(samples);
+ SORT(depthSize);
+ SORT(stencilSize);
+ SORT(alphaMaskSize);
+ SORT(nativeVisualType);
+ SORT(configID);
+
+ #undef SORT
+
+ return false;
+ }
+
+ private:
+ void scanForWantedComponents(const AttributeMap &attributeMap)
+ {
+ // [EGL 1.5] section 3.4.1.2 page 30
+ // Sorting rule #3: by larger total number of color bits, not considering
+ // components that are 0 or don't-care.
+ for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
+ {
+ EGLAttrib attributeKey = attribIter->first;
+ EGLAttrib attributeValue = attribIter->second;
+ if (attributeKey != 0 && attributeValue != EGL_DONT_CARE)
+ {
+ switch (attributeKey)
+ {
+ 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;
+ }
+ }
+ }
+ }
+
+ EGLint wantedComponentsSize(const Config &config) const
+ {
+ EGLint total = 0;
+
+ if (mWantRed) total += config.redSize;
+ if (mWantGreen) total += config.greenSize;
+ if (mWantBlue) total += config.blueSize;
+ if (mWantAlpha) total += config.alphaSize;
+ if (mWantLuminance) total += config.luminanceSize;
+
+ return total;
+ }
+
+ bool mWantRed;
+ bool mWantGreen;
+ bool mWantBlue;
+ bool mWantAlpha;
+ bool mWantLuminance;
+};
+
+std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) const
+{
+ std::vector<const Config*> result;
+ result.reserve(mConfigs.size());
+
+ for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
+ {
+ const Config &config = configIter->second;
+ bool match = true;
+
+ for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
+ {
+ EGLAttrib attributeKey = attribIter->first;
+ EGLAttrib attributeValue = attribIter->second;
+
+ switch (attributeKey)
+ {
+ case EGL_BUFFER_SIZE: match = config.bufferSize >= attributeValue; break;
+ case EGL_ALPHA_SIZE: match = config.alphaSize >= attributeValue; break;
+ case EGL_BLUE_SIZE: match = config.blueSize >= attributeValue; break;
+ case EGL_GREEN_SIZE: match = config.greenSize >= attributeValue; break;
+ case EGL_RED_SIZE: match = config.redSize >= attributeValue; break;
+ case EGL_DEPTH_SIZE: match = config.depthSize >= attributeValue; break;
+ case EGL_STENCIL_SIZE: match = config.stencilSize >= attributeValue; break;
+ case EGL_CONFIG_CAVEAT: match = config.configCaveat == (EGLenum)attributeValue; break;
+ case EGL_CONFIG_ID: match = config.configID == attributeValue; break;
+ case EGL_LEVEL: match = config.level >= attributeValue; break;
+ case EGL_NATIVE_RENDERABLE: match = config.nativeRenderable == (EGLBoolean)attributeValue; break;
+ case EGL_NATIVE_VISUAL_TYPE: match = config.nativeVisualType == attributeValue; break;
+ case EGL_SAMPLES: match = config.samples >= attributeValue; break;
+ case EGL_SAMPLE_BUFFERS: match = config.sampleBuffers >= attributeValue; break;
+ case EGL_SURFACE_TYPE: match = (config.surfaceType & attributeValue) == attributeValue; break;
+ case EGL_TRANSPARENT_TYPE: match = config.transparentType == (EGLenum)attributeValue; break;
+ case EGL_TRANSPARENT_BLUE_VALUE: match = config.transparentBlueValue == attributeValue; break;
+ case EGL_TRANSPARENT_GREEN_VALUE: match = config.transparentGreenValue == attributeValue; break;
+ case EGL_TRANSPARENT_RED_VALUE: match = config.transparentRedValue == attributeValue; break;
+ case EGL_BIND_TO_TEXTURE_RGB: match = config.bindToTextureRGB == (EGLBoolean)attributeValue; break;
+ case EGL_BIND_TO_TEXTURE_RGBA: match = config.bindToTextureRGBA == (EGLBoolean)attributeValue; break;
+ case EGL_MIN_SWAP_INTERVAL: match = config.minSwapInterval == attributeValue; break;
+ case EGL_MAX_SWAP_INTERVAL: match = config.maxSwapInterval == attributeValue; break;
+ case EGL_LUMINANCE_SIZE: match = config.luminanceSize >= attributeValue; break;
+ case EGL_ALPHA_MASK_SIZE: match = config.alphaMaskSize >= attributeValue; break;
+ case EGL_COLOR_BUFFER_TYPE: match = config.colorBufferType == (EGLenum)attributeValue; break;
+ case EGL_RENDERABLE_TYPE: match = (config.renderableType & attributeValue) == attributeValue; break;
+ case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
+ case EGL_CONFORMANT: match = (config.conformant & attributeValue) == attributeValue; break;
+ case EGL_MAX_PBUFFER_WIDTH: match = config.maxPBufferWidth >= attributeValue; break;
+ case EGL_MAX_PBUFFER_HEIGHT: match = config.maxPBufferHeight >= attributeValue; break;
+ case EGL_MAX_PBUFFER_PIXELS: match = config.maxPBufferPixels >= attributeValue; break;
+ case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
+ match = config.optimalOrientation == attributeValue;
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (!match)
+ {
+ break;
+ }
+ }
+
+ if (match)
+ {
+ result.push_back(&config);
+ }
+ }
+
+ // Sort the result
+ std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));
+
+ return result;
+}
+
+}