summaryrefslogtreecommitdiffstats
path: root/skia/sgl/SkFlattenable.cpp
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
commitae2c20f398933a9e86c387dcc465ec0f71065ffc (patch)
treede668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/sgl/SkFlattenable.cpp
parent09911bf300f1a419907a9412154760efd0b7abc3 (diff)
downloadchromium_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.cpp259
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;
+}
+