Home | History | Annotate | Download | only in lazy
      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