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