RecordDrawTest.cpp revision 00f30bdc9e34b013da54b4406f36556c5be8d041
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"
13d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecord.h"
14ad8ce572f69633ffebe2fa486275d82a5e9a71fecommit-bot@chromium.org#include "SkRecordOpts.h"
15d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecordDraw.h"
16d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecorder.h"
17d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecords.h"
18d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
19d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.orgstatic const int W = 1920, H = 1080;
20d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org
21c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinclass JustOneDraw : public SkDrawPictureCallback {
22c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinpublic:
23c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw() : fCalls(0) {}
24c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
25c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
26c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinprivate:
27c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    int fCalls;
28c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein};
29c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
30c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) {
31c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    // Record two commands.
32c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
33c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
34c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint());
35c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.clipRect(SkRect::MakeWH(100, 200));
36c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
37c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
38c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
39c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
40c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    JustOneDraw callback;
415ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(record, &canvas, NULL/*bbh*/, &callback);
42c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
43c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 3 == rerecord.count());
44c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 0);
45c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
46c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 2);
47c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
48c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
49c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) {
50c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord record;
51c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder recorder(&record, W, H);
52c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    recorder.save();  // We won't balance this, but SkRecordDraw will for us.
53c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
54c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecord rerecord;
55c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    SkRecorder canvas(&rerecord, W, H);
565ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(record, &canvas, NULL/*bbh*/, NULL/*callback*/);
57c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
58c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == rerecord.count());
59c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 0);
60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>    (r, rerecord, 1);
61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 2);
62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore> (r, rerecord, 3);
63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}
64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein
650a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) {
660a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord that just scales by 2x,3x.
670a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord scaleRecord;
68a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder scaleCanvas(&scaleRecord, W, H);
690a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix scale;
700a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scale.setScale(2, 3);
710a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    scaleCanvas.setMatrix(scale);
720a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
730a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // Set up an SkRecord with an initial +20, +20 translate.
740a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkRecord translateRecord;
75a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder translateCanvas(&translateRecord, W, H);
760a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix translate;
770a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translate.setTranslate(20, 20);
780a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    translateCanvas.setMatrix(translate);
790a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
805ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein    SkRecordDraw(scaleRecord, &translateCanvas, NULL/*bbh*/, NULL/*callback*/);
81c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    REPORTER_ASSERT(r, 4 == translateRecord.count());
82c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
83c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Save>     (r, translateRecord, 1);
84c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
85c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    assert_type<SkRecords::Restore>  (r, translateRecord, 3);
860a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
870a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // When we look at translateRecord now, it should have its first +20,+20 translate,
880a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    // then a 2x,3x scale that's been concatted with that +20,+20 translate.
890a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    const SkRecords::SetMatrix* setMatrix;
900a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
910a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == translate);
920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org
93c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
940a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    SkMatrix expected = scale;
950a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    expected.postConcat(translate);
960a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org    REPORTER_ASSERT(r, setMatrix->matrix == expected);
970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org}
98a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
99a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinstruct TestBBH : public SkBBoxHierarchy {
100533eb782edaa0b6fece6166d3001edf72ec39f11mtklein    virtual void insert(void* data, const SkRect& bounds, bool defer) SK_OVERRIDE {
101a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        Entry e = { (uintptr_t)data, bounds };
102a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        entries.push(e);
103a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
104a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual int getCount() const SK_OVERRIDE { return entries.count(); }
105a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
106a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual void flushDeferredInserts() SK_OVERRIDE {}
107a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
108533eb782edaa0b6fece6166d3001edf72ec39f11mtklein    virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE {}
109a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual void clear() SK_OVERRIDE {}
110a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual void rewindInserts() SK_OVERRIDE {}
111a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    virtual int getDepth() const SK_OVERRIDE { return -1; }
112a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
113a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    struct Entry {
114a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        uintptr_t data;
115533eb782edaa0b6fece6166d3001edf72ec39f11mtklein        SkRect bounds;
116a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    };
117a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkTDArray<Entry> entries;
118a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein};
119a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
120a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// This test is not meant to make total sense yet.  It's testing the status quo
121a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// of SkRecordFillBounds(), which itself doesn't make total sense yet.
122a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinDEF_TEST(RecordDraw_BBH, r) {
123a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    TestBBH bbh;
124a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
125a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecord record;
126a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
127a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecorder recorder(&record, W, H);
128a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.save();
129a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.clipRect(SkRect::MakeWH(400, 500));
130a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.scale(2, 2);
131a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint());
132a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    recorder.restore();
133a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    SkRecordFillBounds(record, &bbh);
135a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
136a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    REPORTER_ASSERT(r, bbh.entries.count() == 5);
137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    for (int i = 0; i < bbh.entries.count(); i++) {
138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein        REPORTER_ASSERT(r, bbh.entries[i].data == (uintptr_t)i);
139a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein
14090e8457ab32bcc14b15876144ca47489d7b836cemtklein        // We'd like to assert bounds == SkRect::MakeWH(400, 480).
14190e8457ab32bcc14b15876144ca47489d7b836cemtklein        // But we allow a little slop in recognition that float equality can be weird.
14290e8457ab32bcc14b15876144ca47489d7b836cemtklein        REPORTER_ASSERT(r,  SkRect::MakeLTRB(-1, -1, 401, 481).contains(bbh.entries[i].bounds));
14390e8457ab32bcc14b15876144ca47489d7b836cemtklein        REPORTER_ASSERT(r, !SkRect::MakeLTRB(+1, +1, 399, 479).contains(bbh.entries[i].bounds));
144a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein    }
145a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein}
14600f30bdc9e34b013da54b4406f36556c5be8d041mtklein
14700f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected
14800f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) {
14900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
15000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
15100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r1 = { 0, 0, kWidth,   kHeight };
15200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r2 = { 0, 0, kWidth,   kHeight/2 };
15300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect r3 = { 0, 0, kWidth/2, kHeight };
15400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkPaint p;
15500f30bdc9e34b013da54b4406f36556c5be8d041mtklein
15600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
15700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
15800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r1, p);
15900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r2, p);
16000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.drawRect(r3, p);
16100f30bdc9e34b013da54b4406f36556c5be8d041mtklein
16200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
16300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
16400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecordPartialDraw(record, &canvas, r1, 1, 2); // replay just drawRect of r2
16500f30bdc9e34b013da54b4406f36556c5be8d041mtklein
16600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, 3 == rerecord.count());
16700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Save>     (r, rerecord, 0);
16800f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::DrawRect> (r, rerecord, 1);
16900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Restore>  (r, rerecord, 2);
17000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
17100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
17200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == r2);
17300f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
17400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
17500f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Check that clears are converted to drawRects
17600f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialClear, r) {
17700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    static const int kWidth = 10, kHeight = 10;
17800f30bdc9e34b013da54b4406f36556c5be8d041mtklein
17900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRect rect = { 0, 0, kWidth, kHeight };
18000f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord record;
18200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder recorder(&record, kWidth, kHeight);
18300f30bdc9e34b013da54b4406f36556c5be8d041mtklein    recorder.clear(SK_ColorRED);
18400f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecord rerecord;
18600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecorder canvas(&rerecord, kWidth, kHeight);
18700f30bdc9e34b013da54b4406f36556c5be8d041mtklein    SkRecordPartialDraw(record, &canvas, rect, 0, 1); // replay just the clear
18800f30bdc9e34b013da54b4406f36556c5be8d041mtklein
18900f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, 3 == rerecord.count());
19000f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Save>    (r, rerecord, 0);
19100f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
19200f30bdc9e34b013da54b4406f36556c5be8d041mtklein    assert_type<SkRecords::Restore> (r, rerecord, 2);
19300f30bdc9e34b013da54b4406f36556c5be8d041mtklein
19400f30bdc9e34b013da54b4406f36556c5be8d041mtklein    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
19500f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->rect == rect);
19600f30bdc9e34b013da54b4406f36556c5be8d041mtklein    REPORTER_ASSERT(r, drawRect->paint.getColor() == SK_ColorRED);
19700f30bdc9e34b013da54b4406f36556c5be8d041mtklein}
198