SkFlattenable.cpp revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/* 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Copyright 2011 Google Inc. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Use of this source code is governed by a BSD-style license that can be 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * found in the LICENSE file. 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch */ 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "SkFlattenable.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "SkTypeface.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "SkMatrix.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "SkRegion.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkReadMatrix(SkReader32* reader, SkMatrix* matrix) { 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t size = matrix->unflatten(reader->peek()); 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkASSERT(SkAlign4(size) == size); 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (void)reader->skip(size); 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkWriteMatrix(SkWriter32* writer, const SkMatrix& matrix) { 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t size = matrix.flatten(NULL); 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkASSERT(SkAlign4(size) == size); 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch matrix.flatten(writer->reserve(size)); 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkReadRegion(SkReader32* reader, SkRegion* rgn) { 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t size = rgn->unflatten(reader->peek()); 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkASSERT(SkAlign4(size) == size); 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (void)reader->skip(size); 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkWriteRegion(SkWriter32* writer, const SkRegion& rgn) { 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t size = rgn.flatten(NULL); 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkASSERT(SkAlign4(size) == size); 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch rgn.flatten(writer->reserve(size)); 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/////////////////////////////////////////////////////////////////////////////// 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkFlattenable::flatten(SkFlattenableWriteBuffer&) 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch{ 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /* we don't write anything at the moment, but this allows our subclasses 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch to not know that, since we want them to always call INHERITED::flatten() 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch in their code. 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch */ 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/////////////////////////////////////////////////////////////////////////////// 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/////////////////////////////////////////////////////////////////////////////// 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkFlattenableReadBuffer::SkFlattenableReadBuffer() { 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fRCArray = NULL; 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fRCCount = 0; 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fTFArray = NULL; 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fTFCount = 0; 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryTDArray = NULL; 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryArray = NULL; 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryCount = 0; 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) : 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch INHERITED(data, 1024 * 1024) { 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fRCArray = NULL; 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fRCCount = 0; 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fTFArray = NULL; 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fTFCount = 0; 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryTDArray = NULL; 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryArray = NULL; 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryCount = 0; 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size) 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : INHERITED(data, size) { 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) fRCArray = NULL; 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) fRCCount = 0; 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) fTFArray = NULL; 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) fTFCount = 0; 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryTDArray = NULL; 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryArray = NULL; 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactoryCount = 0; 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkTypeface* SkFlattenableReadBuffer::readTypeface() { 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint32_t index = this->readU32(); 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (0 == index || index > (unsigned)fTFCount) { 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (index) { 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkDebugf("====== typeface index %d\n", index); 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkASSERT(fTFArray); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return fTFArray[index - 1]; 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)SkRefCnt* SkFlattenableReadBuffer::readRefCnt() { 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32_t index = this->readU32(); 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (0 == index || index > (unsigned)fRCCount) { 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkASSERT(fRCArray); 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return fRCArray[index - 1]; 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkFlattenable* SkFlattenableReadBuffer::readFlattenable() { 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkFlattenable::Factory factory = NULL; 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (fFactoryCount > 0) { 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int32_t index = this->readU32(); 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (0 == index) { 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return NULL; // writer failed to give us the flattenable 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = -index; // we stored the negative of the index 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index -= 1; // we stored the index-base-1 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkASSERT(index < fFactoryCount); 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) factory = fFactoryArray[index]; 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (fFactoryTDArray) { 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const int32_t* peek = (const int32_t*)this->peek(); 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (*peek <= 0) { 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int32_t index = this->readU32(); 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (0 == index) { 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return NULL; // writer failed to give us the flattenable 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch index = -index; // we stored the negative of the index 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch index -= 1; // we stored the index-base-1 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch factory = (*fFactoryTDArray)[index]; 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const char* name = this->readString(); 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch factory = SkFlattenable::NameToFactory(name); 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (factory) { 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkASSERT(fFactoryTDArray->find(factory) < 0); 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *fFactoryTDArray->append() = factory; 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// SkDebugf("can't find factory for [%s]\n", name); 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // if we didn't find a factory, that's our failure, not the writer's, 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // so we fall through, so we can skip the sizeRecorded data. 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch factory = (SkFlattenable::Factory)readFunctionPtr(); 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (NULL == factory) { 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return NULL; // writer failed to give us the flattenable 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // if we get here, factory may still be null, but if that is the case, the 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // failure was ours, not the writer. 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkFlattenable* obj = NULL; 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint32_t sizeRecorded = this->readU32(); 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (factory) { 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint32_t offset = this->offset(); 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch obj = (*factory)(*this); 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // check that we read the amount we expected 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint32_t sizeRead = this->offset() - offset; 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (sizeRecorded != sizeRead) { 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // we could try to fix up the offset... 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sk_throw(); 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // we must skip the remaining data 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this->skip(sizeRecorded); 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return obj; 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid* SkFlattenableReadBuffer::readFunctionPtr() { 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void* proc; 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->read(&proc, sizeof(proc)); 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return proc; 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/////////////////////////////////////////////////////////////////////////////// 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) : 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch INHERITED(minSize) { 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFlags = (Flags)0; 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fRCSet = NULL; 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fTFSet = NULL; 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fFactorySet = NULL; 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkSafeUnref(fRCSet); 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkSafeUnref(fTFSet); 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkSafeUnref(fFactorySet); 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) { 1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkRefCnt_SafeAssign(fRCSet, rec); 1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return rec; 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkRefCnt_SafeAssign(fTFSet, rec); 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return rec; 2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkRefCnt_SafeAssign(fFactorySet, rec); 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return rec; 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) { 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (NULL == obj || NULL == fTFSet) { 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->write32(0); 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->write32(fTFSet->add(obj)); 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) { 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (NULL == obj || NULL == fRCSet) { 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->write32(0); 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->write32(fRCSet->add(obj)); 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) { 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /* 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * If we have a factoryset, then the first 32bits tell us... 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 0: failure to write the flattenable 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * <0: we store the negative of the (1-based) index 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * >0: the length of the name 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * If we don't have a factoryset, then the first "ptr" is either the 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * factory, or null for failure. 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * The distinction is important, since 0-index is 32bits (always), but a 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 0-functionptr might be 32 or 64 bits. 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch */ 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkFlattenable::Factory factory = NULL; 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (flattenable) { 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch factory = flattenable->getFactory(); 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (NULL == factory) { 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (fFactorySet) { 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->write32(0); 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this->writeFunctionPtr(NULL); 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /* 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * We can write 1 of 3 versions of the flattenable: 254 * 1. function-ptr : this is the fastest for the reader, but assumes that 255 * the writer and reader are in the same process. 256 * 2. index into fFactorySet : This is assumes the writer will later 257 * resolve the function-ptrs into strings for its reader. SkPicture 258 * does exactly this, by writing a table of names (matching the indices) 259 * up front in its serialized form. 260 * 3. names : Reuse fFactorySet to store indices, but only after we've 261 * written the name the first time. SkGPipe uses this technique, as it 262 * doesn't require the reader to be told to know the table of names 263 * up front. 264 */ 265 if (fFactorySet) { 266 if (this->inlineFactoryNames()) { 267 int index = fFactorySet->find(factory); 268 if (index) { 269 // we write the negative of the index, to distinguish it from 270 // the length of a string 271 this->write32(-index); 272 } else { 273 const char* name = SkFlattenable::FactoryToName(factory); 274 if (NULL == name) { 275 this->write32(0); 276 return; 277 } 278 this->writeString(name); 279 index = fFactorySet->add(factory); 280 } 281 } else { 282 // we write the negative of the index, to distinguish it from 283 // the length of a string 284 this->write32(-(int)fFactorySet->add(factory)); 285 } 286 } else { 287 this->writeFunctionPtr((void*)factory); 288 } 289 290 // make room for the size of the flatttened object 291 (void)this->reserve(sizeof(uint32_t)); 292 // record the current size, so we can subtract after the object writes. 293 uint32_t offset = this->size(); 294 // now flatten the object 295 flattenable->flatten(*this); 296 uint32_t objSize = this->size() - offset; 297 // record the obj's size 298 *this->peek32(offset - sizeof(uint32_t)) = objSize; 299} 300 301void SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) { 302 *(void**)this->reserve(sizeof(void*)) = proc; 303} 304 305/////////////////////////////////////////////////////////////////////////////// 306 307SkRefCntSet::~SkRefCntSet() { 308 // call this now, while our decPtr() is sill in scope 309 this->reset(); 310} 311 312void SkRefCntSet::incPtr(void* ptr) { 313 ((SkRefCnt*)ptr)->ref(); 314} 315 316void SkRefCntSet::decPtr(void* ptr) { 317 ((SkRefCnt*)ptr)->unref(); 318} 319 320/////////////////////////////////////////////////////////////////////////////// 321/////////////////////////////////////////////////////////////////////////////// 322/////////////////////////////////////////////////////////////////////////////// 323 324#define MAX_PAIR_COUNT 64 325 326struct Pair { 327 const char* fName; 328 SkFlattenable::Factory fFactory; 329}; 330 331static int gCount; 332static Pair gPairs[MAX_PAIR_COUNT]; 333 334void SkFlattenable::Register(const char name[], Factory factory) { 335 SkASSERT(name); 336 SkASSERT(factory); 337 338 static bool gOnce; 339 if (!gOnce) { 340 gCount = 0; 341 gOnce = true; 342 } 343 344 SkASSERT(gCount < MAX_PAIR_COUNT); 345 346 gPairs[gCount].fName = name; 347 gPairs[gCount].fFactory = factory; 348 gCount += 1; 349} 350 351SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { 352 const Pair* pairs = gPairs; 353 for (int i = gCount - 1; i >= 0; --i) { 354 if (strcmp(pairs[i].fName, name) == 0) { 355 return pairs[i].fFactory; 356 } 357 } 358 return NULL; 359} 360 361const char* SkFlattenable::FactoryToName(Factory fact) { 362 const Pair* pairs = gPairs; 363 for (int i = gCount - 1; i >= 0; --i) { 364 if (pairs[i].fFactory == fact) { 365 return pairs[i].fName; 366 } 367 } 368 return NULL; 369} 370 371bool SkFlattenable::toDumpString(SkString* str) const { 372 return false; 373} 374 375