SkFlattenable.cpp revision 0c3e5fe728ce4b8606819ee919a4b82f4d9efc85
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
1115e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.comSK_DEFINE_INST_COUNT(SkFlattenable)
1215e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
13f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com///////////////////////////////////////////////////////////////////////////////
14f2eb5ab7806a62e89b8cb572b1b33b70b83b13abreed@google.com
1554924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkFlattenable::flatten(SkFlattenableWriteBuffer&) const
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /*  we don't write anything at the moment, but this allows our subclasses
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        to not know that, since we want them to always call INHERITED::flatten()
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        in their code.
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableReadBuffer::SkFlattenableReadBuffer() {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCArray = NULL;
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRCCount = 0;
2882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFArray = NULL;
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fTFCount = 0;
3182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
326bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com    fFactoryTDArray = NULL;
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryArray = NULL;
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryCount = 0;
3534342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
3634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    // Set default values. These should be explicitly set by our client
3734342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    // via setFlags() if the buffer came from serialization.
3834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    fFlags = 0;
3934342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com#ifdef SK_SCALAR_IS_FLOAT
4034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    fFlags |= kScalarIsFloat_Flag;
4134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com#endif
4234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    if (8 == sizeof(void*)) {
4334342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        fFlags |= kPtrIs64Bit_Flag;
4434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    }
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
490c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comSkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
500c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
510c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comuint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
520c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    uint32_t index = fFactorySet.find(factory);
530c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (index > 0) {
540c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        return index;
550c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
560c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    const char* name = SkFlattenable::FactoryToName(factory);
570c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (NULL == name) {
580c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        return 0;
590c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
600c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    *fNames.append() = name;
610c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    return fFactorySet.add(factory);
620c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
630c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
640c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comconst char* SkNamedFactorySet::getNextAddedFactoryName() {
650c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (fNextAddedFactory < fNames.count()) {
660c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        return fNames[fNextAddedFactory++];
670c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
680c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    return NULL;
690c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
700c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
710c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com///////////////////////////////////////////////////////////////////////////////
720c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
732b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.comSkFlattenableWriteBuffer::SkFlattenableWriteBuffer() {
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFlags = (Flags)0;
75e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    fRCSet = NULL;
76e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    fTFSet = NULL;
77e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    fFactorySet = NULL;
780c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    fNamedFactorySet = NULL;
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() {
82e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    SkSafeUnref(fRCSet);
83e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    SkSafeUnref(fTFSet);
84e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    SkSafeUnref(fFactorySet);
850c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    SkSafeUnref(fNamedFactorySet);
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) {
89e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    SkRefCnt_SafeAssign(fRCSet, rec);
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return rec;
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
93e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
94e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    SkRefCnt_SafeAssign(fTFSet, rec);
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return rec;
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
98e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
99e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    SkRefCnt_SafeAssign(fFactorySet, rec);
1000c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (fNamedFactorySet != NULL) {
1010c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        fNamedFactorySet->unref();
1020c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        fNamedFactorySet = NULL;
1030c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
1040c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    return rec;
1050c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
1060c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
1070c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comSkNamedFactorySet* SkFlattenableWriteBuffer::setNamedFactoryRecorder(
1080c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        SkNamedFactorySet* rec) {
1090c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    SkRefCnt_SafeAssign(fNamedFactorySet, rec);
1100c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (fFactorySet != NULL) {
1110c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        fFactorySet->unref();
1120c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        fFactorySet = NULL;
1130c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return rec;
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
1182b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    SkASSERT(!isCrossProcess());
119e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    if (NULL == obj || NULL == fRCSet) {
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->write32(0);
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
122e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org        this->write32(fRCSet->add(obj));
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1262b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.comvoid SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
1272b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    if (NULL == obj || NULL == fTFSet) {
1282b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        this->write32(0);
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
1302b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        this->write32(fTFSet->add(obj));
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
136e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgSkRefCntSet::~SkRefCntSet() {
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // call this now, while our decPtr() is sill in scope
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->reset();
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
141e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgvoid SkRefCntSet::incPtr(void* ptr) {
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ((SkRefCnt*)ptr)->ref();
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
145e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.orgvoid SkRefCntSet::decPtr(void* ptr) {
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ((SkRefCnt*)ptr)->unref();
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
153488379e5ac780e8f0a3724b5fcb6e636eefc0303bungeman@google.com#define MAX_PAIR_COUNT  1024
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct Pair {
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const char*             fName;
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory  fFactory;
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int gCount;
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic Pair gPairs[MAX_PAIR_COUNT];
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFlattenable::Register(const char name[], Factory factory) {
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(name);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(factory);
16682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool gOnce;
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!gOnce) {
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gCount = 0;
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gOnce = true;
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(gCount < MAX_PAIR_COUNT);
17482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gPairs[gCount].fName = name;
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gPairs[gCount].fFactory = factory;
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gCount += 1;
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
180d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
181d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comstatic void report_no_entries(const char* functionName) {
182d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    if (!gCount) {
183d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com        SkDebugf("%s has no registered name/factory pairs."
1849245498e40399199ed6d32aa67fe028b634cc582caryclark@google.com                 " Call SkGraphics::Init() at process initialization time.",
1859245498e40399199ed6d32aa67fe028b634cc582caryclark@google.com                 functionName);
186d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    }
187d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com}
188d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif
189d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
191d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
192d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    report_no_entries(__FUNCTION__);
193d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const Pair* pairs = gPairs;
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = gCount - 1; i >= 0; --i) {
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (strcmp(pairs[i].fName, name) == 0) {
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return pairs[i].fFactory;
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkFlattenable::FactoryToName(Factory fact) {
204d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
205d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com    report_no_entries(__FUNCTION__);
206d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com#endif
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const Pair* pairs = gPairs;
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = gCount - 1; i >= 0; --i) {
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (pairs[i].fFactory == fact) {
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return pairs[i].fName;
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
215