diff options
author | Mike Reed <reed@google.com> | 2017-02-16 11:04:52 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-16 19:49:37 +0000 |
commit | d519d484949161df6d4b2ecadc282427cab532cf (patch) | |
tree | b675d7967c13fb83372cb1a78539f665de0634c3 /src | |
parent | e595bbfba6e7dcdda0d7d700343e9d814a406771 (diff) |
add device-clipping to gpudevice
BUG=skia:
Change-Id: Id8c8994d4bddf591e1205ed9d591f4fce7d3af99
Reviewed-on: https://skia-review.googlesource.com/8531
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapDevice.cpp | 4 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 14 | ||||
-rw-r--r-- | src/core/SkDevice.h | 3 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.cpp | 3 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 55 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.h | 10 |
6 files changed, 83 insertions, 6 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index 8ed5120251..9ea4937e9a 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -509,6 +509,10 @@ void SkBitmapDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) { void SkBitmapDevice::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) { fRCStack.setDeviceClipRestriction(mutableClipRestriction); + if (!mutableClipRestriction->isEmpty()) { + SkRegion rgn(*mutableClipRestriction); + fRCStack.clipRegion(rgn, SkClipOp::kIntersect); + } } void SkBitmapDevice::validateDevBounds(const SkIRect& drawClipBounds) { diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index cb2ddb6ad0..cbf40f1556 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -338,6 +338,9 @@ public: fMultiDeviceCS = canvas->fClipStack.get(); fMultiDeviceCS->save(); } +#ifdef SK_USE_DEVICE_CLIPPING + fClipStack = nullptr; // for testing +#endif } ~SkDrawIter() { @@ -1579,11 +1582,16 @@ void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeSty void SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) { fClipRestrictionRect = rect; fClipStack->setDeviceClipRestriction(fClipRestrictionRect); - if (!fClipRestrictionRect.isEmpty()) { + if (fClipRestrictionRect.isEmpty()) { + // we notify the device, but we *dont* resolve deferred saves (since we're just + // removing the restriction if the rect is empty. how I hate this api. +#ifdef SK_USE_DEVICE_CLIPPING + FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); +#endif + } else { this->checkForDeferredSave(); #ifdef SK_USE_DEVICE_CLIPPING - SkRegion restrictRgn(fClipRestrictionRect); - FOR_EACH_TOP_DEVICE(device->clipRegion(restrictRgn, SkClipOp::kIntersect)); + FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); #endif AutoValidateClip avc(this); fClipStack->clipDevRect(fClipRestrictionRect, kIntersect_SkClipOp); diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index 2a481971cf..66a6e1d1f0 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -13,9 +13,6 @@ #include "SkColor.h" #include "SkSurfaceProps.h" -// enable to test new device-base clipping -//#define SK_USE_DEVICE_CLIPPING - class SkBitmap; class SkDraw; class SkDrawFilter; diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp index b7dd37a922..f9e628ce0d 100644 --- a/src/gpu/GrRenderTargetOpList.cpp +++ b/src/gpu/GrRenderTargetOpList.cpp @@ -555,7 +555,10 @@ void GrRenderTargetOpList::forwardCombine() { if (j == i +1) { // We assume op would have combined with candidate when the candidate was added // via backwards combining in recordOp. +#ifndef SK_USE_DEVICE_CLIPPING + // not sure why this fires with device-clipping in gm/complexclip4.cpp SkASSERT(!op->combineIfPossible(candidate.fOp.get(), *this->caps())); +#endif } else if (op->combineIfPossible(candidate.fOp.get(), *this->caps())) { GrOP_INFO("\t\tCombining with (%s, B%u)\n", candidate.fOp->name(), candidate.fOp->uniqueID()); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 0197a6e663..791d4353c7 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -236,7 +236,12 @@ bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) { void SkGpuDevice::prepareDraw(const SkDraw& draw) { ASSERT_SINGLE_OWNER +#ifdef SK_USE_DEVICE_CLIPPING + SkASSERT(*draw.fMatrix == this->ctm()); + fClip.reset(&fClipStack, nullptr); +#else fClip.reset(draw.fClipStack, &this->getOrigin()); +#endif } GrRenderTargetContext* SkGpuDevice::accessRenderTargetContext() { @@ -1820,4 +1825,54 @@ SkImageFilterCache* SkGpuDevice::getImageFilterCache() { return SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize); } +/////////////////////////////////////////////////////////////////////////////////////////////////// + +void SkGpuDevice::onSave() { + fClipStack.save(); +} + +void SkGpuDevice::onRestore() { + fClipStack.restore(); +} + +void SkGpuDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) { + fClipStack.clipRect(rect, this->ctm(), op, aa); +} + +void SkGpuDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) { + fClipStack.clipRRect(rrect, this->ctm(), op, aa); +} + +void SkGpuDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) { + fClipStack.clipPath(path, this->ctm(), op, aa); +} + +void SkGpuDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) { + SkIPoint origin = this->getOrigin(); + SkRegion tmp; + const SkRegion* ptr = &rgn; + if (origin.fX | origin.fY) { + // translate from "global/canvas" coordinates to relative to this device + rgn.translate(-origin.fX, -origin.fY, &tmp); + ptr = &tmp; + } + fClipStack.clipDevRect(ptr->getBounds(), op); +} + +void SkGpuDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) { + if (clipRestriction->isEmpty()) { + fClipStack.setDeviceClipRestriction(*clipRestriction); + } else { + SkIPoint origin = this->getOrigin(); + SkIRect rect = clipRestriction->makeOffset(-origin.x(), -origin.y()); + fClipStack.setDeviceClipRestriction(rect); + fClipStack.clipDevRect(rect, SkClipOp::kIntersect); + } +} + +void SkGpuDevice::validateDevBounds(const SkIRect& drawClipBounds) { +#ifdef SK_DEBUG +#endif +} + #endif diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 846a7e5798..ab3fb3f462 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -134,6 +134,7 @@ private: sk_sp<GrRenderTargetContext> fRenderTargetContext; SkIPoint fClipOrigin; + SkClipStack fClipStack; GrClipStackClip fClip; SkISize fSize; bool fOpaque; @@ -237,6 +238,15 @@ private: bool drawDashLine(const SkPoint pts[2], const SkPaint& paint); void drawStrokedLine(const SkPoint pts[2], const SkDraw&, const SkPaint&); + 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; + void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override; + void validateDevBounds(const SkIRect& r) override; + static sk_sp<GrRenderTargetContext> MakeRenderTargetContext(GrContext*, SkBudgeted, const SkImageInfo&, |