diff options
author | Mike Reed <reed@google.com> | 2017-02-08 10:07:53 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-08 15:42:46 +0000 |
commit | 7627fa51044e35dc21251f925b56f6dd6887df97 (patch) | |
tree | fdef2c19e28f5ca8c10aa137672696a2746c8170 /src | |
parent | 688ded2ee6c3472986eec2122830667378697577 (diff) |
add virtuals in prep for device-clipping
Build flag available for backends to begin testing their impl.
Need to formalize save/restore, and how to forward these to device but not on picture canvases.
BUG=skia:6214
Change-Id: Ic5c0afba3e8c84fcf124567e63fe2f5880b623e7
Reviewed-on: https://skia-review.googlesource.com/8183
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapDevice.cpp | 35 | ||||
-rw-r--r-- | src/core/SkBitmapDevice.h | 9 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 41 | ||||
-rw-r--r-- | src/core/SkDevice.h | 40 |
4 files changed, 123 insertions, 2 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index fe43ba24b6..2b5c37fa2e 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -74,6 +74,8 @@ SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) { SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr)); fBitmap.lockPixels(); + + fRCStack.push_back().setRect(SkIRect::MakeWH(bitmap.width(), bitmap.height())); } SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) { @@ -88,6 +90,8 @@ SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& sur { SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr)); fBitmap.lockPixels(); + + fRCStack.push_back().setRect(SkIRect::MakeWH(bitmap.width(), bitmap.height())); } SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo, @@ -439,7 +443,7 @@ SkImageFilterCache* SkBitmapDevice::getImageFilterCache() { return cache; } -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const { if (kN32_SkColorType != fBitmap.colorType() || @@ -453,3 +457,32 @@ bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const { } return false; } + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +void SkBitmapDevice::onSave() { + fRCStack.push_back(fRCStack.back()); +} + +void SkBitmapDevice::onRestore() { + fRCStack.pop_back(); +} + +void SkBitmapDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) { + fRCStack.back().op(rect, this->ctm(), SkIRect::MakeWH(this->width(), this->height()), + (SkRegion::Op)op, aa); +} + +void SkBitmapDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) { + fRCStack.back().op(rrect, this->ctm(), SkIRect::MakeWH(this->width(), this->height()), + (SkRegion::Op)op, aa); +} + +void SkBitmapDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) { + fRCStack.back().op(path, this->ctm(), SkIRect::MakeWH(this->width(), this->height()), + (SkRegion::Op)op, aa); +} + +void SkBitmapDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) { + fRCStack.back().op(rgn, (SkRegion::Op)op); +} diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h index 1f72d8df3c..0a6471080b 100644 --- a/src/core/SkBitmapDevice.h +++ b/src/core/SkBitmapDevice.h @@ -14,6 +14,7 @@ #include "SkDevice.h" #include "SkImageInfo.h" #include "SkPixelRef.h" +#include "SkRasterClip.h" #include "SkRect.h" #include "SkScalar.h" #include "SkSize.h" @@ -125,6 +126,13 @@ protected: bool onPeekPixels(SkPixmap*) override; bool onAccessPixels(SkPixmap*) override; + void onSave() override; + void onRestore() override; + void onClipRect(const SkRect& rect, SkClipOp, bool aa) override; + void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override; + void onClipPath(const SkPath& path, SkClipOp, bool aa) override; + void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override; + private: friend class SkCanvas; friend struct DeviceCM; //for setMatrixClip @@ -147,6 +155,7 @@ private: SkBitmap fBitmap; void* fRasterHandle = nullptr; + SkTArray<SkRasterClip> fRCStack; void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture(). diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index eb81bd7951..64ef348e13 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -387,6 +387,16 @@ private: typedef SkDraw INHERITED; }; +#define FOR_EACH_TOP_DEVICE( code ) \ + do { \ + DeviceCM* layer = fMCRec->fTopLayer; \ + while (layer) { \ + SkBaseDevice* device = layer->fDevice; \ + code; \ + layer = layer->fNext; \ + } \ + } while (0) + ///////////////////////////////////////////////////////////////////////////// static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { @@ -999,6 +1009,9 @@ void SkCanvas::doSave() { SkASSERT(fMCRec->fDeferredSaveCount > 0); fMCRec->fDeferredSaveCount -= 1; this->internalSave(); +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->save()); +#endif } void SkCanvas::restore() { @@ -1014,6 +1027,9 @@ void SkCanvas::restore() { fSaveCount -= 1; this->internalRestore(); this->didRestore(); +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix)); +#endif } } } @@ -1456,6 +1472,11 @@ void SkCanvas::concat(const SkMatrix& matrix) { fDeviceCMDirty = true; fMCRec->fMatrix.preConcat(matrix); fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); + +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); +#endif + this->didConcat(matrix); } @@ -1505,6 +1526,11 @@ void SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) { void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; + +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA)); +#endif + AutoValidateClip avc(this); fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA); fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, @@ -1542,6 +1568,11 @@ void SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edge fDeviceCMDirty = true; bool isAA = kSoft_ClipEdgeStyle == edgeStyle; + +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA)); +#endif + fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA); fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, isAA); @@ -1579,7 +1610,11 @@ void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeSty fDeviceCMDirty = true; bool isAA = kSoft_ClipEdgeStyle == edgeStyle; - + +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA)); +#endif + fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA); const SkPath* rasterClipPath = &path; @@ -1602,6 +1637,10 @@ void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) { } void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) { +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op)); +#endif + AutoValidateClip avc(this); fDeviceCMDirty = true; diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index 92396725a4..3c0b7785d3 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -13,6 +13,9 @@ #include "SkColor.h" #include "SkSurfaceProps.h" +// enable to test new device-base clipping +//#define SK_USE_DEVICE_CLIPPING + class SkBitmap; class SkDraw; class SkDrawFilter; @@ -101,6 +104,35 @@ public: virtual void* getRasterHandle() const { return nullptr; } + void save() { this->onSave(); } + void restore(const SkMatrix& ctm) { + this->onRestore(); + this->setGlobalCTM(ctm); + } + void clipRect(const SkRect& rect, SkClipOp op, bool aa) { + this->onClipRect(rect, op, aa); + } + void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) { + this->onClipRRect(rrect, op, aa); + } + void clipPath(const SkPath& path, SkClipOp op, bool aa) { + this->onClipPath(path, op, aa); + } + void clipRegion(const SkRegion& region, SkClipOp op) { + this->onClipRegion(region, op); + } + + const SkMatrix& ctm() const { return fCTM; } + void setCTM(const SkMatrix& ctm) { + fCTM = ctm; + } + void setGlobalCTM(const SkMatrix& ctm) { + fCTM = ctm; + if (fOrigin.fX | fOrigin.fY) { + fCTM.postTranslate(-SkIntToScalar(fOrigin.fX), -SkIntToScalar(fOrigin.fY)); + } + } + protected: enum TileUsage { kPossible_TileUsage, //!< the created device may be drawn tiled @@ -119,6 +151,13 @@ protected: virtual bool onShouldDisableLCD(const SkPaint&) const { return false; } + virtual void onSave() {} + virtual void onRestore() {} + virtual void onClipRect(const SkRect& rect, SkClipOp, bool aa) {} + virtual void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) {} + virtual void onClipPath(const SkPath& path, SkClipOp, bool aa) {} + virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp) {} + /** These are called inside the per-device-layer loop for each draw call. When these are called, we have already applied any saveLayer operations, and are handling any looping from the paint, and any effects from the @@ -348,6 +387,7 @@ private: SkIPoint fOrigin; const SkImageInfo fInfo; const SkSurfaceProps fSurfaceProps; + SkMatrix fCTM; typedef SkRefCnt INHERITED; }; |