SkFlattenable.cpp revision 0c3e5fe728ce4b8606819ee919a4b82f4d9efc85
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
49SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
50
51uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
52    uint32_t index = fFactorySet.find(factory);
53    if (index > 0) {
54        return index;
55    }
56    const char* name = SkFlattenable::FactoryToName(factory);
57    if (NULL == name) {
58        return 0;
59    }
60    *fNames.append() = name;
61    return fFactorySet.add(factory);
62}
63
64const char* SkNamedFactorySet::getNextAddedFactoryName() {
65    if (fNextAddedFactory < fNames.count()) {
66        return fNames[fNextAddedFactory++];
67    }
68    return NULL;
69}
70
71///////////////////////////////////////////////////////////////////////////////
72
73SkFlattenableWriteBuffer::SkFlattenableWriteBuffer() {
74    fFlags = (Flags)0;
75    fRCSet = NULL;
76    fTFSet = NULL;
77    fFactorySet = NULL;
78    fNamedFactorySet = NULL;
79}
80
81SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() {
82    SkSafeUnref(fRCSet);
83    SkSafeUnref(fTFSet);
84    SkSafeUnref(fFactorySet);
85    SkSafeUnref(fNamedFactorySet);
86}
87
88SkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) {
89    SkRefCnt_SafeAssign(fRCSet, rec);
90    return rec;
91}
92
93SkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
94    SkRefCnt_SafeAssign(fTFSet, rec);
95    return rec;
96}
97
98SkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
99    SkRefCnt_SafeAssign(fFactorySet, rec);
100    if (fNamedFactorySet != NULL) {
101        fNamedFactorySet->unref();
102        fNamedFactorySet = NULL;
103    }
104    return rec;
105}
106
107SkNamedFactorySet* SkFlattenableWriteBuffer::setNamedFactoryRecorder(
108        SkNamedFactorySet* rec) {
109    SkRefCnt_SafeAssign(fNamedFactorySet, rec);
110    if (fFactorySet != NULL) {
111        fFactorySet->unref();
112        fFactorySet = NULL;
113    }
114    return rec;
115}
116
117void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
118    SkASSERT(!isCrossProcess());
119    if (NULL == obj || NULL == fRCSet) {
120        this->write32(0);
121    } else {
122        this->write32(fRCSet->add(obj));
123    }
124}
125
126void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
127    if (NULL == obj || NULL == fTFSet) {
128        this->write32(0);
129    } else {
130        this->write32(fTFSet->add(obj));
131    }
132}
133
134///////////////////////////////////////////////////////////////////////////////
135
136SkRefCntSet::~SkRefCntSet() {
137    // call this now, while our decPtr() is sill in scope
138    this->reset();
139}
140
141void SkRefCntSet::incPtr(void* ptr) {
142    ((SkRefCnt*)ptr)->ref();
143}
144
145void SkRefCntSet::decPtr(void* ptr) {
146    ((SkRefCnt*)ptr)->unref();
147}
148
149///////////////////////////////////////////////////////////////////////////////
150///////////////////////////////////////////////////////////////////////////////
151///////////////////////////////////////////////////////////////////////////////
152
153#define MAX_PAIR_COUNT  1024
154
155struct Pair {
156    const char*             fName;
157    SkFlattenable::Factory  fFactory;
158};
159
160static int gCount;
161static Pair gPairs[MAX_PAIR_COUNT];
162
163void SkFlattenable::Register(const char name[], Factory factory) {
164    SkASSERT(name);
165    SkASSERT(factory);
166
167    static bool gOnce;
168    if (!gOnce) {
169        gCount = 0;
170        gOnce = true;
171    }
172
173    SkASSERT(gCount < MAX_PAIR_COUNT);
174
175    gPairs[gCount].fName = name;
176    gPairs[gCount].fFactory = factory;
177    gCount += 1;
178}
179
180#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
181static void report_no_entries(const char* functionName) {
182    if (!gCount) {
183        SkDebugf("%s has no registered name/factory pairs."
184                 " Call SkGraphics::Init() at process initialization time.",
185                 functionName);
186    }
187}
188#endif
189
190SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
191#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
192    report_no_entries(__FUNCTION__);
193#endif
194    const Pair* pairs = gPairs;
195    for (int i = gCount - 1; i >= 0; --i) {
196        if (strcmp(pairs[i].fName, name) == 0) {
197            return pairs[i].fFactory;
198        }
199    }
200    return NULL;
201}
202
203const char* SkFlattenable::FactoryToName(Factory fact) {
204#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
205    report_no_entries(__FUNCTION__);
206#endif
207    const Pair* pairs = gPairs;
208    for (int i = gCount - 1; i >= 0; --i) {
209        if (pairs[i].fFactory == fact) {
210            return pairs[i].fName;
211        }
212    }
213    return NULL;
214}
215