1d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips/*
2d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips * Copyright 2014 Google Inc.
3d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips *
4d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips * Use of this source code is governed by a BSD-style license that can be
5d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips * found in the LICENSE file.
6d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips */
7d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
8d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#if SK_SUPPORT_GPU
9d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
10d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "Test.h"
11d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "RecordTestUtils.h"
12d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
13d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkBBHFactory.h"
14d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecordDraw.h"
15d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecorder.h"
16d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkUtils.h"
17d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "GrRecordReplaceDraw.h"
18d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
19d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kWidth = 100;
20d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kHeight = 100;
21d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
22d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsclass JustOneDraw : public SkDrawPictureCallback {
23d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipspublic:
24d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    JustOneDraw() : fCalls(0) {}
25d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
26d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
27d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsprivate:
28d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    int fCalls;
29d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips};
30d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
31d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure the abort callback works
32d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Abort, r) {
33d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    // Record two commands.
34d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord record;
35d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder recorder(&record, kWidth, kHeight);
36d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
37d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));
38d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
39d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
40d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
41d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
42d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements replacements;
43d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    JustOneDraw callback;
44d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrRecordReplaceDraw(record, &canvas, NULL/*bbh*/, &replacements, &callback);
45d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
46d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    REPORTER_ASSERT(r, 3 == rerecord.count());
47d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
48d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
49d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 2);
50d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
51d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
52d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure GrRecordReplaceDraw balances unbalanced saves
53d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Unbalanced, r) {
54d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord record;
55d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder recorder(&record, kWidth, kHeight);
56d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.save();  // We won't balance this, but GrRecordReplaceDraw will for us.
57d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
58d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
59d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
60d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
61d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements replacements;
62d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrRecordReplaceDraw(record, &canvas, NULL/*bbh*/, &replacements, NULL/*callback*/);
63d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
64d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    REPORTER_ASSERT(r, 4 == rerecord.count());
65d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
66d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 1);
67d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 2);
68d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 3);
69d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
70d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
71d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic SkImage* make_image(SkColor color) {
72d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    const SkPMColor pmcolor = SkPreMultiplyColor(color);
73d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
74d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    const size_t rowBytes = info.minRowBytes();
75e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const size_t size = rowBytes * info.height();
76d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
77d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkAutoMalloc addr(size);
78d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    sk_memset32((SkPMColor*)addr.get(), pmcolor, SkToInt(size >> 2));
79d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
80d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    return SkImage::NewRasterCopy(info, addr.get(), rowBytes);
81d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
82d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
83d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Test out the layer replacement functionality with and w/o a BBH
84d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsvoid test_replacements(skiatest::Reporter* r, bool useBBH) {
85d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord record;
86d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder recorder(&record, kWidth, kHeight);
87d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkAutoTDelete<SkPaint> paint(SkNEW(SkPaint));
88d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.saveLayer(NULL, paint);
89d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.clear(SK_ColorRED);
90d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.restore();
91d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    recorder.drawRect(SkRect::MakeWH(SkIntToScalar(kWidth/2), SkIntToScalar(kHeight/2)),
92d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips                      SkPaint());
93d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
94d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements replacements;
95d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements::ReplacementInfo* ri = replacements.push();
96d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fStart = 0;
97d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fStop = 2;
98d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fPos.set(0, 0);
99d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fImage = make_image(SK_ColorRED);
100a0537deca24abc2713e72f61e9cec14bdcc703d0robertphillips    ri->fPaint = SkNEW(SkPaint);
101d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fSrcRect = SkIRect::MakeWH(kWidth, kHeight);
102d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
103d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkAutoTUnref<SkBBoxHierarchy> bbh;
104d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
105d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    if (useBBH) {
106d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips        SkRTreeFactory factory;
107d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips        bbh.reset((factory)(kWidth, kHeight));
108d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips        SkRecordFillBounds(record, bbh);
109d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    }
110d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
111d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
112d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
113d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrRecordReplaceDraw(record, &canvas, bbh, &replacements, NULL/*callback*/);
114d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
11546625e06e23b65c05013fc686a8223d6d5b49050robertphillips    REPORTER_ASSERT(r, 7 == rerecord.count());
116d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
11746625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Save>(r, rerecord, 1);
11846625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
11946625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 3);
12046625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 4);
12146625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::DrawRect>(r, rerecord, 5);
12246625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 6);
123d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
124d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
125d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Replace, r)        { test_replacements(r, false); }
126d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_ReplaceWithBBH, r) { test_replacements(r, true); }
127d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
128d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#endif
129