/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkPictureFlat.h" #include "SkChecksum.h" #include "SkColorFilter.h" #include "SkDrawLooper.h" #include "SkMaskFilter.h" #include "SkRasterizer.h" #include "SkShader.h" #include "SkTypeface.h" #include "SkXfermode.h" SK_DEFINE_INST_COUNT(SkFlatController) /////////////////////////////////////////////////////////////////////////////// SkTypefacePlayback::SkTypefacePlayback() : fCount(0), fArray(NULL) {} SkTypefacePlayback::~SkTypefacePlayback() { this->reset(NULL); } void SkTypefacePlayback::reset(const SkRefCntSet* rec) { for (int i = 0; i < fCount; i++) { SkASSERT(fArray[i]); fArray[i]->unref(); } SkDELETE_ARRAY(fArray); if (rec!= NULL && rec->count() > 0) { fCount = rec->count(); fArray = SkNEW_ARRAY(SkRefCnt*, fCount); rec->copyToArray(fArray); for (int i = 0; i < fCount; i++) { fArray[i]->ref(); } } else { fCount = 0; fArray = NULL; } } void SkTypefacePlayback::setCount(int count) { this->reset(NULL); fCount = count; fArray = SkNEW_ARRAY(SkRefCnt*, count); sk_bzero(fArray, count * sizeof(SkRefCnt*)); } SkRefCnt* SkTypefacePlayback::set(int index, SkRefCnt* obj) { SkASSERT((unsigned)index < (unsigned)fCount); SkRefCnt_SafeAssign(fArray[index], obj); return obj; } /////////////////////////////////////////////////////////////////////////////// SkFlatController::SkFlatController() : fBitmapHeap(NULL) , fTypefaceSet(NULL) , fTypefacePlayback(NULL) , fFactorySet(NULL) , fWriteBufferFlags(0) {} SkFlatController::~SkFlatController() { SkSafeUnref(fBitmapHeap); SkSafeUnref(fTypefaceSet); SkSafeUnref(fFactorySet); } void SkFlatController::setBitmapHeap(SkBitmapHeap* heap) { SkRefCnt_SafeAssign(fBitmapHeap, heap); } void SkFlatController::setTypefaceSet(SkRefCntSet *set) { SkRefCnt_SafeAssign(fTypefaceSet, set); } void SkFlatController::setTypefacePlayback(SkTypefacePlayback* playback) { fTypefacePlayback = playback; } SkNamedFactorySet* SkFlatController::setNamedFactorySet(SkNamedFactorySet* set) { SkRefCnt_SafeAssign(fFactorySet, set); return set; } /////////////////////////////////////////////////////////////////////////////// void SkFlatData::stampHeaderAndSentinel(int index, int32_t size) { fIndex = index; fFlatSize = size; fChecksum = SkChecksum::Compute(this->data32(), size); this->setTopBotUnwritten(); this->setSentinelAsCandidate(); } SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj, int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*)) { // a buffer of 256 bytes should be sufficient for most paints, regions, // and matrices. intptr_t storage[256]; SkOrderedWriteBuffer buffer(256, storage, sizeof(storage)); buffer.setBitmapHeap(controller->getBitmapHeap()); buffer.setTypefaceRecorder(controller->getTypefaceSet()); buffer.setNamedFactoryRecorder(controller->getNamedFactorySet()); buffer.setFlags(controller->getWriteBufferFlags()); flattenProc(buffer, obj); uint32_t size = buffer.size(); SkASSERT(SkIsAlign4(size)); /** * Allocate enough memory to hold * 1. SkFlatData struct * 2. flattenProc's data (4-byte aligned) * 3. 4-byte sentinel */ size_t allocSize = sizeof(SkFlatData) + size + sizeof(uint32_t); SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize); // put the serialized contents into the data section of the new allocation buffer.writeToMemory(result->data()); result->stampHeaderAndSentinel(index, size); return result; } void SkFlatData::unflatten(void* result, void (*unflattenProc)(SkOrderedReadBuffer&, void*), SkBitmapHeap* bitmapHeap, SkTypefacePlayback* facePlayback) const { SkOrderedReadBuffer buffer(this->data(), fFlatSize); if (bitmapHeap) { buffer.setBitmapStorage(bitmapHeap); } if (facePlayback) { facePlayback->setupBuffer(buffer); } unflattenProc(buffer, result); SkASSERT(fFlatSize == (int32_t)buffer.offset()); }