Add API to get canvas wrapped by SkPaintFilterCanvas
Implement SkAndroidFrameworkUtil::getBaseWrappedCanvas, which gets
the real canvas behind SkPaintFilterCanvas. This is useful, because
SkCanvas::drawDrawable works differently on a GPU backed canvas.
Test: Built and ran with Android
Bug: b/128792554
Change-Id: I5b75d42256d7a4efca987d55be2ce064c10fb4e7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/204442
Commit-Queue: Stan Iliev <stani@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/include/android/SkAndroidFrameworkUtils.h b/include/android/SkAndroidFrameworkUtils.h
index 67b8492..a4a937e 100644
--- a/include/android/SkAndroidFrameworkUtils.h
+++ b/include/android/SkAndroidFrameworkUtils.h
@@ -40,6 +40,15 @@
static sk_sp<SkSurface> getSurfaceFromCanvas(SkCanvas* canvas);
static int SaveBehind(SkCanvas* canvas, const SkRect* subset);
+
+ /**
+ * Unrolls a chain of nested SkPaintFilterCanvas to return the base wrapped canvas.
+ *
+ * @param canvas A SkPaintFilterCanvas or any other SkCanvas subclass.
+ *
+ * @return SkCanvas that was found in the innermost SkPaintFilterCanvas.
+ */
+ static SkCanvas* getBaseWrappedCanvas(SkCanvas* canvas);
};
#endif // SK_BUILD_FOR_ANDROID_ANDROID
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index d223e86..d66fd8d 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -31,6 +31,7 @@
class SkGlyphRunBuilder;
class SkImage;
class SkImageFilter;
+class SkPaintFilterCanvas;
class SkPath;
class SkPicture;
class SkPixmap;
@@ -2668,6 +2669,8 @@
*/
bool androidFramework_isClipAA() const;
+ virtual SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const { return nullptr; }
+
/**
* Keep track of the device clip bounds and if the matrix is scale-translate. This allows
* us to do a fast quick reject in the common case.
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h
index 23019d3..a89c3ad 100644
--- a/include/utils/SkPaintFilterCanvas.h
+++ b/include/utils/SkPaintFilterCanvas.h
@@ -12,6 +12,8 @@
#include "SkNWayCanvas.h"
#include "SkTLazy.h"
+class SkAndroidFrameworkUtils;
+
/** \class SkPaintFilterCanvas
A utility proxy base class for implementing draw/paint filters.
@@ -119,6 +121,12 @@
class AutoPaintFilter;
SkCanvas* proxy() const { SkASSERT(fList.count() == 1); return fList[0]; }
+
+ SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const override {
+ return const_cast<SkPaintFilterCanvas*>(this);
+ }
+
+ friend class SkAndroidFrameworkUtils;
};
#endif
diff --git a/src/android/SkAndroidFrameworkUtils.cpp b/src/android/SkAndroidFrameworkUtils.cpp
index d0f4499..a13e8a2 100644
--- a/src/android/SkAndroidFrameworkUtils.cpp
+++ b/src/android/SkAndroidFrameworkUtils.cpp
@@ -8,6 +8,7 @@
#include "SkAndroidFrameworkUtils.h"
#include "SkCanvas.h"
#include "SkDevice.h"
+#include "SkPaintFilterCanvas.h"
#include "SkSurface_Base.h"
#if SK_SUPPORT_GPU
@@ -67,5 +68,15 @@
int SkAndroidFrameworkUtils::SaveBehind(SkCanvas* canvas, const SkRect* subset) {
return canvas->only_axis_aligned_saveBehind(subset);
}
+
+SkCanvas* SkAndroidFrameworkUtils::getBaseWrappedCanvas(SkCanvas* canvas) {
+ auto pfc = canvas->internal_private_asPaintFilterCanvas();
+ auto result = canvas;
+ while (pfc) {
+ result = pfc->proxy();
+ pfc = result->internal_private_asPaintFilterCanvas();
+ }
+ return result;
+}
#endif // SK_BUILD_FOR_ANDROID_FRAMEWORK