1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkFont.h" 9cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h" 10cb93a386Sopenharmony_ci#include "src/core/SkScalerCache.h" 11cb93a386Sopenharmony_ci#include "src/core/SkStrikeSpec.h" 12cb93a386Sopenharmony_ci#include "src/core/SkTaskGroup.h" 13cb93a386Sopenharmony_ci#include "tests/Test.h" 14cb93a386Sopenharmony_ci#include "tools/ToolUtils.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci#include <atomic> 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass Barrier { 19cb93a386Sopenharmony_cipublic: 20cb93a386Sopenharmony_ci Barrier(int threadCount) : fThreadCount(threadCount) { } 21cb93a386Sopenharmony_ci void waitForAll() { 22cb93a386Sopenharmony_ci fThreadCount -= 1; 23cb93a386Sopenharmony_ci while (fThreadCount > 0) { } 24cb93a386Sopenharmony_ci } 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ciprivate: 27cb93a386Sopenharmony_ci std::atomic<int> fThreadCount; 28cb93a386Sopenharmony_ci}; 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ciDEF_TEST(SkScalerCacheMultiThread, Reporter) { 31cb93a386Sopenharmony_ci sk_sp<SkTypeface> typeface = 32cb93a386Sopenharmony_ci ToolUtils::create_portable_typeface("serif", SkFontStyle::Italic()); 33cb93a386Sopenharmony_ci static constexpr int kThreadCount = 4; 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci Barrier barrier{kThreadCount}; 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci SkFont font; 38cb93a386Sopenharmony_ci font.setEdging(SkFont::Edging::kAntiAlias); 39cb93a386Sopenharmony_ci font.setSubpixel(true); 40cb93a386Sopenharmony_ci font.setTypeface(typeface); 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci SkGlyphID glyphs['z']; 43cb93a386Sopenharmony_ci SkPoint pos['z']; 44cb93a386Sopenharmony_ci for (int c = ' '; c < 'z'; c++) { 45cb93a386Sopenharmony_ci glyphs[c] = font.unicharToGlyph(c); 46cb93a386Sopenharmony_ci pos[c] = {30.0f * c + 30, 30.0f}; 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci constexpr size_t glyphCount = 'z' - ' '; 49cb93a386Sopenharmony_ci auto data = SkMakeZip(glyphs, pos).subspan(SkTo<int>(' '), glyphCount); 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci SkPaint defaultPaint; 52cb93a386Sopenharmony_ci SkStrikeSpec strikeSpec = SkStrikeSpec::MakeMask( 53cb93a386Sopenharmony_ci font, defaultPaint, SkSurfaceProps(0, kUnknown_SkPixelGeometry), 54cb93a386Sopenharmony_ci SkScalerContextFlags::kNone, SkMatrix::I()); 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci // Make our own executor so the --threads parameter doesn't mess things up. 57cb93a386Sopenharmony_ci auto executor = SkExecutor::MakeFIFOThreadPool(kThreadCount); 58cb93a386Sopenharmony_ci for (int tries = 0; tries < 100; tries++) { 59cb93a386Sopenharmony_ci SkScalerCache scalerCache{strikeSpec.createScalerContext()}; 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci auto perThread = [&](int threadIndex) { 62cb93a386Sopenharmony_ci barrier.waitForAll(); 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci auto local = data.subspan(threadIndex * 2, data.size() - kThreadCount * 2); 65cb93a386Sopenharmony_ci for (int i = 0; i < 100; i++) { 66cb93a386Sopenharmony_ci SkDrawableGlyphBuffer drawable; 67cb93a386Sopenharmony_ci SkSourceGlyphBuffer rejects; 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci drawable.ensureSize(glyphCount); 70cb93a386Sopenharmony_ci rejects.setSource(local); 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci drawable.startBitmapDevice(rejects.source(), {0, 0}, SkMatrix::I(), 73cb93a386Sopenharmony_ci scalerCache.roundingSpec()); 74cb93a386Sopenharmony_ci scalerCache.prepareForMaskDrawing(&drawable, &rejects); 75cb93a386Sopenharmony_ci rejects.flipRejectsToSource(); 76cb93a386Sopenharmony_ci drawable.reset(); 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci }; 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci SkTaskGroup(*executor).batch(kThreadCount, perThread); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci} 83