180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 7910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImageRef_ashmem.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImageDecoder.h" 10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkFlattenableBuffers.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkThread.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "android/ashmem.h" 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <sys/mman.h> 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <unistd.h> 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//#define TRACE_ASH_PURGE // just trace purges 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef DUMP_IMAGEREF_LIFECYCLE 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define DUMP_ASHMEM_LIFECYCLE 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// #define DUMP_ASHMEM_LIFECYCLE 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// ashmem likes lengths on page boundaries 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic size_t roundToPageSize(size_t size) { 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const size_t mask = getpagesize() - 1; 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t newsize = (size + mask) & ~mask; 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkDebugf("---- oldsize %d newsize %d\n", size, newsize); 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return newsize; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34910f694aefb0b671dd8522a9afe9b6be645701c1Derek SollenbergerSkImageRef_ashmem::SkImageRef_ashmem(const SkImageInfo& info, 35910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger SkStreamRewindable* stream, 36910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger int sampleSize) 37910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger : SkImageRef(info, stream, sampleSize) 38910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger{ 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fFD = -1; 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fAddr = NULL; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fSize = 0; 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fPinned = false; 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCT = NULL; 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkImageRef_ashmem::~SkImageRef_ashmem() { 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSafeUnref(fCT); 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->closeFD(); 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageRef_ashmem::closeFD() { 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (-1 != fRec.fFD) { 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef DUMP_ASHMEM_LIFECYCLE 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("=== ashmem close %d\n", fRec.fFD); 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fRec.fAddr); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fRec.fSize); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru munmap(fRec.fAddr, fRec.fSize); 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru close(fRec.fFD); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fFD = -1; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass AshmemAllocator : public SkBitmap::Allocator { 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AshmemAllocator(SkAshmemRec* rec, const char name[]) 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fRec(rec), fName(name) {} 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) { 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const size_t size = roundToPageSize(bm->getSize()); 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fd = fRec->fFD; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* addr = fRec->fAddr; 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!fRec->fPinned); 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (-1 == fd) { 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL == addr); 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0 == fRec->fSize); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fd = ashmem_create_region(fName, size); 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef DUMP_ASHMEM_LIFECYCLE 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("=== ashmem_create_region %s size=%d fd=%d\n", fName, size, fd); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (-1 == fd) { 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("------- imageref_ashmem create failed <%s> %d\n", 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fName, size); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (err) { 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n", 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fd, err); 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru close(fd); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (-1 == (long)addr) { 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n", 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size); 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru close(fd); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec->fFD = fd; 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec->fAddr = addr; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec->fSize = size; 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(addr); 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(size == fRec->fSize); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (void)ashmem_pin_region(fd, 0, 0); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bm->setPixels(addr, ct); 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec->fPinned = true; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we just point to our caller's memory, these are not copies 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAshmemRec* fRec; 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* fName; 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkImageRef_ashmem::onDecode(SkImageDecoder* codec, SkStreamRewindable* stream, 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap* bitmap, SkBitmap::Config config, 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkImageDecoder::Mode mode) { 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkImageDecoder::kDecodeBounds_Mode == mode) { 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->INHERITED::onDecode(codec, stream, bitmap, config, mode); 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // Ashmem memory is guaranteed to be initialized to 0. 1380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger codec->setSkipWritingZeroes(true); 1390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AshmemAllocator alloc(&fRec, this->getURI()); 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru codec->setAllocator(&alloc); 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool success = this->INHERITED::onDecode(codec, stream, bitmap, config, 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mode); 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // remove the allocator, since its on the stack 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru codec->setAllocator(NULL); 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (success) { 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // remember the colortable (if any) 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRefCnt_SafeAssign(fCT, bitmap->getColorTable()); 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fRec.fPinned) { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ashmem_unpin_region(fRec.fFD, 0, 0); 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fPinned = false; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->closeFD(); 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid* SkImageRef_ashmem::onLockPixels(SkColorTable** ct) { 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fBitmap.getPixels() == NULL); 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fBitmap.getColorTable() == NULL); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // fast case: check if we can just pin and get the cached data 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (-1 != fRec.fFD) { 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fRec.fAddr); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!fRec.fPinned); 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int pin = ashmem_pin_region(fRec.fFD, 0, 0); 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (ASHMEM_NOT_PURGED == pin) { // yea, fast case! 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fBitmap.setPixels(fRec.fAddr, fCT); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fPinned = true; 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (ASHMEM_WAS_PURGED == pin) { 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ashmem_unpin_region(fRec.fFD, 0, 0); 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // let go of our colortable if we lost the pixels. Well get it back 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // again when we re-decode 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fCT) { 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCT->unref(); 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCT = NULL; 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(DUMP_ASHMEM_LIFECYCLE) || defined(TRACE_ASH_PURGE) 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("===== ashmem purged %d\n", fBitmap.getSize()); 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("===== ashmem pin_region(%d) returned %d\n", fRec.fFD, pin); 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // return null result for failure 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (ct) { 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *ct = NULL; 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // no FD, will create an ashmem region in allocator 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->INHERITED::onLockPixels(ct); 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageRef_ashmem::onUnlockPixels() { 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::onUnlockPixels(); 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (-1 != fRec.fFD) { 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fRec.fAddr); 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fRec.fPinned); 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ashmem_unpin_region(fRec.fFD, 0, 0); 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fPinned = false; 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we clear this with or without an error, since we've either closed or 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // unpinned the region 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fBitmap.setPixels(NULL, NULL); 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageRef_ashmem::flatten(SkFlattenableWriteBuffer& buffer) const { 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::flatten(buffer); 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeString(getURI()); 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkImageRef_ashmem::SkImageRef_ashmem(SkFlattenableReadBuffer& buffer) 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : INHERITED(buffer) { 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fFD = -1; 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fAddr = NULL; 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fSize = 0; 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRec.fPinned = false; 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCT = NULL; 2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkString uri; 2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger buffer.readString(&uri); 2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->setURI(uri); 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 234