| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrPictureUtils.h" | 8 #include "GrPictureUtils.h" |
| 9 #include "SkCanvasPriv.h" | 9 |
| 10 #include "SkDevice.h" | |
| 11 #include "SkDraw.h" | |
| 12 #include "SkPaintPriv.h" | 10 #include "SkPaintPriv.h" |
| 13 #include "SkPictureData.h" | 11 #include "SkRecord.h" |
| 14 #include "SkPicturePlayback.h" | 12 #include "SkRecords.h" |
| 15 | 13 |
| 16 SkPicture::AccelData::Key GrAccelData::ComputeAccelDataKey() { | 14 SkPicture::AccelData::Key GrAccelData::ComputeAccelDataKey() { |
| 17 static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::Genera
teDomain(); | 15 static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::Genera
teDomain(); |
| 18 | 16 |
| 19 return gGPUID; | 17 return gGPUID; |
| 20 } | 18 } |
| 21 | 19 |
| 22 // The GrGather device performs GPU-backend-specific preprocessing on | 20 // SkRecord visitor to gather saveLayer/restore information. |
| 23 // a picture. The results are stored in a GrAccelData. | 21 class CollectLayers { |
| 24 // | |
| 25 // Currently the only interesting work is done in drawDevice (i.e., when a | |
| 26 // saveLayer is collapsed back into its parent) and, maybe, in onCreateDevice. | |
| 27 // All the current work could be done much more efficiently by just traversing t
he | |
| 28 // raw op codes in the SkPicture (although we would still need to replay all the | |
| 29 // clip calls). | |
| 30 class GrGatherDevice : public SkBaseDevice { | |
| 31 public: | 22 public: |
| 32 SK_DECLARE_INST_COUNT(GrGatherDevice) | 23 CollectLayers(const SkPicture* pict, GrAccelData* accelData) |
| 33 | 24 : fPictureID(pict->uniqueID()) |
| 34 GrGatherDevice(int width, int height, SkPicturePlayback* playback, GrAccelDa
ta* accelData, | 25 , fCTM(&SkMatrix::I()) |
| 35 int saveLayerDepth) { | 26 , fCurrentClipBounds(SkIRect::MakeXYWH(0, 0, pict->width(), pict->height
())) |
| 36 fPlayback = playback; | 27 , fSaveLayersInStack(0) |
| 37 fSaveLayerDepth = saveLayerDepth; | 28 , fAccelData(accelData) { |
| 38 fInfo.fValid = true; | 29 |
| 39 fInfo.fSize.set(width, height); | 30 if (NULL == pict->fRecord.get()) { |
| 40 fInfo.fPaint = NULL; | |
| 41 fInfo.fSaveLayerOpID = fPlayback->curOpID(); | |
| 42 fInfo.fRestoreOpID = 0; | |
| 43 fInfo.fHasNestedLayers = false; | |
| 44 fInfo.fIsNested = (2 == fSaveLayerDepth); | |
| 45 | |
| 46 fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(fInfo.fSize.fWidth, fInfo.
fSize.fHeight)); | |
| 47 fAccelData = accelData; | |
| 48 fAlreadyDrawn = false; | |
| 49 } | |
| 50 | |
| 51 virtual ~GrGatherDevice() { } | |
| 52 | |
| 53 virtual SkImageInfo imageInfo() const SK_OVERRIDE { | |
| 54 return fEmptyBitmap.info(); | |
| 55 } | |
| 56 | |
| 57 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG | |
| 58 virtual void writePixels(const SkBitmap& bitmap, int x, int y, | |
| 59 SkCanvas::Config8888 config8888) SK_OVERRIDE { | |
| 60 NotSupported(); | |
| 61 } | |
| 62 #endif | |
| 63 virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } | |
| 64 | |
| 65 protected: | |
| 66 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { | |
| 67 return false; | |
| 68 } | |
| 69 virtual void clear(SkColor color) SK_OVERRIDE { | |
| 70 NothingToDo(); | |
| 71 } | |
| 72 virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE
{ | |
| 73 } | |
| 74 virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t
count, | |
| 75 const SkPoint points[], const SkPaint& paint) SK_OVE
RRIDE { | |
| 76 } | |
| 77 virtual void drawRect(const SkDraw& draw, const SkRect& rect, | |
| 78 const SkPaint& paint) SK_OVERRIDE { | |
| 79 } | |
| 80 virtual void drawOval(const SkDraw& draw, const SkRect& rect, | |
| 81 const SkPaint& paint) SK_OVERRIDE { | |
| 82 } | |
| 83 virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect, | |
| 84 const SkPaint& paint) SK_OVERRIDE { | |
| 85 } | |
| 86 virtual void drawPath(const SkDraw& draw, const SkPath& path, | |
| 87 const SkPaint& paint, const SkMatrix* prePathMatrix, | |
| 88 bool pathIsMutable) SK_OVERRIDE { | |
| 89 } | |
| 90 virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap, | |
| 91 const SkMatrix& matrix, const SkPaint& paint) SK_OVE
RRIDE { | |
| 92 } | |
| 93 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, | |
| 94 int x, int y, const SkPaint& paint) SK_OVERRIDE { | |
| 95 } | |
| 96 virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, | |
| 97 const SkRect* srcOrNull, const SkRect& dst, | |
| 98 const SkPaint& paint, | |
| 99 SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE
{ | |
| 100 } | |
| 101 virtual void drawText(const SkDraw& draw, const void* text, size_t len, | |
| 102 SkScalar x, SkScalar y, | |
| 103 const SkPaint& paint) SK_OVERRIDE { | |
| 104 } | |
| 105 virtual void drawPosText(const SkDraw& draw, const void* text, size_t len, | |
| 106 const SkScalar pos[], SkScalar constY, | |
| 107 int scalarsPerPos, const SkPaint& paint) SK_OVERRID
E { | |
| 108 } | |
| 109 virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len
, | |
| 110 const SkPath& path, const SkMatrix* matrix, | |
| 111 const SkPaint& paint) SK_OVERRIDE { | |
| 112 } | |
| 113 virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vert
exCount, | |
| 114 const SkPoint verts[], const SkPoint texs[], | |
| 115 const SkColor colors[], SkXfermode* xmode, | |
| 116 const uint16_t indices[], int indexCount, | |
| 117 const SkPaint& paint) SK_OVERRIDE { | |
| 118 } | |
| 119 virtual void drawDevice(const SkDraw& draw, SkBaseDevice* deviceIn, int x, i
nt y, | |
| 120 const SkPaint& paint) SK_OVERRIDE { | |
| 121 // deviceIn is the one that is being "restored" back to its parent | |
| 122 GrGatherDevice* device = static_cast<GrGatherDevice*>(deviceIn); | |
| 123 | |
| 124 if (device->fAlreadyDrawn) { | |
| 125 return; | 31 return; |
| 126 } | 32 } |
| 127 | 33 |
| 128 device->fInfo.fRestoreOpID = fPlayback->curOpID(); | 34 for (fCurrentOp = 0; fCurrentOp < pict->fRecord->count(); ++fCurrentOp)
{ |
| 129 device->fInfo.fCTM = *draw.fMatrix; | 35 pict->fRecord->visit<void>(fCurrentOp, *this); |
| 130 device->fInfo.fCTM.postTranslate(SkIntToScalar(-device->getOrigin().fX), | 36 } |
| 131 SkIntToScalar(-device->getOrigin().fY))
; | 37 |
| 132 | 38 while (!fSaveStack.isEmpty()) { |
| 133 device->fInfo.fOffset = device->getOrigin(); | 39 this->popSaveBlock(); |
| 134 | 40 } |
| 135 if (NeedsDeepCopy(paint)) { | 41 } |
| 136 // This NULL acts as a signal that the paint was uncopyable (for now
) | 42 |
| 137 device->fInfo.fPaint = NULL; | 43 template <typename T> void operator()(const T& op) { |
| 138 device->fInfo.fValid = false; | 44 this->updateCTM(op); |
| 45 this->updateClipBounds(op); |
| 46 this->trackSaveLayers(op); |
| 47 } |
| 48 |
| 49 private: |
| 50 |
| 51 class SaveInfo { |
| 52 public: |
| 53 SaveInfo() { } |
| 54 SaveInfo(int opIndex, bool isSaveLayer, const SkPaint* paint, const SkIR
ect& bounds) |
| 55 : fStartIndex(opIndex) |
| 56 , fIsSaveLayer(isSaveLayer) |
| 57 , fHasNestedSaveLayer(false) |
| 58 , fPaint(paint) |
| 59 , fBounds(bounds) { |
| 60 |
| 61 } |
| 62 |
| 63 int fStartIndex; |
| 64 bool fIsSaveLayer; |
| 65 bool fHasNestedSaveLayer; |
| 66 const SkPaint* fPaint; |
| 67 SkIRect fBounds; |
| 68 }; |
| 69 |
| 70 uint32_t fPictureID; |
| 71 unsigned int fCurrentOp; |
| 72 const SkMatrix* fCTM; |
| 73 SkIRect fCurrentClipBounds; |
| 74 int fSaveLayersInStack; |
| 75 SkTDArray<SaveInfo> fSaveStack; |
| 76 GrAccelData* fAccelData; |
| 77 |
| 78 template <typename T> void updateCTM(const T&) { /* most ops don't change th
e CTM */ } |
| 79 void updateCTM(const SkRecords::Restore& op) { fCTM = &op.matrix; } |
| 80 void updateCTM(const SkRecords::SetMatrix& op) { fCTM = &op.matrix; } |
| 81 |
| 82 template <typename T> void updateClipBounds(const T&) { /* most ops don't ch
ange the clip */ } |
| 83 // Each of these devBounds fields is the state of the device bounds after th
e op. |
| 84 // So Restore's devBounds are those bounds saved by its paired Save or SaveL
ayer. |
| 85 void updateClipBounds(const SkRecords::Restore& op) { fCurrentClipBounds
= op.devBounds; } |
| 86 void updateClipBounds(const SkRecords::ClipPath& op) { fCurrentClipBounds
= op.devBounds; } |
| 87 void updateClipBounds(const SkRecords::ClipRRect& op) { fCurrentClipBounds
= op.devBounds; } |
| 88 void updateClipBounds(const SkRecords::ClipRect& op) { fCurrentClipBounds
= op.devBounds; } |
| 89 void updateClipBounds(const SkRecords::ClipRegion& op) { fCurrentClipBounds
= op.devBounds; } |
| 90 void updateClipBounds(const SkRecords::SaveLayer& op) { |
| 91 if (NULL != op.bounds) { |
| 92 fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint
)); |
| 93 } |
| 94 } |
| 95 |
| 96 template <typename T> void trackSaveLayers(const T& op) { |
| 97 /* most ops aren't involved in saveLayers */ |
| 98 } |
| 99 void trackSaveLayers(const SkRecords::Save& s) { this->pushSaveBlock(); } |
| 100 void trackSaveLayers(const SkRecords::SaveLayer& sl) { this->pushSaveLayerBl
ock(sl.paint); } |
| 101 void trackSaveLayers(const SkRecords::Restore& r) { this->popSaveBlock(); } |
| 102 void trackSaveLayers(const SkRecords::DrawPicture& dp) { |
| 103 // For sub-pictures, we wrap their layer information within the parent |
| 104 // picture's rendering hierarchy |
| 105 const GrAccelData* childData = GPUOptimize(dp.picture); |
| 106 |
| 107 for (int i = 0; i < childData->numSaveLayers(); ++i) { |
| 108 const GrAccelData::SaveLayerInfo& src = childData->saveLayerInfo(i); |
| 109 |
| 110 this->updateStackForSaveLayer(); |
| 111 |
| 112 GrAccelData::SaveLayerInfo dst; |
| 113 |
| 114 // TODO: need to store an SkRect in GrAccelData::SaveLayerInfo? |
| 115 SkRect srcRect = SkRect::MakeXYWH(SkIntToScalar(src.fOffset.fX), |
| 116 SkIntToScalar(src.fOffset.fY), |
| 117 SkIntToScalar(src.fSize.width()), |
| 118 SkIntToScalar(src.fSize.height()))
; |
| 119 SkIRect newClip(fCurrentClipBounds); |
| 120 newClip.intersect(this->adjustAndMap(srcRect, dp.paint)); |
| 121 |
| 122 dst.fValid = true; |
| 123 dst.fPictureID = dp.picture->uniqueID(); |
| 124 dst.fSize = SkISize::Make(newClip.width(), newClip.height()); |
| 125 dst.fOffset = SkIPoint::Make(newClip.fLeft, newClip.fTop); |
| 126 dst.fOriginXform = *fCTM; |
| 127 dst.fOriginXform.postConcat(src.fOriginXform); |
| 128 dst.fOriginXform.postTranslate(SkIntToScalar(-newClip.fLeft), |
| 129 SkIntToScalar(-newClip.fTop)); |
| 130 |
| 131 if (NULL == src.fPaint) { |
| 132 dst.fPaint = NULL; |
| 133 } else { |
| 134 dst.fPaint = SkNEW_ARGS(SkPaint, (*src.fPaint)); |
| 135 } |
| 136 |
| 137 dst.fSaveLayerOpID = src.fSaveLayerOpID; |
| 138 dst.fRestoreOpID = src.fRestoreOpID; |
| 139 dst.fHasNestedLayers = src.fHasNestedLayers; |
| 140 dst.fIsNested = fSaveLayersInStack > 0 || src.fIsNested; |
| 141 |
| 142 fAccelData->addSaveLayerInfo(dst); |
| 143 } |
| 144 } |
| 145 |
| 146 void pushSaveBlock() { |
| 147 fSaveStack.push(SaveInfo(fCurrentOp, false, NULL, SkIRect::MakeEmpty()))
; |
| 148 } |
| 149 |
| 150 // Inform all the saveLayers already on the stack that they now have a |
| 151 // nested saveLayer inside them |
| 152 void updateStackForSaveLayer() { |
| 153 for (int index = fSaveStack.count() - 1; index >= 0; --index) { |
| 154 if (fSaveStack[index].fHasNestedSaveLayer) { |
| 155 break; |
| 156 } |
| 157 fSaveStack[index].fHasNestedSaveLayer = true; |
| 158 if (fSaveStack[index].fIsSaveLayer) { |
| 159 break; |
| 160 } |
| 161 } |
| 162 } |
| 163 |
| 164 void pushSaveLayerBlock(const SkPaint* paint) { |
| 165 this->updateStackForSaveLayer(); |
| 166 |
| 167 fSaveStack.push(SaveInfo(fCurrentOp, true, paint, fCurrentClipBounds)); |
| 168 ++fSaveLayersInStack; |
| 169 } |
| 170 |
| 171 void popSaveBlock() { |
| 172 if (fSaveStack.count() <= 0) { |
| 173 SkASSERT(false); |
| 174 return; |
| 175 } |
| 176 |
| 177 SaveInfo si; |
| 178 fSaveStack.pop(&si); |
| 179 |
| 180 if (!si.fIsSaveLayer) { |
| 181 return; |
| 182 } |
| 183 |
| 184 --fSaveLayersInStack; |
| 185 |
| 186 GrAccelData::SaveLayerInfo slInfo; |
| 187 |
| 188 slInfo.fValid = true; |
| 189 slInfo.fPictureID = fPictureID; |
| 190 slInfo.fSize = SkISize::Make(si.fBounds.width(), si.fBounds.height()); |
| 191 slInfo.fOffset = SkIPoint::Make(si.fBounds.fLeft, si.fBounds.fTop); |
| 192 slInfo.fOriginXform = *fCTM; |
| 193 slInfo.fOriginXform.postTranslate(SkIntToScalar(-si.fBounds.fLeft), |
| 194 SkIntToScalar(-si.fBounds.fTop)); |
| 195 |
| 196 if (NULL == si.fPaint) { |
| 197 slInfo.fPaint = NULL; |
| 139 } else { | 198 } else { |
| 140 device->fInfo.fPaint = SkNEW_ARGS(SkPaint, (paint)); | 199 slInfo.fPaint = SkNEW_ARGS(SkPaint, (*si.fPaint)); |
| 141 } | 200 } |
| 142 | 201 |
| 143 fAccelData->addSaveLayerInfo(device->fInfo); | 202 slInfo.fSaveLayerOpID = si.fStartIndex; |
| 144 device->fAlreadyDrawn = true; | 203 slInfo.fRestoreOpID = fCurrentOp; |
| 145 } | 204 slInfo.fHasNestedLayers = si.fHasNestedSaveLayer; |
| 146 // TODO: allow this call to return failure, or move to SkBitmapDevice only. | 205 slInfo.fIsNested = fSaveLayersInStack > 0; |
| 147 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { | 206 |
| 148 return fEmptyBitmap; | 207 fAccelData->addSaveLayerInfo(slInfo); |
| 149 } | 208 } |
| 150 #ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG | 209 |
| 151 virtual bool onReadPixels(const SkBitmap& bitmap, | 210 // Returns true if rect was meaningfully adjusted for the effects of paint, |
| 152 int x, int y, | 211 // false if the paint could affect the rect in unknown ways. |
| 153 SkCanvas::Config8888 config8888) SK_OVERRIDE { | 212 static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) { |
| 154 NotSupported(); | 213 if (paint) { |
| 155 return false; | 214 if (paint->canComputeFastBounds()) { |
| 156 } | 215 *rect = paint->computeFastBounds(*rect, rect); |
| 157 #endif | 216 return true; |
| 158 virtual void lockPixels() SK_OVERRIDE { NothingToDo(); } | 217 } |
| 159 virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } | 218 return false; |
| 160 virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return fal
se; } | 219 } |
| 161 virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return
false; } | 220 return true; |
| 162 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImag
eFilter::Context&, | 221 } |
| 163 SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { | 222 |
| 164 return false; | 223 // Adjust rect for all paints that may affect its geometry, then map it to d
evice space. |
| 165 } | 224 SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) const { |
| 166 | 225 // Inverted rectangles really confuse our BBHs. |
| 167 private: | 226 rect.sort(); |
| 168 // The playback object driving this rendering | 227 |
| 169 SkPicturePlayback *fPlayback; | 228 // Adjust the rect for its own paint. |
| 170 | 229 if (!AdjustForPaint(paint, &rect)) { |
| 171 SkBitmap fEmptyBitmap; // legacy -- need to remove | 230 // The paint could do anything to our bounds. The only safe answer
is the current clip. |
| 172 | 231 return fCurrentClipBounds; |
| 173 // All information gathered during the gather process is stored here | 232 } |
| 174 GrAccelData* fAccelData; | 233 |
| 175 | 234 // Adjust rect for all the paints from the SaveLayers we're inside. |
| 176 // true if this device has already been drawn back to its parent(s) at least | 235 for (int i = fSaveStack.count() - 1; i >= 0; i--) { |
| 177 // once. | 236 if (!AdjustForPaint(fSaveStack[i].fPaint, &rect)) { |
| 178 bool fAlreadyDrawn; | 237 // Same deal as above. |
| 179 | 238 return fCurrentClipBounds; |
| 180 // The information regarding the saveLayer call this device represents. | 239 } |
| 181 GrAccelData::SaveLayerInfo fInfo; | 240 } |
| 182 | 241 |
| 183 // The depth of this device in the saveLayer stack | 242 // Map the rect back to device space. |
| 184 int fSaveLayerDepth; | 243 fCTM->mapRect(&rect); |
| 185 | 244 SkIRect devRect; |
| 186 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRI
DE { | 245 rect.roundOut(&devRect); |
| 187 NotSupported(); | 246 |
| 188 } | 247 // Nothing can draw outside the current clip. |
| 189 | 248 // (Only bounded ops call into this method, so oddballs like Clear don't
matter here.) |
| 190 virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) S
K_OVERRIDE { | 249 devRect.intersect(fCurrentClipBounds); |
| 191 // we expect to only get called via savelayer, in which case it is fine. | 250 return devRect; |
| 192 SkASSERT(kSaveLayer_Usage == usage); | 251 } |
| 193 | |
| 194 fInfo.fHasNestedLayers = true; | |
| 195 return SkNEW_ARGS(GrGatherDevice, (info.width(), info.height(), fPlaybac
k, | |
| 196 fAccelData, fSaveLayerDepth+1)); | |
| 197 } | |
| 198 | |
| 199 virtual void flush() SK_OVERRIDE {} | |
| 200 | |
| 201 static void NotSupported() { | |
| 202 SkDEBUGFAIL("this method should never be called"); | |
| 203 } | |
| 204 | |
| 205 static void NothingToDo() {} | |
| 206 | |
| 207 typedef SkBaseDevice INHERITED; | |
| 208 }; | 252 }; |
| 209 | 253 |
| 210 // The GrGatherCanvas allows saveLayers but simplifies clipping. It is really | 254 |
| 211 // only intended to be used as: | 255 // GPUOptimize is only intended to be called within the context of SkGpuDevice's |
| 212 // | |
| 213 // GrGatherDevice dev(w, h, picture, accelData); | |
| 214 // GrGatherCanvas canvas(..., picture); | |
| 215 // canvas.gather(); | |
| 216 // | |
| 217 // which is all just to fill in 'accelData' | |
| 218 class SK_API GrGatherCanvas : public SkCanvas { | |
| 219 public: | |
| 220 GrGatherCanvas(GrGatherDevice* device) : INHERITED(device) {} | |
| 221 | |
| 222 protected: | |
| 223 // disable aa for speed | |
| 224 virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle)
SK_OVERRIDE { | |
| 225 this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle); | |
| 226 } | |
| 227 | |
| 228 // for speed, just respect the bounds, and disable AA. May give us a few | |
| 229 // false positives and negatives. | |
| 230 virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle)
SK_OVERRIDE { | |
| 231 this->updateClipConservativelyUsingBounds(path.getBounds(), op, | |
| 232 path.isInverseFillType()); | |
| 233 } | |
| 234 virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl
e) SK_OVERRIDE { | |
| 235 this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); | |
| 236 } | |
| 237 | |
| 238 virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, | |
| 239 const SkPaint* paint) SK_OVERRIDE { | |
| 240 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->width(), pict
ure->height()); | |
| 241 | |
| 242 if (NULL != picture->fData.get()) { | |
| 243 // Disable the BBH for the old path so all the draw calls | |
| 244 // will be seen. The stock SkPicture::draw method can't be | |
| 245 // invoked since it just uses a vanilla SkPicturePlayback. | |
| 246 SkPicturePlayback playback(picture); | |
| 247 playback.setUseBBH(false); | |
| 248 playback.draw(this, NULL); | |
| 249 } else { | |
| 250 // Since we know this is the SkRecord path we can just call | |
| 251 // SkPicture::draw. | |
| 252 picture->draw(this); | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 private: | |
| 257 typedef SkCanvas INHERITED; | |
| 258 }; | |
| 259 | |
| 260 // GatherGPUInfo is only intended to be called within the context of SkGpuDevice
's | |
| 261 // EXPERIMENTAL_optimize method. | 256 // EXPERIMENTAL_optimize method. |
| 262 void GatherGPUInfo(const SkPicture* pict, GrAccelData* accelData) { | 257 const GrAccelData* GPUOptimize(const SkPicture* pict) { |
| 263 if (NULL == pict || 0 == pict->width() || 0 == pict->height()) { | 258 if (NULL == pict || 0 == pict->width() || 0 == pict->height()) { |
| 264 return ; | 259 return NULL; |
| 265 } | 260 } |
| 266 | 261 |
| 267 // BBH-based rendering doesn't re-issue many of the operations the gather | 262 SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); |
| 268 // process cares about (e.g., saves and restores) so it must be disabled. | 263 |
| 269 SkPicturePlayback playback(pict); | 264 const GrAccelData* existing = |
| 270 playback.setUseBBH(false); | 265 static_cast<const GrAccelData*>(pict->EXPERIMENTAL_g
etAccelData(key)); |
| 271 | 266 if (NULL != existing) { |
| 272 GrGatherDevice device(pict->width(), pict->height(), &playback, accelData, 0
); | 267 return existing; |
| 273 GrGatherCanvas canvas(&device); | 268 } |
| 274 | 269 |
| 275 canvas.clipRect(SkRect::MakeWH(SkIntToScalar(pict->width()), | 270 SkAutoTUnref<GrAccelData> data(SkNEW_ARGS(GrAccelData, (key))); |
| 276 SkIntToScalar(pict->height())), | 271 |
| 277 SkRegion::kIntersect_Op, false); | 272 pict->EXPERIMENTAL_addAccelData(data); |
| 278 playback.draw(&canvas, NULL); | 273 |
| 274 CollectLayers collector(pict, data); |
| 275 |
| 276 return data; |
| 279 } | 277 } |
| OLD | NEW |