Chromium Code Reviews| Index: src/core/SkMipMap.cpp |
| diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp |
| index c851d64a908a959b4b90234aba4ba81377f0566b..615675cf2436eae74d43324cdaac351daf5d6134 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,33 @@ 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 = 0; |
| + int height = 0; |
| + for (int currentMipLevel = 0; currentMipLevel <= level; currentMipLevel++) { |
|
reed1
2016/06/01 12:55:56
Can we do this without a loop?
width = max(1, bas
cblume
2016/06/01 17:02:16
Oh. Yeah. That's the whole benefit of this method
|
| + width = SkTMax(1, baseWidth / (1 << currentMipLevel)); |
| + height = SkTMax(1, baseHeight / (1 << currentMipLevel)); |
| + } |
| + |
| + return SkSize::Make(width, height); |
| +} |
| + |
| /////////////////////////////////////////////////////////////////////////////// |
| bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const { |