skia2/tests/GrTextBlobTest.cpp
Herb Derby 5d9d837994 error on the side of safety for empty blobs
If the blob is empty, then try to regenerate it. Using
this method caused a slowdown in Skia perf, so we
added an extra check to allow some empty blobs through
for perf performance. The perf problem was caused by
SKPs generate empty blobs because of font mismatches.
Flutter has shown that scaling from very small to
normal size is not correctly handled by the existing
check. This CL favors correctness over optimizing empty
text blob and always regenerates empty blobs.

https://github.com/flutter/flutter/issues/64936

Change-Id: Ib18ecb684b0af5cf6dce274b6dc09a9c61b17c77
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319031
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
2020-09-23 21:18:27 +00:00

69 lines
2.1 KiB
C++

/*
* 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 "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "src/core/SkSurfacePriv.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
SkBitmap rasterize_blob(SkTextBlob* blob,
const SkPaint& paint,
GrRecordingContext* rContext,
const SkMatrix& matrix) {
const SkImageInfo info =
SkImageInfo::Make(500, 500, kN32_SkColorType, kPremul_SkAlphaType);
auto surface = SkSurface::MakeRenderTarget(rContext, SkBudgeted::kNo, info);
auto canvas = surface->getCanvas();
canvas->drawColor(SK_ColorWHITE);
canvas->concat(matrix);
canvas->drawTextBlob(blob, 10, 250, paint);
SkBitmap bitmap;
bitmap.allocN32Pixels(500, 500);
surface->readPixels(bitmap, 0, 0);
return bitmap;
}
bool check_for_black(const SkBitmap& bm) {
for (int y = 0; y < bm.height(); y++) {
for (int x = 0; x < bm.width(); x++) {
if (bm.getColor(x, y) == SK_ColorBLACK) {
return true;
}
}
}
return false;
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextBlobScaleAnimation, reporter, ctxInfo) {
auto tf = ToolUtils::create_portable_typeface("Mono", SkFontStyle());
SkFont font{tf};
font.setHinting(SkFontHinting::kNormal);
font.setSize(12);
font.setEdging(SkFont::Edging::kAntiAlias);
font.setSubpixel(true);
SkTextBlobBuilder builder;
const auto& runBuffer = builder.allocRunPosH(font, 30, 0, nullptr);
for (int i = 0; i < 30; i++) {
runBuffer.glyphs[i] = static_cast<SkGlyphID>(i);
runBuffer.pos[i] = SkIntToScalar(i);
}
auto blob = builder.make();
auto dContext = ctxInfo.directContext();
bool anyBlack = false;
for (int n = -13; n < 5; n++) {
SkMatrix m = SkMatrix::Scale(std::exp2(n), std::exp2(n));
auto bm = rasterize_blob(blob.get(), SkPaint(), dContext, m);
anyBlack |= check_for_black(bm);
}
REPORTER_ASSERT(reporter, anyBlack);
}