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