Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: src/core/SkRecordAnalysis.cpp

Issue 364823009: Port suitableForGpuRasterization to SkRecord (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: More SkPicture.h cleanup Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkRecordAnalysis.cpp
diff --git a/src/core/SkRecordAnalysis.cpp b/src/core/SkRecordAnalysis.cpp
index 0bfbaef9a65febd570b649bd16b01bdb85d1c17a..2d6d8fdaccf550485655fddda9d60991316df36a 100644
--- a/src/core/SkRecordAnalysis.cpp
+++ b/src/core/SkRecordAnalysis.cpp
@@ -1,8 +1,12 @@
#include "SkRecordAnalysis.h"
+#include "SkPathEffect.h"
#include "SkShader.h"
#include "SkTLogic.h"
+
+namespace {
+
/** SkRecords visitor to determine whether an instance may require an
"external" bitmap to rasterize. May return false positives.
Does not return true for bitmap text.
@@ -55,7 +59,7 @@ struct BitmapTester {
static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return false; }
};
-bool SkRecordWillPlaybackBitmaps(const SkRecord& record) {
+bool SkWillPlaybackBitmaps(const SkRecord& record) {
BitmapTester tester;
for (unsigned i = 0; i < record.count(); i++) {
if (record.visit<bool>(i, tester)) {
@@ -64,3 +68,127 @@ bool SkRecordWillPlaybackBitmaps(const SkRecord& record) {
}
return false;
}
+
+struct PathCounter {
+ SK_CREATE_MEMBER_DETECTOR(paint);
+ SK_CREATE_TYPE_DETECTOR(DrawPoints);
+ SK_CREATE_TYPE_DETECTOR(DrawPath);
+
+ // Some commands have a paint, some have an optional paint. Either way, get back a pointer.
+ static const SkPaint* AsPtr(const SkPaint& p) { return &p; }
+ static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; }
+
+ PathCounter()
+ : numPaintWithPathEffectUses (0)
+ , numFastPathDashEffects (0)
+ , numAAConcavePaths (0)
+ , numAAHairlineConcavePaths (0) {
+ }
+
+ // Must have a return type to make the SkRecord vistor templates happy.
+ template <typename T>
+ bool operator()(const T& r) {
+ CheckPaint(r);
+ CheckDrawPoints(r);
+ CheckDrawPath(r);
+ return true;
+ }
+
+ template <typename T>
+ SK_WHEN(HasMember_paint<T>, void) CheckPaint(const T& r) {
+ const SkPaint* paint = AsPtr(r.paint);
+ if (paint && paint->getPathEffect()) {
+ numPaintWithPathEffectUses++;
+ }
+ }
+
+ template <typename T>
+ SK_WHEN(!HasMember_paint<T>, void) CheckPaint(const T& r) { /* do nothing */ }
+
+ template <typename T>
+ SK_WHEN(HasType_DrawPoints<T>, void) CheckDrawPoints(const T& r) {
+ const SkPathEffect* effect = r.paint.getPathEffect();
+ if (effect) {
+ SkPathEffect::DashInfo info;
+ SkPathEffect::DashType dashType = effect->asADash(&info);
+ if (2 == r.count && SkPaint::kRound_Cap != r.paint.getStrokeCap() &&
+ SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
+ numFastPathDashEffects++;
+ }
+ }
+ }
+
+ template <typename T>
+ SK_WHEN(!HasType_DrawPoints<T>, void) CheckDrawPoints(const T& r) { /* do nothing */ }
+
+ template <typename T>
+ SK_WHEN(HasType_DrawPath<T>, void) CheckDrawPath(const T& r) {
+ if (r.paint.isAntiAlias() && !r.path.isConvex()) {
+ numAAConcavePaths++;
+
+ if (SkPaint::kStroke_Style == r.paint.getStyle() &&
+ 0 == r.paint.getStrokeWidth()) {
+ numAAHairlineConcavePaths++;
+ }
+ }
+ }
+
+ template <typename T>
+ SK_WHEN(!HasType_DrawPath<T>, void) CheckDrawPath(const T& r) { /* do nothing */ }
+
+
+ int numPaintWithPathEffectUses;
+ int numFastPathDashEffects;
+ int numAAConcavePaths;
+ int numAAHairlineConcavePaths;
+};
+
+bool SkRecordSuitableForGpuRasterization(const SkRecord& record,
+ const char** reason = NULL,
+ int sampleCount = 0) {
+ PathCounter counter;
+ for (unsigned i = 0; i < record.count(); i++) {
+ record.visit<bool>(i, counter);
+ }
+
+ // TODO: the heuristic used here needs to be refined
+ static const int kNumPaintWithPathEffectsUsesTol = 1;
+ static const int kNumAAConcavePathsTol = 5;
+
+ int numNonDashedPathEffects = counter.numPaintWithPathEffectUses -
+ counter.numFastPathDashEffects;
+ bool suitableForDash = (0 == counter.numPaintWithPathEffectUses) ||
+ (numNonDashedPathEffects < kNumPaintWithPathEffectsUsesTol
+ && 0 == sampleCount);
+
+ bool ret = suitableForDash &&
+ (counter.numAAConcavePaths - counter.numAAHairlineConcavePaths)
+ < kNumAAConcavePathsTol;
+
+ if (!ret && NULL != reason) {
+ if (!suitableForDash) {
+ if (0 != sampleCount) {
+ *reason = "Can't use multisample on dash effect.";
+ } else {
+ *reason = "Too many non dashed path effects.";
+ }
+ } else if ((counter.numAAConcavePaths - counter.numAAHairlineConcavePaths)
+ >= kNumAAConcavePathsTol)
+ *reason = "Too many anti-aliased concave paths.";
+ else
+ *reason = "Unknown reason for GPU unsuitability.";
+ }
+ return ret;
+}
+
+} // namespace
+
+SkRecordAnalysis AnalyzeSkRecord(const SkRecord& record) {
+ SkRecordAnalysis results;
+
+ results.fWillPlaybackBitmaps = SkWillPlaybackBitmaps(record);
+ results.fSuitableForGpuRasterization = SkRecordSuitableForGpuRasterization(record);
+
+ return results;
+}
+
« src/core/SkRecord.h ('K') | « src/core/SkRecordAnalysis.h ('k') | tests/RecordTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698