1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontTypes.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkGraphics.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSerialProcs.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextOptions.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMalloc.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMutex.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/SkChromeRemoteGlyphCache.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/Slug.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkFontPriv.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkGlyph.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkStrikeSpec.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTHash.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTypeface_remote.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkWriteBuffer.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
50*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderCaps.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunControl.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
55*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
56*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/TestEmptyTypeface.h"
58*c8dee2aaSAndroid Build Coastguard Worker
59*c8dee2aaSAndroid Build Coastguard Worker #include <cmath>
60*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
61*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
62*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
63*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
64*c8dee2aaSAndroid Build Coastguard Worker #include <optional>
65*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
68*c8dee2aaSAndroid Build Coastguard Worker using Slug = sktext::gpu::Slug;
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker class DiscardableManager : public SkStrikeServer::DiscardableHandleManager,
71*c8dee2aaSAndroid Build Coastguard Worker public SkStrikeClient::DiscardableHandleManager {
72*c8dee2aaSAndroid Build Coastguard Worker public:
DiscardableManager()73*c8dee2aaSAndroid Build Coastguard Worker DiscardableManager() { sk_bzero(&fCacheMissCount, sizeof(fCacheMissCount)); }
74*c8dee2aaSAndroid Build Coastguard Worker ~DiscardableManager() override = default;
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker // Server implementation.
createHandle()77*c8dee2aaSAndroid Build Coastguard Worker SkDiscardableHandleId createHandle() override {
78*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker // Handles starts as locked.
81*c8dee2aaSAndroid Build Coastguard Worker fLockedHandles.add(++fNextHandleId);
82*c8dee2aaSAndroid Build Coastguard Worker return fNextHandleId;
83*c8dee2aaSAndroid Build Coastguard Worker }
lockHandle(SkDiscardableHandleId id)84*c8dee2aaSAndroid Build Coastguard Worker bool lockHandle(SkDiscardableHandleId id) override {
85*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker if (id <= fLastDeletedHandleId) return false;
88*c8dee2aaSAndroid Build Coastguard Worker fLockedHandles.add(id);
89*c8dee2aaSAndroid Build Coastguard Worker return true;
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker // Client implementation.
deleteHandle(SkDiscardableHandleId id)93*c8dee2aaSAndroid Build Coastguard Worker bool deleteHandle(SkDiscardableHandleId id) override {
94*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
95*c8dee2aaSAndroid Build Coastguard Worker
96*c8dee2aaSAndroid Build Coastguard Worker return id <= fLastDeletedHandleId;
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
notifyCacheMiss(SkStrikeClient::CacheMissType type,int fontSize)99*c8dee2aaSAndroid Build Coastguard Worker void notifyCacheMiss(SkStrikeClient::CacheMissType type, int fontSize) override {
100*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker fCacheMissCount[type]++;
103*c8dee2aaSAndroid Build Coastguard Worker }
isHandleDeleted(SkDiscardableHandleId id)104*c8dee2aaSAndroid Build Coastguard Worker bool isHandleDeleted(SkDiscardableHandleId id) override {
105*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
106*c8dee2aaSAndroid Build Coastguard Worker
107*c8dee2aaSAndroid Build Coastguard Worker return id <= fLastDeletedHandleId;
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker
unlockAll()110*c8dee2aaSAndroid Build Coastguard Worker void unlockAll() {
111*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker fLockedHandles.reset();
114*c8dee2aaSAndroid Build Coastguard Worker }
unlockAndDeleteAll()115*c8dee2aaSAndroid Build Coastguard Worker void unlockAndDeleteAll() {
116*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
117*c8dee2aaSAndroid Build Coastguard Worker
118*c8dee2aaSAndroid Build Coastguard Worker fLockedHandles.reset();
119*c8dee2aaSAndroid Build Coastguard Worker fLastDeletedHandleId = fNextHandleId;
120*c8dee2aaSAndroid Build Coastguard Worker }
lockedHandles() const121*c8dee2aaSAndroid Build Coastguard Worker const THashSet<SkDiscardableHandleId>& lockedHandles() const {
122*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
123*c8dee2aaSAndroid Build Coastguard Worker
124*c8dee2aaSAndroid Build Coastguard Worker return fLockedHandles;
125*c8dee2aaSAndroid Build Coastguard Worker }
handleCount()126*c8dee2aaSAndroid Build Coastguard Worker SkDiscardableHandleId handleCount() {
127*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker return fNextHandleId;
130*c8dee2aaSAndroid Build Coastguard Worker }
cacheMissCount(uint32_t type)131*c8dee2aaSAndroid Build Coastguard Worker int cacheMissCount(uint32_t type) {
132*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker return fCacheMissCount[type];
135*c8dee2aaSAndroid Build Coastguard Worker }
hasCacheMiss() const136*c8dee2aaSAndroid Build Coastguard Worker bool hasCacheMiss() const {
137*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
138*c8dee2aaSAndroid Build Coastguard Worker
139*c8dee2aaSAndroid Build Coastguard Worker for (uint32_t i = 0; i <= SkStrikeClient::CacheMissType::kLast; ++i) {
140*c8dee2aaSAndroid Build Coastguard Worker if (fCacheMissCount[i] > 0) { return true; }
141*c8dee2aaSAndroid Build Coastguard Worker }
142*c8dee2aaSAndroid Build Coastguard Worker return false;
143*c8dee2aaSAndroid Build Coastguard Worker }
resetCacheMissCounts()144*c8dee2aaSAndroid Build Coastguard Worker void resetCacheMissCounts() {
145*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive l(fMutex);
146*c8dee2aaSAndroid Build Coastguard Worker sk_bzero(&fCacheMissCount, sizeof(fCacheMissCount));
147*c8dee2aaSAndroid Build Coastguard Worker }
148*c8dee2aaSAndroid Build Coastguard Worker
149*c8dee2aaSAndroid Build Coastguard Worker private:
150*c8dee2aaSAndroid Build Coastguard Worker // The tests below run in parallel on multiple threads and use the same
151*c8dee2aaSAndroid Build Coastguard Worker // process global SkStrikeCache. So the implementation needs to be
152*c8dee2aaSAndroid Build Coastguard Worker // thread-safe.
153*c8dee2aaSAndroid Build Coastguard Worker mutable SkMutex fMutex;
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker SkDiscardableHandleId fNextHandleId = 0u;
156*c8dee2aaSAndroid Build Coastguard Worker SkDiscardableHandleId fLastDeletedHandleId = 0u;
157*c8dee2aaSAndroid Build Coastguard Worker THashSet<SkDiscardableHandleId> fLockedHandles;
158*c8dee2aaSAndroid Build Coastguard Worker int fCacheMissCount[SkStrikeClient::CacheMissType::kLast + 1u];
159*c8dee2aaSAndroid Build Coastguard Worker };
160*c8dee2aaSAndroid Build Coastguard Worker
buildTextBlob(sk_sp<SkTypeface> tf,int glyphCount,int textSize=1)161*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> buildTextBlob(sk_sp<SkTypeface> tf, int glyphCount, int textSize = 1) {
162*c8dee2aaSAndroid Build Coastguard Worker SkFont font;
163*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(tf);
164*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(tf);
165*c8dee2aaSAndroid Build Coastguard Worker font.setHinting(SkFontHinting::kNormal);
166*c8dee2aaSAndroid Build Coastguard Worker font.setSize(textSize);
167*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kAntiAlias);
168*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel(true);
169*c8dee2aaSAndroid Build Coastguard Worker
170*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder builder;
171*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = SkRect::MakeWH(10, 10);
172*c8dee2aaSAndroid Build Coastguard Worker const auto& runBuffer = builder.allocRunPosH(font, glyphCount, 0, &bounds);
173*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(runBuffer.utf8text == nullptr);
174*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(runBuffer.clusters == nullptr);
175*c8dee2aaSAndroid Build Coastguard Worker
176*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < glyphCount; i++) {
177*c8dee2aaSAndroid Build Coastguard Worker runBuffer.glyphs[i] = static_cast<SkGlyphID>(i);
178*c8dee2aaSAndroid Build Coastguard Worker runBuffer.pos[i] = SkIntToScalar(i);
179*c8dee2aaSAndroid Build Coastguard Worker }
180*c8dee2aaSAndroid Build Coastguard Worker return builder.make();
181*c8dee2aaSAndroid Build Coastguard Worker }
182*c8dee2aaSAndroid Build Coastguard Worker
compare_blobs(const SkBitmap & expected,const SkBitmap & actual,skiatest::Reporter * reporter,int tolerance=0)183*c8dee2aaSAndroid Build Coastguard Worker static void compare_blobs(const SkBitmap& expected, const SkBitmap& actual,
184*c8dee2aaSAndroid Build Coastguard Worker skiatest::Reporter* reporter, int tolerance = 0) {
185*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(expected.width() == actual.width());
186*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(expected.height() == actual.height());
187*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < expected.width(); ++i) {
188*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < expected.height(); ++j) {
189*c8dee2aaSAndroid Build Coastguard Worker SkColor expectedColor = expected.getColor(i, j);
190*c8dee2aaSAndroid Build Coastguard Worker SkColor actualColor = actual.getColor(i, j);
191*c8dee2aaSAndroid Build Coastguard Worker if (0 == tolerance) {
192*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expectedColor == actualColor);
193*c8dee2aaSAndroid Build Coastguard Worker } else {
194*c8dee2aaSAndroid Build Coastguard Worker for (int k = 0; k < 4; ++k) {
195*c8dee2aaSAndroid Build Coastguard Worker int expectedChannel = (expectedColor >> (k*8)) & 0xff;
196*c8dee2aaSAndroid Build Coastguard Worker int actualChannel = (actualColor >> (k*8)) & 0xff;
197*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, abs(expectedChannel - actualChannel) <= tolerance);
198*c8dee2aaSAndroid Build Coastguard Worker }
199*c8dee2aaSAndroid Build Coastguard Worker }
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker }
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker
MakeSurface(int width,int height,GrRecordingContext * rContext)204*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> MakeSurface(int width, int height, GrRecordingContext* rContext) {
205*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo info =
206*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
207*c8dee2aaSAndroid Build Coastguard Worker return SkSurfaces::RenderTarget(rContext, skgpu::Budgeted::kNo, info);
208*c8dee2aaSAndroid Build Coastguard Worker }
209*c8dee2aaSAndroid Build Coastguard Worker
FindSurfaceProps(GrRecordingContext * rContext)210*c8dee2aaSAndroid Build Coastguard Worker SkSurfaceProps FindSurfaceProps(GrRecordingContext* rContext) {
211*c8dee2aaSAndroid Build Coastguard Worker auto surface = MakeSurface(1, 1, rContext);
212*c8dee2aaSAndroid Build Coastguard Worker return surface->props();
213*c8dee2aaSAndroid Build Coastguard Worker }
214*c8dee2aaSAndroid Build Coastguard Worker
RasterBlob(sk_sp<SkTextBlob> blob,int width,int height,const SkPaint & paint,GrRecordingContext * rContext,const SkMatrix * matrix=nullptr,SkScalar x=0)215*c8dee2aaSAndroid Build Coastguard Worker SkBitmap RasterBlob(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint& paint,
216*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext, const SkMatrix* matrix = nullptr,
217*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = 0) {
218*c8dee2aaSAndroid Build Coastguard Worker auto surface = MakeSurface(width, height, rContext);
219*c8dee2aaSAndroid Build Coastguard Worker if (matrix) {
220*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->concat(*matrix);
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawTextBlob(blob.get(), x, height/2, paint);
223*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
224*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocN32Pixels(width, height);
225*c8dee2aaSAndroid Build Coastguard Worker surface->readPixels(bitmap, 0, 0);
226*c8dee2aaSAndroid Build Coastguard Worker return bitmap;
227*c8dee2aaSAndroid Build Coastguard Worker }
228*c8dee2aaSAndroid Build Coastguard Worker
RasterBlobThroughSlug(sk_sp<SkTextBlob> blob,int width,int height,const SkPaint & paint,GrRecordingContext * rContext,const SkMatrix * matrix=nullptr,SkScalar x=0)229*c8dee2aaSAndroid Build Coastguard Worker SkBitmap RasterBlobThroughSlug(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint& paint,
230*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext, const SkMatrix* matrix = nullptr,
231*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = 0) {
232*c8dee2aaSAndroid Build Coastguard Worker auto surface = MakeSurface(width, height, rContext);
233*c8dee2aaSAndroid Build Coastguard Worker if (matrix) {
234*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->concat(*matrix);
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker auto canvas = surface->getCanvas();
237*c8dee2aaSAndroid Build Coastguard Worker auto slug = Slug::ConvertBlob(canvas, *blob, {x, height/2.0f}, paint);
238*c8dee2aaSAndroid Build Coastguard Worker slug->draw(canvas, paint);
239*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
240*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocN32Pixels(width, height);
241*c8dee2aaSAndroid Build Coastguard Worker surface->readPixels(bitmap, 0, 0);
242*c8dee2aaSAndroid Build Coastguard Worker return bitmap;
243*c8dee2aaSAndroid Build Coastguard Worker }
244*c8dee2aaSAndroid Build Coastguard Worker
RasterSlug(sk_sp<Slug> slug,int width,int height,const SkPaint & paint,GrRecordingContext * rContext,const SkMatrix * matrix=nullptr,SkScalar x=0)245*c8dee2aaSAndroid Build Coastguard Worker SkBitmap RasterSlug(sk_sp<Slug> slug, int width, int height, const SkPaint& paint,
246*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext, const SkMatrix* matrix = nullptr,
247*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = 0) {
248*c8dee2aaSAndroid Build Coastguard Worker auto surface = MakeSurface(width, height, rContext);
249*c8dee2aaSAndroid Build Coastguard Worker auto canvas = surface->getCanvas();
250*c8dee2aaSAndroid Build Coastguard Worker if (matrix) {
251*c8dee2aaSAndroid Build Coastguard Worker canvas->concat(*matrix);
252*c8dee2aaSAndroid Build Coastguard Worker }
253*c8dee2aaSAndroid Build Coastguard Worker slug->draw(canvas, paint);
254*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
255*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocN32Pixels(width, height);
256*c8dee2aaSAndroid Build Coastguard Worker surface->readPixels(bitmap, 0, 0);
257*c8dee2aaSAndroid Build Coastguard Worker return bitmap;
258*c8dee2aaSAndroid Build Coastguard Worker }
259*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_StrikeSerialization,reporter,ctxInfo,CtsEnforcement::kNever)260*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_StrikeSerialization,
261*c8dee2aaSAndroid Build Coastguard Worker reporter,
262*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
263*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
264*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
265*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
266*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
267*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
268*c8dee2aaSAndroid Build Coastguard Worker const SkPaint paint;
269*c8dee2aaSAndroid Build Coastguard Worker
270*c8dee2aaSAndroid Build Coastguard Worker // Server.
271*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
272*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
273*c8dee2aaSAndroid Build Coastguard Worker
274*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
275*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
276*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(dContext);
277*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> analysisCanvas = server.makeAnalysisCanvas(
278*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, dContext->supportsDistanceFieldText(),
279*c8dee2aaSAndroid Build Coastguard Worker !dContext->priv().caps()->disablePerspectiveSDFText());
280*c8dee2aaSAndroid Build Coastguard Worker analysisCanvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
281*c8dee2aaSAndroid Build Coastguard Worker
282*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
283*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
284*c8dee2aaSAndroid Build Coastguard Worker
285*c8dee2aaSAndroid Build Coastguard Worker // Client.
286*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
287*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
288*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker // Ensure typeface serialization/deserialization worked.
291*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
292*c8dee2aaSAndroid Build Coastguard Worker static_cast<SkTypefaceProxy*>(clientTypeface.get())->remoteTypefaceID() ==
293*c8dee2aaSAndroid Build Coastguard Worker serverTypefaceID);
294*c8dee2aaSAndroid Build Coastguard Worker
295*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount);
296*c8dee2aaSAndroid Build Coastguard Worker
297*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlob(serverBlob, 10, 10, paint, dContext);
298*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, dContext);
299*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
300*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
301*c8dee2aaSAndroid Build Coastguard Worker
302*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
303*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker
use_padding_options(GrContextOptions * options)306*c8dee2aaSAndroid Build Coastguard Worker static void use_padding_options(GrContextOptions* options) {
307*c8dee2aaSAndroid Build Coastguard Worker options->fSupportBilerpFromGlyphAtlas = true;
308*c8dee2aaSAndroid Build Coastguard Worker }
309*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlug,skgpu::IsRenderingContext,reporter,ctxInfo,use_padding_options,CtsEnforcement::kNever)310*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlug,
311*c8dee2aaSAndroid Build Coastguard Worker skgpu::IsRenderingContext,
312*c8dee2aaSAndroid Build Coastguard Worker reporter,
313*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
314*c8dee2aaSAndroid Build Coastguard Worker use_padding_options,
315*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
316*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
317*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
318*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
319*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
320*c8dee2aaSAndroid Build Coastguard Worker const SkPaint paint;
321*c8dee2aaSAndroid Build Coastguard Worker
322*c8dee2aaSAndroid Build Coastguard Worker // Server.
323*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
324*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
325*c8dee2aaSAndroid Build Coastguard Worker
326*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
327*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
328*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(dContext);
329*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> analysisCanvas = server.makeAnalysisCanvas(
330*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, dContext->supportsDistanceFieldText(),
331*c8dee2aaSAndroid Build Coastguard Worker !dContext->priv().caps()->disablePerspectiveSDFText());
332*c8dee2aaSAndroid Build Coastguard Worker
333*c8dee2aaSAndroid Build Coastguard Worker // Generate strike updates.
334*c8dee2aaSAndroid Build Coastguard Worker (void)Slug::ConvertBlob(analysisCanvas.get(), *serverBlob, {0, 0}, paint);
335*c8dee2aaSAndroid Build Coastguard Worker
336*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
337*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
338*c8dee2aaSAndroid Build Coastguard Worker
339*c8dee2aaSAndroid Build Coastguard Worker // Client.
340*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
341*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
342*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
343*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount);
344*c8dee2aaSAndroid Build Coastguard Worker
345*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlobThroughSlug(serverBlob, 10, 10, paint, dContext);
346*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlobThroughSlug(clientBlob, 10, 10, paint, dContext);
347*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
348*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
349*c8dee2aaSAndroid Build Coastguard Worker
350*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
351*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
352*c8dee2aaSAndroid Build Coastguard Worker }
353*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlugForcePath,skgpu::IsRenderingContext,reporter,ctxInfo,use_padding_options,CtsEnforcement::kNever)354*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlugForcePath,
355*c8dee2aaSAndroid Build Coastguard Worker skgpu::IsRenderingContext,
356*c8dee2aaSAndroid Build Coastguard Worker reporter,
357*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
358*c8dee2aaSAndroid Build Coastguard Worker use_padding_options,
359*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
360*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
361*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
362*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
363*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
364*c8dee2aaSAndroid Build Coastguard Worker const SkPaint paint;
365*c8dee2aaSAndroid Build Coastguard Worker
366*c8dee2aaSAndroid Build Coastguard Worker // Server.
367*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
368*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
369*c8dee2aaSAndroid Build Coastguard Worker
370*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
371*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount, 360);
372*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(dContext);
373*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> analysisCanvas = server.makeAnalysisCanvas(
374*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, dContext->supportsDistanceFieldText(),
375*c8dee2aaSAndroid Build Coastguard Worker !dContext->priv().caps()->disablePerspectiveSDFText());
376*c8dee2aaSAndroid Build Coastguard Worker
377*c8dee2aaSAndroid Build Coastguard Worker // Generate strike updates.
378*c8dee2aaSAndroid Build Coastguard Worker (void)Slug::ConvertBlob(analysisCanvas.get(), *serverBlob, {0, 0}, paint);
379*c8dee2aaSAndroid Build Coastguard Worker
380*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
381*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
382*c8dee2aaSAndroid Build Coastguard Worker
383*c8dee2aaSAndroid Build Coastguard Worker // Client.
384*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
385*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
386*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
387*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount, 360);
388*c8dee2aaSAndroid Build Coastguard Worker
389*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlobThroughSlug(serverBlob, 10, 10, paint, dContext);
390*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlobThroughSlug(clientBlob, 10, 10, paint, dContext);
391*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
392*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
393*c8dee2aaSAndroid Build Coastguard Worker
394*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
395*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
396*c8dee2aaSAndroid Build Coastguard Worker }
397*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_SlugSerialization,skgpu::IsRenderingContext,reporter,ctxInfo,use_padding_options,CtsEnforcement::kNever)398*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_SlugSerialization,
399*c8dee2aaSAndroid Build Coastguard Worker skgpu::IsRenderingContext,
400*c8dee2aaSAndroid Build Coastguard Worker reporter,
401*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
402*c8dee2aaSAndroid Build Coastguard Worker use_padding_options,
403*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
404*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
405*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
406*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
407*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
408*c8dee2aaSAndroid Build Coastguard Worker const SkPaint paint;
409*c8dee2aaSAndroid Build Coastguard Worker
410*c8dee2aaSAndroid Build Coastguard Worker // Server.
411*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
412*c8dee2aaSAndroid Build Coastguard Worker
413*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
414*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
415*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(dContext);
416*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> analysisCanvas = server.makeAnalysisCanvas(
417*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, dContext->supportsDistanceFieldText(),
418*c8dee2aaSAndroid Build Coastguard Worker !dContext->priv().caps()->disablePerspectiveSDFText());
419*c8dee2aaSAndroid Build Coastguard Worker
420*c8dee2aaSAndroid Build Coastguard Worker // Generate strike updates.
421*c8dee2aaSAndroid Build Coastguard Worker auto srcSlug = Slug::ConvertBlob(analysisCanvas.get(), *serverBlob, {0.3f, 0}, paint);
422*c8dee2aaSAndroid Build Coastguard Worker auto dstSlugData = srcSlug->serialize();
423*c8dee2aaSAndroid Build Coastguard Worker
424*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
425*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
426*c8dee2aaSAndroid Build Coastguard Worker
427*c8dee2aaSAndroid Build Coastguard Worker // Client.
428*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
429*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
430*c8dee2aaSAndroid Build Coastguard Worker
431*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterSlug(srcSlug, 10, 10, paint, dContext);
432*c8dee2aaSAndroid Build Coastguard Worker auto dstSlug = client.deserializeSlugForTest(dstSlugData->data(), dstSlugData->size());
433*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, dstSlug != nullptr);
434*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterSlug(dstSlug, 10, 10, paint, dContext);
435*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
436*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
437*c8dee2aaSAndroid Build Coastguard Worker
438*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
439*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
440*c8dee2aaSAndroid Build Coastguard Worker }
441*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_ReleaseTypeFace,reporter,ctxInfo,CtsEnforcement::kNever)442*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_ReleaseTypeFace,
443*c8dee2aaSAndroid Build Coastguard Worker reporter,
444*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
445*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
446*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
447*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
448*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
449*c8dee2aaSAndroid Build Coastguard Worker
450*c8dee2aaSAndroid Build Coastguard Worker // Server.
451*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = TestEmptyTypeface::Make();
452*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, serverTypeface->unique());
453*c8dee2aaSAndroid Build Coastguard Worker
454*c8dee2aaSAndroid Build Coastguard Worker {
455*c8dee2aaSAndroid Build Coastguard Worker const SkPaint paint;
456*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
457*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
458*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
459*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
460*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, ctxInfo.directContext()->supportsDistanceFieldText(),
461*c8dee2aaSAndroid Build Coastguard Worker !ctxInfo.directContext()->priv().caps()->disablePerspectiveSDFText());
462*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
463*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !serverTypeface->unique());
464*c8dee2aaSAndroid Build Coastguard Worker
465*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
466*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
467*c8dee2aaSAndroid Build Coastguard Worker }
468*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, serverTypeface->unique());
469*c8dee2aaSAndroid Build Coastguard Worker
470*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
471*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
472*c8dee2aaSAndroid Build Coastguard Worker }
473*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkRemoteGlyphCache_StrikeLockingServer,reporter)474*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkRemoteGlyphCache_StrikeLockingServer, reporter) {
475*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
476*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
477*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
478*c8dee2aaSAndroid Build Coastguard Worker
479*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
480*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
481*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
482*c8dee2aaSAndroid Build Coastguard Worker
483*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
484*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas =
485*c8dee2aaSAndroid Build Coastguard Worker server.makeAnalysisCanvas(10, 10, props, nullptr, true, true);
486*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
487*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
488*c8dee2aaSAndroid Build Coastguard Worker
489*c8dee2aaSAndroid Build Coastguard Worker // The strike from the blob should be locked after it has been drawn on the canvas.
490*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->handleCount() == 1u);
491*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->lockedHandles().count() == 1u);
492*c8dee2aaSAndroid Build Coastguard Worker
493*c8dee2aaSAndroid Build Coastguard Worker // Write the strike data and unlock everything. Re-analyzing the blob should lock the handle
494*c8dee2aaSAndroid Build Coastguard Worker // again.
495*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> fontData;
496*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&fontData);
497*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAll();
498*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->lockedHandles().count() == 0u);
499*c8dee2aaSAndroid Build Coastguard Worker
500*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
501*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->handleCount() == 1u);
502*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->lockedHandles().count() == 1u);
503*c8dee2aaSAndroid Build Coastguard Worker
504*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
505*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
506*c8dee2aaSAndroid Build Coastguard Worker }
507*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkRemoteGlyphCache_StrikeDeletionServer,reporter)508*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkRemoteGlyphCache_StrikeDeletionServer, reporter) {
509*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
510*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
511*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
512*c8dee2aaSAndroid Build Coastguard Worker
513*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
514*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
515*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
516*c8dee2aaSAndroid Build Coastguard Worker
517*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
518*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas =
519*c8dee2aaSAndroid Build Coastguard Worker server.makeAnalysisCanvas(10, 10, props, nullptr, true, true);
520*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
521*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
522*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->handleCount() == 1u);
523*c8dee2aaSAndroid Build Coastguard Worker
524*c8dee2aaSAndroid Build Coastguard Worker // Write the strike data and delete all the handles. Re-analyzing the blob should create new
525*c8dee2aaSAndroid Build Coastguard Worker // handles.
526*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> fontData;
527*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&fontData);
528*c8dee2aaSAndroid Build Coastguard Worker
529*c8dee2aaSAndroid Build Coastguard Worker // Another analysis pass, to ensure that deleting handles after a complete cache hit still
530*c8dee2aaSAndroid Build Coastguard Worker // works. This is a regression test for crbug.com/999682.
531*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
532*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&fontData);
533*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->handleCount() == 1u);
534*c8dee2aaSAndroid Build Coastguard Worker
535*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
536*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
537*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->handleCount() == 2u);
538*c8dee2aaSAndroid Build Coastguard Worker
539*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
540*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
541*c8dee2aaSAndroid Build Coastguard Worker }
542*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkRemoteGlyphCache_StrikePinningClient,reporter)543*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkRemoteGlyphCache_StrikePinningClient, reporter) {
544*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
545*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
546*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
547*c8dee2aaSAndroid Build Coastguard Worker
548*c8dee2aaSAndroid Build Coastguard Worker // Server.
549*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
550*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
551*c8dee2aaSAndroid Build Coastguard Worker
552*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
553*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
554*c8dee2aaSAndroid Build Coastguard Worker
555*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
556*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas =
557*c8dee2aaSAndroid Build Coastguard Worker server.makeAnalysisCanvas(10, 10, props, nullptr, true, true);
558*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
559*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
560*c8dee2aaSAndroid Build Coastguard Worker
561*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
562*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
563*c8dee2aaSAndroid Build Coastguard Worker
564*c8dee2aaSAndroid Build Coastguard Worker // Client.
565*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
566*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
567*c8dee2aaSAndroid Build Coastguard Worker auto* clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID).get();
568*c8dee2aaSAndroid Build Coastguard Worker
569*c8dee2aaSAndroid Build Coastguard Worker // The cache remains alive until it is pinned in the discardable manager.
570*c8dee2aaSAndroid Build Coastguard Worker SkGraphics::PurgeFontCache();
571*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !clientTypeface->unique());
572*c8dee2aaSAndroid Build Coastguard Worker
573*c8dee2aaSAndroid Build Coastguard Worker // Once the strike is unpinned and purged, SkStrikeClient should be the only owner of the
574*c8dee2aaSAndroid Build Coastguard Worker // clientTf.
575*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
576*c8dee2aaSAndroid Build Coastguard Worker SkGraphics::PurgeFontCache();
577*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientTypeface->unique());
578*c8dee2aaSAndroid Build Coastguard Worker
579*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
580*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
581*c8dee2aaSAndroid Build Coastguard Worker }
582*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkRemoteGlyphCache_ClientMemoryAccounting,reporter)583*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkRemoteGlyphCache_ClientMemoryAccounting, reporter) {
584*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
585*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
586*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
587*c8dee2aaSAndroid Build Coastguard Worker
588*c8dee2aaSAndroid Build Coastguard Worker // Server.
589*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
590*c8dee2aaSAndroid Build Coastguard Worker
591*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
592*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
593*c8dee2aaSAndroid Build Coastguard Worker
594*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
595*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas =
596*c8dee2aaSAndroid Build Coastguard Worker server.makeAnalysisCanvas(10, 10, props, nullptr, true, true);
597*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
598*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
599*c8dee2aaSAndroid Build Coastguard Worker
600*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
601*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
602*c8dee2aaSAndroid Build Coastguard Worker
603*c8dee2aaSAndroid Build Coastguard Worker // Client.
604*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
605*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
606*c8dee2aaSAndroid Build Coastguard Worker
607*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
608*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
609*c8dee2aaSAndroid Build Coastguard Worker }
610*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkRemoteGlyphCache_PurgesServerEntries,reporter)611*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkRemoteGlyphCache_PurgesServerEntries, reporter) {
612*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
613*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
614*c8dee2aaSAndroid Build Coastguard Worker server.setMaxEntriesInDescriptorMapForTesting(1u);
615*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
616*c8dee2aaSAndroid Build Coastguard Worker
617*c8dee2aaSAndroid Build Coastguard Worker {
618*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
619*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
620*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
621*c8dee2aaSAndroid Build Coastguard Worker
622*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
623*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas =
624*c8dee2aaSAndroid Build Coastguard Worker server.makeAnalysisCanvas(10, 10, props, nullptr, true, true);
625*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
626*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, server.remoteStrikeMapSizeForTesting() == 0u);
627*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
628*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, server.remoteStrikeMapSizeForTesting() == 1u);
629*c8dee2aaSAndroid Build Coastguard Worker }
630*c8dee2aaSAndroid Build Coastguard Worker
631*c8dee2aaSAndroid Build Coastguard Worker // Serialize to release the lock from the strike server and delete all current
632*c8dee2aaSAndroid Build Coastguard Worker // handles.
633*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> fontData;
634*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&fontData);
635*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
636*c8dee2aaSAndroid Build Coastguard Worker
637*c8dee2aaSAndroid Build Coastguard Worker // Use a different typeface. Creating a new strike should evict the previous
638*c8dee2aaSAndroid Build Coastguard Worker // one.
639*c8dee2aaSAndroid Build Coastguard Worker {
640*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("Georgia", SkFontStyle());
641*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
642*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
643*c8dee2aaSAndroid Build Coastguard Worker
644*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
645*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas =
646*c8dee2aaSAndroid Build Coastguard Worker server.makeAnalysisCanvas(10, 10, props, nullptr, true, true);
647*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
648*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, server.remoteStrikeMapSizeForTesting() == 1u);
649*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
650*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, server.remoteStrikeMapSizeForTesting() == 1u);
651*c8dee2aaSAndroid Build Coastguard Worker }
652*c8dee2aaSAndroid Build Coastguard Worker
653*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
654*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
655*c8dee2aaSAndroid Build Coastguard Worker }
656*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsPath,reporter,ctxInfo,CtsEnforcement::kNever)657*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsPath,
658*c8dee2aaSAndroid Build Coastguard Worker reporter,
659*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
660*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
661*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
662*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
663*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
664*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
665*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
666*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
667*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(0);
668*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
669*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
670*c8dee2aaSAndroid Build Coastguard Worker SkStrikeSpec::ShouldDrawAsPath(paint, font, SkMatrix::I()));
671*c8dee2aaSAndroid Build Coastguard Worker
672*c8dee2aaSAndroid Build Coastguard Worker // Server.
673*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
674*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
675*c8dee2aaSAndroid Build Coastguard Worker
676*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
677*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
678*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(direct);
679*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
680*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, direct->supportsDistanceFieldText(),
681*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
682*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
683*c8dee2aaSAndroid Build Coastguard Worker
684*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
685*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
686*c8dee2aaSAndroid Build Coastguard Worker
687*c8dee2aaSAndroid Build Coastguard Worker // Client.
688*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
689*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
690*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
691*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount);
692*c8dee2aaSAndroid Build Coastguard Worker
693*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlob(serverBlob, 10, 10, paint, direct);
694*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, direct);
695*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter, 1);
696*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
697*c8dee2aaSAndroid Build Coastguard Worker
698*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
699*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
700*c8dee2aaSAndroid Build Coastguard Worker }
701*c8dee2aaSAndroid Build Coastguard Worker
make_blob_causing_fallback(sk_sp<SkTypeface> targetTf,const SkTypeface * glyphTf,skiatest::Reporter * reporter)702*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> make_blob_causing_fallback(
703*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> targetTf, const SkTypeface* glyphTf, skiatest::Reporter* reporter) {
704*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
705*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel(true);
706*c8dee2aaSAndroid Build Coastguard Worker font.setSize(96);
707*c8dee2aaSAndroid Build Coastguard Worker font.setHinting(SkFontHinting::kNormal);
708*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(targetTf);
709*c8dee2aaSAndroid Build Coastguard Worker
710*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
711*c8dee2aaSAndroid Build Coastguard Worker !SkStrikeSpec::ShouldDrawAsPath(SkPaint(), font, SkMatrix::I()));
712*c8dee2aaSAndroid Build Coastguard Worker
713*c8dee2aaSAndroid Build Coastguard Worker char s[] = "Skia";
714*c8dee2aaSAndroid Build Coastguard Worker int runSize = strlen(s);
715*c8dee2aaSAndroid Build Coastguard Worker
716*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder builder;
717*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = SkRect::MakeIWH(100, 100);
718*c8dee2aaSAndroid Build Coastguard Worker const auto& runBuffer = builder.allocRunPosH(font, runSize, 10, &bounds);
719*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(runBuffer.utf8text == nullptr);
720*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(runBuffer.clusters == nullptr);
721*c8dee2aaSAndroid Build Coastguard Worker
722*c8dee2aaSAndroid Build Coastguard Worker SkFont(sk_ref_sp(glyphTf)).textToGlyphs(s, strlen(s), SkTextEncoding::kUTF8,
723*c8dee2aaSAndroid Build Coastguard Worker runBuffer.glyphs, runSize);
724*c8dee2aaSAndroid Build Coastguard Worker
725*c8dee2aaSAndroid Build Coastguard Worker SkRect glyphBounds;
726*c8dee2aaSAndroid Build Coastguard Worker font.getWidths(runBuffer.glyphs, 1, nullptr, &glyphBounds);
727*c8dee2aaSAndroid Build Coastguard Worker
728*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, glyphBounds.width() > SkGlyphDigest::kSkSideTooBigForAtlas);
729*c8dee2aaSAndroid Build Coastguard Worker
730*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < runSize; i++) {
731*c8dee2aaSAndroid Build Coastguard Worker runBuffer.pos[i] = i * 10;
732*c8dee2aaSAndroid Build Coastguard Worker }
733*c8dee2aaSAndroid Build Coastguard Worker
734*c8dee2aaSAndroid Build Coastguard Worker return builder.make();
735*c8dee2aaSAndroid Build Coastguard Worker }
736*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsMaskWithPathFallback,reporter,ctxInfo,CtsEnforcement::kNever)737*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsMaskWithPathFallback,
738*c8dee2aaSAndroid Build Coastguard Worker reporter,
739*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
740*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
741*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
742*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
743*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
744*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
745*c8dee2aaSAndroid Build Coastguard Worker
746*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
747*c8dee2aaSAndroid Build Coastguard Worker
748*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTypefaceFromResource("fonts/HangingS.ttf");
749*c8dee2aaSAndroid Build Coastguard Worker // TODO: when the cq bots can handle this font remove the check.
750*c8dee2aaSAndroid Build Coastguard Worker if (serverTypeface == nullptr) {
751*c8dee2aaSAndroid Build Coastguard Worker return;
752*c8dee2aaSAndroid Build Coastguard Worker }
753*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
754*c8dee2aaSAndroid Build Coastguard Worker
755*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = make_blob_causing_fallback(serverTypeface, serverTypeface.get(), reporter);
756*c8dee2aaSAndroid Build Coastguard Worker
757*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(direct);
758*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
759*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, direct->supportsDistanceFieldText(),
760*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
761*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
762*c8dee2aaSAndroid Build Coastguard Worker
763*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
764*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
765*c8dee2aaSAndroid Build Coastguard Worker
766*c8dee2aaSAndroid Build Coastguard Worker // Client.
767*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
768*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
769*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
770*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = make_blob_causing_fallback(clientTypeface, serverTypeface.get(), reporter);
771*c8dee2aaSAndroid Build Coastguard Worker
772*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlob(serverBlob, 10, 10, paint, direct);
773*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, direct);
774*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
775*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
776*c8dee2aaSAndroid Build Coastguard Worker
777*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
778*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
779*c8dee2aaSAndroid Build Coastguard Worker }
780*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextXY,reporter,ctxInfo,CtsEnforcement::kNever)781*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextXY,
782*c8dee2aaSAndroid Build Coastguard Worker reporter,
783*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
784*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
785*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
786*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
787*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
788*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
789*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
790*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
791*c8dee2aaSAndroid Build Coastguard Worker
792*c8dee2aaSAndroid Build Coastguard Worker // Server.
793*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
794*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
795*c8dee2aaSAndroid Build Coastguard Worker
796*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
797*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
798*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(direct);
799*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
800*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, direct->supportsDistanceFieldText(),
801*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
802*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0.5, 0, paint);
803*c8dee2aaSAndroid Build Coastguard Worker
804*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
805*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
806*c8dee2aaSAndroid Build Coastguard Worker
807*c8dee2aaSAndroid Build Coastguard Worker // Client.
808*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
809*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
810*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
811*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount);
812*c8dee2aaSAndroid Build Coastguard Worker
813*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlob(serverBlob, 10, 10, paint, direct, nullptr, 0.5);
814*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, direct, nullptr, 0.5);
815*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
816*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
817*c8dee2aaSAndroid Build Coastguard Worker
818*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
819*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
820*c8dee2aaSAndroid Build Coastguard Worker }
821*c8dee2aaSAndroid Build Coastguard Worker
822*c8dee2aaSAndroid Build Coastguard Worker #if !defined(SK_DISABLE_SDF_TEXT)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsDFT,reporter,ctxInfo,CtsEnforcement::kNever)823*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsDFT,
824*c8dee2aaSAndroid Build Coastguard Worker reporter,
825*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
826*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
827*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
828*c8dee2aaSAndroid Build Coastguard Worker if (!direct->priv().caps()->shaderCaps()->supportsDistanceFieldText()) {
829*c8dee2aaSAndroid Build Coastguard Worker return;
830*c8dee2aaSAndroid Build Coastguard Worker }
831*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
832*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
833*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
834*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
835*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
836*c8dee2aaSAndroid Build Coastguard Worker
837*c8dee2aaSAndroid Build Coastguard Worker // A scale transform forces fallback to dft.
838*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix = SkMatrix::Scale(16, 16);
839*c8dee2aaSAndroid Build Coastguard Worker sktext::gpu::SubRunControl control =
840*c8dee2aaSAndroid Build Coastguard Worker direct->priv().asRecordingContext()->priv().getSubRunControl(true);
841*c8dee2aaSAndroid Build Coastguard Worker SkScalar approximateDeviceTextSize = SkFontPriv::ApproximateTransformedTextSize(font, matrix,
842*c8dee2aaSAndroid Build Coastguard Worker {0, 0});
843*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, control.isSDFT(approximateDeviceTextSize, paint, matrix));
844*c8dee2aaSAndroid Build Coastguard Worker
845*c8dee2aaSAndroid Build Coastguard Worker // Server.
846*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
847*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
848*c8dee2aaSAndroid Build Coastguard Worker
849*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
850*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = buildTextBlob(serverTypeface, glyphCount);
851*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps props;
852*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
853*c8dee2aaSAndroid Build Coastguard Worker 10, 10, props, nullptr, direct->supportsDistanceFieldText(),
854*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
855*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->concat(matrix);
856*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0, paint);
857*c8dee2aaSAndroid Build Coastguard Worker
858*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
859*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
860*c8dee2aaSAndroid Build Coastguard Worker
861*c8dee2aaSAndroid Build Coastguard Worker // Client.
862*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
863*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
864*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
865*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount);
866*c8dee2aaSAndroid Build Coastguard Worker
867*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected = RasterBlob(serverBlob, 10, 10, paint, direct, &matrix);
868*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, direct, &matrix);
869*c8dee2aaSAndroid Build Coastguard Worker compare_blobs(expected, actual, reporter);
870*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
871*c8dee2aaSAndroid Build Coastguard Worker
872*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
873*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
874*c8dee2aaSAndroid Build Coastguard Worker }
875*c8dee2aaSAndroid Build Coastguard Worker #endif // !defined(SK_DISABLE_SDF_TEXT)
876*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_CacheMissReporting,reporter,ctxInfo,CtsEnforcement::kNever)877*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_CacheMissReporting,
878*c8dee2aaSAndroid Build Coastguard Worker reporter,
879*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
880*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
881*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
882*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
883*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
884*c8dee2aaSAndroid Build Coastguard Worker
885*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
886*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, serverTypeface);
887*c8dee2aaSAndroid Build Coastguard Worker
888*c8dee2aaSAndroid Build Coastguard Worker // Create the clientTypeface proxy directly from the serverTypeface.
889*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = sk_make_sp<SkTypefaceProxy>(
890*c8dee2aaSAndroid Build Coastguard Worker serverTypeface->uniqueID(),
891*c8dee2aaSAndroid Build Coastguard Worker serverTypeface->countGlyphs(),
892*c8dee2aaSAndroid Build Coastguard Worker serverTypeface->fontStyle(),
893*c8dee2aaSAndroid Build Coastguard Worker serverTypeface->isFixedPitch(),
894*c8dee2aaSAndroid Build Coastguard Worker /*glyphMaskNeedsCurrentColor=*/ false,
895*c8dee2aaSAndroid Build Coastguard Worker discardableManager,
896*c8dee2aaSAndroid Build Coastguard Worker /*isLogging=*/ false);
897*c8dee2aaSAndroid Build Coastguard Worker
898*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientTypeface);
899*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = 10;
900*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = buildTextBlob(clientTypeface, glyphCount);
901*c8dee2aaSAndroid Build Coastguard Worker
902*c8dee2aaSAndroid Build Coastguard Worker // Raster the client-side blob without the glyph data, we should get cache miss notifications.
903*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
904*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix = SkMatrix::I();
905*c8dee2aaSAndroid Build Coastguard Worker RasterBlob(clientBlob, 10, 10, paint, ctxInfo.directContext(), &matrix);
906*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
907*c8dee2aaSAndroid Build Coastguard Worker discardableManager->cacheMissCount(SkStrikeClient::kFontMetrics) == 1);
908*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
909*c8dee2aaSAndroid Build Coastguard Worker discardableManager->cacheMissCount(SkStrikeClient::kGlyphMetrics) == 10);
910*c8dee2aaSAndroid Build Coastguard Worker
911*c8dee2aaSAndroid Build Coastguard Worker // There shouldn't be any image or path requests, since we mark the glyph as empty on a cache
912*c8dee2aaSAndroid Build Coastguard Worker // miss.
913*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->cacheMissCount(SkStrikeClient::kGlyphImage) == 0);
914*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, discardableManager->cacheMissCount(SkStrikeClient::kGlyphPath) == 0);
915*c8dee2aaSAndroid Build Coastguard Worker
916*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
917*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
918*c8dee2aaSAndroid Build Coastguard Worker }
919*c8dee2aaSAndroid Build Coastguard Worker
MakeEmojiBlob(sk_sp<SkTypeface> serverTf,SkScalar textSize,sk_sp<SkTypeface> clientTf=nullptr)920*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> MakeEmojiBlob(sk_sp<SkTypeface> serverTf, SkScalar textSize,
921*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> clientTf = nullptr) {
922*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
923*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(serverTf);
924*c8dee2aaSAndroid Build Coastguard Worker font.setSize(textSize);
925*c8dee2aaSAndroid Build Coastguard Worker
926*c8dee2aaSAndroid Build Coastguard Worker const char* text = ToolUtils::EmojiSample().sampleText;
927*c8dee2aaSAndroid Build Coastguard Worker auto blob = SkTextBlob::MakeFromText(text, strlen(text), font);
928*c8dee2aaSAndroid Build Coastguard Worker if (clientTf == nullptr) return blob;
929*c8dee2aaSAndroid Build Coastguard Worker
930*c8dee2aaSAndroid Build Coastguard Worker SkSerialProcs s_procs;
931*c8dee2aaSAndroid Build Coastguard Worker s_procs.fTypefaceProc = [](SkTypeface*, void* ctx) -> sk_sp<SkData> {
932*c8dee2aaSAndroid Build Coastguard Worker return SkData::MakeUninitialized(1u);
933*c8dee2aaSAndroid Build Coastguard Worker };
934*c8dee2aaSAndroid Build Coastguard Worker auto serialized = blob->serialize(s_procs);
935*c8dee2aaSAndroid Build Coastguard Worker
936*c8dee2aaSAndroid Build Coastguard Worker SkDeserialProcs d_procs;
937*c8dee2aaSAndroid Build Coastguard Worker d_procs.fTypefaceCtx = &clientTf;
938*c8dee2aaSAndroid Build Coastguard Worker d_procs.fTypefaceProc = [](const void* data, size_t length, void* ctx) -> sk_sp<SkTypeface> {
939*c8dee2aaSAndroid Build Coastguard Worker return *(static_cast<sk_sp<SkTypeface>*>(ctx));
940*c8dee2aaSAndroid Build Coastguard Worker };
941*c8dee2aaSAndroid Build Coastguard Worker return SkTextBlob::Deserialize(serialized->data(), serialized->size(), d_procs);
942*c8dee2aaSAndroid Build Coastguard Worker }
943*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_TypefaceWithNoPaths,reporter,ctxInfo,CtsEnforcement::kNever)944*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_TypefaceWithNoPaths,
945*c8dee2aaSAndroid Build Coastguard Worker reporter,
946*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
947*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
948*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
949*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
950*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
951*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, false);
952*c8dee2aaSAndroid Build Coastguard Worker
953*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::EmojiSample().typeface;
954*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
955*c8dee2aaSAndroid Build Coastguard Worker
956*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(direct);
957*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
958*c8dee2aaSAndroid Build Coastguard Worker 500, 500, props, nullptr, direct->supportsDistanceFieldText(),
959*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
960*c8dee2aaSAndroid Build Coastguard Worker for (SkScalar textSize : { 70, 180, 270, 340}) {
961*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = MakeEmojiBlob(serverTypeface, textSize);
962*c8dee2aaSAndroid Build Coastguard Worker
963*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
964*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100, paint);
965*c8dee2aaSAndroid Build Coastguard Worker
966*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
967*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
968*c8dee2aaSAndroid Build Coastguard Worker if (!serverStrikeData.empty()) {
969*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
970*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(),
971*c8dee2aaSAndroid Build Coastguard Worker serverStrikeData.size()));
972*c8dee2aaSAndroid Build Coastguard Worker }
973*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
974*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = MakeEmojiBlob(serverTypeface, textSize, clientTypeface);
975*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientBlob);
976*c8dee2aaSAndroid Build Coastguard Worker
977*c8dee2aaSAndroid Build Coastguard Worker RasterBlob(clientBlob, 500, 500, paint, direct);
978*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
979*c8dee2aaSAndroid Build Coastguard Worker discardableManager->resetCacheMissCounts();
980*c8dee2aaSAndroid Build Coastguard Worker }
981*c8dee2aaSAndroid Build Coastguard Worker
982*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
983*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
984*c8dee2aaSAndroid Build Coastguard Worker }
985*c8dee2aaSAndroid Build Coastguard Worker
986*c8dee2aaSAndroid Build Coastguard Worker class SkRemoteGlyphCacheTest {
987*c8dee2aaSAndroid Build Coastguard Worker public:
MakeNormalBlob(SkPaint * paint,sk_sp<SkTypeface> serverTf,bool asPaths,SkScalar textSize,sk_sp<SkTypeface> clientTf=nullptr)988*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkTextBlob> MakeNormalBlob(SkPaint* paint,
989*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> serverTf, bool asPaths, SkScalar textSize,
990*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> clientTf = nullptr) {
991*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
992*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(serverTf);
993*c8dee2aaSAndroid Build Coastguard Worker font.setSize(textSize);
994*c8dee2aaSAndroid Build Coastguard Worker
995*c8dee2aaSAndroid Build Coastguard Worker const char* text = "Hel lo";
996*c8dee2aaSAndroid Build Coastguard Worker if (asPaths) {
997*c8dee2aaSAndroid Build Coastguard Worker font.setupForAsPaths(paint);
998*c8dee2aaSAndroid Build Coastguard Worker } else {
999*c8dee2aaSAndroid Build Coastguard Worker SkFont font2(font);
1000*c8dee2aaSAndroid Build Coastguard Worker font2.setupForAsPaths(paint);
1001*c8dee2aaSAndroid Build Coastguard Worker }
1002*c8dee2aaSAndroid Build Coastguard Worker auto blob = SkTextBlob::MakeFromText(text, strlen(text), font);
1003*c8dee2aaSAndroid Build Coastguard Worker if (clientTf == nullptr) return blob;
1004*c8dee2aaSAndroid Build Coastguard Worker
1005*c8dee2aaSAndroid Build Coastguard Worker SkSerialProcs s_procs;
1006*c8dee2aaSAndroid Build Coastguard Worker s_procs.fTypefaceProc = [](SkTypeface*, void* ctx) -> sk_sp<SkData> {
1007*c8dee2aaSAndroid Build Coastguard Worker return SkData::MakeUninitialized(1u);
1008*c8dee2aaSAndroid Build Coastguard Worker };
1009*c8dee2aaSAndroid Build Coastguard Worker auto serialized = blob->serialize(s_procs);
1010*c8dee2aaSAndroid Build Coastguard Worker
1011*c8dee2aaSAndroid Build Coastguard Worker SkDeserialProcs d_procs;
1012*c8dee2aaSAndroid Build Coastguard Worker d_procs.fTypefaceCtx = &clientTf;
1013*c8dee2aaSAndroid Build Coastguard Worker d_procs.fTypefaceProc = [](const void* data, size_t length, void* ctx) -> sk_sp<SkTypeface> {
1014*c8dee2aaSAndroid Build Coastguard Worker return *(static_cast<sk_sp<SkTypeface>*>(ctx));
1015*c8dee2aaSAndroid Build Coastguard Worker };
1016*c8dee2aaSAndroid Build Coastguard Worker return SkTextBlob::Deserialize(serialized->data(), serialized->size(), d_procs);
1017*c8dee2aaSAndroid Build Coastguard Worker }
1018*c8dee2aaSAndroid Build Coastguard Worker };
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_TypefaceWithPaths_MaskThenPath,reporter,ctxInfo,CtsEnforcement::kNever)1019*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_TypefaceWithPaths_MaskThenPath,
1020*c8dee2aaSAndroid Build Coastguard Worker reporter,
1021*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
1022*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
1023*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
1024*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
1025*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
1026*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, true);
1027*c8dee2aaSAndroid Build Coastguard Worker
1028*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::DefaultPortableTypeface();
1029*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
1030*c8dee2aaSAndroid Build Coastguard Worker
1031*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(direct);
1032*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
1033*c8dee2aaSAndroid Build Coastguard Worker 500, 500, props, nullptr, direct->supportsDistanceFieldText(),
1034*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
1035*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1036*c8dee2aaSAndroid Build Coastguard Worker using Rgct = SkRemoteGlyphCacheTest;
1037*c8dee2aaSAndroid Build Coastguard Worker
1038*c8dee2aaSAndroid Build Coastguard Worker // Draw from mask out of the strike which provides paths.
1039*c8dee2aaSAndroid Build Coastguard Worker {
1040*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, true, 64);
1041*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100, paint);
1042*c8dee2aaSAndroid Build Coastguard Worker }
1043*c8dee2aaSAndroid Build Coastguard Worker // Draw from path out of the strike which provides paths.
1044*c8dee2aaSAndroid Build Coastguard Worker {
1045*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, false, 440);
1046*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100, paint);
1047*c8dee2aaSAndroid Build Coastguard Worker }
1048*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
1049*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
1050*c8dee2aaSAndroid Build Coastguard Worker if (!serverStrikeData.empty()) {
1051*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1052*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(),
1053*c8dee2aaSAndroid Build Coastguard Worker serverStrikeData.size()));
1054*c8dee2aaSAndroid Build Coastguard Worker }
1055*c8dee2aaSAndroid Build Coastguard Worker
1056*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
1057*c8dee2aaSAndroid Build Coastguard Worker
1058*c8dee2aaSAndroid Build Coastguard Worker {
1059*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, true, 64, clientTypeface);
1060*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientBlob);
1061*c8dee2aaSAndroid Build Coastguard Worker
1062*c8dee2aaSAndroid Build Coastguard Worker RasterBlob(clientBlob, 100, 100, paint, direct);
1063*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
1064*c8dee2aaSAndroid Build Coastguard Worker discardableManager->resetCacheMissCounts();
1065*c8dee2aaSAndroid Build Coastguard Worker }
1066*c8dee2aaSAndroid Build Coastguard Worker {
1067*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, false, 440, clientTypeface);
1068*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientBlob);
1069*c8dee2aaSAndroid Build Coastguard Worker
1070*c8dee2aaSAndroid Build Coastguard Worker RasterBlob(clientBlob, 100, 100, paint, direct);
1071*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
1072*c8dee2aaSAndroid Build Coastguard Worker discardableManager->resetCacheMissCounts();
1073*c8dee2aaSAndroid Build Coastguard Worker }
1074*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
1075*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
1076*c8dee2aaSAndroid Build Coastguard Worker }
1077*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_TypefaceWithPaths_PathThenMask,reporter,ctxInfo,CtsEnforcement::kNever)1078*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_TypefaceWithPaths_PathThenMask,
1079*c8dee2aaSAndroid Build Coastguard Worker reporter,
1080*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
1081*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
1082*c8dee2aaSAndroid Build Coastguard Worker auto direct = ctxInfo.directContext();
1083*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
1084*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServer server(discardableManager.get());
1085*c8dee2aaSAndroid Build Coastguard Worker SkStrikeClient client(discardableManager, true);
1086*c8dee2aaSAndroid Build Coastguard Worker
1087*c8dee2aaSAndroid Build Coastguard Worker auto serverTypeface = ToolUtils::DefaultPortableTypeface();
1088*c8dee2aaSAndroid Build Coastguard Worker const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
1089*c8dee2aaSAndroid Build Coastguard Worker
1090*c8dee2aaSAndroid Build Coastguard Worker auto props = FindSurfaceProps(direct);
1091*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> cache_diff_canvas = server.makeAnalysisCanvas(
1092*c8dee2aaSAndroid Build Coastguard Worker 500, 500, props, nullptr, direct->supportsDistanceFieldText(),
1093*c8dee2aaSAndroid Build Coastguard Worker !direct->priv().caps()->disablePerspectiveSDFText());
1094*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1095*c8dee2aaSAndroid Build Coastguard Worker using Rgct = SkRemoteGlyphCacheTest;
1096*c8dee2aaSAndroid Build Coastguard Worker
1097*c8dee2aaSAndroid Build Coastguard Worker // Draw from path out of the strike which provides paths.
1098*c8dee2aaSAndroid Build Coastguard Worker {
1099*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, false, 440);
1100*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100, paint);
1101*c8dee2aaSAndroid Build Coastguard Worker }
1102*c8dee2aaSAndroid Build Coastguard Worker // Draw from mask out of the strike which provides paths.
1103*c8dee2aaSAndroid Build Coastguard Worker {
1104*c8dee2aaSAndroid Build Coastguard Worker auto serverBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, true, 64);
1105*c8dee2aaSAndroid Build Coastguard Worker cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100, paint);
1106*c8dee2aaSAndroid Build Coastguard Worker }
1107*c8dee2aaSAndroid Build Coastguard Worker std::vector<uint8_t> serverStrikeData;
1108*c8dee2aaSAndroid Build Coastguard Worker server.writeStrikeData(&serverStrikeData);
1109*c8dee2aaSAndroid Build Coastguard Worker if (!serverStrikeData.empty()) {
1110*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
1111*c8dee2aaSAndroid Build Coastguard Worker client.readStrikeData(serverStrikeData.data(),
1112*c8dee2aaSAndroid Build Coastguard Worker serverStrikeData.size()));
1113*c8dee2aaSAndroid Build Coastguard Worker }
1114*c8dee2aaSAndroid Build Coastguard Worker
1115*c8dee2aaSAndroid Build Coastguard Worker auto clientTypeface = client.retrieveTypefaceUsingServerIDForTest(serverTypefaceID);
1116*c8dee2aaSAndroid Build Coastguard Worker
1117*c8dee2aaSAndroid Build Coastguard Worker {
1118*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, true, 64, clientTypeface);
1119*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientBlob);
1120*c8dee2aaSAndroid Build Coastguard Worker
1121*c8dee2aaSAndroid Build Coastguard Worker RasterBlob(clientBlob, 100, 100, paint, direct);
1122*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
1123*c8dee2aaSAndroid Build Coastguard Worker discardableManager->resetCacheMissCounts();
1124*c8dee2aaSAndroid Build Coastguard Worker }
1125*c8dee2aaSAndroid Build Coastguard Worker {
1126*c8dee2aaSAndroid Build Coastguard Worker auto clientBlob = Rgct::MakeNormalBlob(&paint, serverTypeface, false, 440, clientTypeface);
1127*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, clientBlob);
1128*c8dee2aaSAndroid Build Coastguard Worker
1129*c8dee2aaSAndroid Build Coastguard Worker RasterBlob(clientBlob, 100, 100, paint, direct);
1130*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
1131*c8dee2aaSAndroid Build Coastguard Worker discardableManager->resetCacheMissCounts();
1132*c8dee2aaSAndroid Build Coastguard Worker }
1133*c8dee2aaSAndroid Build Coastguard Worker // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
1134*c8dee2aaSAndroid Build Coastguard Worker discardableManager->unlockAndDeleteAll();
1135*c8dee2aaSAndroid Build Coastguard Worker }
1136*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkTypefaceProxy_Basic_Serial,reporter)1137*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkTypefaceProxy_Basic_Serial, reporter) {
1138*c8dee2aaSAndroid Build Coastguard Worker auto typeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
1139*c8dee2aaSAndroid Build Coastguard Worker sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
1140*c8dee2aaSAndroid Build Coastguard Worker SkTypefaceProxyPrototype srcProto{*typeface};
1141*c8dee2aaSAndroid Build Coastguard Worker
1142*c8dee2aaSAndroid Build Coastguard Worker SkBinaryWriteBuffer writeBuffer({});
1143*c8dee2aaSAndroid Build Coastguard Worker srcProto.flatten(writeBuffer);
1144*c8dee2aaSAndroid Build Coastguard Worker
1145*c8dee2aaSAndroid Build Coastguard Worker auto data = writeBuffer.snapshotAsData();
1146*c8dee2aaSAndroid Build Coastguard Worker SkReadBuffer readBuffer{data->data(), data->size()};
1147*c8dee2aaSAndroid Build Coastguard Worker std::optional<SkTypefaceProxyPrototype> dstProto =
1148*c8dee2aaSAndroid Build Coastguard Worker SkTypefaceProxyPrototype::MakeFromBuffer(readBuffer);
1149*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, dstProto.has_value());
1150*c8dee2aaSAndroid Build Coastguard Worker auto proxy = sk_make_sp<SkTypefaceProxy>(dstProto.value(), discardableManager, false);
1151*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, typeface->uniqueID() == proxy->remoteTypefaceID());
1152*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, typeface->uniqueID() != proxy->uniqueID());
1153*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, typeface->countGlyphs() == proxy->countGlyphs());
1154*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, typeface->fontStyle() == proxy->fontStyle());
1155*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, typeface->isFixedPitch() == proxy->isFixedPitch());
1156*c8dee2aaSAndroid Build Coastguard Worker
1157*c8dee2aaSAndroid Build Coastguard Worker // Must be multiple of 4 bytes or the buffer will be invalid.
1158*c8dee2aaSAndroid Build Coastguard Worker uint8_t brokenBytes[] = {1, 2, 3, 4, 5, 6, 7, 8};
1159*c8dee2aaSAndroid Build Coastguard Worker SkReadBuffer brokenBuffer{std::data(brokenBytes), std::size(brokenBytes)};
1160*c8dee2aaSAndroid Build Coastguard Worker std::optional<SkTypefaceProxyPrototype> brokenProto =
1161*c8dee2aaSAndroid Build Coastguard Worker SkTypefaceProxyPrototype::MakeFromBuffer(brokenBuffer);
1162*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !brokenProto.has_value());
1163*c8dee2aaSAndroid Build Coastguard Worker }
1164*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkGraphics_Limits,reporter)1165*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkGraphics_Limits, reporter) {
1166*c8dee2aaSAndroid Build Coastguard Worker const auto prev1 = SkGraphics::GetTypefaceCacheCountLimit();
1167*c8dee2aaSAndroid Build Coastguard Worker
1168*c8dee2aaSAndroid Build Coastguard Worker auto prev2 = SkGraphics::SetTypefaceCacheCountLimit(prev1 + 1);
1169*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, prev1 == prev2);
1170*c8dee2aaSAndroid Build Coastguard Worker prev2 = SkGraphics::GetTypefaceCacheCountLimit();
1171*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, prev2 == prev1 + 1);
1172*c8dee2aaSAndroid Build Coastguard Worker
1173*c8dee2aaSAndroid Build Coastguard Worker SkGraphics::SetTypefaceCacheCountLimit(prev1); // restore orig
1174*c8dee2aaSAndroid Build Coastguard Worker }
1175