16ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com/* 26ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com * Copyright 2013 Google Inc. 36ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com * 46ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com * Use of this source code is governed by a BSD-style license that can be 56ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com * found in the LICENSE file. 66ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com */ 76ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com 86ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com#include "SkDiscardablePixelRef.h" 96ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com#include "SkDiscardableMemory.h" 106168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com#include "SkImageGenerator.h" 116ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com 12c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.comSkDiscardablePixelRef::SkDiscardablePixelRef(const SkImageInfo& info, 13c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com SkImageGenerator* generator, 149ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com size_t rowBytes, 159ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com SkDiscardableMemory::Factory* fact) 16c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com : INHERITED(info) 17c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com , fGenerator(generator) 189ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com , fDMFactory(fact) 196ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com , fRowBytes(rowBytes) 20c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com , fDiscardableMemory(NULL) 21c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com{ 226ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkASSERT(fGenerator != NULL); 236ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkASSERT(fRowBytes > 0); 24053509a4127881aa90bd365935125436589c9530commit-bot@chromium.org // The SkImageGenerator contract requires fGenerator to always 25053509a4127881aa90bd365935125436589c9530commit-bot@chromium.org // decode the same image on each call to getPixels(). 26053509a4127881aa90bd365935125436589c9530commit-bot@chromium.org this->setImmutable(); 279ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com SkSafeRef(fDMFactory); 286ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com} 296ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com 306ac702e890656e801469060c1b9474912a5b704ahalcanary@google.comSkDiscardablePixelRef::~SkDiscardablePixelRef() { 31113de4128a2a8cfaf886d7a72ee2be0203b79111reed@google.com if (this->isLocked()) { 32113de4128a2a8cfaf886d7a72ee2be0203b79111reed@google.com fDiscardableMemory->unlock(); 33113de4128a2a8cfaf886d7a72ee2be0203b79111reed@google.com } 349ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com SkDELETE(fDiscardableMemory); 359ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com SkSafeUnref(fDMFactory); 366ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkDELETE(fGenerator); 376ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com} 386ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com 39e406b3ba8294010dfdb8d71eb773f697ffc3cc4arobertphillips@google.comvoid* SkDiscardablePixelRef::onLockPixels(SkColorTable**) { 406ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com if (fDiscardableMemory != NULL) { 416ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com if (fDiscardableMemory->lock()) { 42e406b3ba8294010dfdb8d71eb773f697ffc3cc4arobertphillips@google.com return fDiscardableMemory->data(); 436ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com } 449ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com SkDELETE(fDiscardableMemory); 456ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com fDiscardableMemory = NULL; 466ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com } 47c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com 48c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com const size_t size = this->info().getSafeSize(fRowBytes); 49c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com 509ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com if (fDMFactory != NULL) { 51c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com fDiscardableMemory = fDMFactory->create(size); 529ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com } else { 53c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com fDiscardableMemory = SkDiscardableMemory::Create(size); 549ab9c97883d0a0b7084cbb91eaf1ba6fb4c46affhalcanary@google.com } 556ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com if (NULL == fDiscardableMemory) { 56e406b3ba8294010dfdb8d71eb773f697ffc3cc4arobertphillips@google.com return NULL; // Memory allocation failed. 576ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com } 586ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com void* pixels = fDiscardableMemory->data(); 59c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com if (!fGenerator->getPixels(this->info(), pixels, fRowBytes)) { 60ee2574b16e1cfe10bcab00a78a432a467ecde64areed@google.com fDiscardableMemory->unlock(); 61ee2574b16e1cfe10bcab00a78a432a467ecde64areed@google.com SkDELETE(fDiscardableMemory); 62ee2574b16e1cfe10bcab00a78a432a467ecde64areed@google.com fDiscardableMemory = NULL; 63e406b3ba8294010dfdb8d71eb773f697ffc3cc4arobertphillips@google.com return NULL; 646ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com } 65e406b3ba8294010dfdb8d71eb773f697ffc3cc4arobertphillips@google.com return pixels; 666ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com} 676ac702e890656e801469060c1b9474912a5b704ahalcanary@google.comvoid SkDiscardablePixelRef::onUnlockPixels() { 68ee2574b16e1cfe10bcab00a78a432a467ecde64areed@google.com fDiscardableMemory->unlock(); 696ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com} 706ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com 716168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.combool SkInstallDiscardablePixelRef(SkImageGenerator* generator, 726168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com SkBitmap* dst, 736168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com SkDiscardableMemory::Factory* factory) { 746ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkImageInfo info; 756ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkASSERT(generator != NULL); 766ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com if ((NULL == generator) 776ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com || (!generator->getInfo(&info)) 786168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com || (!dst->setConfig(info, 0))) { 796ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkDELETE(generator); 806ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com return false; 816ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com } 826168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com SkASSERT(dst->config() != SkBitmap::kNo_Config); 836168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com if (dst->empty()) { // Use a normal pixelref. 846168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com SkDELETE(generator); // Do not need this anymore. 856168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com return dst->allocPixels(NULL, NULL); 866168ea7d412448c88169a565f40bf86379d4bf9ahalcanary@google.com } 876ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com SkAutoTUnref<SkDiscardablePixelRef> ref(SkNEW_ARGS(SkDiscardablePixelRef, 88c2062d0e1bd6b258229669463ab5ce7020780c8areed@google.com (info, generator, dst->rowBytes(), factory))); 896ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com dst->setPixelRef(ref); 906ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com return true; 916ac702e890656e801469060c1b9474912a5b704ahalcanary@google.com} 92