Chromium Code Reviews| Index: src/core/SkMipMap.cpp |
| diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp |
| index c037865fd49b3f25c555a1eb19d5aa217cd8c6bb..30aa9db92c1fd4c4be7224c568866ddf544d92bc 100644 |
| --- a/src/core/SkMipMap.cpp |
| +++ b/src/core/SkMipMap.cpp |
| @@ -8,7 +8,9 @@ |
| #include "SkMipMap.h" |
| #include "SkBitmap.h" |
| #include "SkColorPriv.h" |
| +#include "SkMath.h" |
| #include "SkNx.h" |
| +#include "SkTypes.h" |
| // |
| // ColorTypeFilter is the "Type" we pass to some downsample template functions. |
| @@ -372,3 +374,53 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
| return Build(srcPixmap, fact); |
| } |
| +int SkMipMap::ComputeLevelCount(int baseWidth, int baseHeight) { |
|
reed1
2016/01/28 02:06:03
Its a little odd that the Build code doesn't call
cblume
2016/02/01 09:31:07
I agree.
But when I was writing this I realized th
|
| + // 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. |
| + // Continue scaling down until both axes are size 1. |
| + // |
| + // This means when it maintains isotropic space (both axes scaling down |
| + // at the same rate) until one axis hits size 1. |
| + // At that point, OpenGL continues to scale down into anisotropic space |
| + // (where the scales are not the same between axes). |
| + // |
| + // Skia currently does not go into anisotropic space. |
| + // Once an axis hits size 1 we stop. |
| + // All this means is rather than use the largest axis we will use the |
| + // smallest axis. |
| + |
| + const int smallestAxis = SkTMin(baseWidth, baseHeight); |
| + if (smallestAxis < 2) { |
| + // SkMipMap::Build requires a minimum size of 2. |
| + return 0; |
| + } |
| + const int leadingZeros = SkCLZ(static_cast<uint32_t>(smallestAxis)); |
| + // If the value 00011010 has 3 leading 0s then it has 5 significant bits |
| + // (the bits which are not leading zeros) |
| + const int significantBits = (sizeof(uint32_t) * 8) - leadingZeros; |
| + // This is making the assumption that the size of a byte is 8 bits |
| + // and that sizeof(uint32_t)'s implementation-defined behavior is 4. |
| + const int mipLevelCount = significantBits; |
| + |
| + return mipLevelCount; |
| +} |
| + |
| +int SkMipMap::countLevels() const { |
| + return fCount; |
| +} |
| + |
| +void SkMipMap::getLevel(int index, Level* levelPtr) const { |
| + if (NULL == fLevels) { |
| + return; |
| + } |
| + if (index < 0) { |
| + return; |
| + } |
| + if (index > fCount - 1) { |
| + return; |
| + } |
| + if (levelPtr) { |
| + *levelPtr = fLevels[index]; |
| + } |
| +} |