| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 #include "Test.h" | |
| 9 | |
| 10 #if SK_SUPPORT_GPU | |
| 11 | |
| 12 #include "GrContext.h" | |
| 13 #include "GrLayerCache.h" | |
| 14 #include "GrRecordReplaceDraw.h" | |
| 15 #include "RecordTestUtils.h" | |
| 16 #include "SkBBHFactory.h" | |
| 17 #include "SkPictureRecorder.h" | |
| 18 #include "SkRecordDraw.h" | |
| 19 #include "SkRecorder.h" | |
| 20 #include "SkUtils.h" | |
| 21 | |
| 22 static const int kWidth = 100; | |
| 23 static const int kHeight = 100; | |
| 24 | |
| 25 class JustOneDraw : public SkPicture::AbortCallback { | |
| 26 public: | |
| 27 JustOneDraw() : fCalls(0) {} | |
| 28 | |
| 29 bool abort() override { return fCalls++ > 0; } | |
| 30 private: | |
| 31 int fCalls; | |
| 32 }; | |
| 33 | |
| 34 // Make sure the abort callback works | |
| 35 DEF_TEST(RecordReplaceDraw_Abort, r) { | |
| 36 sk_sp<SkPicture> pic; | |
| 37 | |
| 38 { | |
| 39 // Record two commands. | |
| 40 SkPictureRecorder recorder; | |
| 41 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntT
oScalar(kHeight)); | |
| 42 | |
| 43 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHe
ight)), SkPaint()); | |
| 44 canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHe
ight))); | |
| 45 | |
| 46 pic = recorder.finishRecordingAsPicture(); | |
| 47 } | |
| 48 | |
| 49 SkRecord rerecord; | |
| 50 SkRecorder canvas(&rerecord, kWidth, kHeight); | |
| 51 | |
| 52 JustOneDraw callback; | |
| 53 GrRecordReplaceDraw(pic.get(), &canvas, nullptr, SkMatrix::I(), &callback); | |
| 54 | |
| 55 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 } | |
| 67 } | |
| 68 | |
| 69 // Make sure GrRecordReplaceDraw balances unbalanced saves | |
| 70 DEF_TEST(RecordReplaceDraw_Unbalanced, r) { | |
| 71 sk_sp<SkPicture> pic; | |
| 72 | |
| 73 { | |
| 74 SkPictureRecorder recorder; | |
| 75 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntT
oScalar(kHeight)); | |
| 76 | |
| 77 // We won't balance this, but GrRecordReplaceDraw will for us. | |
| 78 canvas->save(); | |
| 79 canvas->scale(2, 2); | |
| 80 pic = recorder.finishRecordingAsPicture(); | |
| 81 | |
| 82 // we may have optimized everything away. If so, just return | |
| 83 if (pic->approximateOpCount() == 0) { | |
| 84 return; | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 SkRecord rerecord; | |
| 89 SkRecorder canvas(&rerecord, kWidth, kHeight); | |
| 90 | |
| 91 GrRecordReplaceDraw(pic.get(), &canvas, nullptr, SkMatrix::I(), nullptr/*cal
lback*/); | |
| 92 | |
| 93 // ensure rerecord is balanced (in this case by checking that the count is o
dd) | |
| 94 REPORTER_ASSERT(r, (rerecord.count() & 1) == 1); | |
| 95 } | |
| 96 | |
| 97 // Test out the layer replacement functionality with and w/o a BBH | |
| 98 void test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace
) { | |
| 99 sk_sp<SkPicture> pic; | |
| 100 | |
| 101 { | |
| 102 SkPictureRecorder recorder; | |
| 103 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntT
oScalar(kHeight)); | |
| 104 SkPaint paint; | |
| 105 canvas->saveLayer(nullptr, &paint); | |
| 106 canvas->clear(SK_ColorRED); | |
| 107 canvas->restore(); | |
| 108 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar
(kHeight / 2)), | |
| 109 SkPaint()); | |
| 110 pic = recorder.finishRecordingAsPicture(); | |
| 111 } | |
| 112 | |
| 113 SkAutoTUnref<GrTexture> texture; | |
| 114 SkPaint paint; | |
| 115 GrLayerCache* layerCache = context->getLayerCache(); | |
| 116 | |
| 117 if (doReplace) { | |
| 118 int key[1] = { 0 }; | |
| 119 | |
| 120 GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0,
2, | |
| 121 SkIRect::MakeWH(kWi
dth, kHeight), | |
| 122 SkIRect::MakeWH(kWi
dth, kHeight), | |
| 123 SkMatrix::I(), key,
1, &paint); | |
| 124 | |
| 125 GrSurfaceDesc desc; | |
| 126 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 127 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
| 128 desc.fWidth = kWidth; | |
| 129 desc.fHeight = kHeight; | |
| 130 desc.fSampleCnt = 0; | |
| 131 | |
| 132 // Giving the texture some initial data so the Gpu (specifically vulkan)
does not complain | |
| 133 // when reading from an uninitialized texture. | |
| 134 SkAutoTMalloc<uint32_t> srcBuffer(kWidth*kHeight); | |
| 135 memset(srcBuffer.get(), 0, kWidth*kHeight*sizeof(uint32_t)); | |
| 136 | |
| 137 texture.reset(context->textureProvider()->createTexture( | |
| 138 desc, SkBudgeted::kNo, srcBuffer.get(), 0)); | |
| 139 layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false); | |
| 140 } | |
| 141 | |
| 142 SkRecord rerecord; | |
| 143 SkRecorder canvas(&rerecord, kWidth, kHeight); | |
| 144 GrRecordReplaceDraw(pic.get(), &canvas, layerCache, SkMatrix::I(), nullptr/*
callback*/); | |
| 145 | |
| 146 int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord); | |
| 147 if (doReplace) { | |
| 148 REPORTER_ASSERT(r, 0 == numLayers); | |
| 149 } else { | |
| 150 REPORTER_ASSERT(r, 1 == numLayers); | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RecordReplaceDraw, r, ctxInfo) { | |
| 155 test_replacements(r, ctxInfo.grContext(), true); | |
| 156 test_replacements(r, ctxInfo.grContext(), false); | |
| 157 } | |
| 158 | |
| 159 #endif | |
| OLD | NEW |