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