blob: fe8f347d26fe72e871c57d5de9bf27b0479c2b99 [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
robertphillipsd982eb22014-09-03 11:04:30 -07008#include "Test.h"
robertphillipsd982eb22014-09-03 11:04:30 -07009
bsalomond309e7a2015-04-30 14:18:54 -070010#if SK_SUPPORT_GPU
11
kkinnunen15302832015-12-01 04:35:26 -080012#include "GrContext.h"
robertphillipse99d4992014-12-03 07:33:57 -080013#include "GrLayerCache.h"
robertphillipsee6631e2014-09-29 05:32:49 -070014#include "GrRecordReplaceDraw.h"
15#include "RecordTestUtils.h"
robertphillipsd982eb22014-09-03 11:04:30 -070016#include "SkBBHFactory.h"
robertphillipsee6631e2014-09-29 05:32:49 -070017#include "SkPictureRecorder.h"
robertphillipsd982eb22014-09-03 11:04:30 -070018#include "SkRecordDraw.h"
19#include "SkRecorder.h"
20#include "SkUtils.h"
robertphillipsd982eb22014-09-03 11:04:30 -070021
22static const int kWidth = 100;
23static const int kHeight = 100;
24
robertphillips783fe162015-01-07 07:28:41 -080025class JustOneDraw : public SkPicture::AbortCallback {
robertphillipsd982eb22014-09-03 11:04:30 -070026public:
27 JustOneDraw() : fCalls(0) {}
28
mtklein36352bf2015-03-25 18:17:31 -070029 bool abort() override { return fCalls++ > 0; }
robertphillipsd982eb22014-09-03 11:04:30 -070030private:
31 int fCalls;
32};
33
34// Make sure the abort callback works
35DEF_TEST(RecordReplaceDraw_Abort, r) {
robertphillipsee6631e2014-09-29 05:32:49 -070036 SkAutoTUnref<const SkPicture> pic;
37
38 {
39 // Record two commands.
40 SkPictureRecorder recorder;
41 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
42
43 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
44 canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));
45
46 pic.reset(recorder.endRecording());
47 }
robertphillipsd982eb22014-09-03 11:04:30 -070048
49 SkRecord rerecord;
50 SkRecorder canvas(&rerecord, kWidth, kHeight);
51
robertphillipsd982eb22014-09-03 11:04:30 -070052 JustOneDraw callback;
halcanary96fcdcc2015-08-27 07:41:13 -070053 GrRecordReplaceDraw(pic, &canvas, nullptr, SkMatrix::I(), &callback);
robertphillipsd982eb22014-09-03 11:04:30 -070054
reed2ff1fce2014-12-11 07:07:37 -080055 switch (rerecord.count()) {
56 case 3:
57 assert_type<SkRecords::Save>(r, rerecord, 0);
58 assert_type<SkRecords::DrawRect>(r, rerecord, 1);
59 assert_type<SkRecords::Restore>(r, rerecord, 2);
60 break;
61 case 1:
62 assert_type<SkRecords::DrawRect>(r, rerecord, 0);
63 break;
64 default:
65 REPORTER_ASSERT(r, false);
66 }
robertphillipsd982eb22014-09-03 11:04:30 -070067}
68
69// Make sure GrRecordReplaceDraw balances unbalanced saves
70DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
robertphillipsee6631e2014-09-29 05:32:49 -070071 SkAutoTUnref<const SkPicture> pic;
72
73 {
74 SkPictureRecorder recorder;
75 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
76
77 // We won't balance this, but GrRecordReplaceDraw will for us.
78 canvas->save();
reed2ff1fce2014-12-11 07:07:37 -080079 canvas->scale(2, 2);
robertphillipsee6631e2014-09-29 05:32:49 -070080 pic.reset(recorder.endRecording());
81 }
robertphillipsd982eb22014-09-03 11:04:30 -070082
83 SkRecord rerecord;
84 SkRecorder canvas(&rerecord, kWidth, kHeight);
85
halcanary96fcdcc2015-08-27 07:41:13 -070086 GrRecordReplaceDraw(pic, &canvas, nullptr, SkMatrix::I(), nullptr/*callback*/);
robertphillipsd982eb22014-09-03 11:04:30 -070087
reed7bc0b422014-12-11 07:30:58 -080088 // ensure rerecord is balanced (in this case by checking that the count is odd)
89 REPORTER_ASSERT(r, (rerecord.count() & 1) == 1);
robertphillipsd982eb22014-09-03 11:04:30 -070090}
91
robertphillipsd982eb22014-09-03 11:04:30 -070092// Test out the layer replacement functionality with and w/o a BBH
robertphillips07b41eb2015-11-04 04:31:06 -080093void test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace) {
robertphillipsee6631e2014-09-29 05:32:49 -070094 SkAutoTUnref<const SkPicture> pic;
95
96 {
robertphillipsee6631e2014-09-29 05:32:49 -070097 SkPictureRecorder recorder;
robertphillips07b41eb2015-11-04 04:31:06 -080098 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
mtkleinc88ceda2014-12-04 07:53:21 -080099 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700100 canvas->saveLayer(nullptr, &paint);
robertphillipsee6631e2014-09-29 05:32:49 -0700101 canvas->clear(SK_ColorRED);
102 canvas->restore();
103 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)),
104 SkPaint());
robertphillipsee6631e2014-09-29 05:32:49 -0700105 pic.reset(recorder.endRecording());
106 }
robertphillipsd982eb22014-09-03 11:04:30 -0700107
robertphillips07b41eb2015-11-04 04:31:06 -0800108 SkAutoTUnref<GrTexture> texture;
mtkleinc88ceda2014-12-04 07:53:21 -0800109 SkPaint paint;
robertphillipse99d4992014-12-03 07:33:57 -0800110 GrLayerCache* layerCache = context->getLayerCache();
robertphillipse99d4992014-12-03 07:33:57 -0800111
robertphillips07b41eb2015-11-04 04:31:06 -0800112 if (doReplace) {
113 int key[1] = { 0 };
robertphillipse99d4992014-12-03 07:33:57 -0800114
robertphillips07b41eb2015-11-04 04:31:06 -0800115 GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2,
116 SkIRect::MakeWH(kWidth, kHeight),
117 SkIRect::MakeWH(kWidth, kHeight),
118 SkMatrix::I(), key, 1, &paint);
robertphillipsd982eb22014-09-03 11:04:30 -0700119
robertphillips07b41eb2015-11-04 04:31:06 -0800120 GrSurfaceDesc desc;
121 desc.fConfig = kSkia8888_GrPixelConfig;
122 desc.fFlags = kRenderTarget_GrSurfaceFlag;
123 desc.fWidth = kWidth;
124 desc.fHeight = kHeight;
125 desc.fSampleCnt = 0;
126
127 texture.reset(context->textureProvider()->createTexture(desc, false, nullptr, 0));
robertphillips60029a52015-11-09 13:51:06 -0800128 layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false);
robertphillips07b41eb2015-11-04 04:31:06 -0800129 }
robertphillipsd982eb22014-09-03 11:04:30 -0700130
robertphillipsd982eb22014-09-03 11:04:30 -0700131 SkRecord rerecord;
132 SkRecorder canvas(&rerecord, kWidth, kHeight);
halcanary96fcdcc2015-08-27 07:41:13 -0700133 GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), nullptr/*callback*/);
robertphillipsd982eb22014-09-03 11:04:30 -0700134
robertphillips07b41eb2015-11-04 04:31:06 -0800135 int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord);
136 if (doReplace) {
137 REPORTER_ASSERT(r, 0 == numLayers);
138 } else {
139 REPORTER_ASSERT(r, 1 == numLayers);
reed2ff1fce2014-12-11 07:07:37 -0800140 }
robertphillipsd982eb22014-09-03 11:04:30 -0700141}
142
kkinnunen15302832015-12-01 04:35:26 -0800143DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RecordReplaceDraw, r, context) {
144 test_replacements(r, context, false);
145 test_replacements(r, context, true);
robertphillipse99d4992014-12-03 07:33:57 -0800146}
robertphillipsd982eb22014-09-03 11:04:30 -0700147
148#endif