Line data Source code
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 <new>
9 :
10 : #include "SkAutoMalloc.h"
11 : #include "SkImageGenerator.h"
12 : #include "SkPictureData.h"
13 : #include "SkPictureRecord.h"
14 : #include "SkReadBuffer.h"
15 : #include "SkTextBlob.h"
16 : #include "SkTypeface.h"
17 : #include "SkWriteBuffer.h"
18 :
19 : #if SK_SUPPORT_GPU
20 : #include "GrContext.h"
21 : #endif
22 :
23 : template <typename T> int SafeCount(const T* obj) {
24 : return obj ? obj->count() : 0;
25 : }
26 :
27 0 : SkPictureData::SkPictureData(const SkPictInfo& info)
28 0 : : fInfo(info) {
29 0 : this->init();
30 0 : }
31 :
32 0 : void SkPictureData::initForPlayback() const {
33 : // ensure that the paths bounds are pre-computed
34 0 : for (int i = 0; i < fPaths.count(); i++) {
35 0 : fPaths[i].updateBoundsCache();
36 : }
37 0 : }
38 :
39 0 : SkPictureData::SkPictureData(const SkPictureRecord& record,
40 0 : const SkPictInfo& info)
41 0 : : fInfo(info) {
42 :
43 0 : this->init();
44 :
45 0 : fOpData = record.opData();
46 :
47 0 : fContentInfo.set(record.fContentInfo);
48 :
49 0 : fPaints = record.fPaints;
50 :
51 0 : fPaths.reset(record.fPaths.count());
52 0 : record.fPaths.foreach([this](const SkPath& path, int n) {
53 : // These indices are logically 1-based, but we need to serialize them
54 : // 0-based to keep the deserializing SkPictureData::getPath() working.
55 0 : fPaths[n-1] = path;
56 0 : });
57 :
58 0 : this->initForPlayback();
59 :
60 0 : const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
61 0 : fPictureCount = pictures.count();
62 0 : if (fPictureCount > 0) {
63 0 : fPictureRefs = new const SkPicture* [fPictureCount];
64 0 : for (int i = 0; i < fPictureCount; i++) {
65 0 : fPictureRefs[i] = pictures[i];
66 0 : fPictureRefs[i]->ref();
67 : }
68 : }
69 :
70 0 : const SkTDArray<SkDrawable* >& drawables = record.getDrawableRefs();
71 0 : fDrawableCount = drawables.count();
72 0 : if (fDrawableCount > 0) {
73 0 : fDrawableRefs = new SkDrawable* [fDrawableCount];
74 0 : for (int i = 0; i < fDrawableCount; i++) {
75 0 : fDrawableRefs[i] = drawables[i];
76 0 : fDrawableRefs[i]->ref();
77 : }
78 : }
79 :
80 : // templatize to consolidate with similar picture logic?
81 0 : const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs();
82 0 : fTextBlobCount = blobs.count();
83 0 : if (fTextBlobCount > 0) {
84 0 : fTextBlobRefs = new const SkTextBlob* [fTextBlobCount];
85 0 : for (int i = 0; i < fTextBlobCount; ++i) {
86 0 : fTextBlobRefs[i] = SkRef(blobs[i]);
87 : }
88 : }
89 :
90 0 : const SkTDArray<const SkVertices*>& verts = record.getVerticesRefs();
91 0 : fVerticesCount = verts.count();
92 0 : if (fVerticesCount > 0) {
93 0 : fVerticesRefs = new const SkVertices* [fVerticesCount];
94 0 : for (int i = 0; i < fVerticesCount; ++i) {
95 0 : fVerticesRefs[i] = SkRef(verts[i]);
96 : }
97 : }
98 :
99 0 : const SkTDArray<const SkImage*>& imgs = record.getImageRefs();
100 0 : fImageCount = imgs.count();
101 0 : if (fImageCount > 0) {
102 0 : fImageRefs = new const SkImage* [fImageCount];
103 0 : for (int i = 0; i < fImageCount; ++i) {
104 0 : fImageRefs[i] = SkRef(imgs[i]);
105 : }
106 : }
107 0 : }
108 :
109 0 : void SkPictureData::init() {
110 0 : fPictureRefs = nullptr;
111 0 : fPictureCount = 0;
112 0 : fDrawableRefs = nullptr;
113 0 : fDrawableCount = 0;
114 0 : fTextBlobRefs = nullptr;
115 0 : fTextBlobCount = 0;
116 0 : fVerticesRefs = nullptr;
117 0 : fVerticesCount = 0;
118 0 : fImageRefs = nullptr;
119 0 : fImageCount = 0;
120 0 : fFactoryPlayback = nullptr;
121 0 : }
122 :
123 0 : SkPictureData::~SkPictureData() {
124 0 : for (int i = 0; i < fPictureCount; i++) {
125 0 : fPictureRefs[i]->unref();
126 : }
127 0 : delete[] fPictureRefs;
128 :
129 0 : for (int i = 0; i < fDrawableCount; i++) {
130 0 : fDrawableRefs[i]->unref();
131 : }
132 0 : if (fDrawableCount > 0) {
133 0 : SkASSERT(fDrawableRefs);
134 0 : delete[] fDrawableRefs;
135 : }
136 :
137 0 : for (int i = 0; i < fTextBlobCount; i++) {
138 0 : fTextBlobRefs[i]->unref();
139 : }
140 0 : delete[] fTextBlobRefs;
141 :
142 0 : for (int i = 0; i < fVerticesCount; i++) {
143 0 : fVerticesRefs[i]->unref();
144 : }
145 0 : delete[] fVerticesRefs;
146 :
147 0 : for (int i = 0; i < fImageCount; i++) {
148 0 : fImageRefs[i]->unref();
149 : }
150 0 : delete[] fImageRefs;
151 :
152 0 : delete fFactoryPlayback;
153 0 : }
154 :
155 0 : bool SkPictureData::containsBitmaps() const {
156 0 : if (fBitmapImageCount > 0 || fImageCount > 0) {
157 0 : return true;
158 : }
159 0 : for (int i = 0; i < fPictureCount; ++i) {
160 0 : if (fPictureRefs[i]->willPlayBackBitmaps()) {
161 0 : return true;
162 : }
163 : }
164 0 : return false;
165 : }
166 :
167 : ///////////////////////////////////////////////////////////////////////////////
168 : ///////////////////////////////////////////////////////////////////////////////
169 :
170 : #include "SkStream.h"
171 :
172 0 : static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
173 0 : size_t size = 4; // for 'count'
174 :
175 0 : for (int i = 0; i < count; i++) {
176 0 : const char* name = SkFlattenable::FactoryToName(array[i]);
177 0 : if (nullptr == name || 0 == *name) {
178 0 : size += SkWStream::SizeOfPackedUInt(0);
179 : } else {
180 0 : size_t len = strlen(name);
181 0 : size += SkWStream::SizeOfPackedUInt(len);
182 0 : size += len;
183 : }
184 : }
185 :
186 0 : return size;
187 : }
188 :
189 0 : static void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
190 0 : buffer.writeUInt(tag);
191 0 : buffer.writeUInt(SkToU32(size));
192 0 : }
193 :
194 0 : static void write_tag_size(SkWStream* stream, uint32_t tag, size_t size) {
195 0 : stream->write32(tag);
196 0 : stream->write32(SkToU32(size));
197 0 : }
198 :
199 0 : void SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
200 0 : int count = rec.count();
201 :
202 0 : SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
203 0 : SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
204 0 : rec.copyToArray(array);
205 :
206 0 : size_t size = compute_chunk_size(array, count);
207 :
208 : // TODO: write_tag_size should really take a size_t
209 0 : write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
210 0 : SkDEBUGCODE(size_t start = stream->bytesWritten());
211 0 : stream->write32(count);
212 :
213 0 : for (int i = 0; i < count; i++) {
214 0 : const char* name = SkFlattenable::FactoryToName(array[i]);
215 0 : if (nullptr == name || 0 == *name) {
216 0 : stream->writePackedUInt(0);
217 : } else {
218 0 : size_t len = strlen(name);
219 0 : stream->writePackedUInt(len);
220 0 : stream->write(name, len);
221 : }
222 : }
223 :
224 0 : SkASSERT(size == (stream->bytesWritten() - start));
225 0 : }
226 :
227 0 : void SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
228 0 : int count = rec.count();
229 :
230 0 : write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count);
231 :
232 0 : SkAutoSTMalloc<16, SkTypeface*> storage(count);
233 0 : SkTypeface** array = (SkTypeface**)storage.get();
234 0 : rec.copyToArray((SkRefCnt**)array);
235 :
236 0 : for (int i = 0; i < count; i++) {
237 0 : array[i]->serialize(stream);
238 : }
239 0 : }
240 :
241 0 : void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
242 : int i, n;
243 :
244 0 : if ((n = fPaints.count()) > 0) {
245 0 : write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
246 0 : for (i = 0; i < n; i++) {
247 0 : buffer.writePaint(fPaints[i]);
248 : }
249 : }
250 :
251 0 : if ((n = fPaths.count()) > 0) {
252 0 : write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
253 0 : buffer.writeInt(n);
254 0 : for (int i = 0; i < n; i++) {
255 0 : buffer.writePath(fPaths[i]);
256 : }
257 : }
258 :
259 0 : if (fTextBlobCount > 0) {
260 0 : write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount);
261 0 : for (i = 0; i < fTextBlobCount; ++i) {
262 0 : fTextBlobRefs[i]->flatten(buffer);
263 : }
264 : }
265 :
266 0 : if (fVerticesCount > 0) {
267 0 : write_tag_size(buffer, SK_PICT_VERTICES_BUFFER_TAG, fVerticesCount);
268 0 : for (i = 0; i < fVerticesCount; ++i) {
269 0 : buffer.writeDataAsByteArray(fVerticesRefs[i]->encode().get());
270 : }
271 : }
272 :
273 0 : if (fImageCount > 0) {
274 0 : write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount);
275 0 : for (i = 0; i < fImageCount; ++i) {
276 0 : buffer.writeImage(fImageRefs[i]);
277 : }
278 : }
279 0 : }
280 :
281 0 : void SkPictureData::serialize(SkWStream* stream,
282 : SkPixelSerializer* pixelSerializer,
283 : SkRefCntSet* topLevelTypeFaceSet) const {
284 : // This can happen at pretty much any time, so might as well do it first.
285 0 : write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
286 0 : stream->write(fOpData->bytes(), fOpData->size());
287 :
288 : // We serialize all typefaces into the typeface section of the top-level picture.
289 0 : SkRefCntSet localTypefaceSet;
290 0 : SkRefCntSet* typefaceSet = topLevelTypeFaceSet ? topLevelTypeFaceSet : &localTypefaceSet;
291 :
292 : // We delay serializing the bulk of our data until after we've serialized
293 : // factories and typefaces by first serializing to an in-memory write buffer.
294 0 : SkFactorySet factSet; // buffer refs factSet, so factSet must come first.
295 0 : SkBinaryWriteBuffer buffer(SkBinaryWriteBuffer::kCrossProcess_Flag);
296 0 : buffer.setFactoryRecorder(&factSet);
297 0 : buffer.setPixelSerializer(sk_ref_sp(pixelSerializer));
298 0 : buffer.setTypefaceRecorder(typefaceSet);
299 0 : this->flattenToBuffer(buffer);
300 :
301 : // Dummy serialize our sub-pictures for the side effect of filling
302 : // typefaceSet with typefaces from sub-pictures.
303 0 : struct DevNull: public SkWStream {
304 0 : DevNull() : fBytesWritten(0) {}
305 : size_t fBytesWritten;
306 0 : bool write(const void*, size_t size) override { fBytesWritten += size; return true; }
307 0 : size_t bytesWritten() const override { return fBytesWritten; }
308 0 : } devnull;
309 0 : for (int i = 0; i < fPictureCount; i++) {
310 0 : fPictureRefs[i]->serialize(&devnull, pixelSerializer, typefaceSet);
311 : }
312 :
313 : // We need to write factories before we write the buffer.
314 : // We need to write typefaces before we write the buffer or any sub-picture.
315 0 : WriteFactories(stream, factSet);
316 0 : if (typefaceSet == &localTypefaceSet) {
317 0 : WriteTypefaces(stream, *typefaceSet);
318 : }
319 :
320 : // Write the buffer.
321 0 : write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
322 0 : buffer.writeToStream(stream);
323 :
324 : // Write sub-pictures by calling serialize again.
325 0 : if (fPictureCount > 0) {
326 0 : write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
327 0 : for (int i = 0; i < fPictureCount; i++) {
328 0 : fPictureRefs[i]->serialize(stream, pixelSerializer, typefaceSet);
329 : }
330 : }
331 :
332 0 : stream->write32(SK_PICT_EOF_TAG);
333 0 : }
334 :
335 0 : void SkPictureData::flatten(SkWriteBuffer& buffer) const {
336 0 : write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size());
337 0 : buffer.writeByteArray(fOpData->bytes(), fOpData->size());
338 :
339 0 : if (fPictureCount > 0) {
340 0 : write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
341 0 : for (int i = 0; i < fPictureCount; i++) {
342 0 : fPictureRefs[i]->flatten(buffer);
343 : }
344 : }
345 :
346 0 : if (fDrawableCount > 0) {
347 0 : write_tag_size(buffer, SK_PICT_DRAWABLE_TAG, fDrawableCount);
348 0 : for (int i = 0; i < fDrawableCount; i++) {
349 0 : buffer.writeFlattenable(fDrawableRefs[i]);
350 : }
351 : }
352 :
353 : // Write this picture playback's data into a writebuffer
354 0 : this->flattenToBuffer(buffer);
355 0 : buffer.write32(SK_PICT_EOF_TAG);
356 0 : }
357 :
358 : ///////////////////////////////////////////////////////////////////////////////
359 :
360 : /**
361 : * Return the corresponding SkReadBuffer flags, given a set of
362 : * SkPictInfo flags.
363 : */
364 0 : static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
365 : static const struct {
366 : uint32_t fSrc;
367 : uint32_t fDst;
368 : } gSD[] = {
369 : { SkPictInfo::kCrossProcess_Flag, SkReadBuffer::kCrossProcess_Flag },
370 : { SkPictInfo::kScalarIsFloat_Flag, SkReadBuffer::kScalarIsFloat_Flag },
371 : { SkPictInfo::kPtrIs64Bit_Flag, SkReadBuffer::kPtrIs64Bit_Flag },
372 : };
373 :
374 0 : uint32_t rbMask = 0;
375 0 : for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
376 0 : if (pictInfoFlags & gSD[i].fSrc) {
377 0 : rbMask |= gSD[i].fDst;
378 : }
379 : }
380 0 : return rbMask;
381 : }
382 :
383 0 : bool SkPictureData::parseStreamTag(SkStream* stream,
384 : uint32_t tag,
385 : uint32_t size,
386 : SkImageDeserializer* factory,
387 : SkTypefacePlayback* topLevelTFPlayback) {
388 : /*
389 : * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
390 : * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
391 : * but if they are present, they need to have been seen before the buffer.
392 : *
393 : * We assert that if/when we see either of these, that we have not yet seen
394 : * the buffer tag, because if we have, then its too-late to deal with the
395 : * factories or typefaces.
396 : */
397 0 : SkDEBUGCODE(bool haveBuffer = false;)
398 :
399 0 : switch (tag) {
400 : case SK_PICT_READER_TAG:
401 0 : SkASSERT(nullptr == fOpData);
402 0 : fOpData = SkData::MakeFromStream(stream, size);
403 0 : if (!fOpData) {
404 0 : return false;
405 : }
406 0 : break;
407 : case SK_PICT_FACTORY_TAG: {
408 0 : SkASSERT(!haveBuffer);
409 0 : size = stream->readU32();
410 0 : fFactoryPlayback = new SkFactoryPlayback(size);
411 0 : for (size_t i = 0; i < size; i++) {
412 0 : SkString str;
413 0 : const size_t len = stream->readPackedUInt();
414 0 : str.resize(len);
415 0 : if (stream->read(str.writable_str(), len) != len) {
416 0 : return false;
417 : }
418 0 : fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
419 : }
420 0 : } break;
421 : case SK_PICT_TYPEFACE_TAG: {
422 0 : SkASSERT(!haveBuffer);
423 0 : const int count = SkToInt(size);
424 0 : fTFPlayback.setCount(count);
425 0 : for (int i = 0; i < count; i++) {
426 0 : sk_sp<SkTypeface> tf(SkTypeface::MakeDeserialize(stream));
427 0 : if (!tf.get()) { // failed to deserialize
428 : // fTFPlayback asserts it never has a null, so we plop in
429 : // the default here.
430 0 : tf = SkTypeface::MakeDefault();
431 : }
432 0 : fTFPlayback.set(i, tf.get());
433 : }
434 0 : } break;
435 : case SK_PICT_PICTURE_TAG: {
436 0 : fPictureCount = 0;
437 0 : fPictureRefs = new const SkPicture* [size];
438 0 : for (uint32_t i = 0; i < size; i++) {
439 0 : fPictureRefs[i] = SkPicture::MakeFromStream(stream, factory, topLevelTFPlayback).release();
440 0 : if (!fPictureRefs[i]) {
441 0 : return false;
442 : }
443 0 : fPictureCount++;
444 : }
445 0 : } break;
446 : case SK_PICT_BUFFER_SIZE_TAG: {
447 0 : SkAutoMalloc storage(size);
448 0 : if (stream->read(storage.get(), size) != size) {
449 0 : return false;
450 : }
451 :
452 : /* Should we use SkValidatingReadBuffer instead? */
453 0 : SkReadBuffer buffer(storage.get(), size);
454 0 : buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
455 0 : buffer.setVersion(fInfo.getVersion());
456 :
457 0 : if (!fFactoryPlayback) {
458 0 : return false;
459 : }
460 0 : fFactoryPlayback->setupBuffer(buffer);
461 0 : buffer.setImageDeserializer(factory);
462 :
463 0 : if (fTFPlayback.count() > 0) {
464 : // .skp files <= v43 have typefaces serialized with each sub picture.
465 0 : fTFPlayback.setupBuffer(buffer);
466 : } else {
467 : // Newer .skp files serialize all typefaces with the top picture.
468 0 : topLevelTFPlayback->setupBuffer(buffer);
469 : }
470 :
471 0 : while (!buffer.eof() && buffer.isValid()) {
472 0 : tag = buffer.readUInt();
473 0 : size = buffer.readUInt();
474 0 : if (!this->parseBufferTag(buffer, tag, size)) {
475 0 : return false;
476 : }
477 : }
478 0 : if (!buffer.isValid()) {
479 0 : return false;
480 : }
481 0 : SkDEBUGCODE(haveBuffer = true;)
482 0 : } break;
483 : }
484 0 : return true; // success
485 : }
486 :
487 0 : static const SkImage* create_image_from_buffer(SkReadBuffer& buffer) {
488 0 : return buffer.readImage().release();
489 : }
490 0 : static const SkVertices* create_vertices_from_buffer(SkReadBuffer& buffer) {
491 0 : auto data = buffer.readByteArrayAsData();
492 0 : return data ? SkVertices::Decode(data->data(), data->size()).release() : nullptr;
493 : }
494 :
495 0 : static const SkImage* create_bitmap_image_from_buffer(SkReadBuffer& buffer) {
496 0 : return buffer.readBitmapAsImage().release();
497 : }
498 :
499 : // Need a shallow wrapper to return const SkPicture* to match the other factories,
500 : // as SkPicture::CreateFromBuffer() returns SkPicture*
501 0 : static const SkPicture* create_picture_from_buffer(SkReadBuffer& buffer) {
502 0 : return SkPicture::MakeFromBuffer(buffer).release();
503 : }
504 :
505 0 : static const SkDrawable* create_drawable_from_buffer(SkReadBuffer& buffer) {
506 0 : return (SkDrawable*) buffer.readFlattenable(SkFlattenable::kSkDrawable_Type);
507 : }
508 :
509 : template <typename T>
510 0 : bool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount,
511 : const T*** array, int* outCount, const T* (*factory)(SkReadBuffer&)) {
512 0 : if (!buffer.validate((0 == *outCount) && (nullptr == *array))) {
513 0 : return false;
514 : }
515 0 : if (0 == inCount) {
516 0 : return true;
517 : }
518 0 : if (!buffer.validate(SkTFitsIn<int>(inCount))) {
519 0 : return false;
520 : }
521 :
522 0 : *outCount = inCount;
523 0 : *array = new const T* [*outCount];
524 0 : bool success = true;
525 0 : int i = 0;
526 0 : for (; i < *outCount; i++) {
527 0 : (*array)[i] = factory(buffer);
528 0 : if (nullptr == (*array)[i]) {
529 0 : success = false;
530 0 : break;
531 : }
532 : }
533 0 : if (!success) {
534 : // Delete all of the blobs that were already created (up to but excluding i):
535 0 : for (int j = 0; j < i; j++) {
536 0 : (*array)[j]->unref();
537 : }
538 : // Delete the array
539 0 : delete[] * array;
540 0 : *array = nullptr;
541 0 : *outCount = 0;
542 0 : return false;
543 : }
544 0 : return true;
545 : }
546 :
547 0 : bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) {
548 0 : switch (tag) {
549 : case SK_PICT_BITMAP_BUFFER_TAG:
550 0 : if (!new_array_from_buffer(buffer, size, &fBitmapImageRefs, &fBitmapImageCount,
551 : create_bitmap_image_from_buffer)) {
552 0 : return false;
553 : }
554 0 : break;
555 : case SK_PICT_PAINT_BUFFER_TAG: {
556 0 : if (!buffer.validate(SkTFitsIn<int>(size))) {
557 0 : return false;
558 : }
559 0 : const int count = SkToInt(size);
560 0 : fPaints.reset(count);
561 0 : for (int i = 0; i < count; ++i) {
562 0 : buffer.readPaint(&fPaints[i]);
563 : }
564 0 : } break;
565 : case SK_PICT_PATH_BUFFER_TAG:
566 0 : if (size > 0) {
567 0 : const int count = buffer.readInt();
568 0 : fPaths.reset(count);
569 0 : for (int i = 0; i < count; i++) {
570 0 : buffer.readPath(&fPaths[i]);
571 : }
572 0 : } break;
573 : case SK_PICT_TEXTBLOB_BUFFER_TAG:
574 0 : if (!new_array_from_buffer(buffer, size, &fTextBlobRefs, &fTextBlobCount,
575 : SkTextBlob::CreateFromBuffer)) {
576 0 : return false;
577 : }
578 0 : break;
579 : case SK_PICT_VERTICES_BUFFER_TAG:
580 0 : if (!new_array_from_buffer(buffer, size, &fVerticesRefs, &fVerticesCount,
581 : create_vertices_from_buffer)) {
582 0 : return false;
583 : }
584 0 : break;
585 : case SK_PICT_IMAGE_BUFFER_TAG:
586 0 : if (!new_array_from_buffer(buffer, size, &fImageRefs, &fImageCount,
587 : create_image_from_buffer)) {
588 0 : return false;
589 : }
590 0 : break;
591 : case SK_PICT_READER_TAG: {
592 0 : auto data(SkData::MakeUninitialized(size));
593 0 : if (!buffer.readByteArray(data->writable_data(), size) ||
594 0 : !buffer.validate(nullptr == fOpData)) {
595 0 : return false;
596 : }
597 0 : SkASSERT(nullptr == fOpData);
598 0 : fOpData = std::move(data);
599 0 : } break;
600 : case SK_PICT_PICTURE_TAG:
601 0 : if (!new_array_from_buffer(buffer, size, &fPictureRefs, &fPictureCount,
602 : create_picture_from_buffer)) {
603 0 : return false;
604 : }
605 0 : break;
606 : case SK_PICT_DRAWABLE_TAG:
607 0 : if (!new_array_from_buffer(buffer, size, (const SkDrawable***)&fDrawableRefs,
608 : &fDrawableCount, create_drawable_from_buffer)) {
609 0 : return false;
610 : }
611 0 : break;
612 : default:
613 : // The tag was invalid.
614 0 : return false;
615 : }
616 0 : return true; // success
617 : }
618 :
619 0 : SkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
620 : const SkPictInfo& info,
621 : SkImageDeserializer* factory,
622 : SkTypefacePlayback* topLevelTFPlayback) {
623 0 : std::unique_ptr<SkPictureData> data(new SkPictureData(info));
624 0 : if (!topLevelTFPlayback) {
625 0 : topLevelTFPlayback = &data->fTFPlayback;
626 : }
627 :
628 0 : if (!data->parseStream(stream, factory, topLevelTFPlayback)) {
629 0 : return nullptr;
630 : }
631 0 : return data.release();
632 : }
633 :
634 0 : SkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer,
635 : const SkPictInfo& info) {
636 0 : std::unique_ptr<SkPictureData> data(new SkPictureData(info));
637 0 : buffer.setVersion(info.getVersion());
638 :
639 0 : if (!data->parseBuffer(buffer)) {
640 0 : return nullptr;
641 : }
642 0 : return data.release();
643 : }
644 :
645 0 : bool SkPictureData::parseStream(SkStream* stream,
646 : SkImageDeserializer* factory,
647 : SkTypefacePlayback* topLevelTFPlayback) {
648 : for (;;) {
649 0 : uint32_t tag = stream->readU32();
650 0 : if (SK_PICT_EOF_TAG == tag) {
651 0 : break;
652 : }
653 :
654 0 : uint32_t size = stream->readU32();
655 0 : if (!this->parseStreamTag(stream, tag, size, factory, topLevelTFPlayback)) {
656 0 : return false; // we're invalid
657 : }
658 0 : }
659 0 : return true;
660 : }
661 :
662 0 : bool SkPictureData::parseBuffer(SkReadBuffer& buffer) {
663 : for (;;) {
664 0 : uint32_t tag = buffer.readUInt();
665 0 : if (SK_PICT_EOF_TAG == tag) {
666 0 : break;
667 : }
668 :
669 0 : uint32_t size = buffer.readUInt();
670 0 : if (!this->parseBufferTag(buffer, tag, size)) {
671 0 : return false; // we're invalid
672 : }
673 0 : }
674 0 : return true;
675 : }
676 :
677 : ///////////////////////////////////////////////////////////////////////////////
678 : ///////////////////////////////////////////////////////////////////////////////
679 :
680 : #if SK_SUPPORT_GPU
681 0 : bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
682 : int sampleCount) const {
683 0 : return fContentInfo.suitableForGpuRasterization(context, reason, sampleCount);
684 : }
685 :
686 0 : bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
687 : GrPixelConfig config, SkScalar dpi) const {
688 :
689 0 : if (context != nullptr) {
690 0 : return this->suitableForGpuRasterization(context, reason,
691 0 : context->getRecommendedSampleCount(config, dpi));
692 : } else {
693 0 : return this->suitableForGpuRasterization(nullptr, reason);
694 : }
695 : }
696 :
697 0 : bool SkPictureData::suitableForLayerOptimization() const {
698 0 : return fContentInfo.numLayers() > 0;
699 : }
700 : #endif
701 : ///////////////////////////////////////////////////////////////////////////////
|