SkFlattenable.cpp revision 34342f6f5127122ecc32166dcffa7f3d2a45c387
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SkFlattenable.h"
9#include "SkTypeface.h"
10
11SK_DEFINE_INST_COUNT(SkFlattenable)
12
13///////////////////////////////////////////////////////////////////////////////
14
15void SkFlattenable::flatten(SkFlattenableWriteBuffer&) const
16{
17    /*  we don't write anything at the moment, but this allows our subclasses
18        to not know that, since we want them to always call INHERITED::flatten()
19        in their code.
20    */
21}
22
23///////////////////////////////////////////////////////////////////////////////
24
25SkFlattenableReadBuffer::SkFlattenableReadBuffer() {
26    fRCArray = NULL;
27    fRCCount = 0;
28
29    fTFArray = NULL;
30    fTFCount = 0;
31
32    fFactoryTDArray = NULL;
33    fFactoryArray = NULL;
34    fFactoryCount = 0;
35
36    // Set default values. These should be explicitly set by our client
37    // via setFlags() if the buffer came from serialization.
38    fFlags = 0;
39#ifdef SK_SCALAR_IS_FLOAT
40    fFlags |= kScalarIsFloat_Flag;
41#endif
42    if (8 == sizeof(void*)) {
43        fFlags |= kPtrIs64Bit_Flag;
44    }
45}
46
47///////////////////////////////////////////////////////////////////////////////
48
49SkFlattenableWriteBuffer::SkFlattenableWriteBuffer() {
50    fFlags = (Flags)0;
51    fRCSet = NULL;
52    fTFSet = NULL;
53    fFactorySet = NULL;
54}
55
56SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() {
57    SkSafeUnref(fRCSet);
58    SkSafeUnref(fTFSet);
59    SkSafeUnref(fFactorySet);
60}
61
62SkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) {
63    SkRefCnt_SafeAssign(fRCSet, rec);
64    return rec;
65}
66
67SkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
68    SkRefCnt_SafeAssign(fTFSet, rec);
69    return rec;
70}
71
72SkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
73    SkRefCnt_SafeAssign(fFactorySet, rec);
74    return rec;
75}
76
77void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
78    SkASSERT(!isCrossProcess());
79    if (NULL == obj || NULL == fRCSet) {
80        this->write32(0);
81    } else {
82        this->write32(fRCSet->add(obj));
83    }
84}
85
86void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
87    if (NULL == obj || NULL == fTFSet) {
88        this->write32(0);
89    } else {
90        this->write32(fTFSet->add(obj));
91    }
92}
93
94///////////////////////////////////////////////////////////////////////////////
95
96SkRefCntSet::~SkRefCntSet() {
97    // call this now, while our decPtr() is sill in scope
98    this->reset();
99}
100
101void SkRefCntSet::incPtr(void* ptr) {
102    ((SkRefCnt*)ptr)->ref();
103}
104
105void SkRefCntSet::decPtr(void* ptr) {
106    ((SkRefCnt*)ptr)->unref();
107}
108
109///////////////////////////////////////////////////////////////////////////////
110///////////////////////////////////////////////////////////////////////////////
111///////////////////////////////////////////////////////////////////////////////
112
113#define MAX_PAIR_COUNT  64
114
115struct Pair {
116    const char*             fName;
117    SkFlattenable::Factory  fFactory;
118};
119
120static int gCount;
121static Pair gPairs[MAX_PAIR_COUNT];
122
123void SkFlattenable::Register(const char name[], Factory factory) {
124    SkASSERT(name);
125    SkASSERT(factory);
126
127    static bool gOnce;
128    if (!gOnce) {
129        gCount = 0;
130        gOnce = true;
131    }
132
133    SkASSERT(gCount < MAX_PAIR_COUNT);
134
135    gPairs[gCount].fName = name;
136    gPairs[gCount].fFactory = factory;
137    gCount += 1;
138}
139
140#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
141static void report_no_entries(const char* functionName) {
142    if (!gCount) {
143        SkDebugf("%s has no registered name/factory pairs."
144                 " Call SkGraphics::Init() at process initialization time.",
145                 functionName);
146    }
147}
148#endif
149
150SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
151#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
152    report_no_entries(__FUNCTION__);
153#endif
154    const Pair* pairs = gPairs;
155    for (int i = gCount - 1; i >= 0; --i) {
156        if (strcmp(pairs[i].fName, name) == 0) {
157            return pairs[i].fFactory;
158        }
159    }
160    return NULL;
161}
162
163const char* SkFlattenable::FactoryToName(Factory fact) {
164#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
165    report_no_entries(__FUNCTION__);
166#endif
167    const Pair* pairs = gPairs;
168    for (int i = gCount - 1; i >= 0; --i) {
169        if (pairs[i].fFactory == fact) {
170            return pairs[i].fName;
171        }
172    }
173    return NULL;
174}
175