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