Index: src/core/SkRecordOpts.cpp |
diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp |
index 8faa45ce562201ac0c3029d06d2abf8f0f2acffe..2eef11f6e390d9bbdb4cd851583d1e78eb1e6881 100644 |
--- a/src/core/SkRecordOpts.cpp |
+++ b/src/core/SkRecordOpts.cpp |
@@ -13,17 +13,6 @@ |
using namespace SkRecords; |
-void SkRecordOptimize(SkRecord* record) { |
- // This might be useful as a first pass in the future if we want to weed |
- // out junk for other optimization passes. Right now, nothing needs it, |
- // and the bounding box hierarchy will do the work of skipping no-op |
- // Save-NoDraw-Restore sequences better than we can here. |
- //SkRecordNoopSaveRestores(record); |
- |
- SkRecordNoopSaveLayerDrawRestores(record); |
- SkRecordMergeSvgOpacityAndFilterLayers(record); |
-} |
- |
// Most of the optimizations in this file are pattern-based. These are all defined as structs with: |
// - a Pattern typedef |
// - a bool onMatch(SkRceord*, Pattern*, int begin, int end) method, |
@@ -44,6 +33,61 @@ static bool apply(Pass* pass, SkRecord* record) { |
return changed; |
} |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+struct MultipleSetMatrixNooper { |
+ typedef Pattern2<Is<SetMatrix>, |
+ // TODO: tried Star<Or<Is<Noop>, Is<SetMatrix>>>, but it seemed to not match |
mtklein
2015/11/19 16:26:56
After refamiliarizing myself with how these patter
reed1
2015/11/19 17:29:44
Done.
Does this mean I should loop myself, or is
|
+ Is<SetMatrix> > |
+ Pattern; |
+ |
+ bool onMatch(SkRecord* record, Pattern* pattern, int begin, int end) { |
+ SkASSERT(begin + 2 == end); |
+ record->replace<NoOp>(begin); // SetMatrix |
+ return true; |
+ } |
+}; |
+static void multiple_set_matrices(SkRecord* record) { |
mtklein
2015/11/19 16:26:56
I've found it butt-saving to have each pass unit t
|
+ MultipleSetMatrixNooper pass; |
mtklein
2015/11/19 16:26:56
Might want to move the struct in here too like wit
reed1
2015/11/19 17:29:44
Done.
|
+ |
+ // No need to loop, as we never "open up" opportunities for more of this type of optimization. |
+ apply(&pass, record); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+#if 0 // experimental, but needs knowledge of previous matrix to operate correctly |
+static void apply_matrix_to_draw_params(SkRecord* record) { |
+ struct { |
+ typedef Pattern3<Is<SetMatrix>, |
+ Is<DrawBitmapRect>, |
+ Is<Restore> > |
+ Pattern; |
+ |
+ bool onMatch(SkRecord* record, Pattern* pattern, int begin, int end) { |
+ const SkMatrix& m = pattern->first<SetMatrix>()->matrix; |
+ if (m.getType() > (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { |
+ SkDebugf("too complex\n"); |
+ return false; // can't handle rotation or perspective |
+ } |
+ if (m.getScaleX() < 0 || m.getScaleY() < 0) { |
+ SkDebugf("negative\n"); |
+ return false; // can't represent a flip in a rect |
+ } |
+ DrawBitmapRect* dbr = pattern->second<DrawBitmapRect>(); |
+ m.dump(); |
+ // wack the rect, and eliminate the matrix |
+ m.mapRect(&dbr->dst); |
+ record->replace<NoOp>(begin); |
+ return true; |
+ } |
+ } pass; |
+ apply(&pass, record); |
+} |
+#endif |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
// Turns the logical NoOp Save and Restore in Save-Draw*-Restore patterns into actual NoOps. |
struct SaveOnlyDrawsRestoreNooper { |
typedef Pattern3<Is<Save>, |
@@ -230,3 +274,26 @@ void SkRecordMergeSvgOpacityAndFilterLayers(SkRecord* record) { |
SvgOpacityAndFilterLayerMergePass pass; |
apply(&pass, record); |
} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+void SkRecordOptimize(SkRecord* record) { |
+ // This might be useful as a first pass in the future if we want to weed |
+ // out junk for other optimization passes. Right now, nothing needs it, |
+ // and the bounding box hierarchy will do the work of skipping no-op |
+ // Save-NoDraw-Restore sequences better than we can here. |
+ //SkRecordNoopSaveRestores(record); |
+ |
+ SkRecordNoopSaveLayerDrawRestores(record); |
+ SkRecordMergeSvgOpacityAndFilterLayers(record); |
+} |
+ |
+void SkRecordOptimize2(SkRecord* record) { |
+ multiple_set_matrices(record); |
+ |
+ SkRecordNoopSaveRestores(record); |
+ |
+ SkRecordNoopSaveLayerDrawRestores(record); |
+ SkRecordMergeSvgOpacityAndFilterLayers(record); |
+} |
+ |