1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include <memory> 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "bench/Benchmark.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 13cb93a386Sopenharmony_ci#include "include/core/SkDeferredDisplayListRecorder.h" 14cb93a386Sopenharmony_ci#include "include/core/SkSurfaceCharacterization.h" 15cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cistatic SkSurfaceCharacterization create_characterization(GrDirectContext* direct) { 18cb93a386Sopenharmony_ci size_t maxResourceBytes = direct->getResourceCacheLimit(); 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci if (!direct->colorTypeSupportedAsSurface(kRGBA_8888_SkColorType)) { 21cb93a386Sopenharmony_ci return SkSurfaceCharacterization(); 22cb93a386Sopenharmony_ci } 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, 25cb93a386Sopenharmony_ci kPremul_SkAlphaType, nullptr); 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci GrBackendFormat backendFormat = direct->defaultBackendFormat(kRGBA_8888_SkColorType, 28cb93a386Sopenharmony_ci GrRenderable::kYes); 29cb93a386Sopenharmony_ci if (!backendFormat.isValid()) { 30cb93a386Sopenharmony_ci return SkSurfaceCharacterization(); 31cb93a386Sopenharmony_ci } 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci SkSurfaceProps props(0x0, kUnknown_SkPixelGeometry); 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci SkSurfaceCharacterization c = direct->threadSafeProxy()->createCharacterization( 36cb93a386Sopenharmony_ci maxResourceBytes, ii, backendFormat, 1, 37cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, props, false); 38cb93a386Sopenharmony_ci return c; 39cb93a386Sopenharmony_ci} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci// This benchmark tries to simulate how Viz is using SkDDLRecorders. 42cb93a386Sopenharmony_ci// For each config it will create a single DDLRecorder which it reuses for all the runs 43cb93a386Sopenharmony_ci// For each run it creates a DDL and stores it for later deletion. 44cb93a386Sopenharmony_ciclass DDLRecorderBench : public Benchmark { 45cb93a386Sopenharmony_cipublic: 46cb93a386Sopenharmony_ci DDLRecorderBench() { } 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ciprotected: 49cb93a386Sopenharmony_ci bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci const char* onGetName() override { return "DDLRecorder"; } 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* origCanvas) override { 54cb93a386Sopenharmony_ci if (!fRecorder) { 55cb93a386Sopenharmony_ci return; 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci SkASSERT(!fDDLs.size()); 59cb93a386Sopenharmony_ci fDDLs.reserve(loops); 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 62cb93a386Sopenharmony_ci SkCanvas* recordingCanvas = fRecorder->getCanvas(); 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci recordingCanvas->drawRect(SkRect::MakeWH(32, 32), SkPaint()); 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci fDDLs.emplace_back(fRecorder->detach()); 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ciprivate: 71cb93a386Sopenharmony_ci // We create one DDLRecorder for all the timing runs and just keep reusing it 72cb93a386Sopenharmony_ci void onPerCanvasPreDraw(SkCanvas* origCanvas) override { 73cb93a386Sopenharmony_ci auto context = origCanvas->recordingContext()->asDirectContext(); 74cb93a386Sopenharmony_ci if (!context) { 75cb93a386Sopenharmony_ci return; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci SkSurfaceCharacterization c = create_characterization(context); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci fRecorder = std::make_unique<SkDeferredDisplayListRecorder>(c); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci // We defer the clean up of the DDLs so it is done outside of the timing loop 84cb93a386Sopenharmony_ci void onPostDraw(SkCanvas*) override { 85cb93a386Sopenharmony_ci fDDLs.clear(); 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci std::unique_ptr<SkDeferredDisplayListRecorder> fRecorder = nullptr; 89cb93a386Sopenharmony_ci std::vector<sk_sp<SkDeferredDisplayList>> fDDLs; 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci using INHERITED = Benchmark; 92cb93a386Sopenharmony_ci}; 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ciDEF_BENCH(return new DDLRecorderBench();) 95