blob: 9cff53af084ca4bb4cb85d1ed1914f053e6bcbbe [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
reed9fa60da2014-08-21 07:59:51 -07007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkFlattenable.h"
9#include "src/core/SkPtrRecorder.h"
10#include "src/core/SkReadBuffer.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000011
Vladimir Levinad6660a2018-01-18 12:35:11 -080012#include <algorithm>
13
scroggo@google.com0c3e5fe2012-08-01 19:34:20 +000014SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
15
16uint32_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);
halcanary96fcdcc2015-08-27 07:41:13 -070022 if (nullptr == name) {
scroggo@google.com0c3e5fe2012-08-01 19:34:20 +000023 return 0;
24 }
25 *fNames.append() = name;
26 return fFactorySet.add(factory);
27}
28
29const char* SkNamedFactorySet::getNextAddedFactoryName() {
30 if (fNextAddedFactory < fNames.count()) {
31 return fNames[fNextAddedFactory++];
32 }
halcanary96fcdcc2015-08-27 07:41:13 -070033 return nullptr;
scroggo@google.com0c3e5fe2012-08-01 19:34:20 +000034}
35
36///////////////////////////////////////////////////////////////////////////////
37
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000038SkRefCntSet::~SkRefCntSet() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000039 // call this now, while our decPtr() is sill in scope
40 this->reset();
41}
42
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000043void SkRefCntSet::incPtr(void* ptr) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 ((SkRefCnt*)ptr)->ref();
45}
46
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000047void SkRefCntSet::decPtr(void* ptr) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000048 ((SkRefCnt*)ptr)->unref();
49}
50
51///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000052
Vladimir Levinad6660a2018-01-18 12:35:11 -080053namespace {
54
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +000055struct Entry {
reed@android.com8a1c16f2008-12-17 15:59:43 +000056 const char* fName;
57 SkFlattenable::Factory fFactory;
58};
59
Vladimir Levinad6660a2018-01-18 12:35:11 -080060struct 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
72int gCount = 0;
73Entry gEntries[128];
74
75} // namespace
76
77void SkFlattenable::Finalize() {
78 std::sort(gEntries, gEntries + gCount, EntryComparator());
79}
reed@android.com8a1c16f2008-12-17 15:59:43 +000080
Mike Kleina3d40992018-10-20 07:54:41 -040081void SkFlattenable::Register(const char name[], Factory factory) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000082 SkASSERT(name);
83 SkASSERT(factory);
Mike Klein741d7262017-06-13 16:35:32 -040084 SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries));
reed@google.com82065d62011-02-07 15:30:46 +000085
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +000086 gEntries[gCount].fName = name;
87 gEntries[gCount].fFactory = factory;
reed@android.com8a1c16f2008-12-17 15:59:43 +000088 gCount += 1;
89}
90
91SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
Mike Kleinfa5f6ce2018-10-20 08:21:31 -040092 RegisterFlattenablesIfNeeded();
reed@android.com8a1c16f2008-12-17 15:59:43 +000093
Vladimir Levinad6660a2018-01-18 12:35:11 -080094 SkASSERT(std::is_sorted(gEntries, gEntries + gCount, EntryComparator()));
Vladimir Levinad6660a2018-01-18 12:35:11 -080095 auto pair = std::equal_range(gEntries, gEntries + gCount, name, EntryComparator());
Mike Kleina3d40992018-10-20 07:54:41 -040096 if (pair.first == pair.second) {
97 return nullptr;
98 }
99 return pair.first->fFactory;
mtklein3b375452016-04-04 14:57:19 -0700100}
101
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +0000102const char* SkFlattenable::FactoryToName(Factory fact) {
Mike Kleinfa5f6ce2018-10-20 08:21:31 -0400103 RegisterFlattenablesIfNeeded();
Mike Kleina3d40992018-10-20 07:54:41 -0400104
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +0000105 const Entry* entries = gEntries;
106 for (int i = gCount - 1; i >= 0; --i) {
107 if (entries[i].fFactory == fact) {
108 return entries[i].fName;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000109 }
110 }
halcanary96fcdcc2015-08-27 07:41:13 -0700111 return nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000112}
Mike Reedfadbfcd2017-12-06 16:09:20 -0500113
114///////////////////////////////////////////////////////////////////////////////////////////////////
115
116sk_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
Khushal42f8bc42018-04-03 17:51:40 -0700128size_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
Mike Reedfadbfcd2017-12-06 16:09:20 -0500138sk_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}