1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkCachingPixelRef.h" 9#include "SkBitmapCache.h" 10#include "SkRect.h" 11 12bool SkCachingPixelRef::Install(SkImageGenerator* generator, 13 SkBitmap* dst) { 14 SkImageInfo info; 15 SkASSERT(dst != NULL); 16 if ((NULL == generator) 17 || !(generator->getInfo(&info)) 18 || !dst->setInfo(info)) { 19 SkDELETE(generator); 20 return false; 21 } 22 SkAutoTUnref<SkCachingPixelRef> ref(SkNEW_ARGS(SkCachingPixelRef, 23 (info, generator, dst->rowBytes()))); 24 dst->setPixelRef(ref); 25 return true; 26} 27 28SkCachingPixelRef::SkCachingPixelRef(const SkImageInfo& info, 29 SkImageGenerator* generator, 30 size_t rowBytes) 31 : INHERITED(info) 32 , fImageGenerator(generator) 33 , fErrorInDecoding(false) 34 , fRowBytes(rowBytes) { 35 SkASSERT(fImageGenerator != NULL); 36} 37SkCachingPixelRef::~SkCachingPixelRef() { 38 SkDELETE(fImageGenerator); 39 // Assert always unlock before unref. 40} 41 42bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) { 43 if (fErrorInDecoding) { 44 return false; // don't try again. 45 } 46 47 const SkImageInfo& info = this->info(); 48 if (!SkBitmapCache::Find(this->getGenerationID(), 49 SkIRect::MakeWH(info.width(), info.height()), 50 &fLockedBitmap)) { 51 // Cache has been purged, must re-decode. 52 if (!fLockedBitmap.tryAllocPixels(info, fRowBytes)) { 53 fErrorInDecoding = true; 54 return false; 55 } 56 if (!fImageGenerator->getPixels(info, fLockedBitmap.getPixels(), fRowBytes)) { 57 fErrorInDecoding = true; 58 return false; 59 } 60 fLockedBitmap.setImmutable(); 61 SkBitmapCache::Add(this->getGenerationID(), 62 SkIRect::MakeWH(info.width(), info.height()), 63 fLockedBitmap); 64 } 65 66 // Now bitmap should contain a concrete PixelRef of the decoded image. 67 void* pixels = fLockedBitmap.getPixels(); 68 SkASSERT(pixels != NULL); 69 rec->fPixels = pixels; 70 rec->fColorTable = NULL; 71 rec->fRowBytes = fLockedBitmap.rowBytes(); 72 return true; 73} 74 75void SkCachingPixelRef::onUnlockPixels() { 76 fLockedBitmap.reset(); 77} 78