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