| 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 |  | 
|---|
| 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); | 
|---|
| 22 | if (nullptr == name) { | 
|---|
| 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 | } | 
|---|
| 33 | return nullptr; | 
|---|
| 34 | } | 
|---|
| 35 |  | 
|---|
| 36 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 37 |  | 
|---|
| 38 | SkRefCntSet::~SkRefCntSet() { | 
|---|
| 39 | // call this now, while our decPtr() is sill in scope | 
|---|
| 40 | this->reset(); | 
|---|
| 41 | } | 
|---|
| 42 |  | 
|---|
| 43 | void SkRefCntSet::incPtr(void* ptr) { | 
|---|
| 44 | ((SkRefCnt*)ptr)->ref(); | 
|---|
| 45 | } | 
|---|
| 46 |  | 
|---|
| 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 { | 
|---|
| 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 | } | 
|---|
| 80 |  | 
|---|
| 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 |  | 
|---|
| 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 |  | 
|---|
| 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 |  | 
|---|
| 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 |  | 
|---|
| 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 |  | 
|---|
| 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 |  | 
|---|