SkFlattenable.cpp revision 13649ce32f41774a49760e50083c13c349cb0b5c
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "SkFlattenable.h" 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h" 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h" 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "SkRegion.h" 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkReadMatrix(SkReader32* reader, SkMatrix* matrix) { 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t size = matrix->unflatten(reader->peek()); 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com SkASSERT(SkAlign4(size) == size); 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)reader->skip(size); 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkWriteMatrix(SkWriter32* writer, const SkMatrix& matrix) { 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t size = matrix.flatten(NULL); 157ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org SkASSERT(SkAlign4(size) == size); 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.flatten(writer->reserve(size)); 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkReadRegion(SkReader32* reader, SkRegion* rgn) { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t size = rgn->unflatten(reader->peek()); 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkAlign4(size) == size); 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)reader->skip(size); 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkWriteRegion(SkWriter32* writer, const SkRegion& rgn) { 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t size = rgn.flatten(NULL); 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkAlign4(size) == size); 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rgn.flatten(writer->reserve(size)); 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::flatten(SkFlattenableWriteBuffer&) 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* we don't write anything at the moment, but this allows our subclasses 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to not know that, since we want them to always call INHERITED::flatten() 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com in their code. 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer() { 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCArray = NULL; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCCount = 0; 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFArray = NULL; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFCount = 0; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryTDArray = NULL; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryArray = NULL; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryCount = 0; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) : 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED(data, 1024 * 1024) { 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCArray = NULL; 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCCount = 0; 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFArray = NULL; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFCount = 0; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryTDArray = NULL; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryArray = NULL; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryCount = 0; 67b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com} 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size) 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(data, size) { 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCArray = NULL; 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCCount = 0; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFArray = NULL; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFCount = 0; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryTDArray = NULL; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryArray = NULL; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryCount = 0; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 820da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.comSkTypeface* SkFlattenableReadBuffer::readTypeface() { 830da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com uint32_t index = this->readU32(); 840da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com if (0 == index || index > (unsigned)fTFCount) { 850da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com if (index) { 860da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com SkDebugf("====== typeface index %d\n", index); 870da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com } 880da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com return NULL; 890da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com } else { 900da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com SkASSERT(fTFArray); 910da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com return fTFArray[index - 1]; 920da41dbf5bdf9614a3d2f1d3ebd959221bbac44breed@android.com } 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 941271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com 951271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.comSkRefCnt* SkFlattenableReadBuffer::readRefCnt() { 961271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com uint32_t index = this->readU32(); 971271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com if (0 == index || index > (unsigned)fRCCount) { 98b158a82bc18b5535224e3ca315ee6d80c7ad899breed@google.com return NULL; 991271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com } else { 1001271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com SkASSERT(fRCArray); 1011271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com return fRCArray[index - 1]; 1021271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com } 1031271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com} 1041271d78e8ff4cda0622a24dcec6063b50f6be051reed@google.com 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable* SkFlattenableReadBuffer::readFlattenable() { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable::Factory factory = NULL; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fFactoryCount > 0) { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t index = this->readU32(); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == index) { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; // writer failed to give us the flattenable 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index = -index; // we stored the negative of the index 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index -= 1; // we stored the index-base-1 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < fFactoryCount); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com factory = fFactoryArray[index]; 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (fFactoryTDArray) { 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const int32_t* peek = (const int32_t*)this->peek(); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (*peek <= 0) { 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t index = this->readU32(); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == index) { 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; // writer failed to give us the flattenable 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 124fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com index = -index; // we stored the negative of the index 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index -= 1; // we stored the index-base-1 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com factory = (*fFactoryTDArray)[index]; 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name = this->readString(); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com factory = SkFlattenable::NameToFactory(name); 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (factory) { 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fFactoryTDArray->find(factory) < 0); 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fFactoryTDArray->append() = factory; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// SkDebugf("can't find factory for [%s]\n", name); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we didn't find a factory, that's our failure, not the writer's, 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // so we fall through, so we can skip the sizeRecorded data. 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com factory = (SkFlattenable::Factory)readFunctionPtr(); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == factory) { 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; // writer failed to give us the flattenable 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we get here, factory may still be null, but if that is the case, the 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // failure was ours, not the writer. 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable* obj = NULL; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t sizeRecorded = this->readU32(); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (factory) { 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t offset = this->offset(); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com obj = (*factory)(*this); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check that we read the amount we expected 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t sizeRead = this->offset() - offset; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (sizeRecorded != sizeRead) { 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we could try to fix up the offset... 157ffe39bd3b66eb5090684959e7f2409346ab72d93tomhudson@google.com sk_throw(); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we must skip the remaining data 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->skip(sizeRecorded); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return obj; 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid* SkFlattenableReadBuffer::readFunctionPtr() { 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* proc; 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->read(&proc, sizeof(proc)); 169fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com return proc; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 171fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) : 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED(minSize) { 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFlags = (Flags)0; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCSet = NULL; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFSet = NULL; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactorySet = NULL; 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 182ffe39bd3b66eb5090684959e7f2409346ab72d93tomhudson@google.comSkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSafeUnref(fRCSet); 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSafeUnref(fTFSet); 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSafeUnref(fFactorySet); 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) { 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fRCSet, rec); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec; 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fTFSet, rec); 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fFactorySet, rec); 200ffe39bd3b66eb5090684959e7f2409346ab72d93tomhudson@google.com return rec; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == obj || NULL == fTFSet) { 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(0); 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(fTFSet->add(obj)); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == obj || NULL == fRCSet) { 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(0); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(fRCSet->add(obj)); 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) { 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * If we have a factoryset, then the first 32bits tell us... 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 0: failure to write the flattenable 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * <0: we store the negative of the (1-based) index 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * >0: the length of the name 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * If we don't have a factoryset, then the first "ptr" is either the 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * factory, or null for failure. 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * The distinction is important, since 0-index is 32bits (always), but a 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 0-functionptr might be 32 or 64 bits. 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 231df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com 232af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com SkFlattenable::Factory factory = NULL; 233af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com if (flattenable) { 234af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com factory = flattenable->getFactory(); 235af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com } 236af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com if (NULL == factory) { 237af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com if (fFactorySet) { 238af07d065d19ec387b783b6dfdc3deafd7c614b69epoger@google.com this->write32(0); 239df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com } else { 240df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com this->writeFunctionPtr(NULL); 241df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com } 242df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com return; 243df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com } 244df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com 245df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com /* 246df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * We can write 1 of 3 versions of the flattenable: 247df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * 1. function-ptr : this is the fastest for the reader, but assumes that 248df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * the writer and reader are in the same process. 249df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * 2. index into fFactorySet : This is assumes the writer will later 250df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * resolve the function-ptrs into strings for its reader. SkPicture 251df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * does exactly this, by writing a table of names (matching the indices) 252df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * up front in its serialized form. 253df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * 3. names : Reuse fFactorySet to store indices, but only after we've 254df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * written the name the first time. SkGPipe uses this technique, as it 255df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * doesn't require the reader to be told to know the table of names 256df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com * up front. 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fFactorySet) { 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->inlineFactoryNames()) { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = fFactorySet->find(factory); 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (index) { 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we write the negative of the index, to distinguish it from 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // the length of a string 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(-index); 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name = SkFlattenable::FactoryToName(factory); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == name) { 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(0); 269c51db02181982fbcb8888e2a89132363a7d9371cscroggo return; 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->writeString(name); 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index = fFactorySet->add(factory); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we write the negative of the index, to distinguish it from 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // the length of a string 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(-(int)fFactorySet->add(factory)); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->writeFunctionPtr((void*)factory); 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // make room for the size of the flatttened object 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)this->reserve(sizeof(uint32_t)); 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // record the current size, so we can subtract after the object writes. 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t offset = this->size(); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now flatten the object 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flattenable->flatten(*this); 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t objSize = this->size() - offset; 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // record the obj's size 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *this->peek32(offset - sizeof(uint32_t)) = objSize; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2948433b5db1a0f94cd92d2606817d5374ab899b87areed@android.comvoid SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) { 2958433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com *(void**)this->reserve(sizeof(void*)) = proc; 2968433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com} 2978433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com 2988433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com/////////////////////////////////////////////////////////////////////////////// 2998433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com 3008433b5db1a0f94cd92d2606817d5374ab899b87areed@android.comSkRefCntSet::~SkRefCntSet() { 3018433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com // call this now, while our decPtr() is sill in scope 3028433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com this->reset(); 3038433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com} 3048433b5db1a0f94cd92d2606817d5374ab899b87areed@android.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRefCntSet::incPtr(void* ptr) { 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((SkRefCnt*)ptr)->ref(); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkRefCntSet::decPtr(void* ptr) { 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((SkRefCnt*)ptr)->unref(); 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MAX_PAIR_COUNT 64 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct Pair { 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable::Factory fFactory; 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gCount; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic Pair gPairs[MAX_PAIR_COUNT]; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::Register(const char name[], Factory factory) { 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(name); 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(factory); 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static bool gOnce; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!gOnce) { 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gCount = 0; 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gOnce = true; 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(gCount < MAX_PAIR_COUNT); 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gPairs[gCount].fName = name; 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gPairs[gCount].fFactory = factory; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gCount += 1; 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 343 344SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 345 const Pair* pairs = gPairs; 346 for (int i = gCount - 1; i >= 0; --i) { 347 if (strcmp(pairs[i].fName, name) == 0) { 348 return pairs[i].fFactory; 349 } 350 } 351 return NULL; 352} 353 354const char* SkFlattenable::FactoryToName(Factory fact) { 355 const Pair* pairs = gPairs; 356 for (int i = gCount - 1; i >= 0; --i) { 357 if (pairs[i].fFactory == fact) { 358 return pairs[i].fName; 359 } 360 } 361 return NULL; 362} 363 364bool SkFlattenable::toDumpString(SkString* str) const { 365 return false; 366} 367 368