SkFlattenable.cpp revision d26147adbbdca85f07dff432025afee0c8614387
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFlattenable.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com#include "SkMatrix.h" 12f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com#include "SkRegion.h" 13f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com 14f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.comvoid SkReadMatrix(SkReader32* reader, SkMatrix* matrix) { 15f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com size_t size = matrix->unflatten(reader->peek()); 16f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com SkASSERT(SkAlign4(size) == size); 17f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com (void)reader->skip(size); 18f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com} 19f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com 20f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.comvoid SkWriteMatrix(SkWriter32* writer, const SkMatrix& matrix) { 21f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com size_t size = matrix.flatten(NULL); 22f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com SkASSERT(SkAlign4(size) == size); 23f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com matrix.flatten(writer->reserve(size)); 24f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com} 25f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com 26f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.comvoid SkReadRegion(SkReader32* reader, SkRegion* rgn) { 27f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com size_t size = rgn->unflatten(reader->peek()); 28f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com SkASSERT(SkAlign4(size) == size); 29f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com (void)reader->skip(size); 30f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com} 31f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com 32f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.comvoid SkWriteRegion(SkWriter32* writer, const SkRegion& rgn) { 33f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com size_t size = rgn.flatten(NULL); 34f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com SkASSERT(SkAlign4(size) == size); 35f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com rgn.flatten(writer->reserve(size)); 36f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com} 37f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com 38f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com/////////////////////////////////////////////////////////////////////////////// 39f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::flatten(SkFlattenableWriteBuffer&) 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* we don't write anything at the moment, but this allows our subclasses 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to not know that, since we want them to always call INHERITED::flatten() 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com in their code. 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer() { 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCArray = NULL; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCCount = 0; 5482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFArray = NULL; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFCount = 0; 5782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 586bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com fFactoryTDArray = NULL; 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryArray = NULL; 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryCount = 0; 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) : 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED(data, 1024 * 1024) { 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCArray = NULL; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCCount = 0; 6782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFArray = NULL; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFCount = 0; 7082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 716bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com fFactoryTDArray = NULL; 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryArray = NULL; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryCount = 0; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size) 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(data, size) { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCArray = NULL; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRCCount = 0; 8082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFArray = NULL; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTFCount = 0; 8382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 846bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com fFactoryTDArray = NULL; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryArray = NULL; 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFactoryCount = 0; 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface* SkFlattenableReadBuffer::readTypeface() { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t index = this->readU32(); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == index || index > (unsigned)fTFCount) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (index) { 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("====== typeface index %d\n", index); 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fTFArray); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fTFArray[index - 1]; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkRefCnt* SkFlattenableReadBuffer::readRefCnt() { 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t index = this->readU32(); 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == index || index > (unsigned)fRCCount) { 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fRCArray); 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fRCArray[index - 1]; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable* SkFlattenableReadBuffer::readFlattenable() { 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable::Factory factory = NULL; 11482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fFactoryCount > 0) { 1166bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com int32_t index = this->readU32(); 1176bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (0 == index) { 1186bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com return NULL; // writer failed to give us the flattenable 1196bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 1206bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com index = -index; // we stored the negative of the index 1216bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com index -= 1; // we stored the index-base-1 12213649ce32f41774a49760e50083c13c349cb0b5creed@google.com SkASSERT(index < fFactoryCount); 1236bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com factory = fFactoryArray[index]; 1246bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else if (fFactoryTDArray) { 1256bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com const int32_t* peek = (const int32_t*)this->peek(); 1266bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (*peek <= 0) { 1276bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com int32_t index = this->readU32(); 1286bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (0 == index) { 1296bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com return NULL; // writer failed to give us the flattenable 1306bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 1316bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com index = -index; // we stored the negative of the index 1326bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com index -= 1; // we stored the index-base-1 1336bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com factory = (*fFactoryTDArray)[index]; 1346bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else { 1356bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com const char* name = this->readString(); 1366bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com factory = SkFlattenable::NameToFactory(name); 1376bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (factory) { 1386bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com SkASSERT(fFactoryTDArray->find(factory) < 0); 1396bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com *fFactoryTDArray->append() = factory; 1406bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else { 1416bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com// SkDebugf("can't find factory for [%s]\n", name); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1436bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // if we didn't find a factory, that's our failure, not the writer's, 1446bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // so we fall through, so we can skip the sizeRecorded data. 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com factory = (SkFlattenable::Factory)readFunctionPtr(); 1486bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (NULL == factory) { 1496bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com return NULL; // writer failed to give us the flattenable 1506bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1536bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // if we get here, factory may still be null, but if that is the case, the 1546bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // failure was ours, not the writer. 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable* obj = NULL; 1566bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com uint32_t sizeRecorded = this->readU32(); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (factory) { 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t offset = this->offset(); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com obj = (*factory)(*this); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check that we read the amount we expected 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t sizeRead = this->offset() - offset; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (sizeRecorded != sizeRead) { 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we could try to fix up the offset... 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1666bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else { 1676bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // we must skip the remaining data 1686bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com this->skip(sizeRecorded); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return obj; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid* SkFlattenableReadBuffer::readFunctionPtr() { 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* proc; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->read(&proc, sizeof(proc)); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return proc; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) : 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED(minSize) { 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFlags = (Flags)0; 184e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org fRCSet = NULL; 185e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org fTFSet = NULL; 186e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org fFactorySet = NULL; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { 190e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org SkSafeUnref(fRCSet); 191e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org SkSafeUnref(fTFSet); 192e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org SkSafeUnref(fFactorySet); 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 195e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) { 196e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org SkRefCnt_SafeAssign(fRCSet, rec); 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec; 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { 201e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org SkRefCnt_SafeAssign(fTFSet, rec); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec; 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { 206e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org SkRefCnt_SafeAssign(fFactorySet, rec); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec; 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { 211e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org if (NULL == obj || NULL == fTFSet) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(0); 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 214e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org this->write32(fTFSet->add(obj)); 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { 219e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org if (NULL == obj || NULL == fRCSet) { 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->write32(0); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 222e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org this->write32(fRCSet->add(obj)); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) { 2276bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com /* 2286bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * If we have a factoryset, then the first 32bits tell us... 2296bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * 0: failure to write the flattenable 2306bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * <0: we store the negative of the (1-based) index 2316bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * >0: the length of the name 2326bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * If we don't have a factoryset, then the first "ptr" is either the 2336bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * factory, or null for failure. 2346bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * 2356bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * The distinction is important, since 0-index is 32bits (always), but a 2366bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * 0-functionptr might be 32 or 64 bits. 2376bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com */ 2386bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable::Factory factory = NULL; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flattenable) { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com factory = flattenable->getFactory(); 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2436bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (NULL == factory) { 2446bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (fFactorySet) { 2456bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com this->write32(0); 2466bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else { 2476bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com this->writeFunctionPtr(NULL); 2486bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 2496bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com return; 2506bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2526bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com /* 2536bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * We can write 1 of 3 versions of the flattenable: 2546bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * 1. function-ptr : this is the fastest for the reader, but assumes that 2556bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * the writer and reader are in the same process. 2566bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * 2. index into fFactorySet : This is assumes the writer will later 2576bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * resolve the function-ptrs into strings for its reader. SkPicture 2586bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * does exactly this, by writing a table of names (matching the indices) 2596bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * up front in its serialized form. 2606bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * 3. names : Reuse fFactorySet to store indices, but only after we've 2616bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * written the name the first time. SkGPipe uses this technique, as it 2626bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * doesn't require the reader to be told to know the table of names 2636bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com * up front. 2646bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com */ 265e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org if (fFactorySet) { 2666bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (this->inlineFactoryNames()) { 2676bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com int index = fFactorySet->find(factory); 2686bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (index) { 2696bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // we write the negative of the index, to distinguish it from 2706bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // the length of a string 2716bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com this->write32(-index); 2726bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else { 2736bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com const char* name = SkFlattenable::FactoryToName(factory); 2746bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (NULL == name) { 2756bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com this->write32(0); 2766bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com return; 2776bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 2786bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com this->writeString(name); 2796bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com index = fFactorySet->add(factory); 2806bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 2816bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } else { 2826bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // we write the negative of the index, to distinguish it from 2836bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // the length of a string 28413649ce32f41774a49760e50083c13c349cb0b5creed@google.com this->write32(-(int)fFactorySet->add(factory)); 2856bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->writeFunctionPtr((void*)factory); 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2906bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // make room for the size of the flatttened object 2916bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com (void)this->reserve(sizeof(uint32_t)); 2926bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // record the current size, so we can subtract after the object writes. 2936bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com uint32_t offset = this->size(); 2946bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // now flatten the object 2956bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com flattenable->flatten(*this); 2966bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com uint32_t objSize = this->size() - offset; 2976bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // record the obj's size 2986bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com *this->peek32(offset - sizeof(uint32_t)) = objSize; 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) { 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(void**)this->reserve(sizeof(void*)) = proc; 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 307e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet::~SkRefCntSet() { 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // call this now, while our decPtr() is sill in scope 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->reset(); 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 312e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgvoid SkRefCntSet::incPtr(void* ptr) { 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((SkRefCnt*)ptr)->ref(); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 316e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgvoid SkRefCntSet::decPtr(void* ptr) { 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((SkRefCnt*)ptr)->unref(); 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MAX_PAIR_COUNT 64 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct Pair { 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFlattenable::Factory fFactory; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gCount; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic Pair gPairs[MAX_PAIR_COUNT]; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::Register(const char name[], Factory factory) { 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(name); 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(factory); 33782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static bool gOnce; 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!gOnce) { 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gCount = 0; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gOnce = true; 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 34382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(gCount < MAX_PAIR_COUNT); 34582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gPairs[gCount].fName = name; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gPairs[gCount].fFactory = factory; 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gCount += 1; 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 351d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 352d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comstatic void report_no_entries(const char* functionName) { 353d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com if (!gCount) { 354d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com SkDebugf("%s has no registered name/factory pairs." 355d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com " Call SkGraphics::InitializeGlobals() at process initialization" 356d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com " time.", functionName); 357d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com } 358d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com} 359d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif 360d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 362d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 363d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com report_no_entries(__FUNCTION__); 364d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Pair* pairs = gPairs; 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = gCount - 1; i >= 0; --i) { 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (strcmp(pairs[i].fName, name) == 0) { 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return pairs[i].fFactory; 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkFlattenable::FactoryToName(Factory fact) { 375d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG) 376d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com report_no_entries(__FUNCTION__); 377d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Pair* pairs = gPairs; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = gCount - 1; i >= 0; --i) { 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pairs[i].fFactory == fact) { 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return pairs[i].fName; 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkFlattenable::toDumpString(SkString* str) const { 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 390