aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkPictureAnalyzer.h12
-rw-r--r--src/core/SkPictureAnalyzer.cpp21
-rw-r--r--src/core/SkPictureCommon.h7
-rw-r--r--tests/PictureTest.cpp63
4 files changed, 101 insertions, 2 deletions
diff --git a/include/core/SkPictureAnalyzer.h b/include/core/SkPictureAnalyzer.h
index fa8cdb1fd1..b7a76cce80 100644
--- a/include/core/SkPictureAnalyzer.h
+++ b/include/core/SkPictureAnalyzer.h
@@ -9,11 +9,13 @@
#define SkPictureAnalyzer_DEFINED
#include "SkRefCnt.h"
+#include "SkRegion.h"
#include "SkTypes.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
+class SkPath;
class SkPicture;
/** \class SkPictureGpuAnalyzer
@@ -29,7 +31,15 @@ public:
/**
* Process the given picture and accumulate its stats.
*/
- void analyze(const SkPicture*);
+ void analyzePicture(const SkPicture*);
+
+ // Legacy/transitional alias.
+ void analyze(const SkPicture* picture) { this->analyzePicture(picture); }
+
+ /**
+ * Process an explicit clipPath op.
+ */
+ void analyzeClipPath(const SkPath&, SkRegion::Op, bool doAntiAlias);
/**
* Reset all accumulated stats.
diff --git a/src/core/SkPictureAnalyzer.cpp b/src/core/SkPictureAnalyzer.cpp
index 0ba420258b..49c4fce779 100644
--- a/src/core/SkPictureAnalyzer.cpp
+++ b/src/core/SkPictureAnalyzer.cpp
@@ -5,8 +5,11 @@
* found in the LICENSE file.
*/
+#include "SkPath.h"
#include "SkPicture.h"
#include "SkPictureAnalyzer.h"
+#include "SkPictureCommon.h"
+#include "SkRecords.h"
#if SK_SUPPORT_GPU
@@ -27,7 +30,7 @@ SkPictureGpuAnalyzer::SkPictureGpuAnalyzer(const sk_sp<SkPicture>& picture,
this->analyze(picture.get());
}
-void SkPictureGpuAnalyzer::analyze(const SkPicture* picture) {
+void SkPictureGpuAnalyzer::analyzePicture(const SkPicture* picture) {
if (!picture || veto_predicate(fNumSlowPaths)) {
return;
}
@@ -35,6 +38,22 @@ void SkPictureGpuAnalyzer::analyze(const SkPicture* picture) {
fNumSlowPaths += picture->numSlowPaths();
}
+void SkPictureGpuAnalyzer::analyzeClipPath(const SkPath& path, SkRegion::Op op, bool doAntiAlias) {
+ if (veto_predicate(fNumSlowPaths)) {
+ return;
+ }
+
+ const SkRecords::ClipPath clipOp = {
+ SkIRect::MakeEmpty(), // Willie don't care.
+ path,
+ SkRecords::RegionOpAndAA(op, doAntiAlias)
+ };
+
+ SkPathCounter counter;
+ counter(clipOp);
+ fNumSlowPaths += counter.fNumSlowPathsAndDashEffects;
+}
+
void SkPictureGpuAnalyzer::reset() {
fNumSlowPaths = 0;
}
diff --git a/src/core/SkPictureCommon.h b/src/core/SkPictureCommon.h
index 16146be020..1c38b049fa 100644
--- a/src/core/SkPictureCommon.h
+++ b/src/core/SkPictureCommon.h
@@ -123,6 +123,13 @@ struct SkPathCounter {
}
}
+ void operator()(const SkRecords::ClipPath& op) {
+ // TODO: does the SkRegion op matter?
+ if (op.opAA.aa && !op.path.isConvex()) {
+ fNumSlowPathsAndDashEffects++;
+ }
+ }
+
void operator()(const SkRecords::SaveLayer& op) {
this->checkPaint(AsPtr(op.paint));
}
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index c71e66309a..0603eb328f 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -135,6 +135,25 @@ static void rand_op(SkCanvas* canvas, SkRandom& rand) {
#if SK_SUPPORT_GPU
+static SkPath make_convex_path() {
+ SkPath path;
+ path.lineTo(100, 0);
+ path.lineTo(50, 100);
+ path.close();
+
+ return path;
+}
+
+static SkPath make_concave_path() {
+ SkPath path;
+ path.lineTo(50, 50);
+ path.lineTo(100, 0);
+ path.lineTo(50, 100);
+ path.close();
+
+ return path;
+}
+
static void test_gpu_veto(skiatest::Reporter* reporter) {
SkPictureRecorder recorder;
@@ -261,6 +280,34 @@ static void test_gpu_veto(skiatest::Reporter* reporter) {
// ... but only when applied to drawPoint() calls
REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRasterization());
+ canvas = recorder.beginRecording(100, 100);
+ {
+ const SkPath convexClip = make_convex_path();
+ const SkPath concaveClip = make_concave_path();
+
+ for (int i = 0; i < 50; ++i) {
+ canvas->clipPath(convexClip);
+ canvas->clipPath(concaveClip);
+ canvas->clipPath(convexClip, SkRegion::kIntersect_Op, true);
+ canvas->drawRect(SkRect::MakeWH(100, 100), SkPaint());
+ }
+ }
+ picture = recorder.finishRecordingAsPicture();
+ // Convex clips and non-AA concave clips are fine on the GPU.
+ REPORTER_ASSERT(reporter, SkPictureGpuAnalyzer(picture).suitableForGpuRasterization());
+
+ canvas = recorder.beginRecording(100, 100);
+ {
+ const SkPath concaveClip = make_concave_path();
+ for (int i = 0; i < 50; ++i) {
+ canvas->clipPath(concaveClip, SkRegion::kIntersect_Op, true);
+ canvas->drawRect(SkRect::MakeWH(100, 100), SkPaint());
+ }
+ }
+ picture = recorder.finishRecordingAsPicture();
+ // ... but AA concave clips are not.
+ REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRasterization());
+
// Nest the previous picture inside a new one.
canvas = recorder.beginRecording(100, 100);
{
@@ -1380,6 +1427,22 @@ DEF_TEST(PictureGpuAnalyzer, r) {
analyzer.analyze(nestedVetoPicture.get());
REPORTER_ASSERT(r, !analyzer.suitableForGpuRasterization());
+
+ analyzer.reset();
+
+ const SkPath convexClip = make_convex_path();
+ const SkPath concaveClip = make_concave_path();
+ for (int i = 0; i < 50; ++i) {
+ analyzer.analyzeClipPath(convexClip, SkRegion::kIntersect_Op, false);
+ analyzer.analyzeClipPath(convexClip, SkRegion::kIntersect_Op, true);
+ analyzer.analyzeClipPath(concaveClip, SkRegion::kIntersect_Op, false);
+ }
+ REPORTER_ASSERT(r, analyzer.suitableForGpuRasterization());
+
+ for (int i = 0; i < 50; ++i) {
+ analyzer.analyzeClipPath(concaveClip, SkRegion::kIntersect_Op, true);
+ }
+ REPORTER_ASSERT(r, !analyzer.suitableForGpuRasterization());
}
#endif // SK_SUPPORT_GPU