1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkFlattenable.h"
9 #include "SkPtrRecorder.h"
10 #include "SkReadBuffer.h"
11
SkNamedFactorySet()12 SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
13
find(SkFlattenable::Factory factory)14 uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
15 uint32_t index = fFactorySet.find(factory);
16 if (index > 0) {
17 return index;
18 }
19 const char* name = SkFlattenable::FactoryToName(factory);
20 if (NULL == name) {
21 return 0;
22 }
23 *fNames.append() = name;
24 return fFactorySet.add(factory);
25 }
26
getNextAddedFactoryName()27 const char* SkNamedFactorySet::getNextAddedFactoryName() {
28 if (fNextAddedFactory < fNames.count()) {
29 return fNames[fNextAddedFactory++];
30 }
31 return NULL;
32 }
33
34 ///////////////////////////////////////////////////////////////////////////////
35
~SkRefCntSet()36 SkRefCntSet::~SkRefCntSet() {
37 // call this now, while our decPtr() is sill in scope
38 this->reset();
39 }
40
incPtr(void * ptr)41 void SkRefCntSet::incPtr(void* ptr) {
42 ((SkRefCnt*)ptr)->ref();
43 }
44
decPtr(void * ptr)45 void SkRefCntSet::decPtr(void* ptr) {
46 ((SkRefCnt*)ptr)->unref();
47 }
48
49 ///////////////////////////////////////////////////////////////////////////////
50
51 #define MAX_ENTRY_COUNT 1024
52
53 struct Entry {
54 const char* fName;
55 SkFlattenable::Factory fFactory;
56 SkFlattenable::Type fType;
57 };
58
59 static int gCount;
60 static Entry gEntries[MAX_ENTRY_COUNT];
61
Register(const char name[],Factory factory,SkFlattenable::Type type)62 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
63 SkASSERT(name);
64 SkASSERT(factory);
65
66 static bool gOnce = false;
67 if (!gOnce) {
68 gCount = 0;
69 gOnce = true;
70 }
71
72 SkASSERT(gCount < MAX_ENTRY_COUNT);
73
74 gEntries[gCount].fName = name;
75 gEntries[gCount].fFactory = factory;
76 gEntries[gCount].fType = type;
77 gCount += 1;
78 }
79
80 #ifdef SK_DEBUG
report_no_entries(const char * functionName)81 static void report_no_entries(const char* functionName) {
82 if (!gCount) {
83 SkDebugf("%s has no registered name/factory/type entries."
84 " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
85 functionName);
86 }
87 }
88 #endif
89
NameToFactory(const char name[])90 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
91 InitializeFlattenablesIfNeeded();
92 #ifdef SK_DEBUG
93 report_no_entries(__FUNCTION__);
94 #endif
95 const Entry* entries = gEntries;
96 for (int i = gCount - 1; i >= 0; --i) {
97 if (strcmp(entries[i].fName, name) == 0) {
98 return entries[i].fFactory;
99 }
100 }
101 return NULL;
102 }
103
NameToType(const char name[],SkFlattenable::Type * type)104 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
105 SkASSERT(type);
106 InitializeFlattenablesIfNeeded();
107 #ifdef SK_DEBUG
108 report_no_entries(__FUNCTION__);
109 #endif
110 const Entry* entries = gEntries;
111 for (int i = gCount - 1; i >= 0; --i) {
112 if (strcmp(entries[i].fName, name) == 0) {
113 *type = entries[i].fType;
114 return true;
115 }
116 }
117 return false;
118 }
119
FactoryToName(Factory fact)120 const char* SkFlattenable::FactoryToName(Factory fact) {
121 InitializeFlattenablesIfNeeded();
122 #ifdef SK_DEBUG
123 report_no_entries(__FUNCTION__);
124 #endif
125 const Entry* entries = gEntries;
126 for (int i = gCount - 1; i >= 0; --i) {
127 if (entries[i].fFactory == fact) {
128 return entries[i].fName;
129 }
130 }
131 return NULL;
132 }
133