diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
commit | ae2c20f398933a9e86c387dcc465ec0f71065ffc (patch) | |
tree | de668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/sgl/SkFlattenable.cpp | |
parent | 09911bf300f1a419907a9412154760efd0b7abc3 (diff) | |
download | chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.zip chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.gz chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.bz2 |
Add skia to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/sgl/SkFlattenable.cpp')
-rw-r--r-- | skia/sgl/SkFlattenable.cpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/skia/sgl/SkFlattenable.cpp b/skia/sgl/SkFlattenable.cpp new file mode 100644 index 0000000..08dd59c --- /dev/null +++ b/skia/sgl/SkFlattenable.cpp @@ -0,0 +1,259 @@ +#include "SkFlattenable.h" +#include "SkTypeface.h" + +void SkFlattenable::flatten(SkFlattenableWriteBuffer&) +{ + /* we don't write anything at the moment, but this allows our subclasses + to not know that, since we want them to always call INHERITED::flatten() + in their code. + */ +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +SkFlattenableReadBuffer::SkFlattenableReadBuffer() { + fRCArray = NULL; + fRCCount = 0; + + fTFArray = NULL; + fTFCount = 0; + + fFactoryArray = NULL; + fFactoryCount = 0; +} + +SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) : + INHERITED(data, 1024 * 1024) { + fRCArray = NULL; + fRCCount = 0; + + fTFArray = NULL; + fTFCount = 0; + + fFactoryArray = NULL; + fFactoryCount = 0; +} + +SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size) + : INHERITED(data, size) { + fRCArray = NULL; + fRCCount = 0; + + fTFArray = NULL; + fTFCount = 0; + + fFactoryArray = NULL; + fFactoryCount = 0; +} + +SkTypeface* SkFlattenableReadBuffer::readTypeface() { + uint32_t index = this->readU32(); + if (0 == index || index > (unsigned)fTFCount) { + if (index) { + SkDebugf("====== typeface index %d\n", index); + } + return NULL; + } else { + SkASSERT(fTFArray); + return fTFArray[index - 1]; + } +} + +SkRefCnt* SkFlattenableReadBuffer::readRefCnt() { + uint32_t index = this->readU32(); + if (0 == index || index > (unsigned)fRCCount) { + return NULL; + } else { + SkASSERT(fRCArray); + return fRCArray[index - 1]; + } +} + +SkFlattenable* SkFlattenableReadBuffer::readFlattenable() { + SkFlattenable::Factory factory = NULL; + + if (fFactoryCount > 0) { + uint32_t index = this->readU32(); + if (index > 0) { + index -= 1; + SkASSERT(index < (unsigned)fFactoryCount); + factory = fFactoryArray[index]; + // if we recorded an index, but failed to get a factory, we need + // to skip the flattened data in the buffer + if (NULL == factory) { + uint32_t size = this->readU32(); + this->skip(size); + // fall through and return NULL for the object + } + } + } else { + factory = (SkFlattenable::Factory)readFunctionPtr(); + } + + SkFlattenable* obj = NULL; + if (factory) { + uint32_t sizeRecorded = this->readU32(); + uint32_t offset = this->offset(); + obj = (*factory)(*this); + // check that we read the amount we expected + uint32_t sizeRead = this->offset() - offset; + if (sizeRecorded != sizeRead) { + // we could try to fix up the offset... + sk_throw(); + } + } + return obj; +} + +void* SkFlattenableReadBuffer::readFunctionPtr() { + void* proc; + this->read(&proc, sizeof(proc)); + return proc; +} + +/////////////////////////////////////////////////////////////////////////////// + +SkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) : + INHERITED(minSize) { + fFlags = (Flags)0; + fRCRecorder = NULL; + fTFRecorder = NULL; + fFactoryRecorder = NULL; +} + +SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { + fRCRecorder->safeUnref(); + fTFRecorder->safeUnref(); + fFactoryRecorder->safeUnref(); +} + +SkRefCntRecorder* SkFlattenableWriteBuffer::setRefCntRecorder( + SkRefCntRecorder* rec) { + SkRefCnt_SafeAssign(fRCRecorder, rec); + return rec; +} + +SkRefCntRecorder* SkFlattenableWriteBuffer::setTypefaceRecorder( + SkRefCntRecorder* rec) { + SkRefCnt_SafeAssign(fTFRecorder, rec); + return rec; +} + +SkFactoryRecorder* SkFlattenableWriteBuffer::setFactoryRecorder( + SkFactoryRecorder* rec) { + SkRefCnt_SafeAssign(fFactoryRecorder, rec); + return rec; +} + +void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { + if (NULL == obj || NULL == fTFRecorder) { + this->write32(0); + } else { + this->write32(fTFRecorder->record(obj)); + } +} + +void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { + if (NULL == obj || NULL == fRCRecorder) { + this->write32(0); + } else { + this->write32(fRCRecorder->record(obj)); + } +} + +void SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) { + SkFlattenable::Factory factory = NULL; + if (flattenable) { + factory = flattenable->getFactory(); + } + + if (fFactoryRecorder) { + this->write32(fFactoryRecorder->record(factory)); + } else { + this->writeFunctionPtr((void*)factory); + } + + if (factory) { + // make room for the size of the flatttened object + (void)this->reserve(sizeof(uint32_t)); + // record the current size, so we can subtract after the object writes. + uint32_t offset = this->size(); + // now flatten the object + flattenable->flatten(*this); + uint32_t objSize = this->size() - offset; + // record the obj's size + *this->peek32(offset - sizeof(uint32_t)) = objSize; + } +} + +void SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) { + *(void**)this->reserve(sizeof(void*)) = proc; +} + +/////////////////////////////////////////////////////////////////////////////// + +SkRefCntRecorder::~SkRefCntRecorder() { + // call this now, while our decPtr() is sill in scope + this->reset(); +} + +void SkRefCntRecorder::incPtr(void* ptr) { + ((SkRefCnt*)ptr)->ref(); +} + +void SkRefCntRecorder::decPtr(void* ptr) { + ((SkRefCnt*)ptr)->unref(); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#define MAX_PAIR_COUNT 64 + +struct Pair { + const char* fName; + SkFlattenable::Factory fFactory; +}; + +static int gCount; +static Pair gPairs[MAX_PAIR_COUNT]; + +void SkFlattenable::Register(const char name[], Factory factory) { + SkASSERT(name); + SkASSERT(factory); + + static bool gOnce; + if (!gOnce) { + gCount = 0; + gOnce = true; + } + + SkASSERT(gCount < MAX_PAIR_COUNT); + + gPairs[gCount].fName = name; + gPairs[gCount].fFactory = factory; + gCount += 1; +} + +SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { + const Pair* pairs = gPairs; + for (int i = gCount - 1; i >= 0; --i) { + if (strcmp(pairs[i].fName, name) == 0) { + return pairs[i].fFactory; + } + } + return NULL; +} + +const char* SkFlattenable::FactoryToName(Factory fact) { + const Pair* pairs = gPairs; + for (int i = gCount - 1; i >= 0; --i) { + if (pairs[i].fFactory == fact) { + return pairs[i].fName; + } + } + return NULL; +} + |