diff options
-rw-r--r-- | include/core/SkCanvas.h | 5 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 12 | ||||
-rw-r--r-- | src/utils/SkCanvasStateUtils.cpp | 7 | ||||
-rw-r--r-- | tests/CanvasStateTest.cpp | 38 | ||||
-rw-r--r-- | tests/ClipStackTest.cpp | 29 |
5 files changed, 61 insertions, 30 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 47dd47b2c1..02e46e767a 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1321,6 +1321,8 @@ public: */ void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds); + void temporary_internal_getRgnClip(SkRegion*); + protected: #ifdef SK_EXPERIMENTAL_SHADOWING /** Returns the current (cumulative) draw depth of the canvas. @@ -1611,9 +1613,6 @@ private: const char text[], size_t byteLength, SkScalar x, SkScalar y); - // only for canvasutils - const SkRegion& internal_private_getTotalClip() const; - /* * Returns true if drawing the specified rect (or all if it is null) with the specified * paint (or default if null) would overwrite the entire root device of the canvas diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index e3374dde52..0375ab738d 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1819,8 +1819,16 @@ const SkMatrix& SkCanvas::getTotalMatrix() const { return fMCRec->fMatrix; } -const SkRegion& SkCanvas::internal_private_getTotalClip() const { - return fMCRec->fRasterClip.forceGetBW(); +void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) { + // we know that ganesh doesn't track the rgn, so ask for its clipstack + if (this->getGrContext()) { + SkPath path; + this->getClipStack()->asPath(&path); + SkISize size = this->getBaseLayerSize(); + rgn->setPath(path, SkRegion(SkIRect::MakeWH(size.width(), size.height()))); + } else { + *rgn = fMCRec->fRasterClip.forceGetBW(); + } } GrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() { diff --git a/src/utils/SkCanvasStateUtils.cpp b/src/utils/SkCanvasStateUtils.cpp index 6dd0ca337b..a78f3435a4 100644 --- a/src/utils/SkCanvasStateUtils.cpp +++ b/src/utils/SkCanvasStateUtils.cpp @@ -202,8 +202,11 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) { std::unique_ptr<SkCanvasState_v1> canvasState(new SkCanvasState_v1(canvas)); // decompose the total matrix and clip - setup_MC_state(&canvasState->mcState, canvas->getTotalMatrix(), - canvas->internal_private_getTotalClip()); + { + SkRegion rgn; + canvas->temporary_internal_getRgnClip(&rgn); + setup_MC_state(&canvasState->mcState, canvas->getTotalMatrix(), rgn); + } /* * decompose the layers diff --git a/tests/CanvasStateTest.cpp b/tests/CanvasStateTest.cpp index 9533474c56..38fb3fe8bc 100644 --- a/tests/CanvasStateTest.cpp +++ b/tests/CanvasStateTest.cpp @@ -306,9 +306,11 @@ DEF_TEST(CanvasState_test_soft_clips, reporter) { REPORTER_ASSERT(reporter, !state); } -#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG -#include "SkClipStack.h" DEF_TEST(CanvasState_test_saveLayer_clip, reporter) { + const uint32_t dontSaveFlag = 1 << 31; // secret flag for don't save +#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG + static_assert(SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag == dontSaveFlag, ""); +#endif const int WIDTH = 100; const int HEIGHT = 100; const int LAYER_WIDTH = 50; @@ -321,31 +323,21 @@ DEF_TEST(CanvasState_test_saveLayer_clip, reporter) { SkRect bounds = SkRect::MakeWH(SkIntToScalar(LAYER_WIDTH), SkIntToScalar(LAYER_HEIGHT)); canvas.clipRect(SkRect::MakeWH(SkIntToScalar(WIDTH), SkIntToScalar(HEIGHT))); - // Check that saveLayer without the kClipToLayer_SaveFlag leaves the - // clip stack unchanged. - canvas.saveLayer(SkCanvas::SaveLayerRec(&bounds, - nullptr, - SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag)); - SkRect clipStackBounds; - SkClipStack::BoundsType boundsType; - canvas.getClipStack()->getBounds(&clipStackBounds, &boundsType); - // The clip stack will return its bounds, or it may be "full" : i.e. empty + inside_out. - // Either result is consistent with this test, since the canvas' size is WIDTH/HEIGHT - if (SkClipStack::kInsideOut_BoundsType == boundsType) { - REPORTER_ASSERT(reporter, clipStackBounds.isEmpty()); - } else { - REPORTER_ASSERT(reporter, clipStackBounds.width() == WIDTH); - REPORTER_ASSERT(reporter, clipStackBounds.height() == HEIGHT); - } + SkIRect devClip; + // Check that saveLayer without the kClipToLayer_SaveFlag leaves the clip unchanged. + canvas.saveLayer(SkCanvas::SaveLayerRec(&bounds, nullptr, dontSaveFlag)); + canvas.getClipDeviceBounds(&devClip); + REPORTER_ASSERT(reporter, canvas.isClipRect()); + REPORTER_ASSERT(reporter, devClip.width() == WIDTH); + REPORTER_ASSERT(reporter, devClip.height() == HEIGHT); canvas.restore(); // Check that saveLayer with the kClipToLayer_SaveFlag sets the clip // stack to the layer bounds. canvas.saveLayer(&bounds, nullptr); - canvas.getClipStack()->getBounds(&clipStackBounds, &boundsType); - REPORTER_ASSERT(reporter, clipStackBounds.width() == LAYER_WIDTH); - REPORTER_ASSERT(reporter, clipStackBounds.height() == LAYER_HEIGHT); - + canvas.getClipDeviceBounds(&devClip); + REPORTER_ASSERT(reporter, canvas.isClipRect()); + REPORTER_ASSERT(reporter, devClip.width() == LAYER_WIDTH); + REPORTER_ASSERT(reporter, devClip.height() == LAYER_HEIGHT); canvas.restore(); } -#endif diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp index a85f0168b2..8448f4cbe5 100644 --- a/tests/ClipStackTest.cpp +++ b/tests/ClipStackTest.cpp @@ -1456,4 +1456,33 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) { #endif } +#include "SkSurface.h" +DEF_GPUTEST_FOR_ALL_CONTEXTS(canvas_private_clipRgn, reporter, ctxInfo) { + GrContext* context = ctxInfo.grContext(); + + const int w = 10; + const int h = 10; + SkImageInfo info = SkImageInfo::MakeN32Premul(w, h); + sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); + SkCanvas* canvas = surf->getCanvas(); + SkRegion rgn; + + canvas->temporary_internal_getRgnClip(&rgn); + REPORTER_ASSERT(reporter, rgn.isRect()); + REPORTER_ASSERT(reporter, rgn.getBounds() == SkIRect::MakeWH(w, h)); + + canvas->save(); + canvas->clipRect(SkRect::MakeWH(5, 5), kDifference_SkClipOp); + canvas->temporary_internal_getRgnClip(&rgn); + REPORTER_ASSERT(reporter, rgn.isComplex()); + REPORTER_ASSERT(reporter, rgn.getBounds() == SkIRect::MakeWH(w, h)); + canvas->restore(); + + canvas->save(); + canvas->clipRRect(SkRRect::MakeOval(SkRect::MakeLTRB(3, 3, 7, 7))); + canvas->temporary_internal_getRgnClip(&rgn); + REPORTER_ASSERT(reporter, rgn.isComplex()); + REPORTER_ASSERT(reporter, rgn.getBounds() == SkIRect::MakeLTRB(3, 3, 7, 7)); + canvas->restore(); +} #endif |