diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/Config.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/Config.cpp | 279 |
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; +} + +} |