gfx/angle/src/libEGL/Config.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/angle/src/libEGL/Config.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,340 @@
     1.4 +//
     1.5 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
     1.6 +// Use of this source code is governed by a BSD-style license that can be
     1.7 +// found in the LICENSE file.
     1.8 +//
     1.9 +
    1.10 +// Config.cpp: Implements the egl::Config class, describing the format, type
    1.11 +// and size for an egl::Surface. Implements EGLConfig and related functionality.
    1.12 +// [EGL 1.4] section 3.4 page 15.
    1.13 +
    1.14 +#include "libEGL/Config.h"
    1.15 +
    1.16 +#include <algorithm>
    1.17 +#include <vector>
    1.18 +
    1.19 +#include <GLES2/gl2.h>
    1.20 +#include <GLES2/gl2ext.h>
    1.21 +
    1.22 +#include "common/debug.h"
    1.23 +
    1.24 +using namespace std;
    1.25 +
    1.26 +namespace egl
    1.27 +{
    1.28 +Config::Config(rx::ConfigDesc desc, EGLint minInterval, EGLint maxInterval, EGLint texWidth, EGLint texHeight)
    1.29 +    : mRenderTargetFormat(desc.renderTargetFormat), mDepthStencilFormat(desc.depthStencilFormat), mMultiSample(desc.multiSample)
    1.30 +{
    1.31 +    mBindToTextureRGB = EGL_FALSE;
    1.32 +    mBindToTextureRGBA = EGL_FALSE;
    1.33 +    switch (desc.renderTargetFormat)
    1.34 +    {
    1.35 +      case GL_RGB5_A1:
    1.36 +        mBufferSize = 16;
    1.37 +        mRedSize = 5;
    1.38 +        mGreenSize = 5;
    1.39 +        mBlueSize = 5;
    1.40 +        mAlphaSize = 1;
    1.41 +        break;
    1.42 +      case GL_RGBA8_OES:
    1.43 +        mBufferSize = 32;
    1.44 +        mRedSize = 8;
    1.45 +        mGreenSize = 8;
    1.46 +        mBlueSize = 8;
    1.47 +        mAlphaSize = 8;
    1.48 +        mBindToTextureRGBA = true;
    1.49 +        break;
    1.50 +      case GL_RGB565:
    1.51 +        mBufferSize = 16;
    1.52 +        mRedSize = 5;
    1.53 +        mGreenSize = 6;
    1.54 +        mBlueSize = 5;
    1.55 +        mAlphaSize = 0;
    1.56 +        break;
    1.57 +      case GL_RGB8_OES:
    1.58 +        mBufferSize = 32;
    1.59 +        mRedSize = 8;
    1.60 +        mGreenSize = 8;
    1.61 +        mBlueSize = 8;
    1.62 +        mAlphaSize = 0;
    1.63 +        mBindToTextureRGB = true;
    1.64 +        break;
    1.65 +      case GL_BGRA8_EXT:
    1.66 +        mBufferSize = 32;
    1.67 +        mRedSize = 8;
    1.68 +        mGreenSize = 8;
    1.69 +        mBlueSize = 8;
    1.70 +        mAlphaSize = 8;
    1.71 +        mBindToTextureRGBA = true;
    1.72 +        break;
    1.73 +      default:
    1.74 +        UNREACHABLE();   // Other formats should not be valid
    1.75 +    }
    1.76 +
    1.77 +    mLuminanceSize = 0;
    1.78 +    mAlphaMaskSize = 0;
    1.79 +    mColorBufferType = EGL_RGB_BUFFER;
    1.80 +    mConfigCaveat = (desc.fastConfig) ? EGL_NONE : EGL_SLOW_CONFIG;
    1.81 +    mConfigID = 0;
    1.82 +    mConformant = EGL_OPENGL_ES2_BIT;
    1.83 +
    1.84 +    switch (desc.depthStencilFormat)
    1.85 +    {
    1.86 +      case GL_NONE:
    1.87 +        mDepthSize = 0;
    1.88 +        mStencilSize = 0;
    1.89 +        break;
    1.90 +      case GL_DEPTH_COMPONENT32_OES:
    1.91 +        mDepthSize = 32;
    1.92 +        mStencilSize = 0;
    1.93 +        break;
    1.94 +      case GL_DEPTH24_STENCIL8_OES:
    1.95 +        mDepthSize = 24;
    1.96 +        mStencilSize = 8;
    1.97 +        break;
    1.98 +      case GL_DEPTH_COMPONENT24_OES:
    1.99 +        mDepthSize = 24;
   1.100 +        mStencilSize = 0;
   1.101 +        break;
   1.102 +      case GL_DEPTH_COMPONENT16:
   1.103 +        mDepthSize = 16;
   1.104 +        mStencilSize = 0;
   1.105 +        break;
   1.106 +      default:
   1.107 +        UNREACHABLE();
   1.108 +    }
   1.109 +
   1.110 +    mLevel = 0;
   1.111 +    mMatchNativePixmap = EGL_NONE;
   1.112 +    mMaxPBufferWidth = texWidth;
   1.113 +    mMaxPBufferHeight = texHeight;
   1.114 +    mMaxPBufferPixels = texWidth*texHeight;
   1.115 +    mMaxSwapInterval = maxInterval;
   1.116 +    mMinSwapInterval = minInterval;
   1.117 +    mNativeRenderable = EGL_FALSE;
   1.118 +    mNativeVisualID = 0;
   1.119 +    mNativeVisualType = 0;
   1.120 +    mRenderableType = EGL_OPENGL_ES2_BIT;
   1.121 +    mSampleBuffers = desc.multiSample ? 1 : 0;
   1.122 +    mSamples = desc.multiSample;
   1.123 +    mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
   1.124 +    mTransparentType = EGL_NONE;
   1.125 +    mTransparentRedValue = 0;
   1.126 +    mTransparentGreenValue = 0;
   1.127 +    mTransparentBlueValue = 0;
   1.128 +}
   1.129 +
   1.130 +EGLConfig Config::getHandle() const
   1.131 +{
   1.132 +    return (EGLConfig)(size_t)mConfigID;
   1.133 +}
   1.134 +
   1.135 +SortConfig::SortConfig(const EGLint *attribList)
   1.136 +    : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
   1.137 +{
   1.138 +    scanForWantedComponents(attribList);
   1.139 +}
   1.140 +
   1.141 +void SortConfig::scanForWantedComponents(const EGLint *attribList)
   1.142 +{
   1.143 +    // [EGL] section 3.4.1 page 24
   1.144 +    // Sorting rule #3: by larger total number of color bits, not considering
   1.145 +    // components that are 0 or don't-care.
   1.146 +    for (const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
   1.147 +    {
   1.148 +        if (attr[1] != 0 && attr[1] != EGL_DONT_CARE)
   1.149 +        {
   1.150 +            switch (attr[0])
   1.151 +            {
   1.152 +              case EGL_RED_SIZE:       mWantRed = true; break;
   1.153 +              case EGL_GREEN_SIZE:     mWantGreen = true; break;
   1.154 +              case EGL_BLUE_SIZE:      mWantBlue = true; break;
   1.155 +              case EGL_ALPHA_SIZE:     mWantAlpha = true; break;
   1.156 +              case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
   1.157 +            }
   1.158 +        }
   1.159 +    }
   1.160 +}
   1.161 +
   1.162 +EGLint SortConfig::wantedComponentsSize(const Config &config) const
   1.163 +{
   1.164 +    EGLint total = 0;
   1.165 +
   1.166 +    if (mWantRed)       total += config.mRedSize;
   1.167 +    if (mWantGreen)     total += config.mGreenSize;
   1.168 +    if (mWantBlue)      total += config.mBlueSize;
   1.169 +    if (mWantAlpha)     total += config.mAlphaSize;
   1.170 +    if (mWantLuminance) total += config.mLuminanceSize;
   1.171 +
   1.172 +    return total;
   1.173 +}
   1.174 +
   1.175 +bool SortConfig::operator()(const Config *x, const Config *y) const
   1.176 +{
   1.177 +    return (*this)(*x, *y);
   1.178 +}
   1.179 +
   1.180 +bool SortConfig::operator()(const Config &x, const Config &y) const
   1.181 +{
   1.182 +    #define SORT(attribute)                        \
   1.183 +        if (x.attribute != y.attribute)            \
   1.184 +        {                                          \
   1.185 +            return x.attribute < y.attribute;      \
   1.186 +        }
   1.187 +
   1.188 +    META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
   1.189 +    SORT(mConfigCaveat);
   1.190 +
   1.191 +    META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
   1.192 +    SORT(mColorBufferType);
   1.193 +
   1.194 +    // By larger total number of color bits, only considering those that are requested to be > 0.
   1.195 +    EGLint xComponentsSize = wantedComponentsSize(x);
   1.196 +    EGLint yComponentsSize = wantedComponentsSize(y);
   1.197 +    if (xComponentsSize != yComponentsSize)
   1.198 +    {
   1.199 +        return xComponentsSize > yComponentsSize;
   1.200 +    }
   1.201 +
   1.202 +    SORT(mBufferSize);
   1.203 +    SORT(mSampleBuffers);
   1.204 +    SORT(mSamples);
   1.205 +    SORT(mDepthSize);
   1.206 +    SORT(mStencilSize);
   1.207 +    SORT(mAlphaMaskSize);
   1.208 +    SORT(mNativeVisualType);
   1.209 +    SORT(mConfigID);
   1.210 +
   1.211 +    #undef SORT
   1.212 +
   1.213 +    return false;
   1.214 +}
   1.215 +
   1.216 +// We'd like to use SortConfig to also eliminate duplicate configs.
   1.217 +// This works as long as we never have two configs with different per-RGB-component layouts,
   1.218 +// but the same total.
   1.219 +// 5551 and 565 are different because R+G+B is different.
   1.220 +// 5551 and 555 are different because bufferSize is different.
   1.221 +const EGLint ConfigSet::mSortAttribs[] =
   1.222 +{
   1.223 +    EGL_RED_SIZE, 1,
   1.224 +    EGL_GREEN_SIZE, 1,
   1.225 +    EGL_BLUE_SIZE, 1,
   1.226 +    EGL_LUMINANCE_SIZE, 1,
   1.227 +    // BUT NOT ALPHA
   1.228 +    EGL_NONE
   1.229 +};
   1.230 +
   1.231 +ConfigSet::ConfigSet()
   1.232 +    : mSet(SortConfig(mSortAttribs))
   1.233 +{
   1.234 +}
   1.235 +
   1.236 +void ConfigSet::add(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight)
   1.237 +{
   1.238 +    Config config(desc, minSwapInterval, maxSwapInterval, texWidth, texHeight);
   1.239 +    mSet.insert(config);
   1.240 +}
   1.241 +
   1.242 +size_t ConfigSet::size() const
   1.243 +{
   1.244 +    return mSet.size();
   1.245 +}
   1.246 +
   1.247 +bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
   1.248 +{
   1.249 +    vector<const Config*> passed;
   1.250 +    passed.reserve(mSet.size());
   1.251 +
   1.252 +    for (Iterator config = mSet.begin(); config != mSet.end(); config++)
   1.253 +    {
   1.254 +        bool match = true;
   1.255 +        const EGLint *attribute = attribList;
   1.256 +
   1.257 +        while (attribute[0] != EGL_NONE)
   1.258 +        {
   1.259 +            switch (attribute[0])
   1.260 +            {
   1.261 +              case EGL_BUFFER_SIZE:               match = config->mBufferSize >= attribute[1];                      break;
   1.262 +              case EGL_ALPHA_SIZE:                match = config->mAlphaSize >= attribute[1];                       break;
   1.263 +              case EGL_BLUE_SIZE:                 match = config->mBlueSize >= attribute[1];                        break;
   1.264 +              case EGL_GREEN_SIZE:                match = config->mGreenSize >= attribute[1];                       break;
   1.265 +              case EGL_RED_SIZE:                  match = config->mRedSize >= attribute[1];                         break;
   1.266 +              case EGL_DEPTH_SIZE:                match = config->mDepthSize >= attribute[1];                       break;
   1.267 +              case EGL_STENCIL_SIZE:              match = config->mStencilSize >= attribute[1];                     break;
   1.268 +              case EGL_CONFIG_CAVEAT:             match = config->mConfigCaveat == (EGLenum) attribute[1];          break;
   1.269 +              case EGL_CONFIG_ID:                 match = config->mConfigID == attribute[1];                        break;
   1.270 +              case EGL_LEVEL:                     match = config->mLevel >= attribute[1];                           break;
   1.271 +              case EGL_NATIVE_RENDERABLE:         match = config->mNativeRenderable == (EGLBoolean) attribute[1];   break;
   1.272 +              case EGL_NATIVE_VISUAL_TYPE:        match = config->mNativeVisualType == attribute[1];                break;
   1.273 +              case EGL_SAMPLES:                   match = config->mSamples >= attribute[1];                         break;
   1.274 +              case EGL_SAMPLE_BUFFERS:            match = config->mSampleBuffers >= attribute[1];                   break;
   1.275 +              case EGL_SURFACE_TYPE:              match = (config->mSurfaceType & attribute[1]) == attribute[1];    break;
   1.276 +              case EGL_TRANSPARENT_TYPE:          match = config->mTransparentType == (EGLenum) attribute[1];       break;
   1.277 +              case EGL_TRANSPARENT_BLUE_VALUE:    match = config->mTransparentBlueValue == attribute[1];            break;
   1.278 +              case EGL_TRANSPARENT_GREEN_VALUE:   match = config->mTransparentGreenValue == attribute[1];           break;
   1.279 +              case EGL_TRANSPARENT_RED_VALUE:     match = config->mTransparentRedValue == attribute[1];             break;
   1.280 +              case EGL_BIND_TO_TEXTURE_RGB:       match = config->mBindToTextureRGB == (EGLBoolean) attribute[1];   break;
   1.281 +              case EGL_BIND_TO_TEXTURE_RGBA:      match = config->mBindToTextureRGBA == (EGLBoolean) attribute[1];  break;
   1.282 +              case EGL_MIN_SWAP_INTERVAL:         match = config->mMinSwapInterval == attribute[1];                 break;
   1.283 +              case EGL_MAX_SWAP_INTERVAL:         match = config->mMaxSwapInterval == attribute[1];                 break;
   1.284 +              case EGL_LUMINANCE_SIZE:            match = config->mLuminanceSize >= attribute[1];                   break;
   1.285 +              case EGL_ALPHA_MASK_SIZE:           match = config->mAlphaMaskSize >= attribute[1];                   break;
   1.286 +              case EGL_COLOR_BUFFER_TYPE:         match = config->mColorBufferType == (EGLenum) attribute[1];       break;
   1.287 +              case EGL_RENDERABLE_TYPE:           match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
   1.288 +              case EGL_MATCH_NATIVE_PIXMAP:       match = false; UNIMPLEMENTED();                                   break;
   1.289 +              case EGL_CONFORMANT:                match = (config->mConformant & attribute[1]) == attribute[1];     break;
   1.290 +              case EGL_MAX_PBUFFER_WIDTH:         match = config->mMaxPBufferWidth >= attribute[1];                 break;
   1.291 +              case EGL_MAX_PBUFFER_HEIGHT:        match = config->mMaxPBufferHeight >= attribute[1];                break;
   1.292 +              case EGL_MAX_PBUFFER_PIXELS:        match = config->mMaxPBufferPixels >= attribute[1];                break;
   1.293 +              default:
   1.294 +                return false;
   1.295 +            }
   1.296 +
   1.297 +            if (!match)
   1.298 +            {
   1.299 +                break;
   1.300 +            }
   1.301 +
   1.302 +            attribute += 2;
   1.303 +        }
   1.304 +
   1.305 +        if (match)
   1.306 +        {
   1.307 +            passed.push_back(&*config);
   1.308 +        }
   1.309 +    }
   1.310 +
   1.311 +    if (configs)
   1.312 +    {
   1.313 +        sort(passed.begin(), passed.end(), SortConfig(attribList));
   1.314 +
   1.315 +        EGLint index;
   1.316 +        for (index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
   1.317 +        {
   1.318 +            configs[index] = passed[index]->getHandle();
   1.319 +        }
   1.320 +
   1.321 +        *numConfig = index;
   1.322 +    }
   1.323 +    else
   1.324 +    {
   1.325 +        *numConfig = passed.size();
   1.326 +    }
   1.327 +
   1.328 +    return true;
   1.329 +}
   1.330 +
   1.331 +const egl::Config *ConfigSet::get(EGLConfig configHandle)
   1.332 +{
   1.333 +    for (Iterator config = mSet.begin(); config != mSet.end(); config++)
   1.334 +    {
   1.335 +        if (config->getHandle() == configHandle)
   1.336 +        {
   1.337 +            return &(*config);
   1.338 +        }
   1.339 +    }
   1.340 +
   1.341 +    return NULL;
   1.342 +}
   1.343 +}

mercurial