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