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