/* * 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" /////////////////////////////////////////////////////////////////////////////// SkRefCntPlayback::SkRefCntPlayback() : fCount(0), fArray(NULL) {} SkRefCntPlayback::~SkRefCntPlayback() { this->reset(NULL); } void SkRefCntPlayback::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 SkRefCntPlayback::setCount(int count) { this->reset(NULL); fCount = count; fArray = SkNEW_ARRAY(SkRefCnt*, count); sk_bzero(fArray, count * sizeof(SkRefCnt*)); } SkRefCnt* SkRefCntPlayback::set(int index, SkRefCnt* obj) { SkASSERT((unsigned)index < (unsigned)fCount); SkRefCnt_SafeAssign(fArray[index], obj); return obj; } /////////////////////////////////////////////////////////////////////////////// SkFlatController::SkFlatController() : fPixelRefSet(NULL) , fTypefaceSet(NULL) , fPixelRefPlayback(NULL) , fTypefacePlayback(NULL) , fFactorySet(NULL) {} SkFlatController::~SkFlatController() { SkSafeUnref(fPixelRefSet); SkSafeUnref(fTypefaceSet); SkSafeUnref(fFactorySet); } void SkFlatController::setPixelRefSet(SkRefCntSet *set) { SkRefCnt_SafeAssign(fPixelRefSet, set); } void SkFlatController::setTypefaceSet(SkRefCntSet *set) { SkRefCnt_SafeAssign(fTypefaceSet, set); } void SkFlatController::setPixelRefPlayback(SkRefCntPlayback* playback) { fPixelRefPlayback = playback; } void SkFlatController::setTypefacePlayback(SkTypefacePlayback* playback) { fTypefacePlayback = playback; } SkNamedFactorySet* SkFlatController::setNamedFactorySet(SkNamedFactorySet* set) { SkRefCnt_SafeAssign(fFactorySet, set); return set; } /////////////////////////////////////////////////////////////////////////////// SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj, int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*), uint32_t writeBufferflags) { // 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.setRefCntRecorder(controller->getPixelRefSet()); buffer.setTypefaceRecorder(controller->getTypefaceSet()); buffer.setNamedFactoryRecorder(controller->getNamedFactorySet()); buffer.setFlags(writeBufferflags); 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); result->fIndex = index; result->fFlatSize = size; // put the serialized contents into the data section of the new allocation buffer.writeToMemory(result->data()); result->fChecksum = SkChecksum::Compute(result->data32(), size); result->setSentinelAsCandidate(); return result; } void SkFlatData::unflatten(void* result, void (*unflattenProc)(SkOrderedReadBuffer&, void*), SkRefCntPlayback* refCntPlayback, SkTypefacePlayback* facePlayback) const { SkOrderedReadBuffer buffer(this->data(), fFlatSize); if (refCntPlayback) { refCntPlayback->setupBuffer(buffer); } if (facePlayback) { facePlayback->setupBuffer(buffer); } unflattenProc(buffer, result); SkASSERT(fFlatSize == (int32_t)buffer.offset()); }