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