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 12 bool SkCachingPixelRef::Install(SkImageGenerator* generator, 13 SkBitmap* dst) { 14 SkASSERT(dst != NULL); 15 if (NULL == generator) { 16 return false; 17 } 18 const SkImageInfo info = generator->getInfo(); 19 if (!dst->setInfo(info)) { 20 SkDELETE(generator); 21 return false; 22 } 23 SkAutoTUnref<SkCachingPixelRef> ref(SkNEW_ARGS(SkCachingPixelRef, 24 (info, generator, dst->rowBytes()))); 25 dst->setPixelRef(ref); 26 return true; 27 } 28 29 SkCachingPixelRef::SkCachingPixelRef(const SkImageInfo& info, 30 SkImageGenerator* generator, 31 size_t rowBytes) 32 : INHERITED(info) 33 , fImageGenerator(generator) 34 , fErrorInDecoding(false) 35 , fRowBytes(rowBytes) { 36 SkASSERT(fImageGenerator != NULL); 37 } 38 SkCachingPixelRef::~SkCachingPixelRef() { 39 SkDELETE(fImageGenerator); 40 // Assert always unlock before unref. 41 } 42 43 bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) { 44 if (fErrorInDecoding) { 45 return false; // don't try again. 46 } 47 48 const SkImageInfo& info = this->info(); 49 if (!SkBitmapCache::Find( 50 this->getGenerationID(), info.bounds(), &fLockedBitmap)) { 51 // Cache has been purged, must re-decode. 52 if (!fLockedBitmap.tryAllocPixels(info, fRowBytes)) { 53 fErrorInDecoding = true; 54 return false; 55 } 56 const SkImageGenerator::Result result = fImageGenerator->getPixels(info, 57 fLockedBitmap.getPixels(), fRowBytes); 58 switch (result) { 59 case SkImageGenerator::kIncompleteInput: 60 case SkImageGenerator::kSuccess: 61 break; 62 default: 63 fErrorInDecoding = true; 64 return false; 65 } 66 fLockedBitmap.setImmutable(); 67 SkBitmapCache::Add(this, info.bounds(), fLockedBitmap); 68 } 69 70 // Now bitmap should contain a concrete PixelRef of the decoded image. 71 void* pixels = fLockedBitmap.getPixels(); 72 SkASSERT(pixels != NULL); 73 rec->fPixels = pixels; 74 rec->fColorTable = NULL; 75 rec->fRowBytes = fLockedBitmap.rowBytes(); 76 return true; 77 } 78 79 void SkCachingPixelRef::onUnlockPixels() { 80 fLockedBitmap.reset(); 81 } 82