diff options
author | cblume <cblume@chromium.org> | 2016-06-02 09:01:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-02 09:01:48 -0700 |
commit | f95ff4a37aba42a07b0fed9ee760d1a238c6d291 (patch) | |
tree | f064ccc217e64f6cb494578bdc9c12dc6471ea55 /src/core/SkMipMap.cpp | |
parent | 09563cec928da5052972b3dca7f022fca3a72d05 (diff) |
Add getting the size of a given mipmap level.
When allocating memory for mipmaps, it would be very handy to know the
dimensions of a given mipmap level.
R=bsalomon@google.com
BUG=578304
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2018283002
Review-Url: https://codereview.chromium.org/2018283002
Diffstat (limited to 'src/core/SkMipMap.cpp')
-rw-r--r-- | src/core/SkMipMap.cpp | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp index c851d64a90..4c075ea6bb 100644 --- a/src/core/SkMipMap.cpp +++ b/src/core/SkMipMap.cpp @@ -371,23 +371,12 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) { } // whip through our loop to compute the exact size needed size_t size = 0; - int countLevels = 0; - { - int width = src.width(); - int height = src.height(); - for (;;) { - width = SkTMax(1, width >> 1); - height = SkTMax(1, height >> 1); - size += SkColorTypeMinRowBytes(ct, width) * height; - countLevels += 1; - if (1 == width && 1 == height) { - break; - } - } + int countLevels = ComputeLevelCount(src.width(), src.height()); + for (int currentMipLevel = countLevels; currentMipLevel > 0; currentMipLevel--) { + SkSize mipSize = ComputeLevelSize(src.width(), src.height(), currentMipLevel); + size += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight; } - SkASSERT(countLevels == SkMipMap::ComputeLevelCount(src.width(), src.height())); - size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); if (0 == storageSize) { return nullptr; @@ -507,6 +496,29 @@ int SkMipMap::ComputeLevelCount(int baseWidth, int baseHeight) { return mipLevelCount; } +SkSize SkMipMap::ComputeLevelSize(int baseWidth, int baseHeight, int level) { + if (baseWidth < 1 || baseHeight < 1) { + return SkSize::Make(0, 0); + } + + int maxLevelCount = ComputeLevelCount(baseWidth, baseHeight); + if (level > maxLevelCount || level < 0) { + return SkSize::Make(0, 0); + } + if (level == 0) { + return SkSize::Make(baseWidth, baseHeight); + } + + // OpenGL's spec requires that each mipmap level have height/width equal to + // max(1, floor(original_height / 2^i) + // (or original_width) where i is the mipmap level. + + int width = SkTMax(1, baseWidth >> level); + int height = SkTMax(1, baseHeight >> level); + + return SkSize::Make(width, height); +} + /////////////////////////////////////////////////////////////////////////////// bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const { |