epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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 | */ |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 8 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 9 | #ifndef SkPicturePlayback_DEFINED |
| 10 | #define SkPicturePlayback_DEFINED |
| 11 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 12 | #include "SkBitmap.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 13 | #include "SkPathHeap.h" |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 14 | #include "SkPicture.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 15 | #include "SkPictureFlat.h" |
| 16 | |
djsollen@google.com | 56c6977 | 2011-11-08 19:00:26 +0000 | [diff] [blame] | 17 | #ifdef SK_BUILD_FOR_ANDROID |
djsollen@google.com | f5dbe2f | 2011-04-15 13:41:26 +0000 | [diff] [blame] | 18 | #include "SkThread.h" |
| 19 | #endif |
| 20 | |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 21 | class SkData; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 22 | class SkPictureRecord; |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 23 | class SkReader32; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 24 | class SkStream; |
| 25 | class SkWStream; |
rileya@google.com | 8515e79 | 2012-09-13 21:41:51 +0000 | [diff] [blame] | 26 | class SkBBoxHierarchy; |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 27 | class SkMatrix; |
| 28 | class SkPaint; |
| 29 | class SkPath; |
rileya@google.com | 8515e79 | 2012-09-13 21:41:51 +0000 | [diff] [blame] | 30 | class SkPictureStateTree; |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 31 | class SkReadBuffer; |
| 32 | class SkRegion; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 33 | |
reed@google.com | 6756209 | 2012-06-22 15:38:39 +0000 | [diff] [blame] | 34 | struct SkPictInfo { |
| 35 | enum Flags { |
| 36 | kCrossProcess_Flag = 1 << 0, |
| 37 | kScalarIsFloat_Flag = 1 << 1, |
| 38 | kPtrIs64Bit_Flag = 1 << 2, |
| 39 | }; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 40 | |
commit-bot@chromium.org | 9e5f85e | 2014-03-12 14:46:41 +0000 | [diff] [blame] | 41 | char fMagic[8]; |
reed@google.com | 6756209 | 2012-06-22 15:38:39 +0000 | [diff] [blame] | 42 | uint32_t fVersion; |
| 43 | uint32_t fWidth; |
| 44 | uint32_t fHeight; |
| 45 | uint32_t fFlags; |
| 46 | }; |
| 47 | |
commit-bot@chromium.org | 6f4fb0f | 2014-03-03 19:18:39 +0000 | [diff] [blame] | 48 | #define SK_PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') |
| 49 | #define SK_PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') |
| 50 | #define SK_PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') |
| 51 | #define SK_PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') |
| 52 | |
| 53 | // This tag specifies the size of the ReadBuffer, needed for the following tags |
| 54 | #define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y') |
| 55 | // these are all inside the ARRAYS tag |
| 56 | #define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p') |
| 57 | #define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ') |
| 58 | #define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ') |
| 59 | |
| 60 | // Always write this guy last (with no length field afterwards) |
| 61 | #define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ') |
| 62 | |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 63 | // SkPictureContentInfo is not serialized! It is intended solely for use |
| 64 | // with suitableForGpuRasterization. |
| 65 | class SkPictureContentInfo { |
| 66 | public: |
| 67 | SkPictureContentInfo() { this->reset(); } |
| 68 | |
| 69 | SkPictureContentInfo(const SkPictureContentInfo& src) { this->set(src); } |
| 70 | |
| 71 | void set(const SkPictureContentInfo& src) { |
| 72 | fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses; |
egdaniel | 12c2198 | 2014-06-18 07:34:39 -0700 | [diff] [blame] | 73 | fNumFastPathDashEffects = src.fNumFastPathDashEffects; |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 74 | fNumAAConcavePaths = src.fNumAAConcavePaths; |
| 75 | fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths; |
| 76 | } |
| 77 | |
| 78 | void reset() { |
| 79 | fNumPaintWithPathEffectUses = 0; |
egdaniel | 12c2198 | 2014-06-18 07:34:39 -0700 | [diff] [blame] | 80 | fNumFastPathDashEffects = 0; |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 81 | fNumAAConcavePaths = 0; |
| 82 | fNumAAHairlineConcavePaths = 0; |
| 83 | } |
| 84 | |
| 85 | void swap(SkPictureContentInfo* other) { |
| 86 | SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses); |
egdaniel | 12c2198 | 2014-06-18 07:34:39 -0700 | [diff] [blame] | 87 | SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects); |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 88 | SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths); |
| 89 | SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths); |
| 90 | } |
| 91 | |
| 92 | void incPaintWithPathEffectUses() { ++fNumPaintWithPathEffectUses; } |
| 93 | int numPaintWithPathEffectUses() const { return fNumPaintWithPathEffectUses; } |
| 94 | |
egdaniel | 12c2198 | 2014-06-18 07:34:39 -0700 | [diff] [blame] | 95 | void incFastPathDashEffects() { ++fNumFastPathDashEffects; } |
| 96 | int numFastPathDashEffects() const { return fNumFastPathDashEffects; } |
| 97 | |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 98 | void incAAConcavePaths() { ++fNumAAConcavePaths; } |
| 99 | int numAAConcavePaths() const { return fNumAAConcavePaths; } |
| 100 | |
| 101 | void incAAHairlineConcavePaths() { |
| 102 | ++fNumAAHairlineConcavePaths; |
| 103 | SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths); |
| 104 | } |
| 105 | int numAAHairlineConcavePaths() const { return fNumAAHairlineConcavePaths; } |
| 106 | |
| 107 | private: |
| 108 | // This field is incremented every time a paint with a path effect is |
| 109 | // used (i.e., it is not a de-duplicated count) |
| 110 | int fNumPaintWithPathEffectUses; |
egdaniel | 12c2198 | 2014-06-18 07:34:39 -0700 | [diff] [blame] | 111 | // This field is incremented every time a paint with a path effect that is |
| 112 | // dashed, we are drawing a line, and we can use the gpu fast path |
| 113 | int fNumFastPathDashEffects; |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 114 | // This field is incremented every time an anti-aliased drawPath call is |
| 115 | // issued with a concave path |
| 116 | int fNumAAConcavePaths; |
| 117 | // This field is incremented every time a drawPath call is |
| 118 | // issued for a hairline stroked concave path. |
| 119 | int fNumAAHairlineConcavePaths; |
| 120 | }; |
| 121 | |
mtklein | d3e474e | 2014-06-27 12:34:44 -0700 | [diff] [blame^] | 122 | #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE |
djsollen@google.com | c9ab987 | 2012-08-29 18:52:07 +0000 | [diff] [blame] | 123 | /** |
| 124 | * Container for data that is needed to deep copy a SkPicture. The container |
| 125 | * enables the data to be generated once and reused for subsequent copies. |
| 126 | */ |
| 127 | struct SkPictCopyInfo { |
| 128 | SkPictCopyInfo() : initialized(false), controller(1024) {} |
| 129 | |
| 130 | bool initialized; |
| 131 | SkChunkFlatController controller; |
| 132 | SkTDArray<SkFlatData*> paintData; |
| 133 | }; |
mtklein | d3e474e | 2014-06-27 12:34:44 -0700 | [diff] [blame^] | 134 | #endif |
djsollen@google.com | c9ab987 | 2012-08-29 18:52:07 +0000 | [diff] [blame] | 135 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 136 | class SkPicturePlayback { |
| 137 | public: |
mtklein | d3e474e | 2014-06-27 12:34:44 -0700 | [diff] [blame^] | 138 | #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 139 | SkPicturePlayback(const SkPicturePlayback& src, |
commit-bot@chromium.org | 8f831f2 | 2014-04-23 22:35:42 +0000 | [diff] [blame] | 140 | SkPictCopyInfo* deepCopyInfo = NULL); |
mtklein | d3e474e | 2014-06-27 12:34:44 -0700 | [diff] [blame^] | 141 | #else |
| 142 | SkPicturePlayback(const SkPicturePlayback& src); |
| 143 | #endif |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 144 | SkPicturePlayback(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps); |
| 145 | static SkPicturePlayback* CreateFromStream(SkStream*, |
commit-bot@chromium.org | 0943f5f | 2014-03-28 18:05:47 +0000 | [diff] [blame] | 146 | const SkPictInfo&, |
scroggo@google.com | 1270532 | 2013-10-01 15:30:46 +0000 | [diff] [blame] | 147 | SkPicture::InstallPixelRefProc); |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 148 | static SkPicturePlayback* CreateFromBuffer(SkReadBuffer&, |
commit-bot@chromium.org | 8f831f2 | 2014-04-23 22:35:42 +0000 | [diff] [blame] | 149 | const SkPictInfo&); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 150 | |
| 151 | virtual ~SkPicturePlayback(); |
| 152 | |
commit-bot@chromium.org | 70512af | 2014-03-18 17:45:32 +0000 | [diff] [blame] | 153 | const SkPicture::OperationList& getActiveOps(const SkIRect& queryRect); |
| 154 | |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 155 | void setUseBBH(bool useBBH) { fUseBBH = useBBH; } |
| 156 | |
reed@google.com | 74babdf | 2013-05-20 17:02:41 +0000 | [diff] [blame] | 157 | void draw(SkCanvas& canvas, SkDrawPictureCallback*); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 158 | |
scroggo@google.com | 32ef131 | 2013-02-22 22:04:19 +0000 | [diff] [blame] | 159 | void serialize(SkWStream*, SkPicture::EncodeBitmap) const; |
commit-bot@chromium.org | 5e0995e | 2014-02-07 12:20:04 +0000 | [diff] [blame] | 160 | void flatten(SkWriteBuffer&) const; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 161 | |
| 162 | void dumpSize() const; |
vandebo@chromium.org | 74b4619 | 2012-01-28 01:45:11 +0000 | [diff] [blame] | 163 | |
tomhudson@google.com | 381010e | 2013-10-24 11:12:47 +0000 | [diff] [blame] | 164 | bool containsBitmaps() const; |
| 165 | |
djsollen@google.com | d9b0f48 | 2013-02-01 16:18:09 +0000 | [diff] [blame] | 166 | #ifdef SK_BUILD_FOR_ANDROID |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 167 | // Can be called in the middle of playback (the draw() call). WIll abort the |
| 168 | // drawing and return from draw() after the "current" op code is done |
djsollen@google.com | d9b0f48 | 2013-02-01 16:18:09 +0000 | [diff] [blame] | 169 | void abort() { fAbortCurrentPlayback = true; } |
| 170 | #endif |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 171 | |
commit-bot@chromium.org | 75cf29b | 2014-03-24 19:40:49 +0000 | [diff] [blame] | 172 | size_t curOpID() const { return fCurOffset; } |
| 173 | void resetOpID() { fCurOffset = 0; } |
| 174 | |
robertphillips@google.com | 6f6dfb4 | 2012-11-13 18:28:06 +0000 | [diff] [blame] | 175 | protected: |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 176 | explicit SkPicturePlayback(const SkPictInfo& info); |
commit-bot@chromium.org | 0943f5f | 2014-03-28 18:05:47 +0000 | [diff] [blame] | 177 | |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 178 | bool parseStream(SkStream*, SkPicture::InstallPixelRefProc); |
| 179 | bool parseBuffer(SkReadBuffer& buffer); |
robertphillips@google.com | 3f71372 | 2013-01-17 14:39:20 +0000 | [diff] [blame] | 180 | #ifdef SK_DEVELOPER |
robertphillips@google.com | 6d9c92b | 2013-05-23 13:21:18 +0000 | [diff] [blame] | 181 | virtual bool preDraw(int opIndex, int type); |
| 182 | virtual void postDraw(int opIndex); |
robertphillips@google.com | 6f6dfb4 | 2012-11-13 18:28:06 +0000 | [diff] [blame] | 183 | #endif |
| 184 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 185 | private: |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 186 | class TextContainer { |
| 187 | public: |
| 188 | size_t length() { return fByteLength; } |
| 189 | const void* text() { return (const void*) fText; } |
| 190 | size_t fByteLength; |
| 191 | const char* fText; |
| 192 | }; |
| 193 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 194 | const SkBitmap& getBitmap(SkReader32& reader) { |
scroggo@google.com | 4b90b11 | 2012-12-04 15:08:56 +0000 | [diff] [blame] | 195 | const int index = reader.readInt(); |
| 196 | if (SkBitmapHeap::INVALID_SLOT == index) { |
scroggo@google.com | 826b415 | 2013-02-28 15:50:13 +0000 | [diff] [blame] | 197 | #ifdef SK_DEBUG |
scroggo@google.com | 4b90b11 | 2012-12-04 15:08:56 +0000 | [diff] [blame] | 198 | SkDebugf("An invalid bitmap was recorded!\n"); |
scroggo@google.com | 826b415 | 2013-02-28 15:50:13 +0000 | [diff] [blame] | 199 | #endif |
scroggo@google.com | 4b90b11 | 2012-12-04 15:08:56 +0000 | [diff] [blame] | 200 | return fBadBitmap; |
| 201 | } |
djsollen@google.com | 21830d9 | 2012-08-07 19:49:41 +0000 | [diff] [blame] | 202 | return (*fBitmaps)[index]; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 203 | } |
| 204 | |
commit-bot@chromium.org | fed2ab6 | 2014-01-23 15:16:05 +0000 | [diff] [blame] | 205 | void getMatrix(SkReader32& reader, SkMatrix* matrix) { |
| 206 | reader.readMatrix(matrix); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 207 | } |
| 208 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 209 | const SkPath& getPath(SkReader32& reader) { |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 210 | int index = reader.readInt() - 1; |
| 211 | return (*fPathHeap.get())[index]; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 212 | } |
| 213 | |
robertphillips | 9b14f26 | 2014-06-04 05:40:44 -0700 | [diff] [blame] | 214 | const SkPicture* getPicture(SkReader32& reader) { |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 215 | int index = reader.readInt(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 216 | SkASSERT(index > 0 && index <= fPictureCount); |
robertphillips | 9b14f26 | 2014-06-04 05:40:44 -0700 | [diff] [blame] | 217 | return fPictureRefs[index - 1]; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 218 | } |
vandebo@chromium.org | 74b4619 | 2012-01-28 01:45:11 +0000 | [diff] [blame] | 219 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 220 | const SkPaint* getPaint(SkReader32& reader) { |
| 221 | int index = reader.readInt(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 222 | if (index == 0) { |
| 223 | return NULL; |
| 224 | } |
reed@google.com | f4cc187 | 2012-07-23 15:04:45 +0000 | [diff] [blame] | 225 | return &(*fPaints)[index - 1]; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 226 | } |
| 227 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 228 | const SkRect* getRectPtr(SkReader32& reader) { |
| 229 | if (reader.readBool()) { |
| 230 | return &reader.skipT<SkRect>(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 231 | } else { |
| 232 | return NULL; |
| 233 | } |
| 234 | } |
| 235 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 236 | const SkIRect* getIRectPtr(SkReader32& reader) { |
| 237 | if (reader.readBool()) { |
| 238 | return &reader.skipT<SkIRect>(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 239 | } else { |
| 240 | return NULL; |
| 241 | } |
| 242 | } |
| 243 | |
commit-bot@chromium.org | fed2ab6 | 2014-01-23 15:16:05 +0000 | [diff] [blame] | 244 | void getRegion(SkReader32& reader, SkRegion* region) { |
| 245 | reader.readRegion(region); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 246 | } |
skia.committer@gmail.com | 306ab9d | 2012-12-13 02:01:33 +0000 | [diff] [blame] | 247 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 248 | void getText(SkReader32& reader, TextContainer* text) { |
| 249 | size_t length = text->fByteLength = reader.readInt(); |
| 250 | text->fText = (const char*)reader.skip(length); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 251 | } |
| 252 | |
| 253 | void init(); |
| 254 | |
| 255 | #ifdef SK_DEBUG_SIZE |
| 256 | public: |
| 257 | int size(size_t* sizePtr); |
| 258 | int bitmaps(size_t* size); |
| 259 | int paints(size_t* size); |
| 260 | int paths(size_t* size); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 261 | #endif |
| 262 | |
| 263 | #ifdef SK_DEBUG_DUMP |
| 264 | private: |
| 265 | void dumpBitmap(const SkBitmap& bitmap) const; |
| 266 | void dumpMatrix(const SkMatrix& matrix) const; |
| 267 | void dumpPaint(const SkPaint& paint) const; |
| 268 | void dumpPath(const SkPath& path) const; |
| 269 | void dumpPicture(const SkPicture& picture) const; |
| 270 | void dumpRegion(const SkRegion& region) const; |
| 271 | int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType); |
| 272 | int dumpInt(char* bufferPtr, char* buffer, char* name); |
| 273 | int dumpRect(char* bufferPtr, char* buffer, char* name); |
| 274 | int dumpPoint(char* bufferPtr, char* buffer, char* name); |
| 275 | void dumpPointArray(char** bufferPtrPtr, char* buffer, int count); |
| 276 | int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr); |
| 277 | int dumpRectPtr(char* bufferPtr, char* buffer, char* name); |
| 278 | int dumpScalar(char* bufferPtr, char* buffer, char* name); |
| 279 | void dumpText(char** bufferPtrPtr, char* buffer); |
| 280 | void dumpStream(); |
| 281 | |
| 282 | public: |
| 283 | void dump() const; |
| 284 | #endif |
| 285 | |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 286 | #if SK_SUPPORT_GPU |
egdaniel | 12c2198 | 2014-06-18 07:34:39 -0700 | [diff] [blame] | 287 | /** |
| 288 | * sampleCount is the number of samples-per-pixel or zero if non-MSAA. |
| 289 | * It is defaulted to be zero. |
| 290 | */ |
| 291 | bool suitableForGpuRasterization(GrContext* context, const char **reason, |
| 292 | int sampleCount = 0) const; |
| 293 | |
| 294 | /** |
| 295 | * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount |
| 296 | * and then calls the above version of suitableForGpuRasterization |
| 297 | */ |
| 298 | bool suitableForGpuRasterization(GrContext* context, const char **reason, |
| 299 | GrPixelConfig config, SkScalar dpi) const; |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 300 | #endif |
| 301 | |
reed@google.com | 6756209 | 2012-06-22 15:38:39 +0000 | [diff] [blame] | 302 | private: // these help us with reading/writing |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 303 | bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc); |
| 304 | bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size); |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 305 | void flattenToBuffer(SkWriteBuffer&) const; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 306 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 307 | private: |
commit-bot@chromium.org | 66ec1e4 | 2014-04-29 17:22:54 +0000 | [diff] [blame] | 308 | friend class SkPicture; |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 309 | friend class SkGpuDevice; // for access to setDrawLimits & setReplacements |
commit-bot@chromium.org | 66ec1e4 | 2014-04-29 17:22:54 +0000 | [diff] [blame] | 310 | |
scroggo@google.com | 4b90b11 | 2012-12-04 15:08:56 +0000 | [diff] [blame] | 311 | // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty |
| 312 | // bitmap allows playback to draw nothing and move on. |
| 313 | SkBitmap fBadBitmap; |
| 314 | |
djsollen@google.com | c9ab987 | 2012-08-29 18:52:07 +0000 | [diff] [blame] | 315 | SkAutoTUnref<SkBitmapHeap> fBitmapHeap; |
djsollen@google.com | c9ab987 | 2012-08-29 18:52:07 +0000 | [diff] [blame] | 316 | |
reed@google.com | f4cc187 | 2012-07-23 15:04:45 +0000 | [diff] [blame] | 317 | SkTRefArray<SkBitmap>* fBitmaps; |
reed@google.com | f4cc187 | 2012-07-23 15:04:45 +0000 | [diff] [blame] | 318 | SkTRefArray<SkPaint>* fPaints; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 319 | |
reed@google.com | ddf98a8 | 2012-07-21 20:31:09 +0000 | [diff] [blame] | 320 | SkData* fOpData; // opcodes and parameters |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 321 | |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 322 | SkAutoTUnref<const SkPathHeap> fPathHeap; // reference counted |
| 323 | |
robertphillips | 9b14f26 | 2014-06-04 05:40:44 -0700 | [diff] [blame] | 324 | const SkPicture** fPictureRefs; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 325 | int fPictureCount; |
reed@android.com | 09b84a0 | 2009-06-26 20:22:26 +0000 | [diff] [blame] | 326 | |
rileya@google.com | 8515e79 | 2012-09-13 21:41:51 +0000 | [diff] [blame] | 327 | SkBBoxHierarchy* fBoundingHierarchy; |
| 328 | SkPictureStateTree* fStateTree; |
| 329 | |
robertphillips | 0bdbea7 | 2014-06-11 11:37:55 -0700 | [diff] [blame] | 330 | SkPictureContentInfo fContentInfo; |
| 331 | |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 332 | // Limit the opcode playback to be between the offsets 'start' and 'stop'. |
| 333 | // The opcode at 'start' should be a saveLayer while the opcode at |
| 334 | // 'stop' should be a restore. Neither of those commands will be issued. |
| 335 | // Set both start & stop to 0 to disable draw limiting |
| 336 | // Draw limiting cannot be enabled at the same time as draw replacing |
| 337 | void setDrawLimits(size_t start, size_t stop) { |
| 338 | SkASSERT(NULL == fReplacements); |
| 339 | fStart = start; |
| 340 | fStop = stop; |
| 341 | } |
| 342 | |
| 343 | // PlaybackReplacements collects op ranges that can be replaced with |
| 344 | // a single drawBitmap call (using a precomputed bitmap). |
| 345 | class PlaybackReplacements { |
| 346 | public: |
| 347 | // All the operations between fStart and fStop (inclusive) will be replaced with |
| 348 | // a single drawBitmap call using fPos, fBM and fPaint. |
| 349 | // fPaint will be NULL if the picture's paint wasn't copyable |
| 350 | struct ReplacementInfo { |
| 351 | size_t fStart; |
| 352 | size_t fStop; |
commit-bot@chromium.org | f97d65d | 2014-05-08 23:24:05 +0000 | [diff] [blame] | 353 | SkIPoint fPos; |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 354 | SkBitmap* fBM; // fBM is allocated so ReplacementInfo can remain POD |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 355 | const SkPaint* fPaint; // Note: this object doesn't own the paint |
| 356 | }; |
| 357 | |
| 358 | ~PlaybackReplacements() { this->freeAll(); } |
| 359 | |
skia.committer@gmail.com | b2c82c9 | 2014-05-08 03:05:29 +0000 | [diff] [blame] | 360 | // Add a new replacement range. The replacement ranges should be |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 361 | // sorted in increasing order and non-overlapping (esp. no nested |
| 362 | // saveLayers). |
| 363 | ReplacementInfo* push(); |
| 364 | |
| 365 | private: |
| 366 | friend class SkPicturePlayback; // for access to lookupByStart |
| 367 | |
| 368 | // look up a replacement range by its start offset |
| 369 | ReplacementInfo* lookupByStart(size_t start); |
| 370 | |
| 371 | void freeAll(); |
| 372 | |
commit-bot@chromium.org | f97d65d | 2014-05-08 23:24:05 +0000 | [diff] [blame] | 373 | #ifdef SK_DEBUG |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 374 | void validate() const; |
commit-bot@chromium.org | f97d65d | 2014-05-08 23:24:05 +0000 | [diff] [blame] | 375 | #endif |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 376 | |
| 377 | SkTDArray<ReplacementInfo> fReplacements; |
| 378 | }; |
| 379 | |
robertphillips@google.com | beb1af2 | 2014-05-07 21:31:09 +0000 | [diff] [blame] | 380 | // Replace all the draw ops in the replacement ranges in 'replacements' with |
| 381 | // the associated drawBitmap call |
| 382 | // Draw replacing cannot be enabled at the same time as draw limiting |
| 383 | void setReplacements(PlaybackReplacements* replacements) { |
| 384 | SkASSERT(fStart == 0 && fStop == 0); |
| 385 | fReplacements = replacements; |
| 386 | } |
| 387 | |
| 388 | bool fUseBBH; |
| 389 | size_t fStart; |
| 390 | size_t fStop; |
| 391 | PlaybackReplacements* fReplacements; |
| 392 | |
commit-bot@chromium.org | 70512af | 2014-03-18 17:45:32 +0000 | [diff] [blame] | 393 | class CachedOperationList : public SkPicture::OperationList { |
| 394 | public: |
| 395 | CachedOperationList() { |
| 396 | fCacheQueryRect.setEmpty(); |
| 397 | } |
| 398 | |
| 399 | virtual bool valid() const { return true; } |
| 400 | virtual int numOps() const SK_OVERRIDE { return fOps.count(); } |
| 401 | virtual uint32_t offset(int index) const SK_OVERRIDE; |
| 402 | virtual const SkMatrix& matrix(int index) const SK_OVERRIDE; |
| 403 | |
| 404 | // The query rect for which the cached active ops are valid |
| 405 | SkIRect fCacheQueryRect; |
| 406 | |
| 407 | // The operations which are active within 'fCachedQueryRect' |
| 408 | SkTDArray<void*> fOps; |
| 409 | |
| 410 | private: |
| 411 | typedef SkPicture::OperationList INHERITED; |
| 412 | }; |
| 413 | |
| 414 | CachedOperationList* fCachedActiveOps; |
| 415 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 416 | SkTypefacePlayback fTFPlayback; |
djsollen@google.com | 21830d9 | 2012-08-07 19:49:41 +0000 | [diff] [blame] | 417 | SkFactoryPlayback* fFactoryPlayback; |
commit-bot@chromium.org | 75cf29b | 2014-03-24 19:40:49 +0000 | [diff] [blame] | 418 | |
| 419 | // The offset of the current operation when within the draw method |
| 420 | size_t fCurOffset; |
| 421 | |
commit-bot@chromium.org | 0943f5f | 2014-03-28 18:05:47 +0000 | [diff] [blame] | 422 | const SkPictInfo fInfo; |
| 423 | |
commit-bot@chromium.org | 8f831f2 | 2014-04-23 22:35:42 +0000 | [diff] [blame] | 424 | static void WriteFactories(SkWStream* stream, const SkFactorySet& rec); |
| 425 | static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec); |
| 426 | |
robertphillips | e26e65e | 2014-06-12 05:51:22 -0700 | [diff] [blame] | 427 | void initForPlayback() const; |
| 428 | |
djsollen@google.com | 56c6977 | 2011-11-08 19:00:26 +0000 | [diff] [blame] | 429 | #ifdef SK_BUILD_FOR_ANDROID |
djsollen@google.com | f5dbe2f | 2011-04-15 13:41:26 +0000 | [diff] [blame] | 430 | SkMutex fDrawMutex; |
djsollen@google.com | d9b0f48 | 2013-02-01 16:18:09 +0000 | [diff] [blame] | 431 | bool fAbortCurrentPlayback; |
djsollen@google.com | f5dbe2f | 2011-04-15 13:41:26 +0000 | [diff] [blame] | 432 | #endif |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 433 | }; |
| 434 | |
| 435 | #endif |