diff options
author | mtklein <mtklein@chromium.org> | 2015-11-19 07:23:49 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-19 07:23:49 -0800 |
commit | c3c6194ba2b90fde57d8d0bc1d6302656f0dae27 (patch) | |
tree | 52446ca72e146435b47a63afd39f4d15f0d0c474 | |
parent | a2e3e0f7f8ceed2ab152428d7ee2812ad8c842c3 (diff) |
Add SkRecord::defrag().
Called by SkRecordOptimize(), this moves all the NoOps to the end and
slices them off.
This implementation with std::remove_if() is linear and doesn't malloc.
No diffs: https://gold.skia.org/search2?issue=1461663003&unt=true&query=source_type%3Dgm&master=false
BUG=skia:
Review URL: https://codereview.chromium.org/1461663003
-rw-r--r-- | src/core/SkRecord.cpp | 10 | ||||
-rw-r--r-- | src/core/SkRecord.h | 4 | ||||
-rw-r--r-- | src/core/SkRecordOpts.cpp | 2 | ||||
-rw-r--r-- | tests/RecordTest.cpp | 26 | ||||
-rw-r--r-- | tests/RecordTestUtils.h | 1 |
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> |