OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkData.h" | 8 #include "SkData.h" |
9 #include "SkDataTable.h" | 9 #include "SkDataTable.h" |
| 10 #include "SkOnce.h" |
10 | 11 |
11 static void malloc_freeproc(void* context) { | 12 static void malloc_freeproc(void* context) { |
12 sk_free(context); | 13 sk_free(context); |
13 } | 14 } |
14 | 15 |
15 // Makes empty table | 16 // Makes empty table |
16 SkDataTable::SkDataTable() { | 17 SkDataTable::SkDataTable() { |
17 fCount = 0; | 18 fCount = 0; |
18 fElemSize = 0; // 0 signals that we use fDir instead of fElems | 19 fElemSize = 0; // 0 signals that we use fDir instead of fElems |
19 fU.fDir = nullptr; | 20 fU.fDir = nullptr; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 } else { | 70 } else { |
70 if (size) { | 71 if (size) { |
71 *size = fU.fDir[index].fSize; | 72 *size = fU.fDir[index].fSize; |
72 } | 73 } |
73 return fU.fDir[index].fPtr; | 74 return fU.fDir[index].fPtr; |
74 } | 75 } |
75 } | 76 } |
76 | 77 |
77 /////////////////////////////////////////////////////////////////////////////// | 78 /////////////////////////////////////////////////////////////////////////////// |
78 | 79 |
79 SkDataTable* SkDataTable::NewEmpty() { | 80 sk_sp<SkDataTable> SkDataTable::MakeEmpty() { |
80 static SkDataTable* gEmpty; | 81 static SkDataTable* singleton; |
81 if (nullptr == gEmpty) { | 82 static SkOnce once; |
82 gEmpty = new SkDataTable; | 83 once([]{ singleton = new SkDataTable(); }); |
83 } | 84 return sk_ref_sp(singleton); |
84 gEmpty->ref(); | |
85 return gEmpty; | |
86 } | 85 } |
87 | 86 |
88 SkDataTable* SkDataTable::NewCopyArrays(const void * const * ptrs, | 87 sk_sp<SkDataTable> SkDataTable::MakeCopyArrays(const void * const * ptrs, |
89 const size_t sizes[], int count) { | 88 const size_t sizes[], int count)
{ |
90 if (count <= 0) { | 89 if (count <= 0) { |
91 return SkDataTable::NewEmpty(); | 90 return SkDataTable::MakeEmpty(); |
92 } | 91 } |
93 | 92 |
94 size_t dataSize = 0; | 93 size_t dataSize = 0; |
95 for (int i = 0; i < count; ++i) { | 94 for (int i = 0; i < count; ++i) { |
96 dataSize += sizes[i]; | 95 dataSize += sizes[i]; |
97 } | 96 } |
98 | 97 |
99 size_t bufferSize = count * sizeof(Dir) + dataSize; | 98 size_t bufferSize = count * sizeof(Dir) + dataSize; |
100 void* buffer = sk_malloc_throw(bufferSize); | 99 void* buffer = sk_malloc_throw(bufferSize); |
101 | 100 |
102 Dir* dir = (Dir*)buffer; | 101 Dir* dir = (Dir*)buffer; |
103 char* elem = (char*)(dir + count); | 102 char* elem = (char*)(dir + count); |
104 for (int i = 0; i < count; ++i) { | 103 for (int i = 0; i < count; ++i) { |
105 dir[i].fPtr = elem; | 104 dir[i].fPtr = elem; |
106 dir[i].fSize = sizes[i]; | 105 dir[i].fSize = sizes[i]; |
107 memcpy(elem, ptrs[i], sizes[i]); | 106 memcpy(elem, ptrs[i], sizes[i]); |
108 elem += sizes[i]; | 107 elem += sizes[i]; |
109 } | 108 } |
110 | 109 |
111 return new SkDataTable(dir, count, malloc_freeproc, buffer); | 110 return sk_sp<SkDataTable>(new SkDataTable(dir, count, malloc_freeproc, buffe
r)); |
112 } | 111 } |
113 | 112 |
114 SkDataTable* SkDataTable::NewCopyArray(const void* array, size_t elemSize, | 113 sk_sp<SkDataTable> SkDataTable::MakeCopyArray(const void* array, size_t elemSize
, int count) { |
115 int count) { | |
116 if (count <= 0) { | 114 if (count <= 0) { |
117 return SkDataTable::NewEmpty(); | 115 return SkDataTable::MakeEmpty(); |
118 } | 116 } |
119 | 117 |
120 size_t bufferSize = elemSize * count; | 118 size_t bufferSize = elemSize * count; |
121 void* buffer = sk_malloc_throw(bufferSize); | 119 void* buffer = sk_malloc_throw(bufferSize); |
122 memcpy(buffer, array, bufferSize); | 120 memcpy(buffer, array, bufferSize); |
123 | 121 |
124 return new SkDataTable(buffer, elemSize, count, malloc_freeproc, buffer); | 122 return sk_sp<SkDataTable>(new SkDataTable(buffer, elemSize, count, malloc_fr
eeproc, buffer)); |
125 } | 123 } |
126 | 124 |
127 SkDataTable* SkDataTable::NewArrayProc(const void* array, size_t elemSize, | 125 sk_sp<SkDataTable> SkDataTable::MakeArrayProc(const void* array, size_t elemSize
, int count, |
128 int count, FreeProc proc, void* ctx) { | 126 FreeProc proc, void* ctx) { |
129 if (count <= 0) { | 127 if (count <= 0) { |
130 return SkDataTable::NewEmpty(); | 128 return SkDataTable::MakeEmpty(); |
131 } | 129 } |
132 return new SkDataTable(array, elemSize, count, proc, ctx); | 130 return sk_sp<SkDataTable>(new SkDataTable(array, elemSize, count, proc, ctx)
); |
133 } | 131 } |
134 | 132 |
135 /////////////////////////////////////////////////////////////////////////////// | 133 /////////////////////////////////////////////////////////////////////////////// |
136 | 134 |
137 static void chunkalloc_freeproc(void* context) { delete (SkChunkAlloc*)context;
} | 135 static void chunkalloc_freeproc(void* context) { delete (SkChunkAlloc*)context;
} |
138 | 136 |
139 SkDataTableBuilder::SkDataTableBuilder(size_t minChunkSize) | 137 SkDataTableBuilder::SkDataTableBuilder(size_t minChunkSize) |
140 : fHeap(nullptr) | 138 : fHeap(nullptr) |
141 , fMinChunkSize(minChunkSize) {} | 139 , fMinChunkSize(minChunkSize) {} |
142 | 140 |
(...skipping 14 matching lines...) Expand all Loading... |
157 } | 155 } |
158 | 156 |
159 void* dst = fHeap->alloc(size, SkChunkAlloc::kThrow_AllocFailType); | 157 void* dst = fHeap->alloc(size, SkChunkAlloc::kThrow_AllocFailType); |
160 memcpy(dst, src, size); | 158 memcpy(dst, src, size); |
161 | 159 |
162 SkDataTable::Dir* dir = fDir.append(); | 160 SkDataTable::Dir* dir = fDir.append(); |
163 dir->fPtr = dst; | 161 dir->fPtr = dst; |
164 dir->fSize = size; | 162 dir->fSize = size; |
165 } | 163 } |
166 | 164 |
167 SkDataTable* SkDataTableBuilder::detachDataTable() { | 165 sk_sp<SkDataTable> SkDataTableBuilder::detachDataTable() { |
168 const int count = fDir.count(); | 166 const int count = fDir.count(); |
169 if (0 == count) { | 167 if (0 == count) { |
170 return SkDataTable::NewEmpty(); | 168 return SkDataTable::MakeEmpty(); |
171 } | 169 } |
172 | 170 |
173 // Copy the dir into the heap; | 171 // Copy the dir into the heap; |
174 void* dir = fHeap->alloc(count * sizeof(SkDataTable::Dir), | 172 void* dir = fHeap->alloc(count * sizeof(SkDataTable::Dir), SkChunkAlloc::kTh
row_AllocFailType); |
175 SkChunkAlloc::kThrow_AllocFailType); | |
176 memcpy(dir, fDir.begin(), count * sizeof(SkDataTable::Dir)); | 173 memcpy(dir, fDir.begin(), count * sizeof(SkDataTable::Dir)); |
177 | 174 |
178 SkDataTable* table = new SkDataTable((SkDataTable::Dir*)dir, count, chunkall
oc_freeproc, fHeap); | 175 sk_sp<SkDataTable> table( |
| 176 new SkDataTable((SkDataTable::Dir*)dir, count, chunkalloc_freeproc, fHea
p)); |
179 // we have to detach our fHeap, since we are giving that to the table | 177 // we have to detach our fHeap, since we are giving that to the table |
180 fHeap = nullptr; | 178 fHeap = nullptr; |
181 fDir.reset(); | 179 fDir.reset(); |
182 return table; | 180 return table; |
183 } | 181 } |
OLD | NEW |