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 "include/core/SkFlattenable.h" |
9 | #include "src/core/SkPtrRecorder.h" |
10 | #include "src/core/SkReadBuffer.h" |
11 | |
12 | #include <algorithm> |
13 | |
14 | SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {} |
15 | |
16 | uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) { |
17 | uint32_t index = fFactorySet.find(factory); |
18 | if (index > 0) { |
19 | return index; |
20 | } |
21 | const char* name = SkFlattenable::FactoryToName(factory); |
22 | if (nullptr == name) { |
23 | return 0; |
24 | } |
25 | *fNames.append() = name; |
26 | return fFactorySet.add(factory); |
27 | } |
28 | |
29 | const char* SkNamedFactorySet::getNextAddedFactoryName() { |
30 | if (fNextAddedFactory < fNames.count()) { |
31 | return fNames[fNextAddedFactory++]; |
32 | } |
33 | return nullptr; |
34 | } |
35 | |
36 | /////////////////////////////////////////////////////////////////////////////// |
37 | |
38 | SkRefCntSet::~SkRefCntSet() { |
39 | // call this now, while our decPtr() is sill in scope |
40 | this->reset(); |
41 | } |
42 | |
43 | void SkRefCntSet::incPtr(void* ptr) { |
44 | ((SkRefCnt*)ptr)->ref(); |
45 | } |
46 | |
47 | void SkRefCntSet::decPtr(void* ptr) { |
48 | ((SkRefCnt*)ptr)->unref(); |
49 | } |
50 | |
51 | /////////////////////////////////////////////////////////////////////////////// |
52 | |
53 | namespace { |
54 | |
55 | struct Entry { |
56 | const char* fName; |
57 | SkFlattenable::Factory fFactory; |
58 | }; |
59 | |
60 | struct EntryComparator { |
61 | bool operator()(const Entry& a, const Entry& b) const { |
62 | return strcmp(a.fName, b.fName) < 0; |
63 | } |
64 | bool operator()(const Entry& a, const char* b) const { |
65 | return strcmp(a.fName, b) < 0; |
66 | } |
67 | bool operator()(const char* a, const Entry& b) const { |
68 | return strcmp(a, b.fName) < 0; |
69 | } |
70 | }; |
71 | |
72 | int gCount = 0; |
73 | Entry gEntries[128]; |
74 | |
75 | } // namespace |
76 | |
77 | void SkFlattenable::Finalize() { |
78 | std::sort(gEntries, gEntries + gCount, EntryComparator()); |
79 | } |
80 | |
81 | void SkFlattenable::Register(const char name[], Factory factory) { |
82 | SkASSERT(name); |
83 | SkASSERT(factory); |
84 | SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries)); |
85 | |
86 | gEntries[gCount].fName = name; |
87 | gEntries[gCount].fFactory = factory; |
88 | gCount += 1; |
89 | } |
90 | |
91 | SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { |
92 | RegisterFlattenablesIfNeeded(); |
93 | |
94 | SkASSERT(std::is_sorted(gEntries, gEntries + gCount, EntryComparator())); |
95 | auto pair = std::equal_range(gEntries, gEntries + gCount, name, EntryComparator()); |
96 | if (pair.first == pair.second) { |
97 | return nullptr; |
98 | } |
99 | return pair.first->fFactory; |
100 | } |
101 | |
102 | const char* SkFlattenable::FactoryToName(Factory fact) { |
103 | RegisterFlattenablesIfNeeded(); |
104 | |
105 | const Entry* entries = gEntries; |
106 | for (int i = gCount - 1; i >= 0; --i) { |
107 | if (entries[i].fFactory == fact) { |
108 | return entries[i].fName; |
109 | } |
110 | } |
111 | return nullptr; |
112 | } |
113 | |
114 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
115 | |
116 | sk_sp<SkData> SkFlattenable::serialize(const SkSerialProcs* procs) const { |
117 | SkBinaryWriteBuffer writer; |
118 | if (procs) { |
119 | writer.setSerialProcs(*procs); |
120 | } |
121 | writer.writeFlattenable(this); |
122 | size_t size = writer.bytesWritten(); |
123 | auto data = SkData::MakeUninitialized(size); |
124 | writer.writeToMemory(data->writable_data()); |
125 | return data; |
126 | } |
127 | |
128 | size_t SkFlattenable::serialize(void* memory, size_t memory_size, |
129 | const SkSerialProcs* procs) const { |
130 | SkBinaryWriteBuffer writer(memory, memory_size); |
131 | if (procs) { |
132 | writer.setSerialProcs(*procs); |
133 | } |
134 | writer.writeFlattenable(this); |
135 | return writer.usingInitialStorage() ? writer.bytesWritten() : 0u; |
136 | } |
137 | |
138 | sk_sp<SkFlattenable> SkFlattenable::Deserialize(SkFlattenable::Type type, const void* data, |
139 | size_t size, const SkDeserialProcs* procs) { |
140 | SkReadBuffer buffer(data, size); |
141 | if (procs) { |
142 | buffer.setDeserialProcs(*procs); |
143 | } |
144 | return sk_sp<SkFlattenable>(buffer.readFlattenable(type)); |
145 | } |
146 | |