diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-12 20:21:48 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-12 20:21:48 +0000 |
commit | e54a23fcfa42b2fc9d320650de72bcb2d9566b2d (patch) | |
tree | bf63292c10f857384abd6a35a6fd0ff6c5a1fb96 /src/core | |
parent | f11943f21d985cba5af38b1609dbe8a4cfa58179 (diff) |
De-virtualize SkCanvas save/restore.
This moves the state management logic into non-virtual SkCanvas methods,
and turns the virtuals into protected notifiers.
R=reed@google.com, robertphillips@google.com
Author: fmalita@chromium.org
Review URL: https://codereview.chromium.org/194713008
git-svn-id: http://skia.googlecode.com/svn/trunk@13776 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBBoxHierarchyRecord.cpp | 15 | ||||
-rw-r--r-- | src/core/SkBBoxHierarchyRecord.h | 9 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 34 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 24 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 8 |
5 files changed, 57 insertions, 33 deletions
diff --git a/src/core/SkBBoxHierarchyRecord.cpp b/src/core/SkBBoxHierarchyRecord.cpp index 5d310be7bc..e1be2e1972 100644 --- a/src/core/SkBBoxHierarchyRecord.cpp +++ b/src/core/SkBBoxHierarchyRecord.cpp @@ -26,20 +26,21 @@ void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) { fBoundingHierarchy->insert(draw, r, true); } -int SkBBoxHierarchyRecord::save(SaveFlags flags) { +void SkBBoxHierarchyRecord::willSave(SaveFlags flags) { fStateTree->appendSave(); - return INHERITED::save(flags); + this->INHERITED::willSave(flags); } -int SkBBoxHierarchyRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkBBoxHierarchyRecord::willSaveLayer(const SkRect* bounds, + const SkPaint* paint, + SaveFlags flags) { fStateTree->appendSaveLayer(this->writeStream().bytesWritten()); - return INHERITED::saveLayer(bounds, paint, flags); + return this->INHERITED::willSaveLayer(bounds, paint, flags); } -void SkBBoxHierarchyRecord::restore() { +void SkBBoxHierarchyRecord::willRestore() { fStateTree->appendRestore(); - INHERITED::restore(); + this->INHERITED::willRestore(); } bool SkBBoxHierarchyRecord::translate(SkScalar dx, SkScalar dy) { diff --git a/src/core/SkBBoxHierarchyRecord.h b/src/core/SkBBoxHierarchyRecord.h index 80f59c3907..fdfc9f726b 100644 --- a/src/core/SkBBoxHierarchyRecord.h +++ b/src/core/SkBBoxHierarchyRecord.h @@ -23,11 +23,6 @@ public: virtual void handleBBox(const SkRect& bounds) SK_OVERRIDE; - virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags = kARGB_ClipLayer_SaveFlag) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; virtual bool rotate(SkScalar degrees) SK_OVERRIDE; @@ -39,6 +34,10 @@ public: virtual bool shouldRewind(void* data) SK_OVERRIDE; protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 4086291507..6f33280f42 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -347,8 +347,8 @@ public: if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { SkPaint tmp; tmp.setImageFilter(fOrigPaint.getImageFilter()); - (void)canvas->internalSaveLayer(bounds, &tmp, - SkCanvas::kARGB_ClipLayer_SaveFlag, true); + (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, + true, SkCanvas::kFullLayer_SaveLayerStrategy); // we'll clear the imageFilter for the actual draws in next(), so // it will only be applied during the restore(). fDoClearImageFilter = true; @@ -810,7 +810,12 @@ int SkCanvas::internalSave(SaveFlags flags) { return saveCount; } +void SkCanvas::willSave(SaveFlags) { + // Do nothing. Subclasses may do something. +} + int SkCanvas::save(SaveFlags flags) { + this->willSave(flags); // call shared impl return this->internalSave(flags); } @@ -867,9 +872,17 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, return true; } +SkCanvas::SaveLayerStrategy SkCanvas::willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) { + + // Do nothing. Subclasses may do something. + return kFullLayer_SaveLayerStrategy; +} + int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { - return this->internalSaveLayer(bounds, paint, flags, false); + // Overriding classes may return false to signal that we don't need to create a layer. + SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); + return this->internalSaveLayer(bounds, paint, flags, false, strategy); } static SkBaseDevice* createCompatibleDevice(SkCanvas* canvas, @@ -878,8 +891,8 @@ static SkBaseDevice* createCompatibleDevice(SkCanvas* canvas, return device ? device->createCompatibleDevice(info) : NULL; } -int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags, bool justForImageFilter) { +int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, + bool justForImageFilter, SaveLayerStrategy strategy) { #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG flags = (SaveFlags)(flags | kClipToLayer_SaveFlag); #endif @@ -895,6 +908,12 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, return count; } + // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about + // the clipRectBounds() call above? + if (kNoLayer_SaveLayerStrategy == strategy) { + return count; + } + // Kill the imagefilter if our device doesn't allow it SkLazyPaint lazyP; if (paint && paint->getImageFilter()) { @@ -947,9 +966,14 @@ int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, } } +void SkCanvas::willRestore() { + // Do nothing. Subclasses may do something. +} + void SkCanvas::restore() { // check for underflow if (fMCStack.count() > 1) { + this->willRestore(); this->internalRestore(); } } diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 08b69b8527..a85ea8de0b 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -146,7 +146,7 @@ static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { return gPaintOffsets[op] * sizeof(uint32_t) + overflow; } -int SkPictureRecord::save(SaveFlags flags) { +void SkPictureRecord::willSave(SaveFlags flags) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.save(flags); @@ -156,7 +156,8 @@ int SkPictureRecord::save(SaveFlags flags) { fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); this->recordSave(flags); #endif - return this->INHERITED::save(flags); + + this->INHERITED::willSave(flags); } void SkPictureRecord::recordSave(SaveFlags flags) { @@ -168,12 +169,11 @@ void SkPictureRecord::recordSave(SaveFlags flags) { this->validate(initialOffset, size); } -int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkPictureRecord::willSaveLayer(const SkRect* bounds, + const SkPaint* paint, SaveFlags flags) { - int count; #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE - count = fMCMgr.saveLayer(bounds, paint, flags); + fMCMgr.saveLayer(bounds, paint, flags); #else // record the offset to us, making it non-positive to distinguish a save // from a clip entry. @@ -184,15 +184,13 @@ int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, } #endif - /* Don't actually call INHERITED::saveLayer, because that will try to allocate - an offscreen device (potentially very big) which we don't actually need + this->INHERITED::willSaveLayer(bounds, paint, flags); + /* No need for a (potentially very big) layer which we don't actually need at this time (and may not be able to afford since during record our clip starts out the size of the picture, which is often much larger than the size of the actual device we'll use during playback). */ - count = this->INHERITED::save(flags); - this->clipRectBounds(bounds, flags, NULL); - return count; + return kNoLayer_SaveLayerStrategy; } void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint, @@ -605,7 +603,7 @@ static void apply_optimization_to_bbh(PictureRecordOptType opt, SkPictureStateTr } } -void SkPictureRecord::restore() { +void SkPictureRecord::willRestore() { // FIXME: SkDeferredCanvas needs to be refactored to respect // save/restore balancing so that the following test can be // turned on permanently. @@ -653,7 +651,7 @@ void SkPictureRecord::restore() { fRestoreOffsetStack.pop(); #endif - return this->INHERITED::restore(); + this->INHERITED::willRestore(); } void SkPictureRecord::recordRestore(bool fillInSkips) { diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index e91c1c5c12..d1d6362e1a 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -37,9 +37,6 @@ public: SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags); virtual ~SkPictureRecord(); - virtual int save(SaveFlags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; virtual bool rotate(SkScalar degrees) SK_OVERRIDE; @@ -227,6 +224,11 @@ protected: const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE { return NULL; } + + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; virtual void onPushCull(const SkRect&) SK_OVERRIDE; virtual void onPopCull() SK_OVERRIDE; |