aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkMipMap.cpp
diff options
context:
space:
mode:
authorGravatar cblume <cblume@chromium.org>2016-06-02 09:01:48 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-02 09:01:48 -0700
commitf95ff4a37aba42a07b0fed9ee760d1a238c6d291 (patch)
treef064ccc217e64f6cb494578bdc9c12dc6471ea55 /src/core/SkMipMap.cpp
parent09563cec928da5052972b3dca7f022fca3a72d05 (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.cpp42
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 {