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 (nullptr == 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 nullptr;
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 struct Entry {
52 const char* fName;
53 SkFlattenable::Factory fFactory;
54 SkFlattenable::Type fType;
55 };
56
57 static int gCount = 0;
58 static Entry gEntries[128];
59
Register(const char name[],Factory factory,SkFlattenable::Type type)60 void SkFlattenable::Register(const char name[], Factory factory, SkFlattenable::Type type) {
61 SkASSERT(name);
62 SkASSERT(factory);
63 SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries));
64
65 gEntries[gCount].fName = name;
66 gEntries[gCount].fFactory = factory;
67 gEntries[gCount].fType = type;
68 gCount += 1;
69 }
70
71 #ifdef SK_DEBUG
report_no_entries(const char * functionName)72 static void report_no_entries(const char* functionName) {
73 if (!gCount) {
74 SkDebugf("%s has no registered name/factory/type entries."
75 " Call SkFlattenable::InitializeFlattenablesIfNeeded() before using gEntries",
76 functionName);
77 }
78 }
79 #endif
80
NameToFactory(const char name[])81 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
82 InitializeFlattenablesIfNeeded();
83 #ifdef SK_DEBUG
84 report_no_entries(__FUNCTION__);
85 #endif
86 const Entry* entries = gEntries;
87 for (int i = gCount - 1; i >= 0; --i) {
88 if (strcmp(entries[i].fName, name) == 0) {
89 return entries[i].fFactory;
90 }
91 }
92 return nullptr;
93 }
94
NameToType(const char name[],SkFlattenable::Type * type)95 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
96 SkASSERT(type);
97 InitializeFlattenablesIfNeeded();
98 #ifdef SK_DEBUG
99 report_no_entries(__FUNCTION__);
100 #endif
101 const Entry* entries = gEntries;
102 for (int i = gCount - 1; i >= 0; --i) {
103 if (strcmp(entries[i].fName, name) == 0) {
104 *type = entries[i].fType;
105 return true;
106 }
107 }
108 return false;
109 }
110
FactoryToName(Factory fact)111 const char* SkFlattenable::FactoryToName(Factory fact) {
112 InitializeFlattenablesIfNeeded();
113 #ifdef SK_DEBUG
114 report_no_entries(__FUNCTION__);
115 #endif
116 const Entry* entries = gEntries;
117 for (int i = gCount - 1; i >= 0; --i) {
118 if (entries[i].fFactory == fact) {
119 return entries[i].fName;
120 }
121 }
122 return nullptr;
123 }
124