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