RecordReplaceDrawTest.cpp revision 01d6e5f462d1d52203ee1a6660415877e4cf2dde
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
12ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "GrRecordReplaceDraw.h"
13ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "RecordTestUtils.h"
14d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkBBHFactory.h"
15ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "SkPictureRecorder.h"
16d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecordDraw.h"
17d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecorder.h"
18d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkUtils.h"
19d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
20d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kWidth = 100;
21d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kHeight = 100;
22d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
23d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsclass JustOneDraw : public SkDrawPictureCallback {
24d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipspublic:
25d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    JustOneDraw() : fCalls(0) {}
26d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
27d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
28d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsprivate:
29d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    int fCalls;
30d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips};
31d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
32d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure the abort callback works
33d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Abort, r) {
34ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    SkAutoTUnref<const SkPicture> pic;
35ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
36ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    {
37ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        // Record two commands.
38ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkPictureRecorder recorder;
39ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
40ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
41ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
42ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));
43ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
44ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        pic.reset(recorder.endRecording());
45ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    }
46d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
47d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
48d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
49d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
50d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements replacements;
51d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    JustOneDraw callback;
52ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), &callback);
53d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
54d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    REPORTER_ASSERT(r, 3 == rerecord.count());
55d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
56d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
57d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 2);
58d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
59d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
60d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure GrRecordReplaceDraw balances unbalanced saves
61d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Unbalanced, r) {
62ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    SkAutoTUnref<const SkPicture> pic;
63ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
64ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    {
65ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkPictureRecorder recorder;
66ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
67ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
68ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        // We won't balance this, but GrRecordReplaceDraw will for us.
69ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->save();
70ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
71ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        pic.reset(recorder.endRecording());
72ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    }
73d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
74d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
75d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
76d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
77d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements replacements;
78ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
79d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
80d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    REPORTER_ASSERT(r, 4 == rerecord.count());
81d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
82d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 1);
83d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 2);
84d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 3);
85d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
86d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
87d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic SkImage* make_image(SkColor color) {
88d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    const SkPMColor pmcolor = SkPreMultiplyColor(color);
89d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
90d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    const size_t rowBytes = info.minRowBytes();
91e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const size_t size = rowBytes * info.height();
92d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
93d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkAutoMalloc addr(size);
94d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    sk_memset32((SkPMColor*)addr.get(), pmcolor, SkToInt(size >> 2));
95d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
96d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    return SkImage::NewRasterCopy(info, addr.get(), rowBytes);
97d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
98d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
99d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Test out the layer replacement functionality with and w/o a BBH
100d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsvoid test_replacements(skiatest::Reporter* r, bool useBBH) {
101ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    SkAutoTUnref<const SkPicture> pic;
102ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
103ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    {
104ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkRTreeFactory bbhFactory;
105ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkPictureRecorder recorder;
1064477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight),
107ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips                                                   useBBH ? &bbhFactory : NULL);
108ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips
109ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        SkAutoTDelete<SkPaint> paint(SkNEW(SkPaint));
110ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->saveLayer(NULL, paint);
111ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->clear(SK_ColorRED);
112ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->restore();
113ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)),
114ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips                         SkPaint());
115ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips        pic.reset(recorder.endRecording());
116ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    }
117d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
11801d6e5f462d1d52203ee1a6660415877e4cf2dderobertphillips    int key[1] = { 0 };
11901d6e5f462d1d52203ee1a6660415877e4cf2dderobertphillips
120d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    GrReplacements replacements;
12101d6e5f462d1d52203ee1a6660415877e4cf2dderobertphillips    GrReplacements::ReplacementInfo* ri = replacements.newReplacement(pic->uniqueID(),
12201d6e5f462d1d52203ee1a6660415877e4cf2dderobertphillips                                                                      SkMatrix::I(), key, 1);
123d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fStop = 2;
124d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fPos.set(0, 0);
125d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fImage = make_image(SK_ColorRED);
126a0537deca24abc2713e72f61e9cec14bdcc703d0robertphillips    ri->fPaint = SkNEW(SkPaint);
127d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    ri->fSrcRect = SkIRect::MakeWH(kWidth, kHeight);
128d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
129d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkAutoTUnref<SkBBoxHierarchy> bbh;
130d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
131d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecord rerecord;
132d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    SkRecorder canvas(&rerecord, kWidth, kHeight);
133ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips    GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
134d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
13546625e06e23b65c05013fc686a8223d6d5b49050robertphillips    REPORTER_ASSERT(r, 7 == rerecord.count());
136d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips    assert_type<SkRecords::Save>(r, rerecord, 0);
13746625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Save>(r, rerecord, 1);
13846625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
13965151754b9fdb6a968d7307764c20655d1b680a0piotaixr    assert_type<SkRecords::DrawImageRect>(r, rerecord, 3);
14046625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 4);
14146625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::DrawRect>(r, rerecord, 5);
14246625e06e23b65c05013fc686a8223d6d5b49050robertphillips    assert_type<SkRecords::Restore>(r, rerecord, 6);
143d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}
144d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
145d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Replace, r)        { test_replacements(r, false); }
146d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_ReplaceWithBBH, r) { test_replacements(r, true); }
147d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips
148d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#endif
149