Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkMipMap.cpp

Issue 2018283002: Add getting the size of a given mipmap level. (Closed) Base URL: https://skia.googlesource.com/skia.git@add-mip-levels-to-deferred-texture-image-data
Patch Set: Right shifting instead of dividing. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkMipMap.h ('k') | tests/MipMapTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkMipMap.h" 8 #include "SkMipMap.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 // TODO: We could build miplevels for kIndex8 if the levels were in 8888. 364 // TODO: We could build miplevels for kIndex8 if the levels were in 8888.
365 // Means using more ram, but the quality would be fine. 365 // Means using more ram, but the quality would be fine.
366 return nullptr; 366 return nullptr;
367 } 367 }
368 368
369 if (src.width() <= 1 && src.height() <= 1) { 369 if (src.width() <= 1 && src.height() <= 1) {
370 return nullptr; 370 return nullptr;
371 } 371 }
372 // whip through our loop to compute the exact size needed 372 // whip through our loop to compute the exact size needed
373 size_t size = 0; 373 size_t size = 0;
374 int countLevels = 0; 374 int countLevels = ComputeLevelCount(src.width(), src.height());
375 { 375 for (int currentMipLevel = countLevels; currentMipLevel > 0; currentMipLevel --) {
376 int width = src.width(); 376 SkSize mipSize = ComputeLevelSize(src.width(), src.height(), currentMipL evel);
377 int height = src.height(); 377 size += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight;
378 for (;;) {
379 width = SkTMax(1, width >> 1);
380 height = SkTMax(1, height >> 1);
381 size += SkColorTypeMinRowBytes(ct, width) * height;
382 countLevels += 1;
383 if (1 == width && 1 == height) {
384 break;
385 }
386 }
387 } 378 }
388 379
389 SkASSERT(countLevels == SkMipMap::ComputeLevelCount(src.width(), src.height( )));
390
391 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); 380 size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size);
392 if (0 == storageSize) { 381 if (0 == storageSize) {
393 return nullptr; 382 return nullptr;
394 } 383 }
395 384
396 SkMipMap* mipmap; 385 SkMipMap* mipmap;
397 if (fact) { 386 if (fact) {
398 SkDiscardableMemory* dm = fact(storageSize); 387 SkDiscardableMemory* dm = fact(storageSize);
399 if (nullptr == dm) { 388 if (nullptr == dm) {
400 return nullptr; 389 return nullptr;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // For example, it contains levels 1-x instead of 0-x. 489 // For example, it contains levels 1-x instead of 0-x.
501 // This is because the image used to create SkMipMap is the base level. 490 // This is because the image used to create SkMipMap is the base level.
502 // So subtract 1 from the mip level count. 491 // So subtract 1 from the mip level count.
503 if (mipLevelCount > 0) { 492 if (mipLevelCount > 0) {
504 --mipLevelCount; 493 --mipLevelCount;
505 } 494 }
506 495
507 return mipLevelCount; 496 return mipLevelCount;
508 } 497 }
509 498
499 SkSize SkMipMap::ComputeLevelSize(int baseWidth, int baseHeight, int level) {
500 if (baseWidth < 1 || baseHeight < 1) {
501 return SkSize::Make(0, 0);
502 }
503
504 int maxLevelCount = ComputeLevelCount(baseWidth, baseHeight);
505 if (level > maxLevelCount || level < 0) {
506 return SkSize::Make(0, 0);
507 }
508 if (level == 0) {
509 return SkSize::Make(baseWidth, baseHeight);
510 }
511
512 // OpenGL's spec requires that each mipmap level have height/width equal to
513 // max(1, floor(original_height / 2^i)
514 // (or original_width) where i is the mipmap level.
515
516 int width = SkTMax(1, baseWidth >> level);
517 int height = SkTMax(1, baseHeight >> level);
518
519 return SkSize::Make(width, height);
520 }
521
510 /////////////////////////////////////////////////////////////////////////////// 522 ///////////////////////////////////////////////////////////////////////////////
511 523
512 bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const { 524 bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const {
513 if (nullptr == fLevels) { 525 if (nullptr == fLevels) {
514 return false; 526 return false;
515 } 527 }
516 528
517 SkASSERT(scaleSize.width() >= 0 && scaleSize.height() >= 0); 529 SkASSERT(scaleSize.width() >= 0 && scaleSize.height() >= 0);
518 530
519 #ifndef SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE 531 #ifndef SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 return false; 592 return false;
581 } 593 }
582 if (index > fCount - 1) { 594 if (index > fCount - 1) {
583 return false; 595 return false;
584 } 596 }
585 if (levelPtr) { 597 if (levelPtr) {
586 *levelPtr = fLevels[index]; 598 *levelPtr = fLevels[index];
587 } 599 }
588 return true; 600 return true;
589 } 601 }
OLDNEW
« no previous file with comments | « src/core/SkMipMap.h ('k') | tests/MipMapTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698