RecordDrawTest.cpp revision 271a030f5d0d3c59715fbeffb31c761279f3f8ca
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"
14d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecord.h"
15d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecordDraw.h"
16271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkRecordOpts.h"
17d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecorder.h"
18d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecords.h"
19d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
20d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.orgstatic const int W = 1920, H = 1080;
21d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
22c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinclass JustOneDraw : public SkDrawPictureCallback {
23c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinpublic:
24c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw() : fCalls(0) {}
25c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
26c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
27c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinprivate:
28c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    int fCalls;
29c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein};
30c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
31c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) {
32c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    // Record two commands.
33c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
34c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
35c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint());
36c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.clipRect(SkRect::MakeWH(100, 200));
37c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
38c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
39c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
40c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
41c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw callback;
425ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(record, &canvas, NULL/*bbh*/, &callback);
43c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
44c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 3 == rerecord.count());
45c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 0);
46c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
47c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 2);
48c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
49c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
50c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) {
51c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
52c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
53c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.save();  // We won't balance this, but SkRecordDraw will for us.
54c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
55c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
56c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
575ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(record, &canvas, NULL/*bbh*/, NULL/*callback*/);
58c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
59c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == rerecord.count());
60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 0);
61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 1);
62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 2);
63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 3);
64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
65c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
660a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) {
670a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord that just scales by 2x,3x.
680a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord scaleRecord;
69a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder scaleCanvas(&scaleRecord, W, H);
700a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix scale;
710a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scale.setScale(2, 3);
720a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scaleCanvas.setMatrix(scale);
730a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
740a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord with an initial +20, +20 translate.
750a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord translateRecord;
76a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder translateCanvas(&translateRecord, W, H);
770a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix translate;
780a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translate.setTranslate(20, 20);
790a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translateCanvas.setMatrix(translate);
800a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
815ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(scaleRecord, &translateCanvas, NULL/*bbh*/, NULL/*callback*/);
82c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == translateRecord.count());
83c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
84c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>     (r, translateRecord, 1);
85c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
86c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore>  (r, translateRecord, 3);
870a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
880a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // When we look at translateRecord now, it should have its first +20,+20 translate,
890a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // then a 2x,3x scale that's been concatted with that +20,+20 translate.
900a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    const SkRecords::SetMatrix* setMatrix;
910a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == translate);
930a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
94c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
950a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix expected = scale;
960a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    expected.postConcat(translate);
970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == expected);
980a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org}
99a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
100a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinstruct TestBBH : public SkBBoxHierarchy {
101533eb782edaa0b6fece6166d3001edf72ec39f11mtklein    virtual void insert(void* data, const SkRect& bounds, bool defer) SK_OVERRIDE {
102a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        Entry e = { (uintptr_t)data, bounds };
103a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        entries.push(e);
104a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
105a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual int getCount() const SK_OVERRIDE { return entries.count(); }
106a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
107a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual void flushDeferredInserts() SK_OVERRIDE {}
108a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
109533eb782edaa0b6fece6166d3001edf72ec39f11mtklein    virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE {}
110a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual void clear() SK_OVERRIDE {}
111a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual void rewindInserts() SK_OVERRIDE {}
112a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual int getDepth() const SK_OVERRIDE { return -1; }
113a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
114a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    struct Entry {
115a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        uintptr_t data;
116533eb782edaa0b6fece6166d3001edf72ec39f11mtklein        SkRect bounds;
117a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    };
118a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkTDArray<Entry> entries;
119a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein};
120a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
121937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// Like a==b, with a little slop recognizing that float equality can be weird.
122937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinstatic bool sloppy_rect_eq(SkRect a, SkRect b) {
123937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRect inset(a), outset(a);
124937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    inset.inset(1, 1);
125937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    outset.outset(1, 1);
126937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    return outset.contains(b) && !inset.contains(b);
127937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein}
128937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
129a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// This test is not meant to make total sense yet.  It's testing the status quo
130a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// of SkRecordFillBounds(), which itself doesn't make total sense yet.
131a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinDEF_TEST(RecordDraw_BBH, r) {
132a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecord record;
133a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecorder recorder(&record, W, H);
134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.save();
135a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.clipRect(SkRect::MakeWH(400, 500));
136a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.scale(2, 2);
137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint());
138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.restore();
139a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
140937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    TestBBH bbh;
141a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecordFillBounds(record, &bbh);
142a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
143a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    REPORTER_ASSERT(r, bbh.entries.count() == 5);
144a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    for (int i = 0; i < bbh.entries.count(); i++) {
145a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        REPORTER_ASSERT(r, bbh.entries[i].data == (uintptr_t)i);
146a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
147937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein        REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bbh.entries[i].bounds));
148a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
149a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein}
15000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
151937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// A regression test for crbug.com/409110.
152937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinDEF_TEST(RecordDraw_TextBounds, r) {
153937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecord record;
154937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecorder recorder(&record, W, H);
155937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
156937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // Two Chinese characters in UTF-8.
157937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' };
158937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const size_t bytes = SK_ARRAY_COUNT(text);
159937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
160937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const SkScalar xpos[] = { 10, 20 };
161937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint());
162937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
163937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const SkPoint pos[] = { {40, 50}, {60, 70} };
164937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    recorder.drawPosText(text, bytes, pos, SkPaint());
165937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
166937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    TestBBH bbh;
167937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecordFillBounds(record, &bbh);
168937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    REPORTER_ASSERT(r, bbh.entries.count() == 2);
169937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
170937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // We can make these next assertions confidently because SkRecordFillBounds
171937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // builds its bounds by overestimating font metrics in a platform-independent way.
172937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // If that changes, these tests will need to be more flexible.
173937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[0].bounds, SkRect::MakeLTRB(-86,  6, 116, 54)));
174937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[1].bounds, SkRect::MakeLTRB(-56, 26, 156, 94)));
175937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein}
176937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
17700f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected
17800f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) {
17900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
18000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r1 = { 0, 0, kWidth,   kHeight };
18200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r2 = { 0, 0, kWidth,   kHeight/2 };
18300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r3 = { 0, 0, kWidth/2, kHeight };
18400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkPaint p;
18500f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
18700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
18800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r1, p);
18900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r2, p);
19000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r3, p);
19100f30bdc9e34b013da54b4406f36556c5be8d041mtklein
19200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
19300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
1944815fe5a0a497b676677fb4e4a0f05c511855490robertphillips    SkRecordPartialDraw(record, &canvas, r1, 1, 2, SkMatrix::I()); // replay just drawRect of r2
19500f30bdc9e34b013da54b4406f36556c5be8d041mtklein
19600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, 3 == rerecord.count());
19700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Save>     (r, rerecord, 0);
19800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::DrawRect> (r, rerecord, 1);
19900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Restore>  (r, rerecord, 2);
20000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
20200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == r2);
20300f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
20400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20500f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Check that clears are converted to drawRects
20600f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialClear, r) {
20700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
20800f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect rect = { 0, 0, kWidth, kHeight };
21000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
21200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
21300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.clear(SK_ColorRED);
21400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
21600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
2174815fe5a0a497b676677fb4e4a0f05c511855490robertphillips    SkRecordPartialDraw(record, &canvas, rect, 0, 1, SkMatrix::I()); // replay just the clear
21800f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, 3 == rerecord.count());
22000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Save>    (r, rerecord, 0);
22100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
22200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Restore> (r, rerecord, 2);
22300f30bdc9e34b013da54b4406f36556c5be8d041mtklein
22400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
22500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == rect);
22600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->paint.getColor() == SK_ColorRED);
22700f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
228271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
229271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein// A regression test for crbug.com/415468 and skbug.com/2957.
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
244271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    // Under the original bug, all the right edge values would be 20 less than asserted here
245271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    // because we intersected them with a clip that had not been adjusted for the drop shadow.
246271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    TestBBH bbh;
247271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkRecordFillBounds(record, &bbh);
248271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    REPORTER_ASSERT(r, bbh.entries.count() == 4);
249271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[0].bounds, SkRect::MakeLTRB(0, 0, 70, 50)));
250271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[1].bounds, SkRect::MakeLTRB(0, 0, 70, 50)));
251271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[2].bounds, SkRect::MakeLTRB(0, 0, 40, 40)));
252271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[3].bounds, SkRect::MakeLTRB(0, 0, 70, 50)));
253271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein}
254