2017-06-30 18:00:35 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2017 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "bench/Benchmark.h"
|
|
|
|
#include "include/core/SkCanvas.h"
|
|
|
|
#include "include/core/SkPaint.h"
|
|
|
|
#include "include/core/SkPath.h"
|
|
|
|
#include "include/utils/SkRandom.h"
|
2020-02-14 16:47:35 +00:00
|
|
|
#include "src/core/SkScalerCache.h"
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "src/core/SkStrikeCache.h"
|
2019-04-17 22:01:04 +00:00
|
|
|
#include "src/core/SkStrikeSpec.h"
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "tools/ToolUtils.h"
|
2017-06-30 18:00:35 +00:00
|
|
|
|
|
|
|
static constexpr int kScreenWidth = 1500;
|
|
|
|
static constexpr int kScreenHeight = 1500;
|
|
|
|
|
|
|
|
static constexpr int kNumDraws = 2000;
|
|
|
|
|
|
|
|
// I and l are rects on OS X.
|
|
|
|
static constexpr char kGlyphs[] = "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
|
|
|
|
static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
|
|
|
|
static_assert(52 == kNumGlyphs, "expected 52 glyphs");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This class benchmarks drawing many glyphs at random scales and rotations.
|
|
|
|
*/
|
|
|
|
class PathTextBench : public Benchmark {
|
|
|
|
public:
|
2017-11-06 21:10:54 +00:00
|
|
|
PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
|
2017-06-30 18:00:35 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
const char* onGetName() override {
|
2017-11-06 21:10:54 +00:00
|
|
|
fName = "path_text";
|
|
|
|
if (fClipped) {
|
|
|
|
fName.append("_clipped");
|
|
|
|
}
|
|
|
|
if (fUncached) {
|
|
|
|
fName.append("_uncached");
|
|
|
|
}
|
|
|
|
return fName.c_str();
|
2017-06-30 18:00:35 +00:00
|
|
|
}
|
|
|
|
SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
|
|
|
|
|
|
|
|
void onDelayedSetup() override {
|
2018-11-28 15:28:07 +00:00
|
|
|
SkFont defaultFont;
|
2019-06-06 18:33:12 +00:00
|
|
|
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
|
2020-02-24 19:35:51 +00:00
|
|
|
auto strike = strikeSpec.findOrCreateStrike();
|
2017-06-30 18:00:35 +00:00
|
|
|
for (int i = 0; i < kNumGlyphs; ++i) {
|
2019-02-01 14:55:20 +00:00
|
|
|
SkPackedGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
|
2020-02-24 19:35:51 +00:00
|
|
|
sk_ignore_unused_variable(strike->getScalerContext()->getPath(id, &fGlyphs[i]));
|
2017-11-06 21:10:54 +00:00
|
|
|
fGlyphs[i].setIsVolatile(fUncached);
|
2017-06-30 18:00:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SkRandom rand;
|
|
|
|
for (int i = 0; i < kNumDraws; ++i) {
|
|
|
|
const SkPath& glyph = fGlyphs[i % kNumGlyphs];
|
|
|
|
const SkRect& bounds = glyph.getBounds();
|
2020-02-07 15:36:46 +00:00
|
|
|
float glyphSize = std::max(bounds.width(), bounds.height());
|
2017-06-30 18:00:35 +00:00
|
|
|
|
|
|
|
float t0 = pow(rand.nextF(), 100);
|
2020-02-07 15:36:46 +00:00
|
|
|
float size = (1 - t0) * std::min(kScreenWidth, kScreenHeight) / 50 +
|
|
|
|
t0 * std::min(kScreenWidth, kScreenHeight) / 3;
|
2017-06-30 18:00:35 +00:00
|
|
|
float scale = size / glyphSize;
|
|
|
|
float t1 = rand.nextF(), t2 = rand.nextF();
|
|
|
|
fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
|
|
|
|
t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
|
|
|
|
(1 - t2) * sqrt(2) * scale/2 * glyphSize +
|
|
|
|
t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
|
|
|
|
fXforms[i].preRotate(rand.nextF() * 360);
|
|
|
|
fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
|
|
|
|
fXforms[i].preScale(scale, scale);
|
|
|
|
fPaints[i].setAntiAlias(true);
|
|
|
|
fPaints[i].setColor(rand.nextU() | 0x80808080);
|
|
|
|
}
|
2017-11-06 21:10:54 +00:00
|
|
|
|
|
|
|
if (fClipped) {
|
2019-03-20 16:12:10 +00:00
|
|
|
fClipPath = ToolUtils::make_star(SkRect::MakeIWH(kScreenWidth, kScreenHeight), 11, 3);
|
2017-11-06 21:10:54 +00:00
|
|
|
fClipPath.setIsVolatile(fUncached);
|
|
|
|
}
|
2017-06-30 18:00:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void onDraw(int loops, SkCanvas* canvas) override {
|
|
|
|
SkAutoCanvasRestore acr(canvas, true);
|
2017-11-06 21:10:54 +00:00
|
|
|
if (fClipped) {
|
|
|
|
canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
|
|
|
|
}
|
2017-06-30 18:00:35 +00:00
|
|
|
for (int i = 0; i < kNumDraws; ++i) {
|
|
|
|
const SkPath& glyph = fGlyphs[i % kNumGlyphs];
|
|
|
|
canvas->setMatrix(fXforms[i]);
|
|
|
|
canvas->drawPath(glyph, fPaints[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-06 21:10:54 +00:00
|
|
|
const bool fClipped;
|
|
|
|
const bool fUncached;
|
|
|
|
SkString fName;
|
2017-06-30 18:00:35 +00:00
|
|
|
SkPath fGlyphs[kNumGlyphs];
|
|
|
|
SkPaint fPaints[kNumDraws];
|
|
|
|
SkMatrix fXforms[kNumDraws];
|
2017-11-06 21:10:54 +00:00
|
|
|
SkPath fClipPath;
|
2017-06-30 18:00:35 +00:00
|
|
|
|
|
|
|
typedef Benchmark INHERITED;
|
|
|
|
};
|
|
|
|
|
2017-11-06 21:10:54 +00:00
|
|
|
DEF_BENCH(return new PathTextBench(false, false);)
|
|
|
|
DEF_BENCH(return new PathTextBench(false, true);)
|
|
|
|
DEF_BENCH(return new PathTextBench(true, true);)
|