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 
     25 #ifdef SK_BUILD_FOR_ANDROID
     26 #include "SkThread.h"
     27 #endif
     28 
     29 class SkPictureRecord;
     30 class SkStream;
     31 class SkWStream;
     32 class SkBBoxHierarchy;
     33 class SkPictureStateTree;
     34 
     35 struct SkPictInfo {
     36     enum Flags {
     37         kCrossProcess_Flag      = 1 << 0,
     38         kScalarIsFloat_Flag     = 1 << 1,
     39         kPtrIs64Bit_Flag        = 1 << 2,
     40     };
     41 
     42     uint32_t    fVersion;
     43     uint32_t    fWidth;
     44     uint32_t    fHeight;
     45     uint32_t    fFlags;
     46 };
     47 
     48 /**
     49  * Container for data that is needed to deep copy a SkPicture. The container
     50  * enables the data to be generated once and reused for subsequent copies.
     51  */
     52 struct SkPictCopyInfo {
     53     SkPictCopyInfo() : initialized(false), controller(1024) {}
     54 
     55     bool initialized;
     56     SkChunkFlatController controller;
     57     SkTDArray<SkFlatData*> paintData;
     58 };
     59 
     60 class SkPicturePlayback {
     61 public:
     62     SkPicturePlayback();
     63     SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL);
     64     explicit SkPicturePlayback(const SkPictureRecord& record, bool deepCopy = false);
     65     SkPicturePlayback(SkStream*, const SkPictInfo&, SkPicture::InstallPixelRefProc);
     66 
     67     virtual ~SkPicturePlayback();
     68 
     69     void draw(SkCanvas& canvas, SkDrawPictureCallback*);
     70 
     71     void serialize(SkWStream*, SkPicture::EncodeBitmap) const;
     72 
     73     void dumpSize() const;
     74 
     75 #ifdef SK_BUILD_FOR_ANDROID
     76     // Can be called in the middle of playback (the draw() call). WIll abort the
     77     // drawing and return from draw() after the "current" op code is done
     78     void abort() { fAbortCurrentPlayback = true; }
     79 #endif
     80 
     81 protected:
     82 #ifdef SK_DEVELOPER
     83     virtual bool preDraw(int opIndex, int type);
     84     virtual void postDraw(int opIndex);
     85 #endif
     86 
     87 private:
     88     class TextContainer {
     89     public:
     90         size_t length() { return fByteLength; }
     91         const void* text() { return (const void*) fText; }
     92         size_t fByteLength;
     93         const char* fText;
     94     };
     95 
     96     const SkBitmap& getBitmap(SkReader32& reader) {
     97         const int index = reader.readInt();
     98         if (SkBitmapHeap::INVALID_SLOT == index) {
     99 #ifdef SK_DEBUG
    100             SkDebugf("An invalid bitmap was recorded!\n");
    101 #endif
    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     void parseStreamTag(SkStream*, const SkPictInfo&, uint32_t tag, size_t size,
    195                         SkPicture::InstallPixelRefProc);
    196     void 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