1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 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 "bench/Benchmark.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkFont.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 12cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 13cb93a386Sopenharmony_ci#include "include/core/SkString.h" 14cb93a386Sopenharmony_ci#include "include/core/SkTextBlob.h" 15cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h" 16cb93a386Sopenharmony_ci#include "include/private/SkTemplates.h" 17cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 18cb93a386Sopenharmony_ci#include "tools/Resources.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci#include "tools/ToolUtils.h" 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci/* 23cb93a386Sopenharmony_ci * A trivial test which benchmarks the performance of a textblob with a single run. 24cb93a386Sopenharmony_ci */ 25cb93a386Sopenharmony_ciclass SkTextBlobBench : public Benchmark { 26cb93a386Sopenharmony_cipublic: 27cb93a386Sopenharmony_ci SkTextBlobBench() {} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci void onDelayedSetup() override { 30cb93a386Sopenharmony_ci fFont.setTypeface(ToolUtils::create_portable_typeface("serif", SkFontStyle())); 31cb93a386Sopenharmony_ci fFont.setSubpixel(true); 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci // This text seems representative in both length and letter frequency. 34cb93a386Sopenharmony_ci const char* text = "Keep your sentences short, but not overly so."; 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci fGlyphs.setCount(fFont.countText(text, strlen(text), SkTextEncoding::kUTF8)); 37cb93a386Sopenharmony_ci fXPos.setCount(fGlyphs.count()); 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci fFont.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, fGlyphs.begin(), fGlyphs.count()); 40cb93a386Sopenharmony_ci fFont.getXPos(&fGlyphs[0], fGlyphs.count(), fXPos.begin()); 41cb93a386Sopenharmony_ci } 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci sk_sp<SkTextBlob> makeBlob() { 44cb93a386Sopenharmony_ci const SkTextBlobBuilder::RunBuffer& run = 45cb93a386Sopenharmony_ci fBuilder.allocRunPosH(fFont, fGlyphs.count(), 10, nullptr); 46cb93a386Sopenharmony_ci memcpy(run.glyphs, &fGlyphs[0], fGlyphs.count() * sizeof(uint16_t)); 47cb93a386Sopenharmony_ci memcpy(run.pos, &fXPos[0], fXPos.count() * sizeof(SkScalar)); 48cb93a386Sopenharmony_ci return fBuilder.make(); 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ciprivate: 52cb93a386Sopenharmony_ci SkTextBlobBuilder fBuilder; 53cb93a386Sopenharmony_ci SkFont fFont; 54cb93a386Sopenharmony_ci SkTDArray<uint16_t> fGlyphs; 55cb93a386Sopenharmony_ci SkTDArray<SkScalar> fXPos; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci using INHERITED = Benchmark; 58cb93a386Sopenharmony_ci}; 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ciclass TextBlobCachedBench : public SkTextBlobBench { 61cb93a386Sopenharmony_ci const char* onGetName() override { 62cb93a386Sopenharmony_ci return "TextBlobCachedBench"; 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 66cb93a386Sopenharmony_ci SkPaint paint; 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci auto blob = this->makeBlob(); 69cb93a386Sopenharmony_ci auto bigLoops = loops * 100; 70cb93a386Sopenharmony_ci for (int i = 0; i < bigLoops; i++) { 71cb93a386Sopenharmony_ci // To ensure maximum caching, we just redraw the blob at the same place everytime 72cb93a386Sopenharmony_ci canvas->drawTextBlob(blob, 0, 0, paint); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci}; 76cb93a386Sopenharmony_ciDEF_BENCH( return new TextBlobCachedBench(); ) 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ciclass TextBlobFirstTimeBench : public SkTextBlobBench { 79cb93a386Sopenharmony_ci const char* onGetName() override { 80cb93a386Sopenharmony_ci return "TextBlobFirstTimeBench"; 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 84cb93a386Sopenharmony_ci SkPaint paint; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci auto bigLoops = loops * 100; 87cb93a386Sopenharmony_ci for (int i = 0; i < bigLoops; i++) { 88cb93a386Sopenharmony_ci canvas->drawTextBlob(this->makeBlob(), 0, 0, paint); 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci}; 92cb93a386Sopenharmony_ciDEF_BENCH( return new TextBlobFirstTimeBench(); ) 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ciclass TextBlobMakeBench : public SkTextBlobBench { 95cb93a386Sopenharmony_ci const char* onGetName() override { 96cb93a386Sopenharmony_ci return "TextBlobMakeBench"; 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci bool isSuitableFor(Backend backend) override { 100cb93a386Sopenharmony_ci return backend == kNonRendering_Backend; 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas*) override { 104cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 105cb93a386Sopenharmony_ci for (int inner = 0; inner < 1000; ++inner) { 106cb93a386Sopenharmony_ci this->makeBlob(); 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci}; 111cb93a386Sopenharmony_ciDEF_BENCH( return new TextBlobMakeBench(); ) 112