RecordDrawTest.cpp revision 65151754b9fdb6a968d7307764c20655d1b680a0
1c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org/*
2c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * Copyright 2014 Google Inc.
3c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org *
4c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
5c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * found in the LICENSE file.
6c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org */
7c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org
8d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "Test.h"
90a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org#include "RecordTestUtils.h"
10d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
11d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkDebugCanvas.h"
12c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein#include "SkDrawPictureCallback.h"
13271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkDropShadowImageFilter.h"
1465151754b9fdb6a968d7307764c20655d1b680a0piotaixr#include "SkImagePriv.h"
15d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecord.h"
16d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecordDraw.h"
17271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkRecordOpts.h"
18d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecorder.h"
19d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecords.h"
2065151754b9fdb6a968d7307764c20655d1b680a0piotaixr#include "SkSurface.h"
21d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
22d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.orgstatic const int W = 1920, H = 1080;
23d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
24c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinclass JustOneDraw : public SkDrawPictureCallback {
25c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinpublic:
26c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw() : fCalls(0) {}
27c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
28c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
29c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinprivate:
30c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    int fCalls;
31c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein};
32c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
33c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) {
34c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    // Record two commands.
35c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
36c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
37c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint());
38c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.clipRect(SkRect::MakeWH(100, 200));
39c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
40c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
41c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
42c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
43c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw callback;
445ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(record, &canvas, NULL/*bbh*/, &callback);
45c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
46c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 3 == rerecord.count());
47c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 0);
48c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
49c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 2);
50c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
51c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
52c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) {
53c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
54c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
55c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.save();  // We won't balance this, but SkRecordDraw will for us.
56c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
57c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
58c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
595ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(record, &canvas, NULL/*bbh*/, NULL/*callback*/);
60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == rerecord.count());
62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 0);
63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 1);
64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 2);
65c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 3);
66c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
67c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
680a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) {
690a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord that just scales by 2x,3x.
700a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord scaleRecord;
71a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder scaleCanvas(&scaleRecord, W, H);
720a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix scale;
730a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scale.setScale(2, 3);
740a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scaleCanvas.setMatrix(scale);
750a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
760a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord with an initial +20, +20 translate.
770a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord translateRecord;
78a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder translateCanvas(&translateRecord, W, H);
790a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix translate;
800a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translate.setTranslate(20, 20);
810a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translateCanvas.setMatrix(translate);
820a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
835ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(scaleRecord, &translateCanvas, NULL/*bbh*/, NULL/*callback*/);
84c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == translateRecord.count());
85c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
86c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>     (r, translateRecord, 1);
87c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
88c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore>  (r, translateRecord, 3);
890a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
900a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // When we look at translateRecord now, it should have its first +20,+20 translate,
910a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // then a 2x,3x scale that's been concatted with that +20,+20 translate.
920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    const SkRecords::SetMatrix* setMatrix;
930a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
940a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == translate);
950a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
96c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix expected = scale;
980a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    expected.postConcat(translate);
990a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == expected);
1000a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org}
101a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
102a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinstruct TestBBH : public SkBBoxHierarchy {
1036bd41969a0f2283a7a7320bb0025551353c241ecmtklein    virtual void insert(unsigned opIndex, const SkRect& bounds, bool defer) SK_OVERRIDE {
1046bd41969a0f2283a7a7320bb0025551353c241ecmtklein        Entry e = { opIndex, bounds };
1056bd41969a0f2283a7a7320bb0025551353c241ecmtklein        fEntries.push(e);
106a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
107a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
1086bd41969a0f2283a7a7320bb0025551353c241ecmtklein    virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const SK_OVERRIDE {}
109a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
110a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    struct Entry {
1116bd41969a0f2283a7a7320bb0025551353c241ecmtklein        unsigned opIndex;
112533eb782edaa0b6fece6166d3001edf72ec39f11mtklein        SkRect bounds;
113a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    };
1146bd41969a0f2283a7a7320bb0025551353c241ecmtklein    SkTDArray<Entry> fEntries;
115a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein};
116a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
117937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// Like a==b, with a little slop recognizing that float equality can be weird.
118937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinstatic bool sloppy_rect_eq(SkRect a, SkRect b) {
119937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRect inset(a), outset(a);
120937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    inset.inset(1, 1);
121937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    outset.outset(1, 1);
122937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    return outset.contains(b) && !inset.contains(b);
123937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein}
124937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
125a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// This test is not meant to make total sense yet.  It's testing the status quo
126a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// of SkRecordFillBounds(), which itself doesn't make total sense yet.
127a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinDEF_TEST(RecordDraw_BBH, r) {
128a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecord record;
129a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecorder recorder(&record, W, H);
130a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.save();
131a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.clipRect(SkRect::MakeWH(400, 500));
132a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.scale(2, 2);
133a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint());
134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.restore();
135a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
136937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    TestBBH bbh;
137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecordFillBounds(record, &bbh);
138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
1396bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, bbh.fEntries.count() == 5);
1406bd41969a0f2283a7a7320bb0025551353c241ecmtklein    for (int i = 0; i < bbh.fEntries.count(); i++) {
1416bd41969a0f2283a7a7320bb0025551353c241ecmtklein        REPORTER_ASSERT(r, bbh.fEntries[i].opIndex == (unsigned)i);
142a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
1436bd41969a0f2283a7a7320bb0025551353c241ecmtklein        REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bbh.fEntries[i].bounds));
144a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
145a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein}
14600f30bdc9e34b013da54b4406f36556c5be8d041mtklein
147937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// A regression test for crbug.com/409110.
148937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinDEF_TEST(RecordDraw_TextBounds, r) {
149937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecord record;
150937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecorder recorder(&record, W, H);
151937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
152937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // Two Chinese characters in UTF-8.
153937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' };
154937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const size_t bytes = SK_ARRAY_COUNT(text);
155937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
156937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const SkScalar xpos[] = { 10, 20 };
157937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint());
158937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
159937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const SkPoint pos[] = { {40, 50}, {60, 70} };
160937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    recorder.drawPosText(text, bytes, pos, SkPaint());
161937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
162937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    TestBBH bbh;
163937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecordFillBounds(record, &bbh);
1646bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, bbh.fEntries.count() == 2);
165937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
166937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // We can make these next assertions confidently because SkRecordFillBounds
167937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // builds its bounds by overestimating font metrics in a platform-independent way.
168937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // If that changes, these tests will need to be more flexible.
1696bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(-86,  6, 116, 54)));
1706bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(-56, 26, 156, 94)));
171937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein}
172937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
17300f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected
17400f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) {
17500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
17600f30bdc9e34b013da54b4406f36556c5be8d041mtklein
17700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r1 = { 0, 0, kWidth,   kHeight };
17800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r2 = { 0, 0, kWidth,   kHeight/2 };
17900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r3 = { 0, 0, kWidth/2, kHeight };
18000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkPaint p;
18100f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
18300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
18400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r1, p);
18500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r2, p);
18600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r3, p);
18700f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
18900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
1904815fe5a0a497b676677fb4e4a0f05c511855490robertphillips    SkRecordPartialDraw(record, &canvas, r1, 1, 2, SkMatrix::I()); // replay just drawRect of r2
19100f30bdc9e34b013da54b4406f36556c5be8d041mtklein
19200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, 3 == rerecord.count());
19300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Save>     (r, rerecord, 0);
19400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::DrawRect> (r, rerecord, 1);
19500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Restore>  (r, rerecord, 2);
19600f30bdc9e34b013da54b4406f36556c5be8d041mtklein
19700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
19800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == r2);
19900f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
20000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20100f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Check that clears are converted to drawRects
20200f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialClear, r) {
20300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
20400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect rect = { 0, 0, kWidth, kHeight };
20600f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
20800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
20900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.clear(SK_ColorRED);
21000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
21200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
2134815fe5a0a497b676677fb4e4a0f05c511855490robertphillips    SkRecordPartialDraw(record, &canvas, rect, 0, 1, SkMatrix::I()); // replay just the clear
21400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, 3 == rerecord.count());
21600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Save>    (r, rerecord, 0);
21700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
21800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Restore> (r, rerecord, 2);
21900f30bdc9e34b013da54b4406f36556c5be8d041mtklein
22000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
22100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == rect);
22200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->paint.getColor() == SK_ColorRED);
22300f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
224271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
225271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein// A regression test for crbug.com/415468 and skbug.com/2957.
2268e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein//
2278e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// This also now serves as a regression test for crbug.com/418417.  We used to adjust the
2288e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture.
2298e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.)
230271a030f5d0d3c59715fbeffb31c761279f3f8caMike KleinDEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) {
231271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkRecord record;
232271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkRecorder recorder(&record, 50, 50);
233271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
234271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    // We draw a rectangle with a long drop shadow.  We used to not update the clip
235271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    // bounds based on SaveLayer paints, so the drop shadow could be cut off.
236271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkPaint paint;
237271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK))->unref();
238271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
239271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    recorder.saveLayer(NULL, &paint);
240271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein        recorder.clipRect(SkRect::MakeWH(20, 40));
241271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein        recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint());
242271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    recorder.restore();
243271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
2448e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // Under the original bug, the right edge value of the drawRect would be 20 less than asserted
2458e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // here because we intersected it with a clip that had not been adjusted for the drop shadow.
2468e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    //
2478e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too.
2488e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50).
249271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    TestBBH bbh;
250271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkRecordFillBounds(record, &bbh);
2516bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, bbh.fEntries.count() == 4);
2526bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
2536bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
2546bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(0, 0, 40, 40)));
2556bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[3].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
256271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein}
25765151754b9fdb6a968d7307764c20655d1b680a0piotaixr
25865151754b9fdb6a968d7307764c20655d1b680a0piotaixrDEF_TEST(RecordDraw_drawImage, r){
25965151754b9fdb6a968d7307764c20655d1b680a0piotaixr    class SkCanvasMock : public SkCanvas {
26065151754b9fdb6a968d7307764c20655d1b680a0piotaixr    public:
26165151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkCanvasMock(int width, int height) : INHERITED(width, height) {
26265151754b9fdb6a968d7307764c20655d1b680a0piotaixr            this->resetTestValues();
26365151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
26465151754b9fdb6a968d7307764c20655d1b680a0piotaixr        virtual ~SkCanvasMock() {}
26565151754b9fdb6a968d7307764c20655d1b680a0piotaixr        virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
26665151754b9fdb6a968d7307764c20655d1b680a0piotaixr                               const SkPaint* paint = NULL) SK_OVERRIDE {
26765151754b9fdb6a968d7307764c20655d1b680a0piotaixr
26865151754b9fdb6a968d7307764c20655d1b680a0piotaixr            fDrawImageCalled = true;
26965151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
27065151754b9fdb6a968d7307764c20655d1b680a0piotaixr
27165151754b9fdb6a968d7307764c20655d1b680a0piotaixr        virtual void drawImageRect(const SkImage* image, const SkRect* src,
27265151754b9fdb6a968d7307764c20655d1b680a0piotaixr                                   const SkRect& dst,
27365151754b9fdb6a968d7307764c20655d1b680a0piotaixr                                   const SkPaint* paint = NULL) SK_OVERRIDE {
27465151754b9fdb6a968d7307764c20655d1b680a0piotaixr            fDrawImageRectCalled = true;
27565151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
27665151754b9fdb6a968d7307764c20655d1b680a0piotaixr
27765151754b9fdb6a968d7307764c20655d1b680a0piotaixr        void resetTestValues() {
27865151754b9fdb6a968d7307764c20655d1b680a0piotaixr            fDrawImageCalled = fDrawImageRectCalled = false;
27965151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
28065151754b9fdb6a968d7307764c20655d1b680a0piotaixr
28165151754b9fdb6a968d7307764c20655d1b680a0piotaixr        bool fDrawImageCalled;
28265151754b9fdb6a968d7307764c20655d1b680a0piotaixr        bool fDrawImageRectCalled;
28365151754b9fdb6a968d7307764c20655d1b680a0piotaixr    private:
28465151754b9fdb6a968d7307764c20655d1b680a0piotaixr        typedef SkCanvas INHERITED;
28565151754b9fdb6a968d7307764c20655d1b680a0piotaixr    };
28665151754b9fdb6a968d7307764c20655d1b680a0piotaixr
28765151754b9fdb6a968d7307764c20655d1b680a0piotaixr    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(10, 10));
28865151754b9fdb6a968d7307764c20655d1b680a0piotaixr    surface->getCanvas()->clear(SK_ColorGREEN);
28965151754b9fdb6a968d7307764c20655d1b680a0piotaixr    SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
29065151754b9fdb6a968d7307764c20655d1b680a0piotaixr
29165151754b9fdb6a968d7307764c20655d1b680a0piotaixr    SkCanvasMock canvas(10, 10);
29265151754b9fdb6a968d7307764c20655d1b680a0piotaixr
29365151754b9fdb6a968d7307764c20655d1b680a0piotaixr    {
29465151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecord record;
29565151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecorder recorder(&record, 10, 10);
29665151754b9fdb6a968d7307764c20655d1b680a0piotaixr        recorder.drawImage(image, 0, 0);
29765151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecordDraw(record, &canvas, 0, 0);
29865151754b9fdb6a968d7307764c20655d1b680a0piotaixr    }
29965151754b9fdb6a968d7307764c20655d1b680a0piotaixr    REPORTER_ASSERT(r, canvas.fDrawImageCalled);
30065151754b9fdb6a968d7307764c20655d1b680a0piotaixr    canvas.resetTestValues();
30165151754b9fdb6a968d7307764c20655d1b680a0piotaixr
30265151754b9fdb6a968d7307764c20655d1b680a0piotaixr    {
30365151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecord record;
30465151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecorder recorder(&record, 10, 10);
30565151754b9fdb6a968d7307764c20655d1b680a0piotaixr        recorder.drawImageRect(image, 0, SkRect::MakeWH(10, 10));
30665151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecordDraw(record, &canvas, 0, 0);
30765151754b9fdb6a968d7307764c20655d1b680a0piotaixr    }
30865151754b9fdb6a968d7307764c20655d1b680a0piotaixr    REPORTER_ASSERT(r, canvas.fDrawImageRectCalled);
30965151754b9fdb6a968d7307764c20655d1b680a0piotaixr
31065151754b9fdb6a968d7307764c20655d1b680a0piotaixr}
311