diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-19 15:15:24 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-19 15:15:24 +0000 |
commit | 0a98d870448f66ea0df7c37a47b38cf2d3b734e5 (patch) | |
tree | dbb7d62f7226e2bc050e7277d2f5e5623adae175 | |
parent | 71db88225d4e26303b5c3ad2c44305f6a5660754 (diff) |
Don't clobber initial transform with SetMatrix.
BUG=skia:2378
R=reed@google.com, mtklein@google.com, robertphillips@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/290883004
git-svn-id: http://skia.googlecode.com/svn/trunk@14778 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/record/SkRecordDraw.cpp | 8 | ||||
-rw-r--r-- | src/record/SkRecordDraw.h | 4 | ||||
-rw-r--r-- | tests/RecordDrawTest.cpp | 30 | ||||
-rw-r--r-- | tests/RecordOptsTest.cpp | 26 | ||||
-rw-r--r-- | tests/RecordTestUtils.h | 31 |
5 files changed, 72 insertions, 27 deletions
diff --git a/src/record/SkRecordDraw.cpp b/src/record/SkRecordDraw.cpp index 324946e5d7..5df1650a5e 100644 --- a/src/record/SkRecordDraw.cpp +++ b/src/record/SkRecordDraw.cpp @@ -38,7 +38,13 @@ DRAW(PopCull, popCull()); DRAW(PushCull, pushCull(r.rect)); DRAW(Clear, clear(r.color)); DRAW(Concat, concat(r.matrix)); -DRAW(SetMatrix, setMatrix(r.matrix)); + +// We can't clobber the canvas' initial CTM when calling setMatrix. +template <> void Draw::draw(const SetMatrix& r) { + SkMatrix ctm; + ctm.setConcat(fInitialCTM, r.matrix); + fCanvas->setMatrix(ctm); +} DRAW(ClipPath, clipPath(r.path, r.op, r.doAA)); DRAW(ClipRRect, clipRRect(r.rrect, r.op, r.doAA)); diff --git a/src/record/SkRecordDraw.h b/src/record/SkRecordDraw.h index 4ec6e68e92..359679a6d7 100644 --- a/src/record/SkRecordDraw.h +++ b/src/record/SkRecordDraw.h @@ -19,7 +19,8 @@ namespace SkRecords { // This is an SkRecord visitor that will draw that SkRecord to an SkCanvas. class Draw : SkNoncopyable { public: - explicit Draw(SkCanvas* canvas) : fCanvas(canvas), fIndex(0) {} + explicit Draw(SkCanvas* canvas) + : fInitialCTM(canvas->getTotalMatrix()), fCanvas(canvas), fIndex(0) {} unsigned index() const { return fIndex; } void next() { ++fIndex; } @@ -44,6 +45,7 @@ private: bool skip(const PairedPushCull&); bool skip(const BoundedDrawPosTextH&); + const SkMatrix fInitialCTM; SkCanvas* fCanvas; unsigned fIndex; }; diff --git a/tests/RecordDrawTest.cpp b/tests/RecordDrawTest.cpp index d830aea6e5..b0e55a6fdb 100644 --- a/tests/RecordDrawTest.cpp +++ b/tests/RecordDrawTest.cpp @@ -6,6 +6,7 @@ */ #include "Test.h" +#include "RecordTestUtils.h" #include "SkDebugCanvas.h" #include "SkRecord.h" @@ -73,3 +74,32 @@ DEF_TEST(RecordDraw_Culling, r) { // If culling weren't working, we'd see 8 commands recorded here. REPORTER_ASSERT(r, 5 == clipped.count()); } + +DEF_TEST(RecordDraw_SetMatrixClobber, r) { + // Set up an SkRecord that just scales by 2x,3x. + SkRecord scaleRecord; + SkRecorder scaleCanvas(SkRecorder::kReadWrite_Mode, &scaleRecord, W, H); + SkMatrix scale; + scale.setScale(2, 3); + scaleCanvas.setMatrix(scale); + + // Set up an SkRecord with an initial +20, +20 translate. + SkRecord translateRecord; + SkRecorder translateCanvas(SkRecorder::kReadWrite_Mode, &translateRecord, W, H); + SkMatrix translate; + translate.setTranslate(20, 20); + translateCanvas.setMatrix(translate); + + SkRecordDraw(scaleRecord, &translateCanvas); + + // When we look at translateRecord now, it should have its first +20,+20 translate, + // then a 2x,3x scale that's been concatted with that +20,+20 translate. + const SkRecords::SetMatrix* setMatrix; + setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); + REPORTER_ASSERT(r, setMatrix->matrix == translate); + + setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 1); + SkMatrix expected = scale; + expected.postConcat(translate); + REPORTER_ASSERT(r, setMatrix->matrix == expected); +} diff --git a/tests/RecordOptsTest.cpp b/tests/RecordOptsTest.cpp index 34229d7a6b..d4ad73931b 100644 --- a/tests/RecordOptsTest.cpp +++ b/tests/RecordOptsTest.cpp @@ -6,40 +6,16 @@ */ #include "Test.h" +#include "RecordTestUtils.h" #include "SkRecord.h" #include "SkRecordOpts.h" #include "SkRecorder.h" #include "SkRecords.h" - #include "SkXfermode.h" static const int W = 1920, H = 1080; -// If the command we're reading is a U, set ptr to it, otherwise set it to NULL. -template <typename U> -struct ReadAs { - ReadAs() : ptr(NULL), type(SkRecords::Type(~0)) {} - - const U* ptr; - SkRecords::Type type; - - void operator()(const U& r) { ptr = &r; type = U::kType; } - - template <typename T> - void operator()(const T&) { type = U::kType; } -}; - -// Assert that the ith command in record is of type T, and return it. -template <typename T> -static const T* assert_type(skiatest::Reporter* r, const SkRecord& record, unsigned index) { - ReadAs<T> reader; - record.visit<void>(index, reader); - REPORTER_ASSERT(r, T::kType == reader.type); - REPORTER_ASSERT(r, NULL != reader.ptr); - return reader.ptr; -} - DEF_TEST(RecordOpts_Culling, r) { SkRecord record; SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H); diff --git a/tests/RecordTestUtils.h b/tests/RecordTestUtils.h new file mode 100644 index 0000000000..db3f02d3a2 --- /dev/null +++ b/tests/RecordTestUtils.h @@ -0,0 +1,31 @@ +#ifndef RecordTestUtils_DEFINED +#define RecordTestUtils_DEFINED + +#include "SkRecord.h" +#include "SkRecords.h" + +// If the command we're reading is a U, set ptr to it, otherwise set it to NULL. +template <typename U> +struct ReadAs { + ReadAs() : ptr(NULL), type(SkRecords::Type(~0)) {} + + const U* ptr; + SkRecords::Type type; + + void operator()(const U& r) { ptr = &r; type = U::kType; } + + template <typename T> + void operator()(const T&) { type = U::kType; } +}; + +// Assert that the ith command in record is of type T, and return it. +template <typename T> +static const T* assert_type(skiatest::Reporter* r, const SkRecord& record, unsigned index) { + ReadAs<T> reader; + record.visit<void>(index, reader); + REPORTER_ASSERT(r, T::kType == reader.type); + REPORTER_ASSERT(r, NULL != reader.ptr); + return reader.ptr; +} + +#endif//RecordTestUtils_DEFINED |