tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Config.cpp (13895B)


      1 //
      2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Config.cpp: Implements the egl::Config class, describing the format, type
      8 // and size for an egl::Surface. Implements EGLConfig and related functionality.
      9 // [EGL 1.5] section 3.4 page 19.
     10 
     11 #include "libANGLE/Config.h"
     12 #include "libANGLE/AttributeMap.h"
     13 
     14 #include <algorithm>
     15 #include <vector>
     16 
     17 #include <EGL/eglext.h>
     18 #include "angle_gl.h"
     19 
     20 #include "common/debug.h"
     21 
     22 namespace egl
     23 {
     24 
     25 Config::Config()
     26    : renderTargetFormat(GL_NONE),
     27      depthStencilFormat(GL_NONE),
     28      bufferSize(0),
     29      redSize(0),
     30      greenSize(0),
     31      blueSize(0),
     32      luminanceSize(0),
     33      alphaSize(0),
     34      alphaMaskSize(0),
     35      bindToTextureRGB(EGL_FALSE),
     36      bindToTextureRGBA(EGL_FALSE),
     37      bindToTextureTarget(EGL_TEXTURE_2D),
     38      colorBufferType(EGL_RGB_BUFFER),
     39      configCaveat(EGL_NONE),
     40      configID(0),
     41      conformant(0),
     42      depthSize(0),
     43      level(0),
     44      matchNativePixmap(EGL_FALSE),
     45      maxPBufferWidth(0),
     46      maxPBufferHeight(0),
     47      maxPBufferPixels(0),
     48      maxSwapInterval(0),
     49      minSwapInterval(0),
     50      nativeRenderable(EGL_FALSE),
     51      nativeVisualID(0),
     52      nativeVisualType(0),
     53      renderableType(0),
     54      sampleBuffers(0),
     55      samples(0),
     56      stencilSize(0),
     57      surfaceType(0),
     58      transparentType(EGL_NONE),
     59      transparentRedValue(0),
     60      transparentGreenValue(0),
     61      transparentBlueValue(0),
     62      optimalOrientation(0),
     63      colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
     64      recordable(EGL_FALSE),
     65      framebufferTarget(EGL_FALSE),  // TODO: http://anglebug.com/4208
     66      yInverted(EGL_FALSE)
     67 {}
     68 
     69 Config::~Config() {}
     70 
     71 Config::Config(const Config &other) = default;
     72 
     73 Config &Config::operator=(const Config &other) = default;
     74 
     75 ConfigSet::ConfigSet() = default;
     76 
     77 ConfigSet::ConfigSet(const ConfigSet &other) = default;
     78 
     79 ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default;
     80 
     81 ConfigSet::~ConfigSet() = default;
     82 
     83 EGLint ConfigSet::add(const Config &config)
     84 {
     85    // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
     86    EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;
     87 
     88    Config copyConfig(config);
     89    copyConfig.configID = id;
     90    mConfigs.insert(std::make_pair(id, copyConfig));
     91 
     92    return id;
     93 }
     94 
     95 const Config &ConfigSet::get(EGLint id) const
     96 {
     97    ASSERT(mConfigs.find(id) != mConfigs.end());
     98    return mConfigs.find(id)->second;
     99 }
    100 
    101 void ConfigSet::clear()
    102 {
    103    mConfigs.clear();
    104 }
    105 
    106 size_t ConfigSet::size() const
    107 {
    108    return mConfigs.size();
    109 }
    110 
    111 bool ConfigSet::contains(const Config *config) const
    112 {
    113    for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
    114    {
    115        const Config &item = i->second;
    116        if (config == &item)
    117        {
    118            return true;
    119        }
    120    }
    121 
    122    return false;
    123 }
    124 
    125 // Function object used by STL sorting routines for ordering Configs according to [EGL 1.5]
    126 // section 3.4.1.2 page 28.
    127 class ConfigSorter
    128 {
    129  public:
    130    explicit ConfigSorter(const AttributeMap &attributeMap)
    131        : mWantRed(false),
    132          mWantGreen(false),
    133          mWantBlue(false),
    134          mWantAlpha(false),
    135          mWantLuminance(false)
    136    {
    137        scanForWantedComponents(attributeMap);
    138    }
    139 
    140    bool operator()(const Config *x, const Config *y) const { return (*this)(*x, *y); }
    141 
    142    bool operator()(const Config &x, const Config &y) const
    143    {
    144 #define SORT(attribute)                       \
    145    do                                        \
    146    {                                         \
    147        if (x.attribute != y.attribute)       \
    148            return x.attribute < y.attribute; \
    149    } while (0)
    150 
    151        static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG,
    152                      "Unexpected EGL enum value.");
    153        SORT(configCaveat);
    154 
    155        static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
    156                      "Unexpected order of EGL enums.");
    157        SORT(colorComponentType);
    158 
    159        static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
    160        SORT(colorBufferType);
    161 
    162        // By larger total number of color bits, only considering those that are requested to be >
    163        // 0.
    164        EGLint xComponentsSize = wantedComponentsSize(x);
    165        EGLint yComponentsSize = wantedComponentsSize(y);
    166        if (xComponentsSize != yComponentsSize)
    167        {
    168            return xComponentsSize > yComponentsSize;
    169        }
    170 
    171        SORT(bufferSize);
    172        SORT(sampleBuffers);
    173        SORT(samples);
    174        SORT(depthSize);
    175        SORT(stencilSize);
    176        SORT(alphaMaskSize);
    177        SORT(nativeVisualType);
    178        SORT(configID);
    179 
    180 #undef SORT
    181 
    182        return false;
    183    }
    184 
    185  private:
    186    static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component)
    187    {
    188        // [EGL 1.5] section 3.4.1.2 page 30
    189        // Sorting rule #3: by larger total number of color bits, not considering
    190        // components that are 0 or don't-care.
    191        EGLAttrib value = attributeMap.get(component, 0);
    192        return value != 0 && value != EGL_DONT_CARE;
    193    }
    194 
    195    void scanForWantedComponents(const AttributeMap &attributeMap)
    196    {
    197        mWantRed       = wantsComponent(attributeMap, EGL_RED_SIZE);
    198        mWantGreen     = wantsComponent(attributeMap, EGL_GREEN_SIZE);
    199        mWantBlue      = wantsComponent(attributeMap, EGL_BLUE_SIZE);
    200        mWantAlpha     = wantsComponent(attributeMap, EGL_ALPHA_SIZE);
    201        mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE);
    202    }
    203 
    204    EGLint wantedComponentsSize(const Config &config) const
    205    {
    206        EGLint total = 0;
    207 
    208        if (mWantRed)
    209            total += config.redSize;
    210        if (mWantGreen)
    211            total += config.greenSize;
    212        if (mWantBlue)
    213            total += config.blueSize;
    214        if (mWantAlpha)
    215            total += config.alphaSize;
    216        if (mWantLuminance)
    217            total += config.luminanceSize;
    218 
    219        return total;
    220    }
    221 
    222    bool mWantRed;
    223    bool mWantGreen;
    224    bool mWantBlue;
    225    bool mWantAlpha;
    226    bool mWantLuminance;
    227 };
    228 
    229 std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap) const
    230 {
    231    std::vector<const Config *> result;
    232    result.reserve(mConfigs.size());
    233 
    234    for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
    235    {
    236        const Config &config = configIter->second;
    237        bool match           = true;
    238 
    239        for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
    240        {
    241            EGLAttrib attributeKey   = attribIter->first;
    242            EGLAttrib attributeValue = attribIter->second;
    243 
    244            if (attributeValue == EGL_DONT_CARE)
    245            {
    246                continue;
    247            }
    248 
    249            switch (attributeKey)
    250            {
    251                case EGL_BUFFER_SIZE:
    252                    match = config.bufferSize >= attributeValue;
    253                    break;
    254                case EGL_ALPHA_SIZE:
    255                    match = config.alphaSize >= attributeValue;
    256                    break;
    257                case EGL_BLUE_SIZE:
    258                    match = config.blueSize >= attributeValue;
    259                    break;
    260                case EGL_GREEN_SIZE:
    261                    match = config.greenSize >= attributeValue;
    262                    break;
    263                case EGL_RED_SIZE:
    264                    match = config.redSize >= attributeValue;
    265                    break;
    266                case EGL_DEPTH_SIZE:
    267                    match = config.depthSize >= attributeValue;
    268                    break;
    269                case EGL_STENCIL_SIZE:
    270                    match = config.stencilSize >= attributeValue;
    271                    break;
    272                case EGL_CONFIG_CAVEAT:
    273                    match = config.configCaveat == static_cast<EGLenum>(attributeValue);
    274                    break;
    275                case EGL_CONFIG_ID:
    276                    match = config.configID == attributeValue;
    277                    break;
    278                case EGL_LEVEL:
    279                    match = config.level == attributeValue;
    280                    break;
    281                case EGL_NATIVE_RENDERABLE:
    282                    match = config.nativeRenderable == static_cast<EGLBoolean>(attributeValue);
    283                    break;
    284                case EGL_NATIVE_VISUAL_TYPE:
    285                    match = config.nativeVisualType == attributeValue;
    286                    break;
    287                case EGL_SAMPLES:
    288                    match = config.samples >= attributeValue;
    289                    break;
    290                case EGL_SAMPLE_BUFFERS:
    291                    match = config.sampleBuffers >= attributeValue;
    292                    break;
    293                case EGL_SURFACE_TYPE:
    294                    match = (config.surfaceType & attributeValue) == attributeValue;
    295                    break;
    296                case EGL_TRANSPARENT_TYPE:
    297                    match = config.transparentType == static_cast<EGLenum>(attributeValue);
    298                    break;
    299                case EGL_TRANSPARENT_BLUE_VALUE:
    300                    if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
    301                    {
    302                        match = config.transparentBlueValue == attributeValue;
    303                    }
    304                    break;
    305                case EGL_TRANSPARENT_GREEN_VALUE:
    306                    if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
    307                    {
    308                        match = config.transparentGreenValue == attributeValue;
    309                    }
    310                    break;
    311                case EGL_TRANSPARENT_RED_VALUE:
    312                    if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
    313                    {
    314                        match = config.transparentRedValue == attributeValue;
    315                    }
    316                    break;
    317                case EGL_BIND_TO_TEXTURE_RGB:
    318                    match = config.bindToTextureRGB == static_cast<EGLBoolean>(attributeValue);
    319                    break;
    320                case EGL_BIND_TO_TEXTURE_RGBA:
    321                    match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue);
    322                    break;
    323                case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
    324                    match = config.bindToTextureTarget == static_cast<EGLenum>(attributeValue);
    325                    break;
    326                case EGL_MIN_SWAP_INTERVAL:
    327                    match = config.minSwapInterval == attributeValue;
    328                    break;
    329                case EGL_MAX_SWAP_INTERVAL:
    330                    match = config.maxSwapInterval == attributeValue;
    331                    break;
    332                case EGL_LUMINANCE_SIZE:
    333                    match = config.luminanceSize >= attributeValue;
    334                    break;
    335                case EGL_ALPHA_MASK_SIZE:
    336                    match = config.alphaMaskSize >= attributeValue;
    337                    break;
    338                case EGL_COLOR_BUFFER_TYPE:
    339                    match = config.colorBufferType == static_cast<EGLenum>(attributeValue);
    340                    break;
    341                case EGL_RENDERABLE_TYPE:
    342                    match = (config.renderableType & attributeValue) == attributeValue;
    343                    break;
    344                case EGL_MATCH_NATIVE_PIXMAP:
    345                    match = false;
    346                    UNIMPLEMENTED();
    347                    break;
    348                case EGL_CONFORMANT:
    349                    match = (config.conformant & attributeValue) == attributeValue;
    350                    break;
    351                case EGL_MAX_PBUFFER_WIDTH:
    352                    match = config.maxPBufferWidth >= attributeValue;
    353                    break;
    354                case EGL_MAX_PBUFFER_HEIGHT:
    355                    match = config.maxPBufferHeight >= attributeValue;
    356                    break;
    357                case EGL_MAX_PBUFFER_PIXELS:
    358                    match = config.maxPBufferPixels >= attributeValue;
    359                    break;
    360                case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
    361                    match = config.optimalOrientation == attributeValue;
    362                    break;
    363                case EGL_COLOR_COMPONENT_TYPE_EXT:
    364                    match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
    365                    break;
    366                case EGL_RECORDABLE_ANDROID:
    367                    match = config.recordable == static_cast<EGLBoolean>(attributeValue);
    368                    break;
    369                case EGL_FRAMEBUFFER_TARGET_ANDROID:
    370                    match = config.framebufferTarget == static_cast<EGLBoolean>(attributeValue);
    371                    break;
    372                case EGL_Y_INVERTED_NOK:
    373                    match = config.yInverted == static_cast<EGLBoolean>(attributeValue);
    374                    break;
    375                case EGL_MATCH_FORMAT_KHR:
    376                    if (attributeValue == EGL_NONE)
    377                    {
    378                        match = (config.surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == 0;
    379                    }
    380                    else
    381                    {
    382                        match = config.matchFormat == attributeValue;
    383                    }
    384                    break;
    385                default:
    386                    UNREACHABLE();
    387            }
    388 
    389            if (!match)
    390            {
    391                break;
    392            }
    393        }
    394 
    395        if (match)
    396        {
    397            result.push_back(&config);
    398        }
    399    }
    400 
    401    // Sort the result
    402    std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));
    403 
    404    return result;
    405 }
    406 
    407 ConfigSet::ConfigMap::iterator ConfigSet::begin()
    408 {
    409    return mConfigs.begin();
    410 }
    411 
    412 ConfigSet::ConfigMap::iterator ConfigSet::end()
    413 {
    414    return mConfigs.end();
    415 }
    416 }  // namespace egl