SkDiscardablePixelRef.cpp revision 9b06ba4c91484d09565ff4a572d8c5af15dd429e
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 39bool SkDiscardablePixelRef::onNewLockPixels(LockRec* rec) { 40 if (fDiscardableMemory != NULL) { 41 if (fDiscardableMemory->lock()) { 42 rec->fPixels = fDiscardableMemory->data(); 43 rec->fColorTable = NULL; 44 rec->fRowBytes = fRowBytes; 45 return true; 46 } 47 SkDELETE(fDiscardableMemory); 48 fDiscardableMemory = NULL; 49 } 50 51 const size_t size = this->info().getSafeSize(fRowBytes); 52 53 if (fDMFactory != NULL) { 54 fDiscardableMemory = fDMFactory->create(size); 55 } else { 56 fDiscardableMemory = SkDiscardableMemory::Create(size); 57 } 58 if (NULL == fDiscardableMemory) { 59 return false; // Memory allocation failed. 60 } 61 62 void* pixels = fDiscardableMemory->data(); 63 if (!fGenerator->getPixels(this->info(), pixels, fRowBytes)) { 64 fDiscardableMemory->unlock(); 65 SkDELETE(fDiscardableMemory); 66 fDiscardableMemory = NULL; 67 return false; 68 } 69 70 rec->fPixels = pixels; 71 rec->fColorTable = NULL; 72 rec->fRowBytes = fRowBytes; 73 return true; 74} 75 76void SkDiscardablePixelRef::onUnlockPixels() { 77 fDiscardableMemory->unlock(); 78} 79 80bool SkInstallDiscardablePixelRef(SkImageGenerator* generator, 81 SkBitmap* dst, 82 SkDiscardableMemory::Factory* factory) { 83 SkImageInfo info; 84 SkAutoTDelete<SkImageGenerator> autoGenerator(generator); 85 if ((NULL == autoGenerator.get()) 86 || (!autoGenerator->getInfo(&info)) 87 || (!dst->setConfig(info, 0))) { 88 return false; 89 } 90 SkASSERT(dst->config() != SkBitmap::kNo_Config); 91 if (dst->empty()) { // Use a normal pixelref. 92 return dst->allocPixels(NULL, NULL); 93 } 94 SkAutoTUnref<SkDiscardablePixelRef> ref( 95 SkNEW_ARGS(SkDiscardablePixelRef, 96 (info, autoGenerator.detach(), dst->rowBytes(), factory))); 97 dst->setPixelRef(ref); 98 return true; 99} 100