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