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
SkNamedFactorySet()14 SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
15
find(SkFlattenable::Factory factory)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
getNextAddedFactoryName()29 const char* SkNamedFactorySet::getNextAddedFactoryName() {
30 if (fNextAddedFactory < fNames.count()) {
31 return fNames[fNextAddedFactory++];
32 }
33 return nullptr;
34 }
35
36 ///////////////////////////////////////////////////////////////////////////////
37
~SkRefCntSet()38 SkRefCntSet::~SkRefCntSet() {
39 // call this now, while our decPtr() is sill in scope
40 this->reset();
41 }
42
incPtr(void * ptr)43 void SkRefCntSet::incPtr(void* ptr) {
44 ((SkRefCnt*)ptr)->ref();
45 }
46
decPtr(void * ptr)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 {
operator ()__anonf4cfc5100111::EntryComparator61 bool operator()(const Entry& a, const Entry& b) const {
62 return strcmp(a.fName, b.fName) < 0;
63 }
operator ()__anonf4cfc5100111::EntryComparator64 bool operator()(const Entry& a, const char* b) const {
65 return strcmp(a.fName, b) < 0;
66 }
operator ()__anonf4cfc5100111::EntryComparator67 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
Finalize()77 void SkFlattenable::Finalize() {
78 std::sort(gEntries, gEntries + gCount, EntryComparator());
79 }
80
Register(const char name[],Factory factory)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
NameToFactory(const char name[])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
FactoryToName(Factory fact)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
serialize(const SkSerialProcs * procs) const116 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
serialize(void * memory,size_t memory_size,const SkSerialProcs * procs) const128 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
Deserialize(SkFlattenable::Type type,const void * data,size_t size,const SkDeserialProcs * procs)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