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