new hacky api to get cliprgn for android
authorMike Reed <reed@google.com>
Thu, 19 Jan 2017 16:36:41 +0000 (11:36 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 19 Jan 2017 18:31:28 +0000 (18:31 +0000)
BUG=skia:

Change-Id: I42711a474906084adb3c888a599ae02505726484
Reviewed-on: https://skia-review.googlesource.com/7220
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>

include/core/SkCanvas.h
src/core/SkCanvas.cpp
src/utils/SkCanvasStateUtils.cpp
tests/CanvasStateTest.cpp
tests/ClipStackTest.cpp

index 47dd47b..02e46e7 100644 (file)
@@ -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
index e3374dd..0375ab7 100644 (file)
@@ -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() {
index 6dd0ca3..a78f343 100644 (file)
@@ -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
index 9533474..38fb3fe 100644 (file)
@@ -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
index a85f016..8448f4c 100644 (file)
@@ -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