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]; |
+ } |
+} |