Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #ifndef SkPicturePlayback_DEFINED
      9 #define SkPicturePlayback_DEFINED
     10 
     11 #include "SkPicture.h"
     12 #include "SkReader32.h"
     13 
     14 #include "SkBitmap.h"
     15 #include "SkData.h"
     16 #include "SkMatrix.h"
     17 #include "SkOrderedReadBuffer.h"
     18 #include "SkPaint.h"
     19 #include "SkPath.h"
     20 #include "SkPathHeap.h"
     21 #include "SkRegion.h"
     22 #include "SkRRect.h"
     23 #include "SkPictureFlat.h"
     24 #include "SkSerializationHelpers.h"
     25 
     26 #ifdef SK_BUILD_FOR_ANDROID
     27 #include "SkThread.h"
     28 #endif
     29 
     30 class SkPictureRecord;
     31 class SkStream;
     32 class SkWStream;
     33 class SkBBoxHierarchy;
     34 class SkPictureStateTree;
     35 
     36 struct SkPictInfo {
     37     enum Flags {
     38         kCrossProcess_Flag      = 1 << 0,
     39         kScalarIsFloat_Flag     = 1 << 1,
     40         kPtrIs64Bit_Flag        = 1 << 2,
     41     };
     42 
     43     uint32_t    fVersion;
     44     uint32_t    fWidth;
     45     uint32_t    fHeight;
     46     uint32_t    fFlags;
     47 };
     48 
     49 /**
     50  * Container for data that is needed to deep copy a SkPicture. The container
     51  * enables the data to be generated once and reused for subsequent copies.
     52  */
     53 struct SkPictCopyInfo {
     54     SkPictCopyInfo() : initialized(false), controller(1024) {}
     55 
     56     bool initialized;
     57     SkChunkFlatController controller;
     58     SkTDArray<SkFlatData*> paintData;
     59 };
     60 
     61 class SkPicturePlayback {
     62 public:
     63     SkPicturePlayback();
     64     SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL);
     65     explicit SkPicturePlayback(const SkPictureRecord& record, bool deepCopy = false);
     66     SkPicturePlayback(SkStream*, const SkPictInfo&, bool* isValid,
     67                       SkSerializationHelpers::DecodeBitmap decoder);
     68 
     69     virtual ~SkPicturePlayback();
     70 
     71     void draw(SkCanvas& canvas);
     72 
     73     void serialize(SkWStream*, SkSerializationHelpers::EncodeBitmap) const;
     74 
     75     void dumpSize() const;
     76 
     77 #ifdef SK_BUILD_FOR_ANDROID
     78     // Can be called in the middle of playback (the draw() call). WIll abort the
     79     // drawing and return from draw() after the "current" op code is done
     80     void abort() { fAbortCurrentPlayback = true; }
     81 #endif
     82 
     83 protected:
     84 #ifdef SK_DEVELOPER
     85     virtual size_t preDraw(size_t offset, int type);
     86     virtual void postDraw(size_t offset);
     87 #endif
     88 
     89 private:
     90     class TextContainer {
     91     public:
     92         size_t length() { return fByteLength; }
     93         const void* text() { return (const void*) fText; }
     94         size_t fByteLength;
     95         const char* fText;
     96     };
     97 
     98     const SkBitmap& getBitmap(SkReader32& reader) {
     99         const int index = reader.readInt();
    100         if (SkBitmapHeap::INVALID_SLOT == index) {
    101             SkDebugf("An invalid bitmap was recorded!\n");
    102             return fBadBitmap;
    103         }
    104         return (*fBitmaps)[index];
    105     }
    106 
    107     const SkMatrix* getMatrix(SkReader32& reader) {
    108         int index = reader.readInt();
    109         if (index == 0) {
    110             return NULL;
    111         }
    112         return &(*fMatrices)[index - 1];
    113     }
    114 
    115     const SkPath& getPath(SkReader32& reader) {
    116         return (*fPathHeap)[reader.readInt() - 1];
    117     }
    118 
    119     SkPicture& getPicture(SkReader32& reader) {
    120         int index = reader.readInt();
    121         SkASSERT(index > 0 && index <= fPictureCount);
    122         return *fPictureRefs[index - 1];
    123     }
    124 
    125     const SkPaint* getPaint(SkReader32& reader) {
    126         int index = reader.readInt();
    127         if (index == 0) {
    128             return NULL;
    129         }
    130         return &(*fPaints)[index - 1];
    131     }
    132 
    133     const SkRect* getRectPtr(SkReader32& reader) {
    134         if (reader.readBool()) {
    135             return &reader.skipT<SkRect>();
    136         } else {
    137             return NULL;
    138         }
    139     }
    140 
    141     const SkIRect* getIRectPtr(SkReader32& reader) {
    142         if (reader.readBool()) {
    143             return &reader.skipT<SkIRect>();
    144         } else {
    145             return NULL;
    146         }
    147     }
    148 
    149     const SkRegion& getRegion(SkReader32& reader) {
    150         int index = reader.readInt();
    151         return (*fRegions)[index - 1];
    152     }
    153 
    154     void getText(SkReader32& reader, TextContainer* text) {
    155         size_t length = text->fByteLength = reader.readInt();
    156         text->fText = (const char*)reader.skip(length);
    157     }
    158 
    159     void init();
    160 
    161 #ifdef SK_DEBUG_SIZE
    162 public:
    163     int size(size_t* sizePtr);
    164     int bitmaps(size_t* size);
    165     int paints(size_t* size);
    166     int paths(size_t* size);
    167     int regions(size_t* size);
    168 #endif
    169 
    170 #ifdef SK_DEBUG_DUMP
    171 private:
    172     void dumpBitmap(const SkBitmap& bitmap) const;
    173     void dumpMatrix(const SkMatrix& matrix) const;
    174     void dumpPaint(const SkPaint& paint) const;
    175     void dumpPath(const SkPath& path) const;
    176     void dumpPicture(const SkPicture& picture) const;
    177     void dumpRegion(const SkRegion& region) const;
    178     int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType);
    179     int dumpInt(char* bufferPtr, char* buffer, char* name);
    180     int dumpRect(char* bufferPtr, char* buffer, char* name);
    181     int dumpPoint(char* bufferPtr, char* buffer, char* name);
    182     void dumpPointArray(char** bufferPtrPtr, char* buffer, int count);
    183     int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr);
    184     int dumpRectPtr(char* bufferPtr, char* buffer, char* name);
    185     int dumpScalar(char* bufferPtr, char* buffer, char* name);
    186     void dumpText(char** bufferPtrPtr, char* buffer);
    187     void dumpStream();
    188 
    189 public:
    190     void dump() const;
    191 #endif
    192 
    193 private:    // these help us with reading/writing
    194     bool parseStreamTag(SkStream*, const SkPictInfo&, uint32_t tag, size_t size,
    195                         SkSerializationHelpers::DecodeBitmap decoder);
    196     bool parseBufferTag(SkOrderedReadBuffer&, uint32_t tag, size_t size);
    197     void flattenToBuffer(SkOrderedWriteBuffer&) const;
    198 
    199 private:
    200     // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
    201     // bitmap allows playback to draw nothing and move on.
    202     SkBitmap fBadBitmap;
    203 
    204     SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
    205     SkAutoTUnref<SkPathHeap> fPathHeap;
    206 
    207     SkTRefArray<SkBitmap>* fBitmaps;
    208     SkTRefArray<SkMatrix>* fMatrices;
    209     SkTRefArray<SkPaint>* fPaints;
    210     SkTRefArray<SkRegion>* fRegions;
    211 
    212     SkData* fOpData;    // opcodes and parameters
    213 
    214     SkPicture** fPictureRefs;
    215     int fPictureCount;
    216 
    217     SkBBoxHierarchy* fBoundingHierarchy;
    218     SkPictureStateTree* fStateTree;
    219 
    220     SkTypefacePlayback fTFPlayback;
    221     SkFactoryPlayback* fFactoryPlayback;
    222 #ifdef SK_BUILD_FOR_ANDROID
    223     SkMutex fDrawMutex;
    224     bool fAbortCurrentPlayback;
    225 #endif
    226 };
    227 
    228 #endif
    229