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 "SkDiscardablePixelRef.h"
      9 #include "SkDiscardableMemory.h"
     10 #include "SkImageGenerator.h"
     11 
     12 SkDiscardablePixelRef::SkDiscardablePixelRef(const SkImageInfo& info,
     13                                              SkImageGenerator* generator,
     14                                              size_t rowBytes,
     15                                              SkDiscardableMemory::Factory* fact)
     16     : INHERITED(info)
     17     , fGenerator(generator)
     18     , fDMFactory(fact)
     19     , fRowBytes(rowBytes)
     20     , fDiscardableMemory(NULL)
     21 {
     22     SkASSERT(fGenerator != NULL);
     23     SkASSERT(fRowBytes > 0);
     24     // The SkImageGenerator contract requires fGenerator to always
     25     // decode the same image on each call to getPixels().
     26     this->setImmutable();
     27     SkSafeRef(fDMFactory);
     28 }
     29 
     30 SkDiscardablePixelRef::~SkDiscardablePixelRef() {
     31     if (this->isLocked()) {
     32         fDiscardableMemory->unlock();
     33     }
     34     SkDELETE(fDiscardableMemory);
     35     SkSafeUnref(fDMFactory);
     36     SkDELETE(fGenerator);
     37 }
     38 
     39 void* SkDiscardablePixelRef::onLockPixels(SkColorTable**) {
     40     if (fDiscardableMemory != NULL) {
     41         if (fDiscardableMemory->lock()) {
     42             return fDiscardableMemory->data();
     43         }
     44         SkDELETE(fDiscardableMemory);
     45         fDiscardableMemory = NULL;
     46     }
     47 
     48     const size_t size = this->info().getSafeSize(fRowBytes);
     49 
     50     if (fDMFactory != NULL) {
     51         fDiscardableMemory = fDMFactory->create(size);
     52     } else {
     53         fDiscardableMemory = SkDiscardableMemory::Create(size);
     54     }
     55     if (NULL == fDiscardableMemory) {
     56         return NULL;  // Memory allocation failed.
     57     }
     58     void* pixels = fDiscardableMemory->data();
     59     if (!fGenerator->getPixels(this->info(), pixels, fRowBytes)) {
     60         fDiscardableMemory->unlock();
     61         SkDELETE(fDiscardableMemory);
     62         fDiscardableMemory = NULL;
     63         return NULL;
     64     }
     65     return pixels;
     66 }
     67 void SkDiscardablePixelRef::onUnlockPixels() {
     68     fDiscardableMemory->unlock();
     69 }
     70 
     71 bool SkInstallDiscardablePixelRef(SkImageGenerator* generator,
     72                                   SkBitmap* dst,
     73                                   SkDiscardableMemory::Factory* factory) {
     74     SkImageInfo info;
     75     SkASSERT(generator != NULL);
     76     if ((NULL == generator)
     77         || (!generator->getInfo(&info))
     78         || (!dst->setConfig(info, 0))) {
     79         SkDELETE(generator);
     80         return false;
     81     }
     82     SkASSERT(dst->config() != SkBitmap::kNo_Config);
     83     if (dst->empty()) { // Use a normal pixelref.
     84         SkDELETE(generator);  // Do not need this anymore.
     85         return dst->allocPixels(NULL, NULL);
     86     }
     87     SkAutoTUnref<SkDiscardablePixelRef> ref(SkNEW_ARGS(SkDiscardablePixelRef,
     88                                (info, generator, dst->rowBytes(), factory)));
     89     dst->setPixelRef(ref);
     90     return true;
     91 }
     92