Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkWriter32.h
Go to the documentation of this file.
1/*
2 * Copyright 2008 The Android Open Source Project
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#ifndef SkWriter32_DEFINED
9#define SkWriter32_DEFINED
10
11#include "include/core/SkData.h"
12#include "include/core/SkPath.h"
16#include "include/core/SkRect.h"
27
28#include <cstdint>
29#include <cstring>
30
31class SkMatrix;
33
35public:
36 /**
37 * The caller can specify an initial block of storage, which the caller manages.
38 *
39 * SkWriter32 will try to back reserve and write calls with this external storage until the
40 * first time an allocation doesn't fit. From then it will use dynamically allocated storage.
41 * This used to be optional behavior, but pipe now relies on it.
42 */
43 SkWriter32(void* external = nullptr, size_t externalBytes = 0) {
44 this->reset(external, externalBytes);
45 }
46
47 // return the current offset (will always be a multiple of 4)
48 size_t bytesWritten() const { return fUsed; }
49
50 // Returns true iff all of the bytes written so far are stored in the initial storage
51 // buffer provided in the constructor or the most recent call to reset.
52 bool usingInitialStorage() const { return fData == fExternal; }
53
54 void reset(void* external = nullptr, size_t externalBytes = 0) {
55 // we cast this pointer to int* and float* at times, so assert that it is aligned.
56 SkASSERT(SkIsAlign4((uintptr_t)external));
57 // we always write multiples of 4-bytes, so truncate down the size to match that
58 externalBytes &= ~3;
59
60 fData = (uint8_t*)external;
61 fCapacity = externalBytes;
62 fUsed = 0;
63 fExternal = external;
64 }
65
66 // size MUST be multiple of 4
67 uint32_t* reserve(size_t size) {
68 SkASSERT(SkAlign4(size) == size);
69 size_t offset = fUsed;
70 size_t totalRequired = fUsed + size;
71 if (totalRequired > fCapacity) {
72 this->growToAtLeast(totalRequired);
73 }
74 fUsed = totalRequired;
75 return (uint32_t*)(fData + offset);
76 }
77
78 /**
79 * Read a T record at offset, which must be a multiple of 4. Only legal if the record
80 * was written atomically using the write methods below.
81 */
82 template<typename T>
83 const T& readTAt(size_t offset) const {
85 SkASSERT(offset < fUsed);
86 return *(T*)(fData + offset);
87 }
88
89 /**
90 * Overwrite a T record at offset, which must be a multiple of 4. Only legal if the record
91 * was written atomically using the write methods below.
92 */
93 template<typename T>
94 void overwriteTAt(size_t offset, const T& value) {
96 SkASSERT(offset < fUsed);
97 *(T*)(fData + offset) = value;
98 }
99
100 bool writeBool(bool value) {
101 this->write32(value);
102 return value;
103 }
104
105 void writeInt(int32_t value) {
106 this->write32(value);
107 }
108
109 void write8(int32_t value) {
110 *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
111 }
112
113 void write16(int32_t value) {
114 *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
115 }
116
117 void write32(int32_t value) {
118 *(int32_t*)this->reserve(sizeof(value)) = value;
119 }
120
121 void writeScalar(SkScalar value) {
122 *(SkScalar*)this->reserve(sizeof(value)) = value;
123 }
124
125 void writePoint(const SkPoint& pt) {
126 *(SkPoint*)this->reserve(sizeof(pt)) = pt;
127 }
128
129 void writePoint3(const SkPoint3& pt) {
130 *(SkPoint3*)this->reserve(sizeof(pt)) = pt;
131 }
132
133 void writeRect(const SkRect& rect) {
134 *(SkRect*)this->reserve(sizeof(rect)) = rect;
135 }
136
137 void writeIRect(const SkIRect& rect) {
138 *(SkIRect*)this->reserve(sizeof(rect)) = rect;
139 }
140
141 void writeRRect(const SkRRect& rrect) {
143 }
144
145 void writePath(const SkPath& path) {
146 size_t size = path.writeToMemory(nullptr);
147 SkASSERT(SkAlign4(size) == size);
148 path.writeToMemory(this->reserve(size));
149 }
150
151 void writeMatrix(const SkMatrix& matrix);
152
153 void writeRegion(const SkRegion& rgn) {
154 size_t size = rgn.writeToMemory(nullptr);
155 SkASSERT(SkAlign4(size) == size);
156 rgn.writeToMemory(this->reserve(size));
157 }
158
159 void writeSampling(const SkSamplingOptions& sampling);
160
161 // write count bytes (must be a multiple of 4)
162 void writeMul4(const void* values, size_t size) {
163 this->write(values, size);
164 }
165
166 /**
167 * Write size bytes from values. size must be a multiple of 4, though
168 * values need not be 4-byte aligned.
169 */
170 void write(const void* values, size_t size) {
171 SkASSERT(SkAlign4(size) == size);
172 sk_careful_memcpy(this->reserve(size), values, size);
173 }
174
175 /**
176 * Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
177 * filled in with zeroes.
178 */
179 uint32_t* reservePad(size_t size) {
180 size_t alignedSize = SkAlign4(size);
181 uint32_t* p = this->reserve(alignedSize);
182 if (alignedSize != size) {
183 SkASSERT(alignedSize >= 4);
184 p[alignedSize / 4 - 1] = 0;
185 }
186 return p;
187 }
188
189 /**
190 * Write size bytes from src, and pad to 4 byte alignment with zeroes.
191 */
192 void writePad(const void* src, size_t size) {
193 sk_careful_memcpy(this->reservePad(size), src, size);
194 }
195
196 /**
197 * Writes a string to the writer, which can be retrieved with SkReadBuffer::readString().
198 * The length can be specified, or if -1 is passed, it will be computed by calling strlen().
199 * The length must be < max size_t.
200 *
201 * If you write NULL, it will be read as "".
202 */
203 void writeString(const char* str, size_t len = (size_t)-1);
204
205 /**
206 * Computes the size (aligned to multiple of 4) need to write the string
207 * in a call to writeString(). If the length is not specified, it will be
208 * computed by calling strlen().
209 */
210 static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
211
212 void writeData(const SkData* data) {
213 uint32_t len = data ? SkToU32(data->size()) : 0;
214 this->write32(len);
215 if (data) {
216 this->writePad(data->data(), len);
217 }
218 }
219
220 static size_t WriteDataSize(const SkData* data) {
221 return 4 + SkAlign4(data ? data->size() : 0);
222 }
223
224 /**
225 * Move the cursor back to offset bytes from the beginning.
226 * offset must be a multiple of 4 no greater than size().
227 */
228 void rewindToOffset(size_t offset) {
231 fUsed = offset;
232 }
233
234 // copy into a single buffer (allocated by caller). Must be at least size()
235 void flatten(void* dst) const {
236 memcpy(dst, fData, fUsed);
237 }
238
239 bool writeToStream(SkWStream* stream) const {
240 return stream->write(fData, fUsed);
241 }
242
243 // read from the stream, and write up to length bytes. Return the actual
244 // number of bytes written.
245 size_t readFromStream(SkStream* stream, size_t length) {
246 return stream->read(this->reservePad(length), length);
247 }
248
249 /**
250 * Captures a snapshot of the data as it is right now, and return it.
251 */
253private:
254 void growToAtLeast(size_t size);
255
256 uint8_t* fData; // Points to either fInternal or fExternal.
257 size_t fCapacity; // Number of bytes we can write to fData.
258 size_t fUsed; // Number of bytes written.
259 void* fExternal; // Unmanaged memory block.
260 skia_private::AutoTMalloc<uint8_t> fInternal; // Managed memory block.
261};
262
263/**
264 * Helper class to allocated SIZE bytes as part of the writer, and to provide
265 * that storage to the constructor as its initial storage buffer.
266 *
267 * This wrapper ensures proper alignment rules are met for the storage.
268 */
269template <size_t SIZE> class SkSWriter32 : public SkWriter32 {
270public:
271 SkSWriter32() { this->reset(); }
272
273 void reset() {this->INHERITED::reset(fData.fStorage, SIZE); }
274
275private:
276 union {
280 } fData;
281
282 using INHERITED = SkWriter32;
283};
284
285#endif
m reset()
static constexpr bool SkIsAlign4(T x)
Definition SkAlign.h:20
static constexpr T SkAlign4(T x)
Definition SkAlign.h:16
#define SkASSERT(cond)
Definition SkAssert.h:116
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
Definition SkMalloc.h:125
constexpr uint32_t SkToU32(S x)
Definition SkTo.h:26
const void * data() const
Definition SkData.h:37
size_t writeToMemory(void *buffer) const
Definition SkRRect.cpp:599
static constexpr size_t kSizeInMemory
Definition SkRRect.h:422
size_t writeToMemory(void *buffer) const
void * fPtrAlignment
Definition SkWriter32.h:277
double fDoubleAlignment
Definition SkWriter32.h:278
void reset()
Definition SkWriter32.h:273
char fStorage[SIZE]
Definition SkWriter32.h:279
void overwriteTAt(size_t offset, const T &value)
Definition SkWriter32.h:94
void writeInt(int32_t value)
Definition SkWriter32.h:105
static size_t WriteDataSize(const SkData *data)
Definition SkWriter32.h:220
void write32(int32_t value)
Definition SkWriter32.h:117
void write(const void *values, size_t size)
Definition SkWriter32.h:170
bool usingInitialStorage() const
Definition SkWriter32.h:52
void writeRRect(const SkRRect &rrect)
Definition SkWriter32.h:141
void writeSampling(const SkSamplingOptions &sampling)
uint32_t * reservePad(size_t size)
Definition SkWriter32.h:179
void writeRect(const SkRect &rect)
Definition SkWriter32.h:133
void writeScalar(SkScalar value)
Definition SkWriter32.h:121
size_t readFromStream(SkStream *stream, size_t length)
Definition SkWriter32.h:245
void writeIRect(const SkIRect &rect)
Definition SkWriter32.h:137
void writeMatrix(const SkMatrix &matrix)
uint32_t * reserve(size_t size)
Definition SkWriter32.h:67
void write16(int32_t value)
Definition SkWriter32.h:113
void writePoint(const SkPoint &pt)
Definition SkWriter32.h:125
void writeMul4(const void *values, size_t size)
Definition SkWriter32.h:162
void writePad(const void *src, size_t size)
Definition SkWriter32.h:192
void writeData(const SkData *data)
Definition SkWriter32.h:212
SkWriter32(void *external=nullptr, size_t externalBytes=0)
Definition SkWriter32.h:43
void reset(void *external=nullptr, size_t externalBytes=0)
Definition SkWriter32.h:54
void write8(int32_t value)
Definition SkWriter32.h:109
void writePath(const SkPath &path)
Definition SkWriter32.h:145
void writePoint3(const SkPoint3 &pt)
Definition SkWriter32.h:129
bool writeToStream(SkWStream *stream) const
Definition SkWriter32.h:239
static size_t WriteStringSize(const char *str, size_t len=(size_t) -1)
bool writeBool(bool value)
Definition SkWriter32.h:100
const T & readTAt(size_t offset) const
Definition SkWriter32.h:83
void writeRegion(const SkRegion &rgn)
Definition SkWriter32.h:153
void flatten(void *dst) const
Definition SkWriter32.h:235
void rewindToOffset(size_t offset)
Definition SkWriter32.h:228
sk_sp< SkData > snapshotAsData() const
void writeString(const char *str, size_t len=(size_t) -1)
size_t bytesWritten() const
Definition SkWriter32.h:48
float SkScalar
Definition extension.cpp:12
uint8_t value
size_t length
#define T
#define SIZE
Point offset