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