epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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 | */ |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 7 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "include/core/SkFlattenable.h" |
| 9 | #include "src/core/SkPtrRecorder.h" |
| 10 | #include "src/core/SkReadBuffer.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 11 | |
Vladimir Levin | ad6660a | 2018-01-18 12:35:11 -0800 | [diff] [blame] | 12 | #include <algorithm> |
| 13 | |
scroggo@google.com | 0c3e5fe | 2012-08-01 19:34:20 +0000 | [diff] [blame] | 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); |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 22 | if (nullptr == name) { |
scroggo@google.com | 0c3e5fe | 2012-08-01 19:34:20 +0000 | [diff] [blame] | 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 | } |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 33 | return nullptr; |
scroggo@google.com | 0c3e5fe | 2012-08-01 19:34:20 +0000 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | /////////////////////////////////////////////////////////////////////////////// |
| 37 | |
mike@reedtribe.org | e9e08cc | 2011-04-29 01:44:52 +0000 | [diff] [blame] | 38 | SkRefCntSet::~SkRefCntSet() { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 39 | // call this now, while our decPtr() is sill in scope |
| 40 | this->reset(); |
| 41 | } |
| 42 | |
mike@reedtribe.org | e9e08cc | 2011-04-29 01:44:52 +0000 | [diff] [blame] | 43 | void SkRefCntSet::incPtr(void* ptr) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 44 | ((SkRefCnt*)ptr)->ref(); |
| 45 | } |
| 46 | |
mike@reedtribe.org | e9e08cc | 2011-04-29 01:44:52 +0000 | [diff] [blame] | 47 | void SkRefCntSet::decPtr(void* ptr) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 48 | ((SkRefCnt*)ptr)->unref(); |
| 49 | } |
| 50 | |
| 51 | /////////////////////////////////////////////////////////////////////////////// |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 52 | |
Vladimir Levin | ad6660a | 2018-01-18 12:35:11 -0800 | [diff] [blame] | 53 | namespace { |
| 54 | |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 55 | struct Entry { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 56 | const char* fName; |
| 57 | SkFlattenable::Factory fFactory; |
| 58 | }; |
| 59 | |
Vladimir Levin | ad6660a | 2018-01-18 12:35:11 -0800 | [diff] [blame] | 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 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 80 | |
Mike Klein | a3d4099 | 2018-10-20 07:54:41 -0400 | [diff] [blame] | 81 | void SkFlattenable::Register(const char name[], Factory factory) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 82 | SkASSERT(name); |
| 83 | SkASSERT(factory); |
Mike Klein | 741d726 | 2017-06-13 16:35:32 -0400 | [diff] [blame] | 84 | SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries)); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 85 | |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 86 | gEntries[gCount].fName = name; |
| 87 | gEntries[gCount].fFactory = factory; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 88 | gCount += 1; |
| 89 | } |
| 90 | |
| 91 | SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { |
Mike Klein | fa5f6ce | 2018-10-20 08:21:31 -0400 | [diff] [blame] | 92 | RegisterFlattenablesIfNeeded(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 93 | |
Vladimir Levin | ad6660a | 2018-01-18 12:35:11 -0800 | [diff] [blame] | 94 | SkASSERT(std::is_sorted(gEntries, gEntries + gCount, EntryComparator())); |
Vladimir Levin | ad6660a | 2018-01-18 12:35:11 -0800 | [diff] [blame] | 95 | auto pair = std::equal_range(gEntries, gEntries + gCount, name, EntryComparator()); |
Mike Klein | a3d4099 | 2018-10-20 07:54:41 -0400 | [diff] [blame] | 96 | if (pair.first == pair.second) { |
| 97 | return nullptr; |
| 98 | } |
| 99 | return pair.first->fFactory; |
mtklein | 3b37545 | 2016-04-04 14:57:19 -0700 | [diff] [blame] | 100 | } |
| 101 | |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 102 | const char* SkFlattenable::FactoryToName(Factory fact) { |
Mike Klein | fa5f6ce | 2018-10-20 08:21:31 -0400 | [diff] [blame] | 103 | RegisterFlattenablesIfNeeded(); |
Mike Klein | a3d4099 | 2018-10-20 07:54:41 -0400 | [diff] [blame] | 104 | |
commit-bot@chromium.org | c0b7e10 | 2013-10-23 17:06:21 +0000 | [diff] [blame] | 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; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 109 | } |
| 110 | } |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 111 | return nullptr; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 112 | } |
Mike Reed | fadbfcd | 2017-12-06 16:09:20 -0500 | [diff] [blame] | 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 | |
Khushal | 42f8bc4 | 2018-04-03 17:51:40 -0700 | [diff] [blame] | 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 | |
Mike Reed | fadbfcd | 2017-12-06 16:09:20 -0500 | [diff] [blame] | 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 | } |