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 "SkPtrRecorder.h"
10
11 ///////////////////////////////////////////////////////////////////////////////
12
flatten(SkWriteBuffer &) const13 void SkFlattenable::flatten(SkWriteBuffer&) 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
SkNamedFactorySet()23 SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
24
find(SkFlattenable::Factory factory)25 uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
26 uint32_t index = fFactorySet.find(factory);
27 if (index > 0) {
28 return index;
29 }
30 const char* name = SkFlattenable::FactoryToName(factory);
31 if (NULL == name) {
32 return 0;
33 }
34 *fNames.append() = name;
35 return fFactorySet.add(factory);
36 }
37
getNextAddedFactoryName()38 const char* SkNamedFactorySet::getNextAddedFactoryName() {
39 if (fNextAddedFactory < fNames.count()) {
40 return fNames[fNextAddedFactory++];
41 }
42 return NULL;
43 }
44
45 ///////////////////////////////////////////////////////////////////////////////
46
~SkRefCntSet()47 SkRefCntSet::~SkRefCntSet() {
48 // call this now, while our decPtr() is sill in scope
49 this->reset();
50 }
51
incPtr(void * ptr)52 void SkRefCntSet::incPtr(void* ptr) {
53 ((SkRefCnt*)ptr)->ref();
54 }
55
decPtr(void * ptr)56 void SkRefCntSet::decPtr(void* ptr) {
57 ((SkRefCnt*)ptr)->unref();
58 }
59
60 ///////////////////////////////////////////////////////////////////////////////
61 ///////////////////////////////////////////////////////////////////////////////
62 ///////////////////////////////////////////////////////////////////////////////
63
64 #define MAX_ENTRY_COUNT 1024
65
66 struct Entry {
67 const char* fName;
68 SkFlattenable::Factory fFactory;
69 SkFlattenable::Type fType;
70 };
71
72 static int gCount;
73 static Entry gEntries[MAX_ENTRY_COUNT];
74
Register(const char name[],Factory factory,SkFlattenable::Type type)75 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
76 SkASSERT(name);
77 SkASSERT(factory);
78
79 static bool gOnce = false;
80 if (!gOnce) {
81 gCount = 0;
82 gOnce = true;
83 }
84
85 SkASSERT(gCount < MAX_ENTRY_COUNT);
86
87 gEntries[gCount].fName = name;
88 gEntries[gCount].fFactory = factory;
89 gEntries[gCount].fType = type;
90 gCount += 1;
91 }
92
93 #ifdef SK_DEBUG
report_no_entries(const char * functionName)94 static void report_no_entries(const char* functionName) {
95 if (!gCount) {
96 SkDebugf("%s has no registered name/factory/type entries."
97 " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
98 functionName);
99 }
100 }
101 #endif
102
NameToFactory(const char name[])103 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
104 InitializeFlattenablesIfNeeded();
105 #ifdef SK_DEBUG
106 report_no_entries(__FUNCTION__);
107 #endif
108 const Entry* entries = gEntries;
109 for (int i = gCount - 1; i >= 0; --i) {
110 if (strcmp(entries[i].fName, name) == 0) {
111 return entries[i].fFactory;
112 }
113 }
114 return NULL;
115 }
116
NameToType(const char name[],SkFlattenable::Type * type)117 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
118 SkASSERT(NULL != type);
119 InitializeFlattenablesIfNeeded();
120 #ifdef SK_DEBUG
121 report_no_entries(__FUNCTION__);
122 #endif
123 const Entry* entries = gEntries;
124 for (int i = gCount - 1; i >= 0; --i) {
125 if (strcmp(entries[i].fName, name) == 0) {
126 *type = entries[i].fType;
127 return true;
128 }
129 }
130 return false;
131 }
132
FactoryToName(Factory fact)133 const char* SkFlattenable::FactoryToName(Factory fact) {
134 InitializeFlattenablesIfNeeded();
135 #ifdef SK_DEBUG
136 report_no_entries(__FUNCTION__);
137 #endif
138 const Entry* entries = gEntries;
139 for (int i = gCount - 1; i >= 0; --i) {
140 if (entries[i].fFactory == fact) {
141 return entries[i].fName;
142 }
143 }
144 return NULL;
145 }
146