RecordDrawTest.cpp revision 2ff1fcede1e9525285c5de1f35fb2dcb0fab32bd
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
332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedDEF_TEST(RecordDraw_LazySaves, r) {
342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    // Record two commands.
352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    SkRecord record;
362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    SkRecorder recorder(&record, W, H);
372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed
382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 0 == record.count());
392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.save();
402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 0 == record.count());    // the save was not recorded (yet)
412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawColor(SK_ColorRED);
422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 1 == record.count());
432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.scale(2, 2);
442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 3 == record.count());    // now we see the save
452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.restore();
462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 4 == record.count());
472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed
482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    assert_type<SkRecords::DrawPaint>(r, record, 0);
492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    assert_type<SkRecords::Save>     (r, record, 1);
502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    assert_type<SkRecords::SetMatrix>(r, record, 2);
512ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    assert_type<SkRecords::Restore>  (r, record, 3);
522ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed
532ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.save();
542ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.save();
552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.restore();
562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.restore();
572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 4 == record.count());
582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed}
592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed
60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) {
61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    // Record two commands.
62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint());
65c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.clipRect(SkRect::MakeWH(100, 200));
66c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
67c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
68c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
69c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
70c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw callback;
711bdfd3f4f09e47364f76d3f08177b1ce844ac786reed    SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL/*bbh*/, &callback);
72c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord));
742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 0 == count_instances_of_type<SkRecords::ClipRect>(rerecord));
75c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
76c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
77c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) {
78c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
79c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
80c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.save();  // We won't balance this, but SkRecordDraw will for us.
812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.scale(2, 2);
82c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
83c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
84c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
851bdfd3f4f09e47364f76d3f08177b1ce844ac786reed    SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL/*bbh*/, NULL/*callback*/);
86c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    int save_count = count_instances_of_type<SkRecords::Save>(rerecord);
882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    int restore_count = count_instances_of_type<SkRecords::Save>(rerecord);
892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, save_count == restore_count);
90c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
91c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) {
930a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord that just scales by 2x,3x.
940a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord scaleRecord;
95a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder scaleCanvas(&scaleRecord, W, H);
960a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix scale;
970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scale.setScale(2, 3);
980a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scaleCanvas.setMatrix(scale);
990a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
1000a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord with an initial +20, +20 translate.
1010a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord translateRecord;
102a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder translateCanvas(&translateRecord, W, H);
1030a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix translate;
1040a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translate.setTranslate(20, 20);
1050a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translateCanvas.setMatrix(translate);
1060a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
1071bdfd3f4f09e47364f76d3f08177b1ce844ac786reed    SkRecordDraw(scaleRecord, &translateCanvas, NULL, NULL, 0, NULL/*bbh*/, NULL/*callback*/);
108c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == translateRecord.count());
109c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
110c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>     (r, translateRecord, 1);
111c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
112c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore>  (r, translateRecord, 3);
1130a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
1140a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // When we look at translateRecord now, it should have its first +20,+20 translate,
1150a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // then a 2x,3x scale that's been concatted with that +20,+20 translate.
1160a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    const SkRecords::SetMatrix* setMatrix;
1170a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
1180a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == translate);
1190a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
120c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
1210a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix expected = scale;
1220a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    expected.postConcat(translate);
1230a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == expected);
1240a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org}
125a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
126a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinstruct TestBBH : public SkBBoxHierarchy {
1274477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein    virtual void insert(SkAutoTMalloc<SkRect>* boundsArray, int N) SK_OVERRIDE {
1284477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein        fEntries.setCount(N);
1294477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein        for (int i = 0; i < N; i++) {
1304477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein            Entry e = { (unsigned)i, (*boundsArray)[i] };
1314477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein            fEntries[i] = e;
1324477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein        }
133a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
1356bd41969a0f2283a7a7320bb0025551353c241ecmtklein    virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const SK_OVERRIDE {}
136158fcaa031d105dc999d9813fee8927db56a871ctomhudson    virtual size_t bytesUsed() const SK_OVERRIDE { return 0; }
137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    struct Entry {
1396bd41969a0f2283a7a7320bb0025551353c241ecmtklein        unsigned opIndex;
140533eb782edaa0b6fece6166d3001edf72ec39f11mtklein        SkRect bounds;
141a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    };
1426bd41969a0f2283a7a7320bb0025551353c241ecmtklein    SkTDArray<Entry> fEntries;
143a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein};
144a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
145937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// Like a==b, with a little slop recognizing that float equality can be weird.
146937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinstatic bool sloppy_rect_eq(SkRect a, SkRect b) {
147937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRect inset(a), outset(a);
148937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    inset.inset(1, 1);
149937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    outset.outset(1, 1);
150937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    return outset.contains(b) && !inset.contains(b);
151937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein}
152937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
153a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// This test is not meant to make total sense yet.  It's testing the status quo
154a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// of SkRecordFillBounds(), which itself doesn't make total sense yet.
155a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinDEF_TEST(RecordDraw_BBH, r) {
156a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecord record;
157a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecorder recorder(&record, W, H);
158a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.save();
159a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.clipRect(SkRect::MakeWH(400, 500));
160a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.scale(2, 2);
161a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint());
162a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.restore();
163a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
164937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    TestBBH bbh;
1654d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, &bbh);
166a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
1676bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, bbh.fEntries.count() == 5);
1686bd41969a0f2283a7a7320bb0025551353c241ecmtklein    for (int i = 0; i < bbh.fEntries.count(); i++) {
1696bd41969a0f2283a7a7320bb0025551353c241ecmtklein        REPORTER_ASSERT(r, bbh.fEntries[i].opIndex == (unsigned)i);
170a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
1716bd41969a0f2283a7a7320bb0025551353c241ecmtklein        REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bbh.fEntries[i].bounds));
172a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
173a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein}
17400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
175937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// A regression test for crbug.com/409110.
176937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinDEF_TEST(RecordDraw_TextBounds, r) {
177937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecord record;
178937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    SkRecorder recorder(&record, W, H);
179937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
180937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    // Two Chinese characters in UTF-8.
181937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' };
182937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const size_t bytes = SK_ARRAY_COUNT(text);
183937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
184937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const SkScalar xpos[] = { 10, 20 };
185937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint());
186937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
187937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    const SkPoint pos[] = { {40, 50}, {60, 70} };
188937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    recorder.drawPosText(text, bytes, pos, SkPaint());
189937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
190937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein    TestBBH bbh;
1914d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, &bbh);
1926bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, bbh.fEntries.count() == 2);
193937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
194ed167acb7b494bf0aece05ac8a68b560782b027cmtklein    // We can make these next assertions confidently because SkRecordFillBounds
195ed167acb7b494bf0aece05ac8a68b560782b027cmtklein    // builds its bounds by overestimating font metrics in a platform-independent way.
196ed167acb7b494bf0aece05ac8a68b560782b027cmtklein    // If that changes, these tests will need to be more flexible.
1974d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0,  0, 140, 60)));
1984d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 20, 180, 100)));
199937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein}
200937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein
20100f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected
20200f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) {
20300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
20400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
20500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r1 = { 0, 0, kWidth,   kHeight };
20600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r2 = { 0, 0, kWidth,   kHeight/2 };
20700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r3 = { 0, 0, kWidth/2, kHeight };
20800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkPaint p;
20900f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
21100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
21200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r1, p);
21300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r2, p);
21400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r3, p);
21500f30bdc9e34b013da54b4406f36556c5be8d041mtklein
21600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
21700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
2188eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed    SkRecordPartialDraw(record, &canvas, NULL, 0, 1, 2, SkMatrix::I()); // replay just drawRect of r2
21900f30bdc9e34b013da54b4406f36556c5be8d041mtklein
2202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord));
2212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    int index = find_first_instances_of_type<SkRecords::DrawRect>(rerecord);
2222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, index);
22300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == r2);
22400f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
22500f30bdc9e34b013da54b4406f36556c5be8d041mtklein
226271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein// A regression test for crbug.com/415468 and skbug.com/2957.
2278e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein//
2288e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// This also now serves as a regression test for crbug.com/418417.  We used to adjust the
2298e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture.
2308e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.)
231271a030f5d0d3c59715fbeffb31c761279f3f8caMike KleinDEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) {
232271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkRecord record;
233271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkRecorder recorder(&record, 50, 50);
234271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
235271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    // We draw a rectangle with a long drop shadow.  We used to not update the clip
236271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    // bounds based on SaveLayer paints, so the drop shadow could be cut off.
237271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    SkPaint paint;
238234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi    paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK,
239234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi                         SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode))->unref();
240271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
241271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    recorder.saveLayer(NULL, &paint);
242271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein        recorder.clipRect(SkRect::MakeWH(20, 40));
243271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein        recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint());
244271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    recorder.restore();
245271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein
2468e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // Under the original bug, the right edge value of the drawRect would be 20 less than asserted
2478e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // here because we intersected it with a clip that had not been adjusted for the drop shadow.
2488e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    //
2498e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too.
2508e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein    // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50).
251271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein    TestBBH bbh;
2524d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRecordFillBounds(SkRect::MakeWH(50, 50), record, &bbh);
2536bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, bbh.fEntries.count() == 4);
2546bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
2556bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
2566bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(0, 0, 40, 40)));
2576bd41969a0f2283a7a7320bb0025551353c241ecmtklein    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[3].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
258271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein}
25965151754b9fdb6a968d7307764c20655d1b680a0piotaixr
2604d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// When a saveLayer provides an explicit bound and has a complex paint (e.g., one that
2614d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// affects transparent black), that bound should serve to shrink the area of the required
2624d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// backing store.
2634d52afef5cf90a2fed3bb69db71675c6450ab397robertphillipsDEF_TEST(RecordDraw_SaveLayerBoundsAffectsClipBounds, r) {
2644d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRecord record;
2654d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRecorder recorder(&record, 50, 50);
2664d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips
2674d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkPaint p;
2684d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    p.setXfermodeMode(SkXfermode::kSrc_Mode);
2694d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips
2704d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRect bounds = SkRect::MakeLTRB(10, 10, 40, 40);
2714d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    recorder.saveLayer(&bounds, &p);
2724d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    recorder.drawRect(SkRect::MakeLTRB(20, 20, 30, 30), SkPaint());
2734d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    recorder.restore();
2744d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips
2754d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    TestBBH bbh;
2764d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    SkRecordFillBounds(SkRect::MakeWH(50, 50), record, &bbh);
2774d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    REPORTER_ASSERT(r, bbh.fEntries.count() == 3);
2784d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(10, 10, 40, 40)));
2794d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(20, 20, 30, 30)));
2804d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(10, 10, 40, 40)));
2814d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips}
2824d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips
28365151754b9fdb6a968d7307764c20655d1b680a0piotaixrDEF_TEST(RecordDraw_drawImage, r){
28465151754b9fdb6a968d7307764c20655d1b680a0piotaixr    class SkCanvasMock : public SkCanvas {
28565151754b9fdb6a968d7307764c20655d1b680a0piotaixr    public:
286ad8aa1dcf36d64ddf849b914281713b901a01f49mtklein        SkCanvasMock(int width, int height) : SkCanvas(width, height) {
28765151754b9fdb6a968d7307764c20655d1b680a0piotaixr            this->resetTestValues();
28865151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
28965151754b9fdb6a968d7307764c20655d1b680a0piotaixr        virtual ~SkCanvasMock() {}
29065151754b9fdb6a968d7307764c20655d1b680a0piotaixr        virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
29165151754b9fdb6a968d7307764c20655d1b680a0piotaixr                               const SkPaint* paint = NULL) SK_OVERRIDE {
29265151754b9fdb6a968d7307764c20655d1b680a0piotaixr
29365151754b9fdb6a968d7307764c20655d1b680a0piotaixr            fDrawImageCalled = true;
29465151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
29565151754b9fdb6a968d7307764c20655d1b680a0piotaixr
29665151754b9fdb6a968d7307764c20655d1b680a0piotaixr        virtual void drawImageRect(const SkImage* image, const SkRect* src,
29765151754b9fdb6a968d7307764c20655d1b680a0piotaixr                                   const SkRect& dst,
29865151754b9fdb6a968d7307764c20655d1b680a0piotaixr                                   const SkPaint* paint = NULL) SK_OVERRIDE {
29965151754b9fdb6a968d7307764c20655d1b680a0piotaixr            fDrawImageRectCalled = true;
30065151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
30165151754b9fdb6a968d7307764c20655d1b680a0piotaixr
30265151754b9fdb6a968d7307764c20655d1b680a0piotaixr        void resetTestValues() {
30365151754b9fdb6a968d7307764c20655d1b680a0piotaixr            fDrawImageCalled = fDrawImageRectCalled = false;
30465151754b9fdb6a968d7307764c20655d1b680a0piotaixr        }
30565151754b9fdb6a968d7307764c20655d1b680a0piotaixr
30665151754b9fdb6a968d7307764c20655d1b680a0piotaixr        bool fDrawImageCalled;
30765151754b9fdb6a968d7307764c20655d1b680a0piotaixr        bool fDrawImageRectCalled;
30865151754b9fdb6a968d7307764c20655d1b680a0piotaixr    };
30965151754b9fdb6a968d7307764c20655d1b680a0piotaixr
3103054be16dfdb0d06233770cbfc338958edef44eareed    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(10, 10));
31165151754b9fdb6a968d7307764c20655d1b680a0piotaixr    surface->getCanvas()->clear(SK_ColorGREEN);
31265151754b9fdb6a968d7307764c20655d1b680a0piotaixr    SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
31365151754b9fdb6a968d7307764c20655d1b680a0piotaixr
31465151754b9fdb6a968d7307764c20655d1b680a0piotaixr    SkCanvasMock canvas(10, 10);
31565151754b9fdb6a968d7307764c20655d1b680a0piotaixr
31665151754b9fdb6a968d7307764c20655d1b680a0piotaixr    {
31765151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecord record;
31865151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecorder recorder(&record, 10, 10);
31965151754b9fdb6a968d7307764c20655d1b680a0piotaixr        recorder.drawImage(image, 0, 0);
3201bdfd3f4f09e47364f76d3f08177b1ce844ac786reed        SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL, 0);
32165151754b9fdb6a968d7307764c20655d1b680a0piotaixr    }
32265151754b9fdb6a968d7307764c20655d1b680a0piotaixr    REPORTER_ASSERT(r, canvas.fDrawImageCalled);
32365151754b9fdb6a968d7307764c20655d1b680a0piotaixr    canvas.resetTestValues();
32465151754b9fdb6a968d7307764c20655d1b680a0piotaixr
32565151754b9fdb6a968d7307764c20655d1b680a0piotaixr    {
32665151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecord record;
32765151754b9fdb6a968d7307764c20655d1b680a0piotaixr        SkRecorder recorder(&record, 10, 10);
32865151754b9fdb6a968d7307764c20655d1b680a0piotaixr        recorder.drawImageRect(image, 0, SkRect::MakeWH(10, 10));
3291bdfd3f4f09e47364f76d3f08177b1ce844ac786reed        SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL, 0);
33065151754b9fdb6a968d7307764c20655d1b680a0piotaixr    }
33165151754b9fdb6a968d7307764c20655d1b680a0piotaixr    REPORTER_ASSERT(r, canvas.fDrawImageRectCalled);
33265151754b9fdb6a968d7307764c20655d1b680a0piotaixr
33365151754b9fdb6a968d7307764c20655d1b680a0piotaixr}
334