SkDiscardablePixelRef.cpp revision 27f890219b09e4774da75e6a11ec82849eadae5a
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 12SkDiscardablePixelRef::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 30SkDiscardablePixelRef::~SkDiscardablePixelRef() { 31 if (this->isLocked()) { 32 fDiscardableMemory->unlock(); 33 } 34 SkDELETE(fDiscardableMemory); 35 SkSafeUnref(fDMFactory); 36 SkDELETE(fGenerator); 37} 38 39void* 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} 67void SkDiscardablePixelRef::onUnlockPixels() { 68 fDiscardableMemory->unlock(); 69} 70 71bool SkInstallDiscardablePixelRef(SkImageGenerator* generator, 72 SkBitmap* dst, 73 SkDiscardableMemory::Factory* factory) { 74 SkImageInfo info; 75 SkAutoTDelete<SkImageGenerator> autoGenerator(generator); 76 if ((NULL == autoGenerator.get()) 77 || (!autoGenerator->getInfo(&info)) 78 || (!dst->setConfig(info, 0))) { 79 return false; 80 } 81 SkASSERT(dst->config() != SkBitmap::kNo_Config); 82 if (dst->empty()) { // Use a normal pixelref. 83 return dst->allocPixels(NULL, NULL); 84 } 85 SkAutoTUnref<SkDiscardablePixelRef> ref( 86 SkNEW_ARGS(SkDiscardablePixelRef, 87 (info, autoGenerator.detach(), dst->rowBytes(), factory))); 88 dst->setPixelRef(ref); 89 return true; 90} 91