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 #ifndef SkPictureData_DEFINED
      9 #define SkPictureData_DEFINED
     10 
     11 #include "SkBitmap.h"
     12 #include "SkPathHeap.h"
     13 #include "SkPicture.h"
     14 #include "SkPictureContentInfo.h"
     15 #include "SkPictureFlat.h"
     16 #include "SkPictureStateTree.h"
     17 
     18 class SkData;
     19 class SkPictureRecord;
     20 class SkReader32;
     21 class SkStream;
     22 class SkWStream;
     23 class SkBBoxHierarchy;
     24 class SkMatrix;
     25 class SkPaint;
     26 class SkPath;
     27 class SkPictureStateTree;
     28 class SkReadBuffer;
     29 class SkTextBlob;
     30 
     31 struct SkPictInfo {
     32     enum Flags {
     33         kCrossProcess_Flag      = 1 << 0,
     34         kScalarIsFloat_Flag     = 1 << 1,
     35         kPtrIs64Bit_Flag        = 1 << 2,
     36     };
     37 
     38     char        fMagic[8];
     39     uint32_t    fVersion;
     40     SkRect      fCullRect;
     41     uint32_t    fFlags;
     42 };
     43 
     44 #define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
     45 #define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
     46 #define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
     47 #define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
     48 
     49 // This tag specifies the size of the ReadBuffer, needed for the following tags
     50 #define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
     51 // these are all inside the ARRAYS tag
     52 #define SK_PICT_BITMAP_BUFFER_TAG   SkSetFourByteTag('b', 't', 'm', 'p')
     53 #define SK_PICT_PAINT_BUFFER_TAG    SkSetFourByteTag('p', 'n', 't', ' ')
     54 #define SK_PICT_PATH_BUFFER_TAG     SkSetFourByteTag('p', 't', 'h', ' ')
     55 #define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
     56 
     57 // Always write this guy last (with no length field afterwards)
     58 #define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
     59 
     60 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
     61 /**
     62  * Container for data that is needed to deep copy a SkPicture. The container
     63  * enables the data to be generated once and reused for subsequent copies.
     64  */
     65 struct SkPictCopyInfo {
     66     SkPictCopyInfo() : controller(1024) {}
     67 
     68     SkChunkFlatController controller;
     69     SkTDArray<SkFlatData*> paintData;
     70 };
     71 #endif
     72 
     73 class SkPictureData {
     74 public:
     75 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
     76     SkPictureData(const SkPictureData& src, SkPictCopyInfo* deepCopyInfo = NULL);
     77 #endif
     78     SkPictureData(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps);
     79     static SkPictureData* CreateFromStream(SkStream*,
     80                                            const SkPictInfo&,
     81                                            SkPicture::InstallPixelRefProc);
     82     static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
     83 
     84     virtual ~SkPictureData();
     85 
     86     const SkPicture::OperationList* getActiveOps(const SkRect& queryRect) const;
     87 
     88     void serialize(SkWStream*, SkPicture::EncodeBitmap) const;
     89     void flatten(SkWriteBuffer&) const;
     90 
     91     bool containsBitmaps() const;
     92 
     93     bool hasText() const { return fContentInfo.hasText(); }
     94 
     95     int opCount() const { return fContentInfo.numOperations(); }
     96 
     97     const SkData* opData() const { return fOpData; }
     98 
     99 protected:
    100     explicit SkPictureData(const SkPictInfo& info);
    101 
    102     bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
    103     bool parseBuffer(SkReadBuffer& buffer);
    104 
    105 public:
    106     const SkBitmap& getBitmap(SkReader32* reader) const {
    107         const int index = reader->readInt();
    108         if (SkBitmapHeap::INVALID_SLOT == index) {
    109 #ifdef SK_DEBUG
    110             SkDebugf("An invalid bitmap was recorded!\n");
    111 #endif
    112             return fBadBitmap;
    113         }
    114         return (*fBitmaps)[index];
    115     }
    116 
    117     const SkPath& getPath(SkReader32* reader) const {
    118         int index = reader->readInt() - 1;
    119         return (*fPathHeap.get())[index];
    120     }
    121 
    122     const SkPicture* getPicture(SkReader32* reader) const {
    123         int index = reader->readInt();
    124         SkASSERT(index > 0 && index <= fPictureCount);
    125         return fPictureRefs[index - 1];
    126     }
    127 
    128     const SkPaint* getPaint(SkReader32* reader) const {
    129         int index = reader->readInt();
    130         if (index == 0) {
    131             return NULL;
    132         }
    133         return &(*fPaints)[index - 1];
    134     }
    135 
    136     const SkTextBlob* getTextBlob(SkReader32* reader) const {
    137         int index = reader->readInt();
    138         SkASSERT(index > 0 && index <= fTextBlobCount);
    139         return fTextBlobRefs[index - 1];
    140     }
    141 
    142     void initIterator(SkPictureStateTree::Iterator* iter,
    143                       const SkTDArray<void*>& draws,
    144                       SkCanvas* canvas) const {
    145         if (fStateTree) {
    146             fStateTree->initIterator(iter, draws, canvas);
    147         }
    148     }
    149 
    150 #if SK_SUPPORT_GPU
    151     /**
    152      * sampleCount is the number of samples-per-pixel or zero if non-MSAA.
    153      * It is defaulted to be zero.
    154      */
    155     bool suitableForGpuRasterization(GrContext* context, const char **reason,
    156                                      int sampleCount = 0) const;
    157 
    158     /**
    159      * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount
    160      * and then calls the above version of suitableForGpuRasterization
    161      */
    162     bool suitableForGpuRasterization(GrContext* context, const char **reason,
    163                                      GrPixelConfig config, SkScalar dpi) const;
    164 
    165     bool suitableForLayerOptimization() const;
    166 #endif
    167 
    168 private:
    169     friend class SkPicture; // needed in SkPicture::clone (rm when it is removed)
    170 
    171     void init();
    172 
    173     // these help us with reading/writing
    174     bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc);
    175     bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
    176     void flattenToBuffer(SkWriteBuffer&) const;
    177 
    178     // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
    179     // bitmap allows playback to draw nothing and move on.
    180     SkBitmap fBadBitmap;
    181 
    182     SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
    183 
    184     SkTRefArray<SkBitmap>* fBitmaps;
    185     SkTRefArray<SkPaint>* fPaints;
    186 
    187     SkData* fOpData;    // opcodes and parameters
    188 
    189     SkAutoTUnref<const SkPathHeap> fPathHeap;  // reference counted
    190 
    191     const SkPicture** fPictureRefs;
    192     int fPictureCount;
    193     const SkTextBlob** fTextBlobRefs;
    194     int fTextBlobCount;
    195 
    196     SkBBoxHierarchy* fBoundingHierarchy;
    197     SkPictureStateTree* fStateTree;
    198 
    199     SkPictureContentInfo fContentInfo;
    200 
    201     SkTypefacePlayback fTFPlayback;
    202     SkFactoryPlayback* fFactoryPlayback;
    203 
    204     const SkPictInfo fInfo;
    205 
    206     static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
    207     static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
    208 
    209     void initForPlayback() const;
    210 };
    211 
    212 #endif
    213