aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkRecord.cpp10
-rw-r--r--src/core/SkRecord.h4
-rw-r--r--src/core/SkRecordOpts.cpp2
-rw-r--r--tests/RecordTest.cpp26
-rw-r--r--tests/RecordTestUtils.h1
5 files changed, 40 insertions, 3 deletions
diff --git a/src/core/SkRecord.cpp b/src/core/SkRecord.cpp
index 2d2fa58991..2e03e993b8 100644
--- a/src/core/SkRecord.cpp
+++ b/src/core/SkRecord.cpp
@@ -6,6 +6,7 @@
*/
#include "SkRecord.h"
+#include <algorithm>
SkRecord::~SkRecord() {
Destroyer destroyer;
@@ -30,3 +31,12 @@ size_t SkRecord::bytesUsed() const {
}
return bytes;
}
+
+void SkRecord::defrag() {
+ // Remove all the NoOps, preserving the order of other ops, e.g.
+ // Save, ClipRect, NoOp, DrawRect, NoOp, NoOp, Restore
+ // -> Save, ClipRect, DrawRect, Restore
+ Record* noops = std::remove_if(fRecords.get(), fRecords.get() + fCount,
+ [](Record op) { return op.type() == SkRecords::NoOp_Type; });
+ fCount = noops - fRecords.get();
+}
diff --git a/src/core/SkRecord.h b/src/core/SkRecord.h
index ee10b15784..8901d62e91 100644
--- a/src/core/SkRecord.h
+++ b/src/core/SkRecord.h
@@ -111,6 +111,10 @@ public:
// need to iterate with a visitor to measure those they care for.
size_t bytesUsed() const;
+ // Rearrange and resize this record to eliminate any NoOps.
+ // May change count() and the indices of ops, but preserves their order.
+ void defrag();
+
private:
// An SkRecord is structured as an array of pointers into a big chunk of memory where
// records representing each canvas draw call are stored:
diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp
index 8faa45ce56..04c72c32cc 100644
--- a/src/core/SkRecordOpts.cpp
+++ b/src/core/SkRecordOpts.cpp
@@ -22,6 +22,8 @@ void SkRecordOptimize(SkRecord* record) {
SkRecordNoopSaveLayerDrawRestores(record);
SkRecordMergeSvgOpacityAndFilterLayers(record);
+
+ record->defrag();
}
// Most of the optimizations in this file are pattern-based. These are all defined as structs with:
diff --git a/tests/RecordTest.cpp b/tests/RecordTest.cpp
index 9e02c882db..e613b425fd 100644
--- a/tests/RecordTest.cpp
+++ b/tests/RecordTest.cpp
@@ -5,13 +5,14 @@
* found in the LICENSE file.
*/
-#include "Test.h"
-
+#include "RecordTestUtils.h"
#include "SkBitmap.h"
#include "SkImageInfo.h"
-#include "SkShader.h"
#include "SkRecord.h"
#include "SkRecords.h"
+#include "SkShader.h"
+#include "Test.h"
+
// Sums the area of any DrawRect command it sees.
class AreaSummer {
@@ -76,6 +77,25 @@ DEF_TEST(Record, r) {
REPORTER_ASSERT(r, summer.area() == 500);
}
+DEF_TEST(Record_defrag, r) {
+ SkRecord record;
+ APPEND(record, SkRecords::Save);
+ APPEND(record, SkRecords::ClipRect);
+ APPEND(record, SkRecords::NoOp);
+ APPEND(record, SkRecords::DrawRect);
+ APPEND(record, SkRecords::NoOp);
+ APPEND(record, SkRecords::NoOp);
+ APPEND(record, SkRecords::Restore);
+ REPORTER_ASSERT(r, record.count() == 7);
+
+ record.defrag();
+ REPORTER_ASSERT(r, record.count() == 4);
+ assert_type<SkRecords::Save >(r, record, 0);
+ assert_type<SkRecords::ClipRect>(r, record, 1);
+ assert_type<SkRecords::DrawRect>(r, record, 2);
+ assert_type<SkRecords::Restore >(r, record, 3);
+}
+
#undef APPEND
template <typename T>
diff --git a/tests/RecordTestUtils.h b/tests/RecordTestUtils.h
index e4421fab52..a281566652 100644
--- a/tests/RecordTestUtils.h
+++ b/tests/RecordTestUtils.h
@@ -10,6 +10,7 @@
#include "SkRecord.h"
#include "SkRecords.h"
+#include "Test.h"
// If the command we're reading is a U, set ptr to it, otherwise set it to nullptr.
template <typename U>