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#include "Test.h" 9d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 10d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon#if SK_SUPPORT_GPU 11d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon 121530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#include "GrContext.h" 13e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips#include "GrLayerCache.h" 14ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "GrRecordReplaceDraw.h" 15ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "RecordTestUtils.h" 16d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkBBHFactory.h" 17ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips#include "SkPictureRecorder.h" 18d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecordDraw.h" 19d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkRecorder.h" 20d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#include "SkUtils.h" 21d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 22d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kWidth = 100; 23d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsstatic const int kHeight = 100; 24d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 25783fe16b8ed1cd1cff34eacc33296874a32f293brobertphillipsclass JustOneDraw : public SkPicture::AbortCallback { 26d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipspublic: 27d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips JustOneDraw() : fCalls(0) {} 28d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 2936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool abort() override { return fCalls++ > 0; } 30d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsprivate: 31d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips int fCalls; 32d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips}; 33d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 34d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure the abort callback works 35d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Abort, r) { 36ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkAutoTUnref<const SkPicture> pic; 37ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips 38ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips { 39ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips // Record two commands. 40ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkPictureRecorder recorder; 41ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 42ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips 43ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint()); 44ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips canvas->clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight))); 45ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips 46ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips pic.reset(recorder.endRecording()); 47ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips } 48d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 49d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips SkRecord rerecord; 50d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips SkRecorder canvas(&rerecord, kWidth, kHeight); 51d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 52d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips JustOneDraw callback; 5396fcdcc219d2a0d3579719b84b28bede76efba64halcanary GrRecordReplaceDraw(pic, &canvas, nullptr, SkMatrix::I(), &callback); 54d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed switch (rerecord.count()) { 562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed case 3: 572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::Save>(r, rerecord, 0); 582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::DrawRect>(r, rerecord, 1); 592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::Restore>(r, rerecord, 2); 602ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 612ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed case 1: 622ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::DrawRect>(r, rerecord, 0); 632ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 642ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed default: 652ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, false); 662ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 67d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips} 68d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 69d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Make sure GrRecordReplaceDraw balances unbalanced saves 70d982eb22d7bce655a609e9b481b3ddfeff361067robertphillipsDEF_TEST(RecordReplaceDraw_Unbalanced, r) { 71ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkAutoTUnref<const SkPicture> pic; 72ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips 73ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips { 74ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkPictureRecorder recorder; 75ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 76ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips 77ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips // We won't balance this, but GrRecordReplaceDraw will for us. 78ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips canvas->save(); 792ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed canvas->scale(2, 2); 80ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips pic.reset(recorder.endRecording()); 81ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips } 82d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 83d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips SkRecord rerecord; 84d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips SkRecorder canvas(&rerecord, kWidth, kHeight); 85d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 8696fcdcc219d2a0d3579719b84b28bede76efba64halcanary GrRecordReplaceDraw(pic, &canvas, nullptr, SkMatrix::I(), nullptr/*callback*/); 87d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 887bc0b42567a304313a9c6eaaeba28076d24cbd85reed // ensure rerecord is balanced (in this case by checking that the count is odd) 897bc0b42567a304313a9c6eaaeba28076d24cbd85reed REPORTER_ASSERT(r, (rerecord.count() & 1) == 1); 90d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips} 91d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 92d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips// Test out the layer replacement functionality with and w/o a BBH 9307b41eb962fdb007f788fcd82e338d7aef126064robertphillipsvoid test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace) { 94ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkAutoTUnref<const SkPicture> pic; 95ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips 96ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips { 97ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkPictureRecorder recorder; 9807b41eb962fdb007f788fcd82e338d7aef126064robertphillips SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 99c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein SkPaint paint; 10096fcdcc219d2a0d3579719b84b28bede76efba64halcanary canvas->saveLayer(nullptr, &paint); 101ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips canvas->clear(SK_ColorRED); 102ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips canvas->restore(); 103ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)), 104ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips SkPaint()); 105ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips pic.reset(recorder.endRecording()); 106ee6631ef90fb5a9c80de6eacd37632f11367a088robertphillips } 107d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 10807b41eb962fdb007f788fcd82e338d7aef126064robertphillips SkAutoTUnref<GrTexture> texture; 109c88cedaf8806cc9afa36497dc93eb0d1c329fb6cmtklein SkPaint paint; 110e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips GrLayerCache* layerCache = context->getLayerCache(); 111e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips 11207b41eb962fdb007f788fcd82e338d7aef126064robertphillips if (doReplace) { 11307b41eb962fdb007f788fcd82e338d7aef126064robertphillips int key[1] = { 0 }; 114e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips 11507b41eb962fdb007f788fcd82e338d7aef126064robertphillips GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2, 11607b41eb962fdb007f788fcd82e338d7aef126064robertphillips SkIRect::MakeWH(kWidth, kHeight), 11707b41eb962fdb007f788fcd82e338d7aef126064robertphillips SkIRect::MakeWH(kWidth, kHeight), 11807b41eb962fdb007f788fcd82e338d7aef126064robertphillips SkMatrix::I(), key, 1, &paint); 119d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 12007b41eb962fdb007f788fcd82e338d7aef126064robertphillips GrSurfaceDesc desc; 12107b41eb962fdb007f788fcd82e338d7aef126064robertphillips desc.fConfig = kSkia8888_GrPixelConfig; 12207b41eb962fdb007f788fcd82e338d7aef126064robertphillips desc.fFlags = kRenderTarget_GrSurfaceFlag; 12307b41eb962fdb007f788fcd82e338d7aef126064robertphillips desc.fWidth = kWidth; 12407b41eb962fdb007f788fcd82e338d7aef126064robertphillips desc.fHeight = kHeight; 12507b41eb962fdb007f788fcd82e338d7aef126064robertphillips desc.fSampleCnt = 0; 12607b41eb962fdb007f788fcd82e338d7aef126064robertphillips 1275ec26ae9bfca635ccc98283aad5deda11519d826bsalomon texture.reset(context->textureProvider()->createTexture( 1285ec26ae9bfca635ccc98283aad5deda11519d826bsalomon desc, SkBudgeted::kNo, nullptr, 0)); 12960029a5397f75aae4bdb994f26bd297edc3e433crobertphillips layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false); 13007b41eb962fdb007f788fcd82e338d7aef126064robertphillips } 131d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 132d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips SkRecord rerecord; 133d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips SkRecorder canvas(&rerecord, kWidth, kHeight); 13496fcdcc219d2a0d3579719b84b28bede76efba64halcanary GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), nullptr/*callback*/); 135d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 13607b41eb962fdb007f788fcd82e338d7aef126064robertphillips int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord); 13707b41eb962fdb007f788fcd82e338d7aef126064robertphillips if (doReplace) { 13807b41eb962fdb007f788fcd82e338d7aef126064robertphillips REPORTER_ASSERT(r, 0 == numLayers); 13907b41eb962fdb007f788fcd82e338d7aef126064robertphillips } else { 14007b41eb962fdb007f788fcd82e338d7aef126064robertphillips REPORTER_ASSERT(r, 1 == numLayers); 1412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 142d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips} 143d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 1441530283c483cb88aa725bce50a6d193dd00ee570kkinnunenDEF_GPUTEST_FOR_RENDERING_CONTEXTS(RecordReplaceDraw, r, context) { 1451530283c483cb88aa725bce50a6d193dd00ee570kkinnunen test_replacements(r, context, false); 1461530283c483cb88aa725bce50a6d193dd00ee570kkinnunen test_replacements(r, context, true); 147e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips} 148d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips 149d982eb22d7bce655a609e9b481b3ddfeff361067robertphillips#endif 150