Chromium Code Reviews| 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 return; | |
|
mtklein
2014/08/27 16:20:59
Also SkASSERT(false)?
robertphillips
2014/08/27 16:25:51
Done.
| |
| 174 } | |
| 175 | |
| 176 SaveInfo si; | |
| 177 fSaveStack.pop(&si); | |
| 178 | |
| 179 if (!si.fIsSaveLayer) { | |
| 180 return; | |
| 181 } | |
| 182 | |
| 183 --fSaveLayersInStack; | |
| 184 | |
| 185 GrAccelData::SaveLayerInfo slInfo; | |
| 186 | |
| 187 slInfo.fValid = true; | |
| 188 slInfo.fPictureID = fPictureID; | |
| 189 slInfo.fSize = SkISize::Make(si.fBounds.width(), si.fBounds.height()); | |
| 190 slInfo.fOffset = SkIPoint::Make(si.fBounds.fLeft, si.fBounds.fTop); | |
| 191 slInfo.fOriginXform = *fCTM; | |
| 192 slInfo.fOriginXform.postTranslate(SkIntToScalar(-si.fBounds.fLeft), | |
| 193 SkIntToScalar(-si.fBounds.fTop)); | |
| 194 | |
| 195 if (NULL == si.fPaint) { | |
| 196 slInfo.fPaint = NULL; | |
| 139 } else { | 197 } else { |
| 140 device->fInfo.fPaint = SkNEW_ARGS(SkPaint, (paint)); | 198 slInfo.fPaint = SkNEW_ARGS(SkPaint, (*si.fPaint)); |
| 141 } | 199 } |
| 142 | 200 |
| 143 fAccelData->addSaveLayerInfo(device->fInfo); | 201 slInfo.fSaveLayerOpID = si.fStartIndex; |
| 144 device->fAlreadyDrawn = true; | 202 slInfo.fRestoreOpID = fCurrentOp; |
| 145 } | 203 slInfo.fHasNestedLayers = si.fHasNestedSaveLayer; |
| 146 // TODO: allow this call to return failure, or move to SkBitmapDevice only. | 204 slInfo.fIsNested = fSaveLayersInStack > 0; |
| 147 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { | 205 |
| 148 return fEmptyBitmap; | 206 fAccelData->addSaveLayerInfo(slInfo); |
| 149 } | 207 } |
| 150 #ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG | 208 |
| 151 virtual bool onReadPixels(const SkBitmap& bitmap, | 209 // Returns true if rect was meaningfully adjusted for the effects of paint, |
| 152 int x, int y, | 210 // false if the paint could affect the rect in unknown ways. |
| 153 SkCanvas::Config8888 config8888) SK_OVERRIDE { | 211 static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) { |
| 154 NotSupported(); | 212 if (paint) { |
| 155 return false; | 213 if (paint->canComputeFastBounds()) { |
| 156 } | 214 *rect = paint->computeFastBounds(*rect, rect); |
| 157 #endif | 215 return true; |
| 158 virtual void lockPixels() SK_OVERRIDE { NothingToDo(); } | 216 } |
| 159 virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } | 217 return false; |
| 160 virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return fal se; } | 218 } |
| 161 virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } | 219 return true; |
| 162 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImag eFilter::Context&, | 220 } |
| 163 SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { | 221 |
| 164 return false; | 222 // Adjust rect for all paints that may affect its geometry, then map it to d evice space. |
| 165 } | 223 SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) const { |
| 166 | 224 // Inverted rectangles really confuse our BBHs. |
| 167 private: | 225 rect.sort(); |
| 168 // The playback object driving this rendering | 226 |
| 169 SkPicturePlayback *fPlayback; | 227 // Adjust the rect for its own paint. |
| 170 | 228 if (!AdjustForPaint(paint, &rect)) { |
| 171 SkBitmap fEmptyBitmap; // legacy -- need to remove | 229 // The paint could do anything to our bounds. The only safe answer is the current clip. |
| 172 | 230 return fCurrentClipBounds; |
| 173 // All information gathered during the gather process is stored here | 231 } |
| 174 GrAccelData* fAccelData; | 232 |
| 175 | 233 // 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 | 234 for (int i = fSaveStack.count() - 1; i >= 0; i--) { |
| 177 // once. | 235 if (!AdjustForPaint(fSaveStack[i].fPaint, &rect)) { |
| 178 bool fAlreadyDrawn; | 236 // Same deal as above. |
| 179 | 237 return fCurrentClipBounds; |
| 180 // The information regarding the saveLayer call this device represents. | 238 } |
| 181 GrAccelData::SaveLayerInfo fInfo; | 239 } |
| 182 | 240 |
| 183 // The depth of this device in the saveLayer stack | 241 // Map the rect back to device space. |
| 184 int fSaveLayerDepth; | 242 fCTM->mapRect(&rect); |
| 185 | 243 SkIRect devRect; |
| 186 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRI DE { | 244 rect.roundOut(&devRect); |
| 187 NotSupported(); | 245 |
| 188 } | 246 // Nothing can draw outside the current clip. |
| 189 | 247 // (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 { | 248 devRect.intersect(fCurrentClipBounds); |
| 191 // we expect to only get called via savelayer, in which case it is fine. | 249 return devRect; |
| 192 SkASSERT(kSaveLayer_Usage == usage); | 250 } |
| 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 }; | 251 }; |
| 209 | 252 |
| 210 // The GrGatherCanvas allows saveLayers but simplifies clipping. It is really | 253 |
| 211 // only intended to be used as: | 254 // 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. | 255 // EXPERIMENTAL_optimize method. |
| 262 void GatherGPUInfo(const SkPicture* pict, GrAccelData* accelData) { | 256 const GrAccelData* GPUOptimize(const SkPicture* pict) { |
| 263 if (NULL == pict || 0 == pict->width() || 0 == pict->height()) { | 257 if (NULL == pict || 0 == pict->width() || 0 == pict->height()) { |
| 264 return ; | 258 return NULL; |
| 265 } | 259 } |
| 266 | 260 |
| 267 // BBH-based rendering doesn't re-issue many of the operations the gather | 261 SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); |
| 268 // process cares about (e.g., saves and restores) so it must be disabled. | 262 |
| 269 SkPicturePlayback playback(pict); | 263 const GrAccelData* existing = |
| 270 playback.setUseBBH(false); | 264 static_cast<const GrAccelData*>(pict->EXPERIMENTAL_g etAccelData(key)); |
| 271 | 265 if (NULL != existing) { |
| 272 GrGatherDevice device(pict->width(), pict->height(), &playback, accelData, 0 ); | 266 return existing; |
| 273 GrGatherCanvas canvas(&device); | 267 } |
| 274 | 268 |
| 275 canvas.clipRect(SkRect::MakeWH(SkIntToScalar(pict->width()), | 269 SkAutoTUnref<GrAccelData> data(SkNEW_ARGS(GrAccelData, (key))); |
| 276 SkIntToScalar(pict->height())), | 270 |
| 277 SkRegion::kIntersect_Op, false); | 271 pict->EXPERIMENTAL_addAccelData(data); |
| 278 playback.draw(&canvas, NULL); | 272 |
| 273 CollectLayers collector(pict, data); | |
| 274 | |
| 275 return data; | |
| 279 } | 276 } |
| OLD | NEW |