1 /* 2 * Copyright 2020 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 "bench/Benchmark.h" 9 #include "include/core/SkCanvas.h" 10 #include "include/core/SkColorSpace.h" 11 #include "include/core/SkFont.h" 12 #include "include/core/SkTypeface.h" 13 #include "include/gpu/ganesh/GrDirectContext.h" 14 #include "include/gpu/ganesh/GrRecordingContext.h" 15 #include "src/base/SkUTF.h" 16 #include "src/base/SkUtils.h" 17 #include "src/core/SkStrikeCache.h" 18 #include "src/gpu/ganesh/GrRecordingContextPriv.h" 19 #include "src/gpu/ganesh/SkGr.h" 20 #include "src/text/GlyphRun.h" 21 #include "src/text/gpu/StrikeCache.h" 22 #include "src/text/gpu/TextBlob.h" 23 #include "tools/fonts/FontToolUtils.h" 24 #include "tools/gpu/TestCanvas.h" 25 #include "tools/text/gpu/TextBlobTools.h" 26 27 // From Project Guttenberg. This is UTF-8 text. 28 static const char* gText = 29 "Call me Ishmael. Some years ago--never mind how long precisely"; 30 31 class FillBench {}; 32 template <> class skiatest::TestCanvas<FillBench> { 33 public: GetDevice(SkCanvas * canvas)34 static SkDevice* GetDevice(SkCanvas* canvas) { 35 return canvas->topDevice(); 36 } 37 }; 38 39 class DirectMaskGlyphVertexFillBenchmark : public Benchmark { isSuitableFor(Backend backend)40 bool isSuitableFor(Backend backend) override { 41 return backend == Backend::kGanesh; 42 } 43 onGetName()44 const char* onGetName() override { 45 return "DirectMaskGlyphVertexFillBenchmark"; 46 } 47 onPerCanvasPreDraw(SkCanvas * canvas)48 void onPerCanvasPreDraw(SkCanvas* canvas) override { 49 auto typeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle()); 50 SkFont font(typeface); 51 52 SkMatrix view = SkMatrix::I(); 53 size_t len = strlen(gText); 54 sktext::GlyphRunBuilder builder; 55 SkPaint paint; 56 auto glyphRunList = builder.textToGlyphRunList(font, paint, gText, len, {100, 100}); 57 SkASSERT_RELEASE(!glyphRunList.empty()); 58 auto device = skiatest::TestCanvas<FillBench>::GetDevice(canvas); 59 SkMatrix drawMatrix = view; 60 const SkPoint drawOrigin = glyphRunList.origin(); 61 drawMatrix.preTranslate(drawOrigin.x(), drawOrigin.y()); 62 fBlob = sktext::gpu::TextBlob::Make(glyphRunList, 63 paint, 64 drawMatrix, 65 device->strikeDeviceInfo(), 66 SkStrikeCache::GlobalStrikeCache()); 67 68 const sktext::gpu::AtlasSubRun* subRun = 69 sktext::gpu::TextBlobTools::FirstSubRun(fBlob.get()); 70 SkASSERT_RELEASE(subRun); 71 subRun->testingOnly_packedGlyphIDToGlyph(&fCache); 72 fVertices.reset(new char[subRun->vertexStride(drawMatrix) * subRun->glyphCount() * 4]); 73 } 74 onDraw(int loops,SkCanvas * canvas)75 void onDraw(int loops, SkCanvas* canvas) override { 76 const sktext::gpu::AtlasSubRun* subRun = 77 sktext::gpu::TextBlobTools::FirstSubRun(fBlob.get()); 78 SkASSERT_RELEASE(subRun); 79 80 SkIRect clip = SkIRect::MakeEmpty(); 81 SkPaint paint; 82 GrColor grColor = SkColorToPremulGrColor(paint.getColor()); 83 SkMatrix positionMatrix = SkMatrix::Translate(100, 100); 84 85 for (int loop = 0; loop < loops; loop++) { 86 subRun->fillVertexData(fVertices.get(), 0, subRun->glyphCount(), 87 grColor, positionMatrix, {0, 0}, clip); 88 } 89 } 90 91 private: 92 sk_sp<sktext::gpu::TextBlob> fBlob; 93 sktext::gpu::StrikeCache fCache; 94 std::unique_ptr<char[]> fVertices; 95 }; 96 97 DEF_BENCH(return new DirectMaskGlyphVertexFillBenchmark{}); 98