tor-browser

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

ImageIndex.cpp (11938B)


      1 //
      2 // Copyright 2014 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 // ImageIndex.cpp: Implementation for ImageIndex methods.
      8 
      9 #include "libANGLE/ImageIndex.h"
     10 
     11 #include "common/utilities.h"
     12 #include "libANGLE/Constants.h"
     13 #include "libANGLE/angletypes.h"
     14 
     15 #include <tuple>
     16 
     17 namespace gl
     18 {
     19 namespace
     20 {
     21 GLint TextureTargetToLayer(TextureTarget target)
     22 {
     23    switch (target)
     24    {
     25        case TextureTarget::CubeMapPositiveX:
     26            return 0;
     27        case TextureTarget::CubeMapNegativeX:
     28            return 1;
     29        case TextureTarget::CubeMapPositiveY:
     30            return 2;
     31        case TextureTarget::CubeMapNegativeY:
     32            return 3;
     33        case TextureTarget::CubeMapPositiveZ:
     34            return 4;
     35        case TextureTarget::CubeMapNegativeZ:
     36            return 5;
     37        case TextureTarget::External:
     38        case TextureTarget::Rectangle:
     39        case TextureTarget::_2D:
     40        case TextureTarget::VideoImage:
     41        case TextureTarget::_2DArray:
     42        case TextureTarget::_2DMultisample:
     43        case TextureTarget::_2DMultisampleArray:
     44        case TextureTarget::_3D:
     45        case TextureTarget::Buffer:
     46        case TextureTarget::CubeMapArray:
     47            return ImageIndex::kEntireLevel;
     48        default:
     49            UNREACHABLE();
     50            return 0;
     51    }
     52 }
     53 
     54 bool IsArrayTarget(TextureTarget target)
     55 {
     56    switch (target)
     57    {
     58        case TextureTarget::_2DArray:
     59        case TextureTarget::_2DMultisampleArray:
     60        case TextureTarget::CubeMapArray:
     61            return true;
     62        default:
     63            return false;
     64    }
     65 }
     66 }  // anonymous namespace
     67 
     68 TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex)
     69 {
     70    if (type == TextureType::CubeMap)
     71    {
     72        // As GL_TEXTURE_CUBE_MAP cannot be a texture target in texImage*D APIs, so we don't allow
     73        // an entire cube map to have a texture target.
     74        ASSERT(layerIndex != ImageIndex::kEntireLevel);
     75        return CubeFaceIndexToTextureTarget(layerIndex);
     76    }
     77    else
     78    {
     79        return NonCubeTextureTypeToTarget(type);
     80    }
     81 }
     82 
     83 ImageIndex::ImageIndex()
     84    : mType(TextureType::InvalidEnum), mLevelIndex(0), mLayerIndex(0), mLayerCount(kEntireLevel)
     85 {}
     86 
     87 ImageIndex::ImageIndex(const ImageIndex &other) = default;
     88 
     89 ImageIndex &ImageIndex::operator=(const ImageIndex &other) = default;
     90 
     91 bool ImageIndex::hasLayer() const
     92 {
     93    return mLayerIndex != kEntireLevel;
     94 }
     95 
     96 bool ImageIndex::isLayered() const
     97 {
     98    switch (mType)
     99    {
    100        case TextureType::_2DArray:
    101        case TextureType::_2DMultisampleArray:
    102        case TextureType::CubeMap:
    103        case TextureType::_3D:
    104        case TextureType::CubeMapArray:
    105            return mLayerIndex == kEntireLevel;
    106        default:
    107            return false;
    108    }
    109 }
    110 
    111 bool ImageIndex::has3DLayer() const
    112 {
    113    // It's quicker to check != CubeMap than calling usesTex3D, which checks multiple types. This
    114    // ASSERT validates the check gives the same result.
    115    ASSERT(!hasLayer() || ((mType != TextureType::CubeMap) == usesTex3D()));
    116    return (hasLayer() && mType != TextureType::CubeMap);
    117 }
    118 
    119 bool ImageIndex::usesTex3D() const
    120 {
    121    return mType == TextureType::_3D || mType == TextureType::_2DArray ||
    122           mType == TextureType::_2DMultisampleArray || mType == TextureType::CubeMapArray;
    123 }
    124 
    125 TextureTarget ImageIndex::getTarget() const
    126 {
    127    return TextureTypeToTarget(mType, mLayerIndex);
    128 }
    129 
    130 gl::TextureTarget ImageIndex::getTargetOrFirstCubeFace() const
    131 {
    132    if (isEntireLevelCubeMap())
    133    {
    134        return gl::kCubeMapTextureTargetMin;
    135    }
    136    else
    137    {
    138        return getTarget();
    139    }
    140 }
    141 
    142 GLint ImageIndex::cubeMapFaceIndex() const
    143 {
    144    ASSERT(mType == TextureType::CubeMap);
    145    ASSERT(mLayerIndex == kEntireLevel || mLayerIndex < static_cast<GLint>(kCubeFaceCount));
    146    return mLayerIndex;
    147 }
    148 
    149 bool ImageIndex::valid() const
    150 {
    151    return mType != TextureType::InvalidEnum;
    152 }
    153 
    154 bool ImageIndex::isEntireLevelCubeMap() const
    155 {
    156    return mType == TextureType::CubeMap && mLayerIndex == ImageIndex::kEntireLevel;
    157 }
    158 
    159 ImageIndex ImageIndex::Make2D(GLint levelIndex)
    160 {
    161    return ImageIndex(TextureType::_2D, levelIndex, kEntireLevel, 1);
    162 }
    163 
    164 ImageIndex ImageIndex::MakeRectangle(GLint levelIndex)
    165 {
    166    return ImageIndex(TextureType::Rectangle, levelIndex, kEntireLevel, 1);
    167 }
    168 
    169 ImageIndex ImageIndex::MakeCubeMapFace(TextureTarget target, GLint levelIndex)
    170 {
    171    ASSERT(IsCubeMapFaceTarget(target));
    172    return ImageIndex(TextureType::CubeMap, levelIndex, TextureTargetToLayer(target), 1);
    173 }
    174 
    175 ImageIndex ImageIndex::Make2DArray(GLint levelIndex, GLint layerIndex)
    176 {
    177    return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, 1);
    178 }
    179 
    180 ImageIndex ImageIndex::Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint numLayers)
    181 {
    182    return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, numLayers);
    183 }
    184 
    185 ImageIndex ImageIndex::Make3D(GLint levelIndex, GLint layerIndex)
    186 {
    187    return ImageIndex(TextureType::_3D, levelIndex, layerIndex, 1);
    188 }
    189 
    190 ImageIndex ImageIndex::MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth)
    191 {
    192    return ImageIndex(TextureTargetToType(target), levelIndex, TextureTargetToLayer(target),
    193                      IsArrayTarget(target) ? depth : 1);
    194 }
    195 
    196 ImageIndex ImageIndex::MakeFromType(TextureType type,
    197                                    GLint levelIndex,
    198                                    GLint layerIndex,
    199                                    GLint layerCount)
    200 {
    201    GLint overrideLayerCount =
    202        (type == TextureType::CubeMap && layerIndex == kEntireLevel ? kCubeFaceCount : layerCount);
    203    return ImageIndex(type, levelIndex, layerIndex, overrideLayerCount);
    204 }
    205 
    206 ImageIndex ImageIndex::MakeBuffer()
    207 {
    208    return ImageIndex(TextureType::Buffer, 0, kEntireLevel, 1);
    209 }
    210 
    211 ImageIndex ImageIndex::Make2DMultisample()
    212 {
    213    return ImageIndex(TextureType::_2DMultisample, 0, kEntireLevel, 1);
    214 }
    215 
    216 ImageIndex ImageIndex::Make2DMultisampleArray(GLint layerIndex)
    217 {
    218    return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, 1);
    219 }
    220 
    221 ImageIndex ImageIndex::Make2DMultisampleArrayRange(GLint layerIndex, GLint numLayers)
    222 {
    223    return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, numLayers);
    224 }
    225 
    226 bool ImageIndex::operator<(const ImageIndex &b) const
    227 {
    228    return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) <
    229           std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount);
    230 }
    231 
    232 bool ImageIndex::operator==(const ImageIndex &b) const
    233 {
    234    return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) ==
    235           std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount);
    236 }
    237 
    238 bool ImageIndex::operator!=(const ImageIndex &b) const
    239 {
    240    return !(*this == b);
    241 }
    242 
    243 ImageIndex::ImageIndex(TextureType type, GLint levelIndex, GLint layerIndex, GLint layerCount)
    244    : mType(type), mLevelIndex(levelIndex), mLayerIndex(layerIndex), mLayerCount(layerCount)
    245 {}
    246 
    247 ImageIndexIterator ImageIndex::getLayerIterator(GLint layerCount) const
    248 {
    249    ASSERT(mType != TextureType::_2D && !hasLayer());
    250    return ImageIndexIterator::MakeGeneric(mType, mLevelIndex, mLevelIndex + 1, 0, layerCount);
    251 }
    252 
    253 ImageIndexIterator::ImageIndexIterator(const ImageIndexIterator &other) = default;
    254 
    255 ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
    256 {
    257    return ImageIndexIterator(TextureType::_2D, Range<GLint>(minMip, maxMip),
    258                              Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
    259                              nullptr);
    260 }
    261 
    262 ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip)
    263 {
    264    return ImageIndexIterator(TextureType::Rectangle, Range<GLint>(minMip, maxMip),
    265                              Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
    266                              nullptr);
    267 }
    268 
    269 ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
    270 {
    271    return ImageIndexIterator(TextureType::CubeMap, Range<GLint>(minMip, maxMip),
    272                              Range<GLint>(0, 6), nullptr);
    273 }
    274 
    275 ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip,
    276                                              GLint maxMip,
    277                                              GLint minLayer,
    278                                              GLint maxLayer)
    279 {
    280    return ImageIndexIterator(TextureType::_3D, Range<GLint>(minMip, maxMip),
    281                              Range<GLint>(minLayer, maxLayer), nullptr);
    282 }
    283 
    284 ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip,
    285                                                   GLint maxMip,
    286                                                   const GLsizei *layerCounts)
    287 {
    288    return ImageIndexIterator(TextureType::_2DArray, Range<GLint>(minMip, maxMip),
    289                              Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
    290                              layerCounts);
    291 }
    292 
    293 ImageIndexIterator ImageIndexIterator::Make2DMultisample()
    294 {
    295    return ImageIndexIterator(TextureType::_2DMultisample, Range<GLint>(0, 1),
    296                              Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
    297                              nullptr);
    298 }
    299 
    300 ImageIndexIterator ImageIndexIterator::MakeBuffer()
    301 {
    302    return ImageIndexIterator(TextureType::Buffer, Range<GLint>(0, 1),
    303                              Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
    304                              nullptr);
    305 }
    306 
    307 ImageIndexIterator ImageIndexIterator::Make2DMultisampleArray(const GLsizei *layerCounts)
    308 {
    309    return ImageIndexIterator(TextureType::_2DMultisampleArray, Range<GLint>(0, 1),
    310                              Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
    311                              layerCounts);
    312 }
    313 
    314 ImageIndexIterator ImageIndexIterator::MakeGeneric(TextureType type,
    315                                                   GLint minMip,
    316                                                   GLint maxMip,
    317                                                   GLint minLayer,
    318                                                   GLint maxLayer)
    319 {
    320    if (type == TextureType::CubeMap)
    321    {
    322        return MakeCube(minMip, maxMip);
    323    }
    324 
    325    return ImageIndexIterator(type, Range<GLint>(minMip, maxMip), Range<GLint>(minLayer, maxLayer),
    326                              nullptr);
    327 }
    328 
    329 ImageIndexIterator::ImageIndexIterator(TextureType type,
    330                                       const Range<GLint> &mipRange,
    331                                       const Range<GLint> &layerRange,
    332                                       const GLsizei *layerCounts)
    333    : mMipRange(mipRange),
    334      mLayerRange(layerRange),
    335      mLayerCounts(layerCounts),
    336      mCurrentIndex(type, mipRange.low(), layerRange.low(), 1)
    337 {}
    338 
    339 GLint ImageIndexIterator::maxLayer() const
    340 {
    341    if (mLayerCounts)
    342    {
    343        ASSERT(mCurrentIndex.hasLayer());
    344        return (mCurrentIndex.getLevelIndex() < mMipRange.high())
    345                   ? mLayerCounts[mCurrentIndex.getLevelIndex()]
    346                   : 0;
    347    }
    348    return mLayerRange.high();
    349 }
    350 
    351 ImageIndex ImageIndexIterator::next()
    352 {
    353    ASSERT(hasNext());
    354 
    355    // Make a copy of the current index to return
    356    ImageIndex previousIndex = mCurrentIndex;
    357 
    358    // Iterate layers in the inner loop for now. We can add switchable
    359    // layer or mip iteration if we need it.
    360 
    361    if (mCurrentIndex.hasLayer() && mCurrentIndex.getLayerIndex() < maxLayer() - 1)
    362    {
    363        mCurrentIndex.mLayerIndex++;
    364    }
    365    else if (mCurrentIndex.mLevelIndex < mMipRange.high() - 1)
    366    {
    367        mCurrentIndex.mLayerIndex = mLayerRange.low();
    368        mCurrentIndex.mLevelIndex++;
    369    }
    370    else
    371    {
    372        mCurrentIndex = ImageIndex();
    373    }
    374 
    375    return previousIndex;
    376 }
    377 
    378 ImageIndex ImageIndexIterator::current() const
    379 {
    380    return mCurrentIndex;
    381 }
    382 
    383 bool ImageIndexIterator::hasNext() const
    384 {
    385    return mCurrentIndex.valid();
    386 }
    387 
    388 }  // namespace gl