| 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 "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkDraw.h" | 10 #include "SkDraw.h" |
| 11 #include "SkPaintPriv.h" | 11 #include "SkPaintPriv.h" |
| 12 #include "SkPictureData.h" | 12 #include "SkPictureData.h" |
| 13 #include "SkPicturePlayback.h" |
| 13 | 14 |
| 14 SkPicture::AccelData::Key GPUAccelData::ComputeAccelDataKey() { | 15 SkPicture::AccelData::Key GPUAccelData::ComputeAccelDataKey() { |
| 15 static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::Genera
teDomain(); | 16 static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::Genera
teDomain(); |
| 16 | 17 |
| 17 return gGPUID; | 18 return gGPUID; |
| 18 } | 19 } |
| 19 | 20 |
| 20 // The GrGather device performs GPU-backend-specific preprocessing on | 21 // The GrGather device performs GPU-backend-specific preprocessing on |
| 21 // a picture. The results are stored in a GPUAccelData. | 22 // a picture. The results are stored in a GPUAccelData. |
| 22 // | 23 // |
| 23 // Currently the only interesting work is done in drawDevice (i.e., when a | 24 // Currently the only interesting work is done in drawDevice (i.e., when a |
| 24 // saveLayer is collapsed back into its parent) and, maybe, in onCreateDevice. | 25 // saveLayer is collapsed back into its parent) and, maybe, in onCreateDevice. |
| 25 // All the current work could be done much more efficiently by just traversing t
he | 26 // All the current work could be done much more efficiently by just traversing t
he |
| 26 // raw op codes in the SkPicture (although we would still need to replay all the | 27 // raw op codes in the SkPicture (although we would still need to replay all the |
| 27 // clip calls). | 28 // clip calls). |
| 28 class GrGatherDevice : public SkBaseDevice { | 29 class GrGatherDevice : public SkBaseDevice { |
| 29 public: | 30 public: |
| 30 SK_DECLARE_INST_COUNT(GrGatherDevice) | 31 SK_DECLARE_INST_COUNT(GrGatherDevice) |
| 31 | 32 |
| 32 GrGatherDevice(int width, int height, const SkPicture* picture, GPUAccelData
* accelData, | 33 GrGatherDevice(int width, int height, SkPicturePlayback* playback, GPUAccelD
ata* accelData, |
| 33 int saveLayerDepth) { | 34 int saveLayerDepth) { |
| 34 fPicture = picture; | 35 fPlayback = playback; |
| 35 fSaveLayerDepth = saveLayerDepth; | 36 fSaveLayerDepth = saveLayerDepth; |
| 36 fInfo.fValid = true; | 37 fInfo.fValid = true; |
| 37 fInfo.fSize.set(width, height); | 38 fInfo.fSize.set(width, height); |
| 38 fInfo.fPaint = NULL; | 39 fInfo.fPaint = NULL; |
| 39 fInfo.fSaveLayerOpID = fPicture->EXPERIMENTAL_curOpID(); | 40 fInfo.fSaveLayerOpID = fPlayback->curOpID(); |
| 40 fInfo.fRestoreOpID = 0; | 41 fInfo.fRestoreOpID = 0; |
| 41 fInfo.fHasNestedLayers = false; | 42 fInfo.fHasNestedLayers = false; |
| 42 fInfo.fIsNested = (2 == fSaveLayerDepth); | 43 fInfo.fIsNested = (2 == fSaveLayerDepth); |
| 43 | 44 |
| 44 fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(fInfo.fSize.fWidth, fInfo.
fSize.fHeight)); | 45 fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(fInfo.fSize.fWidth, fInfo.
fSize.fHeight)); |
| 45 fAccelData = accelData; | 46 fAccelData = accelData; |
| 46 fAlreadyDrawn = false; | 47 fAlreadyDrawn = false; |
| 47 } | 48 } |
| 48 | 49 |
| 49 virtual ~GrGatherDevice() { } | 50 virtual ~GrGatherDevice() { } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 } | 117 } |
| 117 virtual void drawDevice(const SkDraw& draw, SkBaseDevice* deviceIn, int x, i
nt y, | 118 virtual void drawDevice(const SkDraw& draw, SkBaseDevice* deviceIn, int x, i
nt y, |
| 118 const SkPaint& paint) SK_OVERRIDE { | 119 const SkPaint& paint) SK_OVERRIDE { |
| 119 // deviceIn is the one that is being "restored" back to its parent | 120 // deviceIn is the one that is being "restored" back to its parent |
| 120 GrGatherDevice* device = static_cast<GrGatherDevice*>(deviceIn); | 121 GrGatherDevice* device = static_cast<GrGatherDevice*>(deviceIn); |
| 121 | 122 |
| 122 if (device->fAlreadyDrawn) { | 123 if (device->fAlreadyDrawn) { |
| 123 return; | 124 return; |
| 124 } | 125 } |
| 125 | 126 |
| 126 device->fInfo.fRestoreOpID = fPicture->EXPERIMENTAL_curOpID(); | 127 device->fInfo.fRestoreOpID = fPlayback->curOpID(); |
| 127 device->fInfo.fCTM = *draw.fMatrix; | 128 device->fInfo.fCTM = *draw.fMatrix; |
| 128 device->fInfo.fCTM.postTranslate(SkIntToScalar(-device->getOrigin().fX), | 129 device->fInfo.fCTM.postTranslate(SkIntToScalar(-device->getOrigin().fX), |
| 129 SkIntToScalar(-device->getOrigin().fY))
; | 130 SkIntToScalar(-device->getOrigin().fY))
; |
| 130 | 131 |
| 131 device->fInfo.fOffset = device->getOrigin(); | 132 device->fInfo.fOffset = device->getOrigin(); |
| 132 | 133 |
| 133 if (NeedsDeepCopy(paint)) { | 134 if (NeedsDeepCopy(paint)) { |
| 134 // This NULL acts as a signal that the paint was uncopyable (for now
) | 135 // This NULL acts as a signal that the paint was uncopyable (for now
) |
| 135 device->fInfo.fPaint = NULL; | 136 device->fInfo.fPaint = NULL; |
| 136 device->fInfo.fValid = false; | 137 device->fInfo.fValid = false; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 156 virtual void lockPixels() SK_OVERRIDE { NothingToDo(); } | 157 virtual void lockPixels() SK_OVERRIDE { NothingToDo(); } |
| 157 virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } | 158 virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } |
| 158 virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return fal
se; } | 159 virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return fal
se; } |
| 159 virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return
false; } | 160 virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return
false; } |
| 160 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImag
eFilter::Context&, | 161 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImag
eFilter::Context&, |
| 161 SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { | 162 SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { |
| 162 return false; | 163 return false; |
| 163 } | 164 } |
| 164 | 165 |
| 165 private: | 166 private: |
| 166 // The picture being processed | 167 // The playback object driving this rendering |
| 167 const SkPicture *fPicture; | 168 SkPicturePlayback *fPlayback; |
| 168 | 169 |
| 169 SkBitmap fEmptyBitmap; // legacy -- need to remove | 170 SkBitmap fEmptyBitmap; // legacy -- need to remove |
| 170 | 171 |
| 171 // All information gathered during the gather process is stored here | 172 // All information gathered during the gather process is stored here |
| 172 GPUAccelData* fAccelData; | 173 GPUAccelData* fAccelData; |
| 173 | 174 |
| 174 // true if this device has already been drawn back to its parent(s) at least | 175 // true if this device has already been drawn back to its parent(s) at least |
| 175 // once. | 176 // once. |
| 176 bool fAlreadyDrawn; | 177 bool fAlreadyDrawn; |
| 177 | 178 |
| 178 // The information regarding the saveLayer call this device represents. | 179 // The information regarding the saveLayer call this device represents. |
| 179 GPUAccelData::SaveLayerInfo fInfo; | 180 GPUAccelData::SaveLayerInfo fInfo; |
| 180 | 181 |
| 181 // The depth of this device in the saveLayer stack | 182 // The depth of this device in the saveLayer stack |
| 182 int fSaveLayerDepth; | 183 int fSaveLayerDepth; |
| 183 | 184 |
| 184 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRI
DE { | 185 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRI
DE { |
| 185 NotSupported(); | 186 NotSupported(); |
| 186 } | 187 } |
| 187 | 188 |
| 188 virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) S
K_OVERRIDE { | 189 virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) S
K_OVERRIDE { |
| 189 // we expect to only get called via savelayer, in which case it is fine. | 190 // we expect to only get called via savelayer, in which case it is fine. |
| 190 SkASSERT(kSaveLayer_Usage == usage); | 191 SkASSERT(kSaveLayer_Usage == usage); |
| 191 | 192 |
| 192 fInfo.fHasNestedLayers = true; | 193 fInfo.fHasNestedLayers = true; |
| 193 return SkNEW_ARGS(GrGatherDevice, (info.width(), info.height(), fPicture
, | 194 return SkNEW_ARGS(GrGatherDevice, (info.width(), info.height(), fPlaybac
k, |
| 194 fAccelData, fSaveLayerDepth+1)); | 195 fAccelData, fSaveLayerDepth+1)); |
| 195 } | 196 } |
| 196 | 197 |
| 197 virtual void flush() SK_OVERRIDE {} | 198 virtual void flush() SK_OVERRIDE {} |
| 198 | 199 |
| 199 static void NotSupported() { | 200 static void NotSupported() { |
| 200 SkDEBUGFAIL("this method should never be called"); | 201 SkDEBUGFAIL("this method should never be called"); |
| 201 } | 202 } |
| 202 | 203 |
| 203 static void NothingToDo() {} | 204 static void NothingToDo() {} |
| 204 | 205 |
| 205 typedef SkBaseDevice INHERITED; | 206 typedef SkBaseDevice INHERITED; |
| 206 }; | 207 }; |
| 207 | 208 |
| 208 // The GrGatherCanvas allows saveLayers but simplifies clipping. It is really | 209 // The GrGatherCanvas allows saveLayers but simplifies clipping. It is really |
| 209 // only intended to be used as: | 210 // only intended to be used as: |
| 210 // | 211 // |
| 211 // GrGatherDevice dev(w, h, picture, accelData); | 212 // GrGatherDevice dev(w, h, picture, accelData); |
| 212 // GrGatherCanvas canvas(..., picture); | 213 // GrGatherCanvas canvas(..., picture); |
| 213 // canvas.gather(); | 214 // canvas.gather(); |
| 214 // | 215 // |
| 215 // which is all just to fill in 'accelData' | 216 // which is all just to fill in 'accelData' |
| 216 class SK_API GrGatherCanvas : public SkCanvas { | 217 class SK_API GrGatherCanvas : public SkCanvas { |
| 217 public: | 218 public: |
| 218 GrGatherCanvas(GrGatherDevice* device, const SkPicture* pict) | 219 GrGatherCanvas(GrGatherDevice* device) : INHERITED(device) {} |
| 219 : INHERITED(device) | |
| 220 , fPicture(pict) { | |
| 221 } | |
| 222 | |
| 223 void gather() { | |
| 224 if (NULL == fPicture || 0 == fPicture->width() || 0 == fPicture->height(
)) { | |
| 225 return; | |
| 226 } | |
| 227 | |
| 228 this->clipRect(SkRect::MakeWH(SkIntToScalar(fPicture->width()), | |
| 229 SkIntToScalar(fPicture->height())), | |
| 230 SkRegion::kIntersect_Op, false); | |
| 231 this->drawPicture(fPicture); | |
| 232 } | |
| 233 | 220 |
| 234 protected: | 221 protected: |
| 235 // disable aa for speed | 222 // disable aa for speed |
| 236 virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle)
SK_OVERRIDE { | 223 virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle)
SK_OVERRIDE { |
| 237 this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle); | 224 this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle); |
| 238 } | 225 } |
| 239 | 226 |
| 240 // for speed, just respect the bounds, and disable AA. May give us a few | 227 // for speed, just respect the bounds, and disable AA. May give us a few |
| 241 // false positives and negatives. | 228 // false positives and negatives. |
| 242 virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle)
SK_OVERRIDE { | 229 virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle)
SK_OVERRIDE { |
| 243 this->updateClipConservativelyUsingBounds(path.getBounds(), op, | 230 this->updateClipConservativelyUsingBounds(path.getBounds(), op, |
| 244 path.isInverseFillType()); | 231 path.isInverseFillType()); |
| 245 } | 232 } |
| 246 virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl
e) SK_OVERRIDE { | 233 virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl
e) SK_OVERRIDE { |
| 247 this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); | 234 this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); |
| 248 } | 235 } |
| 249 | 236 |
| 250 virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE { | 237 virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE { |
| 251 // BBH-based rendering doesn't re-issue many of the operations the gathe
r | |
| 252 // process cares about (e.g., saves and restores) so it must be disabled
. | |
| 253 if (NULL != picture->fData.get()) { | 238 if (NULL != picture->fData.get()) { |
| 254 picture->fData->setUseBBH(false); | 239 // Disable the BBH for the old path so all the draw calls |
| 255 } | 240 // will be seen. The stock SkPicture::draw method can't be |
| 256 picture->draw(this); | 241 // invoked since it just uses a vanilla SkPicturePlayback. |
| 257 if (NULL != picture->fData.get()) { | 242 SkPicturePlayback playback(picture); |
| 258 picture->fData->setUseBBH(true); | 243 playback.setUseBBH(false); |
| 244 playback.draw(this, NULL); |
| 245 } else { |
| 246 // Since we know this is the SkRecord path we can just call |
| 247 // SkPicture::draw. |
| 248 picture->draw(this); |
| 259 } | 249 } |
| 260 } | 250 } |
| 261 | 251 |
| 262 private: | 252 private: |
| 263 const SkPicture* fPicture; | |
| 264 | |
| 265 typedef SkCanvas INHERITED; | 253 typedef SkCanvas INHERITED; |
| 266 }; | 254 }; |
| 267 | 255 |
| 268 // GatherGPUInfo is only intended to be called within the context of SkGpuDevice
's | 256 // GatherGPUInfo is only intended to be called within the context of SkGpuDevice
's |
| 269 // EXPERIMENTAL_optimize method. | 257 // EXPERIMENTAL_optimize method. |
| 270 void GatherGPUInfo(const SkPicture* pict, GPUAccelData* accelData) { | 258 void GatherGPUInfo(const SkPicture* pict, GPUAccelData* accelData) { |
| 271 if (0 == pict->width() || 0 == pict->height()) { | 259 if (NULL == pict || 0 == pict->width() || 0 == pict->height()) { |
| 272 return ; | 260 return ; |
| 273 } | 261 } |
| 274 | 262 |
| 275 GrGatherDevice device(pict->width(), pict->height(), pict, accelData, 0); | 263 // BBH-based rendering doesn't re-issue many of the operations the gather |
| 276 GrGatherCanvas canvas(&device, pict); | 264 // process cares about (e.g., saves and restores) so it must be disabled. |
| 265 SkPicturePlayback playback(pict); |
| 266 playback.setUseBBH(false); |
| 277 | 267 |
| 278 canvas.gather(); | 268 GrGatherDevice device(pict->width(), pict->height(), &playback, accelData, 0
); |
| 269 GrGatherCanvas canvas(&device); |
| 270 |
| 271 canvas.clipRect(SkRect::MakeWH(SkIntToScalar(pict->width()), |
| 272 SkIntToScalar(pict->height())), |
| 273 SkRegion::kIntersect_Op, false); |
| 274 playback.draw(&canvas, NULL); |
| 279 } | 275 } |
| OLD | NEW |