blob: 8fc824d8ccb6c664481e07057ed6c5a9d7001731 [file] [log] [blame]
robertphillipsd982eb22014-09-03 11:04:30 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#if SK_SUPPORT_GPU
9
10#include "Test.h"
robertphillipsd982eb22014-09-03 11:04:30 -070011
robertphillipsee6631e2014-09-29 05:32:49 -070012#include "GrRecordReplaceDraw.h"
13#include "RecordTestUtils.h"
robertphillipsd982eb22014-09-03 11:04:30 -070014#include "SkBBHFactory.h"
robertphillipsee6631e2014-09-29 05:32:49 -070015#include "SkPictureRecorder.h"
robertphillipsd982eb22014-09-03 11:04:30 -070016#include "SkRecordDraw.h"
17#include "SkRecorder.h"
18#include "SkUtils.h"
robertphillipsd982eb22014-09-03 11:04:30 -070019
20static const int kWidth = 100;
21static const int kHeight = 100;
22
23class JustOneDraw : public SkDrawPictureCallback {
24public:
25 JustOneDraw() : fCalls(0) {}
26
27 virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
28private:
29 int fCalls;
30};
31
32// Make sure the abort callback works
33DEF_TEST(RecordReplaceDraw_Abort, r) {
robertphillipsee6631e2014-09-29 05:32:49 -070034 SkAutoTUnref<const SkPicture> pic;
35
36 {
37 // Record two commands.
38 SkPictureRecorder recorder;
39 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
40
41 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
42 canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));
43
44 pic.reset(recorder.endRecording());
45 }
robertphillipsd982eb22014-09-03 11:04:30 -070046
47 SkRecord rerecord;
48 SkRecorder canvas(&rerecord, kWidth, kHeight);
49
50 GrReplacements replacements;
51 JustOneDraw callback;
robertphillipsee6631e2014-09-29 05:32:49 -070052 GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), &callback);
robertphillipsd982eb22014-09-03 11:04:30 -070053
54 REPORTER_ASSERT(r, 3 == rerecord.count());
55 assert_type<SkRecords::Save>(r, rerecord, 0);
56 assert_type<SkRecords::DrawRect>(r, rerecord, 1);
57 assert_type<SkRecords::Restore>(r, rerecord, 2);
58}
59
60// Make sure GrRecordReplaceDraw balances unbalanced saves
61DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
robertphillipsee6631e2014-09-29 05:32:49 -070062 SkAutoTUnref<const SkPicture> pic;
63
64 {
65 SkPictureRecorder recorder;
66 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
67
68 // We won't balance this, but GrRecordReplaceDraw will for us.
69 canvas->save();
70
71 pic.reset(recorder.endRecording());
72 }
robertphillipsd982eb22014-09-03 11:04:30 -070073
74 SkRecord rerecord;
75 SkRecorder canvas(&rerecord, kWidth, kHeight);
76
77 GrReplacements replacements;
robertphillipsee6631e2014-09-29 05:32:49 -070078 GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
robertphillipsd982eb22014-09-03 11:04:30 -070079
80 REPORTER_ASSERT(r, 4 == rerecord.count());
81 assert_type<SkRecords::Save>(r, rerecord, 0);
82 assert_type<SkRecords::Save>(r, rerecord, 1);
83 assert_type<SkRecords::Restore>(r, rerecord, 2);
84 assert_type<SkRecords::Restore>(r, rerecord, 3);
85}
86
87static SkImage* make_image(SkColor color) {
88 const SkPMColor pmcolor = SkPreMultiplyColor(color);
89 const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
90 const size_t rowBytes = info.minRowBytes();
reede5ea5002014-09-03 11:54:58 -070091 const size_t size = rowBytes * info.height();
robertphillipsd982eb22014-09-03 11:04:30 -070092
93 SkAutoMalloc addr(size);
94 sk_memset32((SkPMColor*)addr.get(), pmcolor, SkToInt(size >> 2));
95
96 return SkImage::NewRasterCopy(info, addr.get(), rowBytes);
97}
98
99// Test out the layer replacement functionality with and w/o a BBH
100void test_replacements(skiatest::Reporter* r, bool useBBH) {
robertphillipsee6631e2014-09-29 05:32:49 -0700101 SkAutoTUnref<const SkPicture> pic;
102
103 {
104 SkRTreeFactory bbhFactory;
105 SkPictureRecorder recorder;
mtklein4477c3c2014-10-27 10:27:10 -0700106 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight),
robertphillipsee6631e2014-09-29 05:32:49 -0700107 useBBH ? &bbhFactory : NULL);
108
109 SkAutoTDelete<SkPaint> paint(SkNEW(SkPaint));
110 canvas->saveLayer(NULL, paint);
111 canvas->clear(SK_ColorRED);
112 canvas->restore();
113 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)),
114 SkPaint());
robertphillipsee6631e2014-09-29 05:32:49 -0700115 pic.reset(recorder.endRecording());
116 }
robertphillipsd982eb22014-09-03 11:04:30 -0700117
robertphillips01d6e5f2014-12-01 09:09:27 -0800118 int key[1] = { 0 };
119
robertphillipsd982eb22014-09-03 11:04:30 -0700120 GrReplacements replacements;
robertphillips01d6e5f2014-12-01 09:09:27 -0800121 GrReplacements::ReplacementInfo* ri = replacements.newReplacement(pic->uniqueID(),
122 SkMatrix::I(), key, 1);
robertphillipsd982eb22014-09-03 11:04:30 -0700123 ri->fStop = 2;
124 ri->fPos.set(0, 0);
125 ri->fImage = make_image(SK_ColorRED);
robertphillipsa0537de2014-09-18 08:01:23 -0700126 ri->fPaint = SkNEW(SkPaint);
robertphillipsd982eb22014-09-03 11:04:30 -0700127 ri->fSrcRect = SkIRect::MakeWH(kWidth, kHeight);
128
129 SkAutoTUnref<SkBBoxHierarchy> bbh;
130
robertphillipsd982eb22014-09-03 11:04:30 -0700131 SkRecord rerecord;
132 SkRecorder canvas(&rerecord, kWidth, kHeight);
robertphillipsee6631e2014-09-29 05:32:49 -0700133 GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
robertphillipsd982eb22014-09-03 11:04:30 -0700134
robertphillips46625e02014-09-08 11:37:59 -0700135 REPORTER_ASSERT(r, 7 == rerecord.count());
robertphillipsd982eb22014-09-03 11:04:30 -0700136 assert_type<SkRecords::Save>(r, rerecord, 0);
robertphillips46625e02014-09-08 11:37:59 -0700137 assert_type<SkRecords::Save>(r, rerecord, 1);
138 assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
piotaixr65151752014-10-16 11:58:39 -0700139 assert_type<SkRecords::DrawImageRect>(r, rerecord, 3);
robertphillips46625e02014-09-08 11:37:59 -0700140 assert_type<SkRecords::Restore>(r, rerecord, 4);
141 assert_type<SkRecords::DrawRect>(r, rerecord, 5);
142 assert_type<SkRecords::Restore>(r, rerecord, 6);
robertphillipsd982eb22014-09-03 11:04:30 -0700143}
144
145DEF_TEST(RecordReplaceDraw_Replace, r) { test_replacements(r, false); }
146DEF_TEST(RecordReplaceDraw_ReplaceWithBBH, r) { test_replacements(r, true); }
147
148#endif