Chromium Code Reviews| Index: src/lazy/SkCachingPixelRef.cpp |
| diff --git a/src/lazy/SkCachingPixelRef.cpp b/src/lazy/SkCachingPixelRef.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3b4148dfd83454f662c4f2abf80bf80744d2628d |
| --- /dev/null |
| +++ b/src/lazy/SkCachingPixelRef.cpp |
| @@ -0,0 +1,114 @@ |
| +/* |
| + * Copyright 2013 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "SkCachingPixelRef.h" |
| +#include "SkScaledImageCache.h" |
| + |
| +SkCachingPixelRef::SkCachingPixelRef() |
| + : fErrorInDecoding(false) |
| + , fScaledCacheId(NULL) { |
| + // Please note: a non-NULL cache is not thread-safe. |
|
scroggo
2013/11/04 17:18:03
Obsolete comment.
hal.canary
2013/11/04 18:24:19
Done.
|
| + memset(&fInfo, 0xFF, sizeof(fInfo)); |
| +} |
| +SkCachingPixelRef::~SkCachingPixelRef() { |
| + SkASSERT(NULL == fScaledCacheId); |
| + // Assert always unlock before unref. |
| +} |
| + |
| +bool SkCachingPixelRef::getInfo(SkImageInfo* info) { |
| + if (fErrorInDecoding) { |
| + SkASSERT(fInfo.fWidth < 0); |
| + return false; // Don't try again. |
| + } |
| + if (fInfo.fWidth >= 0) { |
| + *info = fInfo; |
|
scroggo
2013/11/04 17:18:03
Can you assert that info is not NULL?
hal.canary
2013/11/04 18:24:19
Done.
|
| + return true; // already successful |
| + } |
| + SkImageInfo tmp; |
| + if (!this->onDecodeInfo(&tmp)) { |
| + fErrorInDecoding = true; |
| + return false; |
| + } |
| + SkASSERT(tmp.fWidth >= 0); |
| + *info = fInfo = tmp; |
| + return true; |
| +} |
| + |
| +bool SkCachingPixelRef::configure(SkBitmap* bitmap) { |
| + SkImageInfo info; |
| + if (!this->getInfo(&info)) { |
| + return false; |
| + } |
| + return bitmap->setConfig(info, 0); |
| +} |
| + |
| +void* SkCachingPixelRef::onLockPixels(SkColorTable** colorTable) { |
| + (void)colorTable; |
| + SkImageInfo info; |
| + if (!this->getInfo(&info)) { |
| + return NULL; |
| + } |
| + SkBitmap bitmap; |
| + |
| + fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(), |
| + info.fWidth, |
|
scroggo
2013/11/04 17:18:03
It looks like these are tabs? If so, please conver
hal.canary
2013/11/04 18:24:19
Done.
|
| + info.fHeight, |
| + &bitmap); |
| + if (NULL == fScaledCacheId) { |
| + // Cache has been purged, must re-decode. |
| + if (!this->onDecodeInto(0, &bitmap)) { |
| + return NULL; |
| + } |
| + fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(), |
| + info.fWidth, |
| + info.fHeight, |
| + bitmap); |
| + SkASSERT(fScaledCacheId != NULL); |
| + } |
| + // Now bitmap should contain a concrete PixelRef of the decoded |
| + // image. |
| + SkAutoLockPixels autoLockPixels(bitmap); |
| + void* pixels = bitmap.getPixels(); |
| + SkASSERT(NULL != pixels); |
| + // At this point, the autoLockPixels will unlockPixels() |
| + // to remove bitmap's lock on the pixels. We will then |
| + // destroy bitmap. The *only* guarantee that this pointer |
| + // remains valid is the guarantee made by |
| + // SkScaledImageCache that it will not destroy the *other* |
| + // bitmap (SkScaledImageCache::Rec.fBitmap) that holds a |
| + // reference to the concrete PixelRef while this record is |
| + // locked. |
| + return pixels; |
| +} |
| + |
| +void SkCachingPixelRef::onUnlockPixels() { |
| + if (NULL != fScaledCacheId) { |
| + SkScaledImageCache::Unlock( |
| + static_cast<SkScaledImageCache::ID*>(fScaledCacheId)); |
| + fScaledCacheId = NULL; |
| + } |
| +} |
| + |
| +bool SkCachingPixelRef::onDecodeInto(int pow2, SkBitmap* bitmap) { |
| + SkBitmap tmp; |
| + SkImageInfo info; |
| + // TODO(halcanary) - Enable SkCachingPixelRef to use a custom |
| + // allocator. `tmp.allocPixels(fAllocator, NULL)` |
| + if (!(this->getInfo(&info) |
| + && this->configure(&tmp) |
| + && tmp.allocPixels(NULL, NULL))) { |
| + fErrorInDecoding = true; |
| + return false; |
| + } |
| + if (!this->onDecodePixels(info, tmp.getPixels(), tmp.rowBytes())) { |
| + fErrorInDecoding = true; |
| + return false; |
| + } |
| + *bitmap = tmp; |
| + return true; |
| +} |
| + |