Index: src/core/SkImageGenerator.cpp |
diff --git a/src/core/SkImageGenerator.cpp b/src/core/SkImageGenerator.cpp |
index 6fe9f84a08821b8e78fc714e1045b7b264818baf..187b46047af7e403feb2577940d15f0ea83a286f 100644 |
--- a/src/core/SkImageGenerator.cpp |
+++ b/src/core/SkImageGenerator.cpp |
@@ -128,41 +128,75 @@ bool SkImageGenerator::onGetPixels(const SkImageInfo& info, void* dst, size_t rb |
#include "SkBitmap.h" |
#include "SkColorTable.h" |
-static void release_malloc_proc(void* pixels, void* ctx) { |
- sk_free(pixels); |
+static bool reset_and_return_false(SkBitmap* bitmap) { |
+ bitmap->reset(); |
+ return false; |
} |
-bool SkImageGenerator::tryGenerateBitmap(SkBitmap* bitmap, const SkImageInfo* infoPtr) { |
- const SkImageInfo info = infoPtr ? *infoPtr : this->getInfo(); |
- const size_t rowBytes = info.minRowBytes(); |
- const size_t pixelSize = info.getSafeSize(rowBytes); |
- if (0 == pixelSize) { |
+bool SkImageGenerator::tryGenerateBitmap(SkBitmap* bitmap, const SkImageInfo* infoPtr, |
+ SkBitmap::Allocator* allocator) { |
+ SkImageInfo info = infoPtr ? *infoPtr : this->getInfo(); |
+ if (0 == info.getSafeSize(info.minRowBytes())) { |
return false; |
} |
- |
- SkAutoFree pixelStorage(sk_malloc_flags(pixelSize, 0)); |
- void* pixels = pixelStorage.get(); |
- if (!pixels) { |
- return false; |
+ if (!bitmap->setInfo(info)) { |
+ return reset_and_return_false(bitmap); |
} |
- |
+ |
SkPMColor ctStorage[256]; |
+ memset(ctStorage, 0xFF, sizeof(ctStorage)); // init with opaque-white for the moment |
+ SkAutoTUnref<SkColorTable> ctable(new SkColorTable(ctStorage, 256)); |
+ if (!bitmap->tryAllocPixels(allocator, ctable)) { |
+ // SkResourceCache's custom allcator can'thandle ctables, so it may fail on |
+ // kIndex_8_SkColorTable. |
+ // skbug.com/4355 |
+#if 1 |
+ // ignroe the allocator, and see if we can succeed without it |
+ if (!bitmap->tryAllocPixels(nullptr, ctable)) { |
+ return reset_and_return_false(bitmap); |
+ } |
+#else |
+ // this is the up-scale technique, not fully debugged, but we keep it here at the moment |
+ // to remind ourselves that this might be better than ignoring the allocator. |
+ |
+ info = SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType()); |
+ if (!bitmap->setInfo(info)) { |
+ return reset_and_return_false(bitmap); |
+ } |
+ // we pass nullptr for the ctable arg, since we are now explicitly N32 |
+ if (!bitmap->tryAllocPixels(allocator, nullptr)) { |
+ return reset_and_return_false(bitmap); |
+ } |
+#endif |
+ } |
+ |
+ bitmap->lockPixels(); |
+ if (!bitmap->getPixels()) { |
+ return reset_and_return_false(bitmap); |
+ } |
+ |
int ctCount = 0; |
- |
- if (!this->getPixels(info, pixels, rowBytes, ctStorage, &ctCount)) { |
- return false; |
+ if (!this->getPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), |
+ ctStorage, &ctCount)) { |
+ return reset_and_return_false(bitmap); |
} |
- |
- SkAutoTUnref<SkColorTable> ctable; |
+ |
if (ctCount > 0) { |
- SkASSERT(kIndex_8_SkColorType == info.colorType()); |
- ctable.reset(new SkColorTable(ctStorage, ctCount)); |
+ SkASSERT(kIndex_8_SkColorType == bitmap->colorType()); |
+ // we and bitmap should be owners |
+ SkASSERT(!ctable->unique()); |
+ |
+ // Now we need to overwrite the ctable we built earlier, with the correct colors. |
+ // This does mean that we may have made the table too big, but that cannot be avoided |
+ // until we can change SkImageGenerator's API to return us the ctable *before* we have to |
+ // allocate space for all the pixels. |
+ ctable->dangerous_overwriteColors(ctStorage, ctCount); |
} else { |
- SkASSERT(kIndex_8_SkColorType != info.colorType()); |
+ SkASSERT(kIndex_8_SkColorType != bitmap->colorType()); |
+ // we should be the only owner |
+ SkASSERT(ctable->unique()); |
} |
- |
- return bitmap->installPixels(info, pixelStorage.detach(), rowBytes, ctable, |
- release_malloc_proc, nullptr); |
+ return true; |
} |
#include "SkGraphics.h" |