| /* |
| * 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 "SkBitmapCache.h" |
| |
| bool SkCachingPixelRef::Install(SkImageGenerator* generator, |
| SkBitmap* dst) { |
| SkImageInfo info; |
| SkASSERT(dst != NULL); |
| if ((NULL == generator) |
| || !(generator->getInfo(&info)) |
| || !dst->setInfo(info)) { |
| SkDELETE(generator); |
| return false; |
| } |
| SkAutoTUnref<SkCachingPixelRef> ref(SkNEW_ARGS(SkCachingPixelRef, |
| (info, generator, dst->rowBytes()))); |
| dst->setPixelRef(ref); |
| return true; |
| } |
| |
| SkCachingPixelRef::SkCachingPixelRef(const SkImageInfo& info, |
| SkImageGenerator* generator, |
| size_t rowBytes) |
| : INHERITED(info) |
| , fImageGenerator(generator) |
| , fErrorInDecoding(false) |
| , fRowBytes(rowBytes) { |
| SkASSERT(fImageGenerator != NULL); |
| } |
| SkCachingPixelRef::~SkCachingPixelRef() { |
| SkDELETE(fImageGenerator); |
| // Assert always unlock before unref. |
| } |
| |
| bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) { |
| if (fErrorInDecoding) { |
| return false; // don't try again. |
| } |
| |
| const SkImageInfo& info = this->info(); |
| if (!SkBitmapCache::Find(this->getGenerationID(), info.fWidth, info.fHeight, &fLockedBitmap)) { |
| // Cache has been purged, must re-decode. |
| if (!fLockedBitmap.tryAllocPixels(info, fRowBytes)) { |
| fErrorInDecoding = true; |
| return false; |
| } |
| if (!fImageGenerator->getPixels(info, fLockedBitmap.getPixels(), fRowBytes)) { |
| fErrorInDecoding = true; |
| return false; |
| } |
| fLockedBitmap.setImmutable(); |
| SkBitmapCache::Add(this->getGenerationID(), info.fWidth, info.fHeight, fLockedBitmap); |
| } |
| |
| // Now bitmap should contain a concrete PixelRef of the decoded image. |
| void* pixels = fLockedBitmap.getPixels(); |
| SkASSERT(pixels != NULL); |
| rec->fPixels = pixels; |
| rec->fColorTable = NULL; |
| rec->fRowBytes = fLockedBitmap.rowBytes(); |
| return true; |
| } |
| |
| void SkCachingPixelRef::onUnlockPixels() { |
| fLockedBitmap.reset(); |
| } |