3 * Copyright 2013 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
9 #include "SkDeferredCanvas.h"
11 #include "SkBitmapDevice.h"
12 #include "SkChunkAlloc.h"
13 #include "SkColorFilter.h"
14 #include "SkDrawFilter.h"
17 #include "SkPaintPriv.h"
20 #include "SkSurface.h"
23 // Deferred canvas will auto-flush when recording reaches this limit
24 kDefaultMaxRecordingStorageBytes = 64*1024*1024,
25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature
27 kNoSaveLayerIndex = -1,
35 static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint,
36 size_t bitmapSizeThreshold) {
37 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
38 (bitmap->getSize() > bitmapSizeThreshold))) {
42 SkShader* shader = paint->getShader();
43 // Here we detect the case where the shader is an SkBitmapProcShader
44 // with a gpu texture attached. Checking this without RTTI
45 // requires making the assumption that only gradient shaders
46 // and SkBitmapProcShader implement asABitmap(). The following
47 // code may need to be revised if that assumption is ever broken.
48 if (shader && !shader->asAGradient(NULL)) {
50 if (shader->asABitmap(&bm, NULL, NULL) &&
59 //-----------------------------------------------------------------------------
60 // DeferredPipeController
61 //-----------------------------------------------------------------------------
63 class DeferredPipeController : public SkGPipeController {
65 DeferredPipeController();
66 void setPlaybackCanvas(SkCanvas*);
67 virtual ~DeferredPipeController();
68 void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
69 void notifyWritten(size_t bytes) SK_OVERRIDE;
70 void playback(bool silent);
71 bool hasPendingCommands() const { return fAllocator.totalUsed() != 0; }
72 size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
78 PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; }
84 SkChunkAlloc fAllocator;
85 SkTDArray<PipeBlock> fBlockList;
86 SkGPipeReader fReader;
89 DeferredPipeController::DeferredPipeController() :
90 fAllocator(kMinBlockSize) {
95 DeferredPipeController::~DeferredPipeController() {
99 void DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) {
100 fReader.setCanvas(canvas);
103 void* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) {
105 // Save the previous block for later
106 PipeBlock previousBloc(fBlock, fBytesWritten);
107 fBlockList.push(previousBloc);
109 size_t blockSize = SkTMax<size_t>(minRequest, kMinBlockSize);
110 fBlock = fAllocator.allocThrow(blockSize);
116 void DeferredPipeController::notifyWritten(size_t bytes) {
117 fBytesWritten += bytes;
120 void DeferredPipeController::playback(bool silent) {
121 uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
122 for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
123 fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize,
129 fReader.playback(fBlock, fBytesWritten, flags);
133 // Release all allocated blocks
137 //-----------------------------------------------------------------------------
139 //-----------------------------------------------------------------------------
140 class SkDeferredDevice : public SkBaseDevice {
142 explicit SkDeferredDevice(SkSurface* surface);
145 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient);
146 SkCanvas* recordingCanvas();
147 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
148 SkBaseDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice();}
149 SkImage* newImageSnapshot();
150 void setSurface(SkSurface* surface);
152 bool hasPendingCommands();
153 size_t storageAllocatedForRecording() const;
154 size_t freeMemoryIfPossible(size_t bytesToFree);
155 void flushPendingCommands(PlaybackMode);
156 void skipPendingCommands();
157 void setMaxRecordingStorage(size_t);
158 void recordedDrawCommand();
159 void setIsDrawingToLayer(bool value) {fIsDrawingToLayer = value;}
161 SkImageInfo imageInfo() const SK_OVERRIDE;
163 GrRenderTarget* accessRenderTarget() SK_OVERRIDE;
165 SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) SK_OVERRIDE;
167 SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
170 const SkBitmap& onAccessBitmap() SK_OVERRIDE;
171 bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) SK_OVERRIDE;
172 bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y) SK_OVERRIDE;
174 // None of the following drawing methods should ever get called on the
176 void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE
178 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
179 size_t count, const SkPoint[],
180 const SkPaint& paint) SK_OVERRIDE
182 virtual void drawRect(const SkDraw&, const SkRect& r,
183 const SkPaint& paint) SK_OVERRIDE
185 void drawOval(const SkDraw&, const SkRect&, const SkPaint&) SK_OVERRIDE
187 virtual void drawRRect(const SkDraw&, const SkRRect& rr,
188 const SkPaint& paint) SK_OVERRIDE
190 virtual void drawPath(const SkDraw&, const SkPath& path,
191 const SkPaint& paint,
192 const SkMatrix* prePathMatrix = NULL,
193 bool pathIsMutable = false) SK_OVERRIDE
195 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
196 const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE
198 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*,
199 const SkRect&, const SkPaint&,
200 SkCanvas::DrawBitmapRectFlags) SK_OVERRIDE
202 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
203 int x, int y, const SkPaint& paint) SK_OVERRIDE
205 virtual void drawText(const SkDraw&, const void* text, size_t len,
206 SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE
208 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
209 const SkScalar pos[], int scalarsPerPos,
210 const SkPoint& offset, const SkPaint& paint) SK_OVERRIDE
212 virtual void drawTextOnPath(const SkDraw&, const void* text,
213 size_t len, const SkPath& path,
214 const SkMatrix* matrix,
215 const SkPaint& paint) SK_OVERRIDE
217 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
218 int vertexCount, const SkPoint verts[],
219 const SkPoint texs[], const SkColor colors[],
220 SkXfermode* xmode, const uint16_t indices[],
221 int indexCount, const SkPaint& paint) SK_OVERRIDE
223 virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
224 const SkPoint texCoords[4], SkXfermode* xmode,
225 const SkPaint& paint) SK_OVERRIDE
227 virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
228 const SkPaint&) SK_OVERRIDE
231 void lockPixels() SK_OVERRIDE {}
232 void unlockPixels() SK_OVERRIDE {}
234 bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE {
237 virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
238 const SkImageFilter::Context&, SkBitmap*, SkIPoint*) SK_OVERRIDE {
243 void flush() SK_OVERRIDE;
244 void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {}
246 void beginRecording();
249 void prepareForImmediatePixelWrite();
251 DeferredPipeController fPipeController;
252 SkGPipeWriter fPipeWriter;
253 SkCanvas* fImmediateCanvas;
254 SkCanvas* fRecordingCanvas;
256 SkDeferredCanvas::NotificationClient* fNotificationClient;
258 bool fCanDiscardCanvasContents;
259 bool fIsDrawingToLayer;
260 size_t fMaxRecordingStorageBytes;
261 size_t fPreviousStorageAllocated;
264 SkDeferredDevice::SkDeferredDevice(SkSurface* surface) {
265 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
266 fNotificationClient = NULL;
267 fImmediateCanvas = NULL;
269 this->setSurface(surface);
273 void SkDeferredDevice::setSurface(SkSurface* surface) {
274 SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas());
275 SkRefCnt_SafeAssign(fSurface, surface);
276 fPipeController.setPlaybackCanvas(fImmediateCanvas);
279 void SkDeferredDevice::init() {
280 fRecordingCanvas = NULL;
282 fIsDrawingToLayer = false;
283 fCanDiscardCanvasContents = false;
284 fPreviousStorageAllocated = 0;
285 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
286 fNotificationClient = NULL;
287 this->beginRecording();
290 SkDeferredDevice::~SkDeferredDevice() {
291 this->flushPendingCommands(kSilent_PlaybackMode);
292 SkSafeUnref(fImmediateCanvas);
293 SkSafeUnref(fSurface);
296 void SkDeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
297 fMaxRecordingStorageBytes = maxStorage;
298 this->recordingCanvas(); // Accessing the recording canvas applies the new limit.
301 void SkDeferredDevice::beginRecording() {
302 SkASSERT(NULL == fRecordingCanvas);
303 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
304 immediateDevice()->width(), immediateDevice()->height());
307 void SkDeferredDevice::setNotificationClient(
308 SkDeferredCanvas::NotificationClient* notificationClient) {
309 fNotificationClient = notificationClient;
312 void SkDeferredDevice::skipPendingCommands() {
313 if (!fIsDrawingToLayer) {
314 fCanDiscardCanvasContents = true;
315 if (fPipeController.hasPendingCommands()) {
317 flushPendingCommands(kSilent_PlaybackMode);
322 bool SkDeferredDevice::isFreshFrame() {
323 bool ret = fFreshFrame;
328 bool SkDeferredDevice::hasPendingCommands() {
329 return fPipeController.hasPendingCommands();
332 void SkDeferredDevice::aboutToDraw()
334 if (fNotificationClient) {
335 fNotificationClient->prepareForDraw();
337 if (fCanDiscardCanvasContents) {
339 fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
341 fCanDiscardCanvasContents = false;
345 void SkDeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
346 if (!fPipeController.hasPendingCommands()) {
349 if (playbackMode == kNormal_PlaybackMode) {
352 fPipeWriter.flushRecording(true);
353 fPipeController.playback(kSilent_PlaybackMode == playbackMode);
354 if (fNotificationClient) {
355 if (playbackMode == kSilent_PlaybackMode) {
356 fNotificationClient->skippedPendingDrawCommands();
358 fNotificationClient->flushedDrawCommands();
362 fPreviousStorageAllocated = storageAllocatedForRecording();
365 void SkDeferredDevice::flush() {
366 this->flushPendingCommands(kNormal_PlaybackMode);
367 fImmediateCanvas->flush();
370 size_t SkDeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
371 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
372 fPreviousStorageAllocated = storageAllocatedForRecording();
376 size_t SkDeferredDevice::storageAllocatedForRecording() const {
377 return (fPipeController.storageAllocatedForRecording()
378 + fPipeWriter.storageAllocatedForRecording());
381 void SkDeferredDevice::recordedDrawCommand() {
382 size_t storageAllocated = this->storageAllocatedForRecording();
384 if (storageAllocated > fMaxRecordingStorageBytes) {
385 // First, attempt to reduce cache without flushing
386 size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
387 if (this->freeMemoryIfPossible(tryFree) < tryFree) {
388 // Flush is necessary to free more space.
389 this->flushPendingCommands(kNormal_PlaybackMode);
390 // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
391 // which could cause a high flushing frequency.
392 this->freeMemoryIfPossible(~0U);
394 storageAllocated = this->storageAllocatedForRecording();
397 if (fNotificationClient &&
398 storageAllocated != fPreviousStorageAllocated) {
399 fPreviousStorageAllocated = storageAllocated;
400 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated);
404 SkCanvas* SkDeferredDevice::recordingCanvas() {
405 return fRecordingCanvas;
408 SkImage* SkDeferredDevice::newImageSnapshot() {
410 return fSurface ? fSurface->newImageSnapshot() : NULL;
413 SkImageInfo SkDeferredDevice::imageInfo() const {
414 return immediateDevice()->imageInfo();
417 GrRenderTarget* SkDeferredDevice::accessRenderTarget() {
418 this->flushPendingCommands(kNormal_PlaybackMode);
419 return immediateDevice()->accessRenderTarget();
422 void SkDeferredDevice::prepareForImmediatePixelWrite() {
423 // The purpose of the following code is to make sure commands are flushed, that
424 // aboutToDraw() is called and that notifyContentWillChange is called, without
425 // calling anything redundantly.
426 if (fPipeController.hasPendingCommands()) {
427 this->flushPendingCommands(kNormal_PlaybackMode);
429 bool mustNotifyDirectly = !fCanDiscardCanvasContents;
431 if (mustNotifyDirectly) {
432 fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
436 fImmediateCanvas->flush();
439 bool SkDeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
441 SkASSERT(x >= 0 && y >= 0);
442 SkASSERT(x + info.width() <= width());
443 SkASSERT(y + info.height() <= height());
445 const SkImageInfo deviceInfo = this->imageInfo();
446 if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height()) {
447 this->skipPendingCommands();
449 this->flushPendingCommands(kNormal_PlaybackMode);
452 this->prepareForImmediatePixelWrite();
453 return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y);
456 const SkBitmap& SkDeferredDevice::onAccessBitmap() {
457 this->flushPendingCommands(kNormal_PlaybackMode);
458 return immediateDevice()->accessBitmap(false);
461 SkBaseDevice* SkDeferredDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint* layerPaint) {
462 // Create a compatible non-deferred device.
463 // We do not create a deferred device because we know the new device
464 // will not be used with a deferred canvas (there is no API for that).
465 // And connecting a SkDeferredDevice to non-deferred canvas can result
466 // in unpredictable behavior.
467 return immediateDevice()->onCreateDevice(cinfo, layerPaint);
470 SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
471 return this->immediateDevice()->newSurface(info, props);
474 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
476 this->flushPendingCommands(kNormal_PlaybackMode);
477 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y);
480 class AutoImmediateDrawIfNeeded {
482 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
483 const SkPaint* paint) {
484 this->init(canvas, bitmap, paint);
487 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
488 this->init(canvas, NULL, paint);
491 ~AutoImmediateDrawIfNeeded() {
493 fCanvas->setDeferredDrawing(true);
497 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) {
498 if (canvas.isDeferredDrawing() &&
499 should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold())) {
500 canvas.setDeferredDrawing(false);
507 SkDeferredCanvas* fCanvas;
510 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) {
511 SkAutoTUnref<SkDeferredDevice> deferredDevice(SkNEW_ARGS(SkDeferredDevice, (surface)));
512 return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
515 SkDeferredCanvas::SkDeferredCanvas(SkDeferredDevice* device) : SkCanvas (device) {
519 void SkDeferredCanvas::init() {
520 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
521 fDeferredDrawing = true; // On by default
522 fCachedCanvasSize.setEmpty();
523 fCachedCanvasSizeDirty = true;
525 fFirstSaveLayerIndex = kNoSaveLayerIndex;
528 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
530 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
533 size_t SkDeferredCanvas::storageAllocatedForRecording() const {
534 return this->getDeferredDevice()->storageAllocatedForRecording();
537 size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
538 return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
541 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
542 fBitmapSizeThreshold = sizeThreshold;
545 void SkDeferredCanvas::recordedDrawCommand() {
546 if (fDeferredDrawing) {
547 this->getDeferredDevice()->recordedDrawCommand();
551 void SkDeferredCanvas::validate() const {
552 SkASSERT(this->getDevice());
555 SkCanvas* SkDeferredCanvas::drawingCanvas() const {
557 return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
558 this->getDeferredDevice()->immediateCanvas();
561 SkCanvas* SkDeferredCanvas::immediateCanvas() const {
563 return this->getDeferredDevice()->immediateCanvas();
566 SkDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
567 return static_cast<SkDeferredDevice*>(this->getDevice());
570 void SkDeferredCanvas::setDeferredDrawing(bool val) {
571 this->validate(); // Must set device before calling this method
572 if (val != fDeferredDrawing) {
573 if (fDeferredDrawing) {
575 this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
577 fDeferredDrawing = val;
581 bool SkDeferredCanvas::isDeferredDrawing() const {
582 return fDeferredDrawing;
585 bool SkDeferredCanvas::isFreshFrame() const {
586 return this->getDeferredDevice()->isFreshFrame();
589 SkISize SkDeferredCanvas::getCanvasSize() const {
590 if (fCachedCanvasSizeDirty) {
591 fCachedCanvasSize = this->getBaseLayerSize();
592 fCachedCanvasSizeDirty = false;
594 return fCachedCanvasSize;
597 bool SkDeferredCanvas::hasPendingCommands() const {
598 return this->getDeferredDevice()->hasPendingCommands();
601 void SkDeferredCanvas::silentFlush() {
602 if (fDeferredDrawing) {
603 this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
607 SkDeferredCanvas::~SkDeferredCanvas() {
610 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
611 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
612 SkASSERT(deferredDevice);
613 // By swapping the surface into the existing device, we preserve
614 // all pending commands, which can help to seamlessly recover from
615 // a lost accelerated graphics context.
616 deferredDevice->setSurface(surface);
617 fCachedCanvasSizeDirty = true;
621 SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
622 NotificationClient* notificationClient) {
624 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
625 SkASSERT(deferredDevice);
626 if (deferredDevice) {
627 deferredDevice->setNotificationClient(notificationClient);
629 return notificationClient;
632 SkImage* SkDeferredCanvas::newImageSnapshot() {
633 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
634 SkASSERT(deferredDevice);
635 return deferredDevice ? deferredDevice->newImageSnapshot() : NULL;
638 bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
639 const SkPaint* paint) const {
640 SkCanvas* canvas = this->drawingCanvas();
641 SkISize canvasSize = this->getCanvasSize();
643 if (!canvas->getTotalMatrix().rectStaysRect()) {
644 return false; // conservative
647 SkRect transformedRect;
648 canvas->getTotalMatrix().mapRect(&transformedRect, *rect);
651 SkPaint::Style paintStyle = paint->getStyle();
652 if (!(paintStyle == SkPaint::kFill_Style ||
653 paintStyle == SkPaint::kStrokeAndFill_Style)) {
656 if (paint->getMaskFilter() || paint->getLooper()
657 || paint->getPathEffect() || paint->getImageFilter()) {
658 return false; // conservative
662 // The following test holds with AA enabled, and is conservative
663 // by a 0.5 pixel margin with AA disabled
664 if (transformedRect.fLeft > SkIntToScalar(0) ||
665 transformedRect.fTop > SkIntToScalar(0) ||
666 transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) ||
667 transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) {
672 return this->getClipStack()->quickContains(SkRect::MakeXYWH(0, 0,
673 SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight)));
676 void SkDeferredCanvas::willSave() {
678 this->drawingCanvas()->save();
679 this->recordedDrawCommand();
680 this->INHERITED::willSave();
683 SkCanvas::SaveLayerStrategy SkDeferredCanvas::willSaveLayer(const SkRect* bounds,
684 const SkPaint* paint, SaveFlags flags) {
686 if (fFirstSaveLayerIndex == kNoSaveLayerIndex) {
687 fFirstSaveLayerIndex = fSaveLevel;
688 this->getDeferredDevice()->setIsDrawingToLayer(true);
690 this->drawingCanvas()->saveLayer(bounds, paint, flags);
691 this->recordedDrawCommand();
692 this->INHERITED::willSaveLayer(bounds, paint, flags);
693 // No need for a full layer.
694 return kNoLayer_SaveLayerStrategy;
697 void SkDeferredCanvas::willRestore() {
698 SkASSERT(fFirstSaveLayerIndex == kNoSaveLayerIndex || fFirstSaveLayerIndex <= fSaveLevel);
699 if (fFirstSaveLayerIndex == fSaveLevel) {
700 fFirstSaveLayerIndex = kNoSaveLayerIndex;
701 this->getDeferredDevice()->setIsDrawingToLayer(false);
704 this->drawingCanvas()->restore();
705 this->recordedDrawCommand();
706 this->INHERITED::willRestore();
709 void SkDeferredCanvas::didConcat(const SkMatrix& matrix) {
710 this->drawingCanvas()->concat(matrix);
711 this->recordedDrawCommand();
712 this->INHERITED::didConcat(matrix);
715 void SkDeferredCanvas::didSetMatrix(const SkMatrix& matrix) {
716 this->drawingCanvas()->setMatrix(matrix);
717 this->recordedDrawCommand();
718 this->INHERITED::didSetMatrix(matrix);
721 void SkDeferredCanvas::onClipRect(const SkRect& rect,
723 ClipEdgeStyle edgeStyle) {
724 this->drawingCanvas()->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
725 this->INHERITED::onClipRect(rect, op, edgeStyle);
726 this->recordedDrawCommand();
729 void SkDeferredCanvas::onClipRRect(const SkRRect& rrect,
731 ClipEdgeStyle edgeStyle) {
732 this->drawingCanvas()->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
733 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
734 this->recordedDrawCommand();
737 void SkDeferredCanvas::onClipPath(const SkPath& path,
739 ClipEdgeStyle edgeStyle) {
740 this->drawingCanvas()->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle);
741 this->INHERITED::onClipPath(path, op, edgeStyle);
742 this->recordedDrawCommand();
745 void SkDeferredCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
746 this->drawingCanvas()->clipRegion(deviceRgn, op);
747 this->INHERITED::onClipRegion(deviceRgn, op);
748 this->recordedDrawCommand();
751 void SkDeferredCanvas::onDrawPaint(const SkPaint& paint) {
752 if (fDeferredDrawing && this->isFullFrame(NULL, &paint) &&
753 isPaintOpaque(&paint)) {
754 this->getDeferredDevice()->skipPendingCommands();
756 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
757 this->drawingCanvas()->drawPaint(paint);
758 this->recordedDrawCommand();
761 void SkDeferredCanvas::onDrawPoints(PointMode mode, size_t count,
762 const SkPoint pts[], const SkPaint& paint) {
763 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
764 this->drawingCanvas()->drawPoints(mode, count, pts, paint);
765 this->recordedDrawCommand();
768 void SkDeferredCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
769 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
770 this->drawingCanvas()->drawOval(rect, paint);
771 this->recordedDrawCommand();
774 void SkDeferredCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
775 if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
776 isPaintOpaque(&paint)) {
777 this->getDeferredDevice()->skipPendingCommands();
780 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
781 this->drawingCanvas()->drawRect(rect, paint);
782 this->recordedDrawCommand();
785 void SkDeferredCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
786 if (rrect.isRect()) {
787 this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
788 } else if (rrect.isOval()) {
789 this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
791 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
792 this->drawingCanvas()->drawRRect(rrect, paint);
793 this->recordedDrawCommand();
797 void SkDeferredCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
798 const SkPaint& paint) {
799 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
800 this->drawingCanvas()->drawDRRect(outer, inner, paint);
801 this->recordedDrawCommand();
804 void SkDeferredCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
805 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
806 this->drawingCanvas()->drawPath(path, paint);
807 this->recordedDrawCommand();
810 void SkDeferredCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar left,
811 SkScalar top, const SkPaint* paint) {
812 SkRect bitmapRect = SkRect::MakeXYWH(left, top,
813 SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
814 if (fDeferredDrawing &&
815 this->isFullFrame(&bitmapRect, paint) &&
816 isPaintOpaque(paint, &bitmap)) {
817 this->getDeferredDevice()->skipPendingCommands();
820 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
821 this->drawingCanvas()->drawBitmap(bitmap, left, top, paint);
822 this->recordedDrawCommand();
825 void SkDeferredCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
827 const SkPaint* paint, DrawBitmapRectFlags flags) {
828 if (fDeferredDrawing &&
829 this->isFullFrame(&dst, paint) &&
830 isPaintOpaque(paint, &bitmap)) {
831 this->getDeferredDevice()->skipPendingCommands();
834 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
835 this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
836 this->recordedDrawCommand();
839 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
840 const SkIRect& center, const SkRect& dst,
841 const SkPaint* paint) {
842 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
843 // covers canvas entirely and dst covers canvas entirely
844 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
845 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint);
846 this->recordedDrawCommand();
849 void SkDeferredCanvas::onDrawSprite(const SkBitmap& bitmap, int left, int top,
850 const SkPaint* paint) {
851 SkRect bitmapRect = SkRect::MakeXYWH(
854 SkIntToScalar(bitmap.width()),
855 SkIntToScalar(bitmap.height()));
856 if (fDeferredDrawing &&
857 this->isFullFrame(&bitmapRect, paint) &&
858 isPaintOpaque(paint, &bitmap)) {
859 this->getDeferredDevice()->skipPendingCommands();
862 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
863 this->drawingCanvas()->drawSprite(bitmap, left, top, paint);
864 this->recordedDrawCommand();
867 void SkDeferredCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
868 const SkPaint& paint) {
869 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
870 this->drawingCanvas()->drawText(text, byteLength, x, y, paint);
871 this->recordedDrawCommand();
874 void SkDeferredCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
875 const SkPaint& paint) {
876 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
877 this->drawingCanvas()->drawPosText(text, byteLength, pos, paint);
878 this->recordedDrawCommand();
881 void SkDeferredCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
882 SkScalar constY, const SkPaint& paint) {
883 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
884 this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
885 this->recordedDrawCommand();
888 void SkDeferredCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
889 const SkMatrix* matrix, const SkPaint& paint) {
890 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
891 this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint);
892 this->recordedDrawCommand();
895 void SkDeferredCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
896 const SkPaint& paint) {
897 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
898 this->drawingCanvas()->drawTextBlob(blob, x, y, paint);
899 this->recordedDrawCommand();
902 void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
903 const SkPaint* paint) {
904 this->drawingCanvas()->drawPicture(picture, matrix, paint);
905 this->recordedDrawCommand();
908 void SkDeferredCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
909 const SkPoint vertices[],
910 const SkPoint texs[],
911 const SkColor colors[], SkXfermode* xmode,
912 const uint16_t indices[], int indexCount,
913 const SkPaint& paint) {
914 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
915 this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
916 indices, indexCount, paint);
917 this->recordedDrawCommand();
920 void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
921 const SkPoint texCoords[4], SkXfermode* xmode,
922 const SkPaint& paint) {
923 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
924 this->drawingCanvas()->drawPatch(cubics, colors, texCoords, xmode, paint);
925 this->recordedDrawCommand();
928 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
929 this->drawingCanvas()->setDrawFilter(filter);
930 this->INHERITED::setDrawFilter(filter);
931 this->recordedDrawCommand();
935 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
936 return this->drawingCanvas();