/* * Copyright 2020 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "bench/Benchmark.h" #include "include/core/SkCanvas.h" #include "include/core/SkColorSpace.h" #include "include/core/SkFont.h" #include "include/core/SkTypeface.h" #include "include/gpu/ganesh/GrDirectContext.h" #include "include/gpu/ganesh/GrRecordingContext.h" #include "src/base/SkUTF.h" #include "src/base/SkUtils.h" #include "src/core/SkStrikeCache.h" #include "src/gpu/ganesh/GrRecordingContextPriv.h" #include "src/gpu/ganesh/SkGr.h" #include "src/text/GlyphRun.h" #include "src/text/gpu/StrikeCache.h" #include "src/text/gpu/TextBlob.h" #include "tools/fonts/FontToolUtils.h" #include "tools/gpu/TestCanvas.h" #include "tools/text/gpu/TextBlobTools.h" // From Project Guttenberg. This is UTF-8 text. static const char* gText = "Call me Ishmael. Some years ago--never mind how long precisely"; class FillBench {}; template <> class skiatest::TestCanvas { public: static SkDevice* GetDevice(SkCanvas* canvas) { return canvas->topDevice(); } }; class DirectMaskGlyphVertexFillBenchmark : public Benchmark { bool isSuitableFor(Backend backend) override { return backend == Backend::kGanesh; } const char* onGetName() override { return "DirectMaskGlyphVertexFillBenchmark"; } void onPerCanvasPreDraw(SkCanvas* canvas) override { auto typeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle()); SkFont font(typeface); SkMatrix view = SkMatrix::I(); size_t len = strlen(gText); sktext::GlyphRunBuilder builder; SkPaint paint; auto glyphRunList = builder.textToGlyphRunList(font, paint, gText, len, {100, 100}); SkASSERT_RELEASE(!glyphRunList.empty()); auto device = skiatest::TestCanvas::GetDevice(canvas); SkMatrix drawMatrix = view; const SkPoint drawOrigin = glyphRunList.origin(); drawMatrix.preTranslate(drawOrigin.x(), drawOrigin.y()); fBlob = sktext::gpu::TextBlob::Make(glyphRunList, paint, drawMatrix, device->strikeDeviceInfo(), SkStrikeCache::GlobalStrikeCache()); const sktext::gpu::AtlasSubRun* subRun = sktext::gpu::TextBlobTools::FirstSubRun(fBlob.get()); SkASSERT_RELEASE(subRun); subRun->testingOnly_packedGlyphIDToGlyph(&fCache); fVertices.reset(new char[subRun->vertexStride(drawMatrix) * subRun->glyphCount() * 4]); } void onDraw(int loops, SkCanvas* canvas) override { const sktext::gpu::AtlasSubRun* subRun = sktext::gpu::TextBlobTools::FirstSubRun(fBlob.get()); SkASSERT_RELEASE(subRun); SkIRect clip = SkIRect::MakeEmpty(); SkPaint paint; GrColor grColor = SkColorToPremulGrColor(paint.getColor()); SkMatrix positionMatrix = SkMatrix::Translate(100, 100); for (int loop = 0; loop < loops; loop++) { subRun->fillVertexData(fVertices.get(), 0, subRun->glyphCount(), grColor, positionMatrix, {0, 0}, clip); } } private: sk_sp fBlob; sktext::gpu::StrikeCache fCache; std::unique_ptr fVertices; }; DEF_BENCH(return new DirectMaskGlyphVertexFillBenchmark{});