diff options
-rw-r--r-- | gm/showmiplevels.cpp | 25 | ||||
-rw-r--r-- | src/core/SkBitmapController.cpp | 3 | ||||
-rw-r--r-- | src/core/SkMipMap.cpp | 59 | ||||
-rw-r--r-- | src/core/SkMipMap.h | 6 | ||||
-rw-r--r-- | tests/MipMapTest.cpp | 16 |
5 files changed, 45 insertions, 64 deletions
diff --git a/gm/showmiplevels.cpp b/gm/showmiplevels.cpp index 23359f046e..7fc40ce029 100644 --- a/gm/showmiplevels.cpp +++ b/gm/showmiplevels.cpp @@ -151,23 +151,19 @@ protected: SkMipMap::Level level; SkScalar scale = 0.5f; while (mm->extractLevel(scale, &level)) { - SkImageInfo info = SkImageInfo::Make(level.fWidth, level.fHeight, - baseBM.colorType(), baseBM.alphaType()); - SkPixmap levelPM{ info, level.fPixels, level.fRowBytes }; - - SkBitmap bm = func(prevPM, levelPM); + SkBitmap bm = func(prevPM, level.fPixmap); DrawAndFrame(canvas, bm, x, y); - if (info.width() <= 2 || info.height() <= 2) { + if (level.fPixmap.width() <= 2 || level.fPixmap.height() <= 2) { break; } if (index & 1) { - x += info.width() + 4; + x += level.fPixmap.width() + 4; } else { - y += info.height() + 4; + y += level.fPixmap.height() + 4; } scale /= 2; - prevPM = levelPM; + prevPM = level.fPixmap; index += 1; } } @@ -263,20 +259,17 @@ protected: SkMipMap::Level level; SkScalar scale = 0.5f; while (mm->extractLevel(scale, &level)) { - SkImageInfo info = SkImageInfo::Make(level.fWidth, level.fHeight, - baseBM.colorType(), baseBM.alphaType()); - SkBitmap bm; - bm.installPixels(info, level.fPixels, level.fRowBytes); + bm.installPixels(level.fPixmap); DrawAndFrame(canvas, bm, x, y); - if (info.width() <= 2 || info.height() <= 2) { + if (level.fPixmap.width() <= 2 || level.fPixmap.height() <= 2) { break; } if (index & 1) { - x += info.width() + 4; + x += level.fPixmap.width() + 4; } else { - y += info.height() + 4; + y += level.fPixmap.height() + 4; } scale /= 2; index += 1; diff --git a/src/core/SkBitmapController.cpp b/src/core/SkBitmapController.cpp index 7182ea7382..61c14dc7b8 100644 --- a/src/core/SkBitmapController.cpp +++ b/src/core/SkBitmapController.cpp @@ -185,10 +185,9 @@ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider SkScalar invScaleFixup = level.fScale; fInvMatrix.postScale(invScaleFixup, invScaleFixup); - const SkImageInfo info = provider.info().makeWH(level.fWidth, level.fHeight); // todo: if we could wrap the fCurrMip in a pixelref, then we could just install // that here, and not need to explicitly track it ourselves. - return fResultBitmap.installPixels(info, level.fPixels, level.fRowBytes); + return fResultBitmap.installPixels(level.fPixmap); } else { // failed to extract, so release the mipmap fCurrMip.reset(nullptr); diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp index eba50bcb4d..5ea40f4048 100644 --- a/src/core/SkMipMap.cpp +++ b/src/core/SkMipMap.cpp @@ -183,7 +183,7 @@ size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { typedef void SkDownSampleProc(void*, int x, int y, const void* srcPtr, const SkPixmap& srcPM); -SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { +SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) { SkDownSampleProc* proc_nocheck, *proc_check; const SkColorType ct = src.colorType(); @@ -236,16 +236,6 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { return nullptr; } - SkAutoPixmapUnlock srcUnlocker; - if (!src.requestLock(&srcUnlocker)) { - return nullptr; - } - const SkPixmap& srcPixmap = srcUnlocker.pixmap(); - // Try to catch where we might have returned nullptr for src crbug.com/492818 - if (nullptr == srcPixmap.addr()) { - sk_throw(); - } - SkMipMap* mipmap; if (fact) { SkDiscardableMemory* dm = fact(storageSize); @@ -267,17 +257,14 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { int width = src.width(); int height = src.height(); uint32_t rowBytes; - SkPixmap srcPM(srcPixmap); + SkPixmap srcPM(src); for (int i = 0; i < countLevels; ++i) { width >>= 1; height >>= 1; rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); - levels[i].fPixels = addr; - levels[i].fWidth = width; - levels[i].fHeight = height; - levels[i].fRowBytes = rowBytes; + levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); levels[i].fScale = (float)width / src.width(); SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); @@ -487,7 +474,7 @@ size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { return sk_64_asS32(size); } -SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { +SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) { typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count); FilterProc* proc_2_2 = nullptr; @@ -555,16 +542,6 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { return nullptr; } - SkAutoPixmapUnlock srcUnlocker; - if (!src.requestLock(&srcUnlocker)) { - return nullptr; - } - const SkPixmap& srcPixmap = srcUnlocker.pixmap(); - // Try to catch where we might have returned nullptr for src crbug.com/492818 - if (nullptr == srcPixmap.addr()) { - sk_throw(); - } - SkMipMap* mipmap; if (fact) { SkDiscardableMemory* dm = fact(storageSize); @@ -586,7 +563,7 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { int width = src.width(); int height = src.height(); uint32_t rowBytes; - SkPixmap srcPM(srcPixmap); + SkPixmap srcPM(src); for (int i = 0; i < countLevels; ++i) { FilterProc* proc; @@ -607,14 +584,10 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { height >>= 1; rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); - levels[i].fPixels = addr; - levels[i].fWidth = width; - levels[i].fHeight = height; - levels[i].fRowBytes = rowBytes; - levels[i].fScale = (float)width / src.width(); - - SkPixmap dstPM(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); + levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); + levels[i].fScale = (float)width / src.width(); + const SkPixmap& dstPM = levels[i].fPixmap; const void* srcBasePtr = srcPM.addr(); void* dstBasePtr = dstPM.writable_addr(); @@ -666,3 +639,19 @@ bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { } return true; } + +// Helper which extacts a pixmap from the src bitmap +// +SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { + SkAutoPixmapUnlock srcUnlocker; + if (!src.requestLock(&srcUnlocker)) { + return nullptr; + } + const SkPixmap& srcPixmap = srcUnlocker.pixmap(); + // Try to catch where we might have returned nullptr for src crbug.com/492818 + if (nullptr == srcPixmap.addr()) { + sk_throw(); + } + return Build(srcPixmap, fact); +} + diff --git a/src/core/SkMipMap.h b/src/core/SkMipMap.h index 36c17ba91e..b3e958d63c 100644 --- a/src/core/SkMipMap.h +++ b/src/core/SkMipMap.h @@ -9,6 +9,7 @@ #define SkMipMap_DEFINED #include "SkCachedData.h" +#include "SkPixmap.h" #include "SkScalar.h" class SkBitmap; @@ -18,12 +19,11 @@ typedef SkDiscardableMemory* (*SkDiscardableFactoryProc)(size_t bytes); class SkMipMap : public SkCachedData { public: + static SkMipMap* Build(const SkPixmap& src, SkDiscardableFactoryProc); static SkMipMap* Build(const SkBitmap& src, SkDiscardableFactoryProc); struct Level { - void* fPixels; - uint32_t fRowBytes; - uint32_t fWidth, fHeight; + SkPixmap fPixmap; float fScale; // < 1.0 }; diff --git a/tests/MipMapTest.cpp b/tests/MipMapTest.cpp index 5e5e894870..11021e6ebf 100644 --- a/tests/MipMapTest.cpp +++ b/tests/MipMapTest.cpp @@ -39,14 +39,14 @@ DEF_TEST(MipMap, reporter) { SkMipMap::Level level; if (mm->extractLevel(scale, &level)) { - REPORTER_ASSERT(reporter, level.fPixels); - REPORTER_ASSERT(reporter, level.fWidth > 0); - REPORTER_ASSERT(reporter, level.fHeight > 0); - REPORTER_ASSERT(reporter, level.fRowBytes >= level.fWidth * 4); - - if (prevLevel.fPixels) { - REPORTER_ASSERT(reporter, level.fWidth <= prevLevel.fWidth); - REPORTER_ASSERT(reporter, level.fHeight <= prevLevel.fHeight); + REPORTER_ASSERT(reporter, level.fPixmap.addr()); + REPORTER_ASSERT(reporter, level.fPixmap.width() > 0); + REPORTER_ASSERT(reporter, level.fPixmap.height() > 0); + REPORTER_ASSERT(reporter, (int)level.fPixmap.rowBytes() >= level.fPixmap.width() * 4); + + if (prevLevel.fPixmap.addr()) { + REPORTER_ASSERT(reporter, level.fPixmap.width() <= prevLevel.fPixmap.width()); + REPORTER_ASSERT(reporter, level.fPixmap.height() <= prevLevel.fPixmap.height()); } prevLevel = level; } |