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