62#include <initializer_list>
81 fLockedHandles.
add(++fNextHandleId);
87 if (
id <= fLastDeletedHandleId)
return false;
88 fLockedHandles.
add(
id);
96 return id <= fLastDeletedHandleId;
102 fCacheMissCount[
type]++;
107 return id <= fLastDeletedHandleId;
113 fLockedHandles.
reset();
118 fLockedHandles.
reset();
119 fLastDeletedHandleId = fNextHandleId;
124 return fLockedHandles;
129 return fNextHandleId;
134 return fCacheMissCount[
type];
139 for (uint32_t
i = 0;
i <= SkStrikeClient::CacheMissType::kLast; ++
i) {
140 if (fCacheMissCount[
i] > 0) {
return true; }
146 sk_bzero(&fCacheMissCount,
sizeof(fCacheMissCount));
153 mutable SkMutex fMutex;
158 int fCacheMissCount[SkStrikeClient::CacheMissType::kLast + 1u];
164 font.setTypeface(tf);
166 font.setSize(textSize);
168 font.setSubpixel(
true);
173 SkASSERT(runBuffer.utf8text ==
nullptr);
174 SkASSERT(runBuffer.clusters ==
nullptr);
176 for (
int i = 0;
i < glyphCount;
i++) {
187 for (
int i = 0;
i < expected.
width(); ++
i) {
188 for (
int j = 0; j < expected.
height(); ++j) {
191 if (0 == tolerance) {
194 for (
int k = 0; k < 4; ++k) {
195 int expectedChannel = (expectedColor >> (k*8)) & 0xff;
196 int actualChannel = (actualColor >> (k*8)) & 0xff;
236 auto canvas =
surface->getCanvas();
238 slug->draw(canvas,
paint);
249 auto canvas =
surface->getCanvas();
253 slug->draw(canvas,
paint);
264 auto dContext = ctxInfo.directContext();
272 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
278 10, 10, props,
nullptr, dContext->supportsDistanceFieldText(),
279 !dContext->priv().caps()->disablePerspectiveSDFText());
280 analysisCanvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
282 std::vector<uint8_t> serverStrikeData;
287 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
303 discardableManager->unlockAndDeleteAll();
307 options->fSupportBilerpFromGlyphAtlas =
true;
316 auto dContext = ctxInfo.directContext();
324 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
330 10, 10, props,
nullptr, dContext->supportsDistanceFieldText(),
331 !dContext->priv().caps()->disablePerspectiveSDFText());
336 std::vector<uint8_t> serverStrikeData;
341 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
351 discardableManager->unlockAndDeleteAll();
360 auto dContext = ctxInfo.directContext();
368 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
371 auto serverBlob =
buildTextBlob(serverTypeface, glyphCount, 360);
374 10, 10, props,
nullptr, dContext->supportsDistanceFieldText(),
375 !dContext->priv().caps()->disablePerspectiveSDFText());
380 std::vector<uint8_t> serverStrikeData;
385 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
387 auto clientBlob =
buildTextBlob(clientTypeface, glyphCount, 360);
395 discardableManager->unlockAndDeleteAll();
404 auto dContext = ctxInfo.directContext();
417 10, 10, props,
nullptr, dContext->supportsDistanceFieldText(),
418 !dContext->priv().caps()->disablePerspectiveSDFText());
422 auto dstSlugData = srcSlug->serialize();
424 std::vector<uint8_t> serverStrikeData;
429 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
439 discardableManager->unlockAndDeleteAll();
460 10, 10, props,
nullptr, ctxInfo.directContext()->supportsDistanceFieldText(),
461 !ctxInfo.directContext()->priv().caps()->disablePerspectiveSDFText());
462 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
465 std::vector<uint8_t> serverStrikeData;
471 discardableManager->unlockAndDeleteAll();
484 std::unique_ptr<SkCanvas> cache_diff_canvas =
487 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
495 std::vector<uint8_t> fontData;
497 discardableManager->unlockAll();
500 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
505 discardableManager->unlockAndDeleteAll();
518 std::unique_ptr<SkCanvas> cache_diff_canvas =
521 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
526 std::vector<uint8_t> fontData;
531 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
535 discardableManager->unlockAndDeleteAll();
536 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
540 discardableManager->unlockAndDeleteAll();
550 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
556 std::unique_ptr<SkCanvas> cache_diff_canvas =
559 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
561 std::vector<uint8_t> serverStrikeData;
566 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
575 discardableManager->unlockAndDeleteAll();
580 discardableManager->unlockAndDeleteAll();
595 std::unique_ptr<SkCanvas> cache_diff_canvas =
598 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
600 std::vector<uint8_t> serverStrikeData;
605 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
608 discardableManager->unlockAndDeleteAll();
623 std::unique_ptr<SkCanvas> cache_diff_canvas =
627 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
633 std::vector<uint8_t> fontData;
635 discardableManager->unlockAndDeleteAll();
645 std::unique_ptr<SkCanvas> cache_diff_canvas =
649 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
654 discardableManager->unlockAndDeleteAll();
661 auto direct = ctxInfo.directContext();
667 paint.setStrokeWidth(0);
674 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
680 10, 10, props,
nullptr, direct->supportsDistanceFieldText(),
681 !direct->priv().caps()->disablePerspectiveSDFText());
682 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
684 std::vector<uint8_t> serverStrikeData;
689 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
699 discardableManager->unlockAndDeleteAll();
705 font.setSubpixel(
true);
708 font.setTypeface(targetTf);
714 int runSize = strlen(
s);
719 SkASSERT(runBuffer.utf8text ==
nullptr);
720 SkASSERT(runBuffer.clusters ==
nullptr);
723 runBuffer.glyphs, runSize);
726 font.getWidths(runBuffer.glyphs, 1,
nullptr, &glyphBounds);
730 for (
int i = 0;
i < runSize;
i++) {
731 runBuffer.pos[
i] =
i * 10;
741 auto direct = ctxInfo.directContext();
750 if (serverTypeface ==
nullptr) {
753 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
759 10, 10, props,
nullptr, direct->supportsDistanceFieldText(),
760 !direct->priv().caps()->disablePerspectiveSDFText());
761 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
763 std::vector<uint8_t> serverStrikeData;
768 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
778 discardableManager->unlockAndDeleteAll();
785 auto direct = ctxInfo.directContext();
790 paint.setAntiAlias(
true);
794 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
800 10, 10, props,
nullptr, direct->supportsDistanceFieldText(),
801 !direct->priv().caps()->disablePerspectiveSDFText());
802 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0.5, 0,
paint);
804 std::vector<uint8_t> serverStrikeData;
809 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
819 discardableManager->unlockAndDeleteAll();
822#if !defined(SK_DISABLE_SDF_TEXT)
827 auto direct = ctxInfo.directContext();
828 if (!direct->priv().caps()->shaderCaps()->supportsDistanceFieldText()) {
840 direct->priv().asRecordingContext()->priv().getSDFTControl(
true);
847 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
853 10, 10, props,
nullptr, direct->supportsDistanceFieldText(),
854 !direct->priv().caps()->disablePerspectiveSDFText());
855 cache_diff_canvas->concat(
matrix);
856 cache_diff_canvas->drawTextBlob(serverBlob.get(), 0, 0,
paint);
858 std::vector<uint8_t> serverStrikeData;
863 client.
readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
873 discardableManager->unlockAndDeleteAll();
889 auto clientTypeface = sk_make_sp<SkTypefaceProxy>(
890 serverTypeface->uniqueID(),
891 serverTypeface->countGlyphs(),
892 serverTypeface->fontStyle(),
893 serverTypeface->isFixedPitch(),
917 discardableManager->unlockAndDeleteAll();
923 font.setTypeface(serverTf);
924 font.setSize(textSize);
928 if (clientTf ==
nullptr)
return blob;
934 auto serialized = blob->serialize(s_procs);
948 auto direct = ctxInfo.directContext();
958 500, 500, props,
nullptr, direct->supportsDistanceFieldText(),
959 !direct->priv().caps()->disablePerspectiveSDFText());
960 for (
SkScalar textSize : { 70, 180, 270, 340}) {
964 cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100,
paint);
966 std::vector<uint8_t> serverStrikeData;
968 if (!serverStrikeData.empty()) {
971 serverStrikeData.size()));
974 auto clientBlob =
MakeEmojiBlob(serverTypeface, textSize, clientTypeface);
979 discardableManager->resetCacheMissCounts();
983 discardableManager->unlockAndDeleteAll();
992 font.setTypeface(serverTf);
993 font.setSize(textSize);
995 const char*
text =
"Hel lo";
1000 font2.setupForAsPaths(
paint);
1003 if (clientTf ==
nullptr)
return blob;
1009 auto serialized = blob->serialize(s_procs);
1023 auto direct = ctxInfo.directContext();
1029 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
1033 500, 500, props,
nullptr, direct->supportsDistanceFieldText(),
1034 !direct->priv().caps()->disablePerspectiveSDFText());
1040 auto serverBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
true, 64);
1041 cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100,
paint);
1045 auto serverBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
false, 440);
1046 cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100,
paint);
1048 std::vector<uint8_t> serverStrikeData;
1050 if (!serverStrikeData.empty()) {
1053 serverStrikeData.size()));
1059 auto clientBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
true, 64, clientTypeface);
1064 discardableManager->resetCacheMissCounts();
1067 auto clientBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
false, 440, clientTypeface);
1072 discardableManager->resetCacheMissCounts();
1075 discardableManager->unlockAndDeleteAll();
1082 auto direct = ctxInfo.directContext();
1088 const SkTypefaceID serverTypefaceID = serverTypeface->uniqueID();
1092 500, 500, props,
nullptr, direct->supportsDistanceFieldText(),
1093 !direct->priv().caps()->disablePerspectiveSDFText());
1099 auto serverBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
false, 440);
1100 cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100,
paint);
1104 auto serverBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
true, 64);
1105 cache_diff_canvas->drawTextBlob(serverBlob.get(), 100, 100,
paint);
1107 std::vector<uint8_t> serverStrikeData;
1109 if (!serverStrikeData.empty()) {
1112 serverStrikeData.size()));
1118 auto clientBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
true, 64, clientTypeface);
1123 discardableManager->resetCacheMissCounts();
1126 auto clientBlob = Rgct::MakeNormalBlob(&
paint, serverTypeface,
false, 440, clientTypeface);
1131 discardableManager->resetCacheMissCounts();
1134 discardableManager->unlockAndDeleteAll();
1143 srcProto.flatten(writeBuffer);
1145 auto data = writeBuffer.snapshotAsData();
1147 std::optional<SkTypefaceProxyPrototype> dstProto =
1150 auto proxy = sk_make_sp<SkTypefaceProxy>(dstProto.value(), discardableManager,
false);
1158 uint8_t brokenBytes[] = {1, 2, 3, 4, 5, 6, 7, 8};
1160 std::optional<SkTypefaceProxyPrototype> brokenProto =
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
sk_bzero(glyphs, sizeof(glyphs))
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
uint32_t SkDiscardableHandleId
@ kNormal
glyph outlines modified to improve constrast
@ kUTF8
uses bytes to represent UTF-8 or ASCII
sk_sp< T > sk_ref_sp(T *obj)
SkBitmap RasterBlobThroughSlug(sk_sp< SkTextBlob > blob, int width, int height, const SkPaint &paint, GrRecordingContext *rContext, const SkMatrix *matrix=nullptr, SkScalar x=0)
DEF_TEST(SkRemoteGlyphCache_StrikeLockingServer, reporter)
SkSurfaceProps FindSurfaceProps(GrRecordingContext *rContext)
sk_sp< SkTextBlob > make_blob_causing_fallback(sk_sp< SkTypeface > targetTf, const SkTypeface *glyphTf, skiatest::Reporter *reporter)
SkBitmap RasterSlug(sk_sp< Slug > slug, int width, int height, const SkPaint &paint, GrRecordingContext *rContext, const SkMatrix *matrix=nullptr, SkScalar x=0)
static void use_padding_options(GrContextOptions *options)
static void compare_blobs(const SkBitmap &expected, const SkBitmap &actual, skiatest::Reporter *reporter, int tolerance=0)
sk_sp< SkTextBlob > MakeEmojiBlob(sk_sp< SkTypeface > serverTf, SkScalar textSize, sk_sp< SkTypeface > clientTf=nullptr)
sk_sp< SkTextBlob > buildTextBlob(sk_sp< SkTypeface > tf, int glyphCount, int textSize=1)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_StrikeSerialization, reporter, ctxInfo, CtsEnforcement::kNever)
sk_sp< SkSurface > MakeSurface(int width, int height, GrRecordingContext *rContext)
DEF_GANESH_TEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlug, skgpu::IsRenderingContext, reporter, ctxInfo, use_padding_options, CtsEnforcement::kNever)
SkBitmap RasterBlob(sk_sp< SkTextBlob > blob, int width, int height, const SkPaint &paint, GrRecordingContext *rContext, const SkMatrix *matrix=nullptr, SkScalar x=0)
#define REPORTER_ASSERT(r, cond,...)
void resetCacheMissCounts()
~DiscardableManager() override=default
const THashSet< SkDiscardableHandleId > & lockedHandles() const
bool isHandleDeleted(SkDiscardableHandleId id) override
void unlockAndDeleteAll()
bool hasCacheMiss() const
bool deleteHandle(SkDiscardableHandleId id) override
void notifyCacheMiss(SkStrikeClient::CacheMissType type, int fontSize) override
int cacheMissCount(uint32_t type)
bool lockHandle(SkDiscardableHandleId id) override
SkDiscardableHandleId handleCount()
SkDiscardableHandleId createHandle() override
SkColor getColor(int x, int y) const
static sk_sp< SkData > MakeUninitialized(size_t length)
static SkScalar ApproximateTransformedTextSize(const SkFont &font, const SkMatrix &matrix, const SkPoint &textLocation)
int textToGlyphs(const void *text, size_t byteLength, SkTextEncoding encoding, SkGlyphID glyphs[], int maxGlyphCount) const
@ kAntiAlias
may have transparent pixels on glyph edges
static constexpr uint16_t kSkSideTooBigForAtlas
static int SetTypefaceCacheCountLimit(int count)
static void PurgeFontCache()
static int GetTypefaceCacheCountLimit()
static SkMatrix Scale(SkScalar sx, SkScalar sy)
static const SkMatrix & I()
@ kStroke_Style
set to stroke geometry
static sk_sp< SkTextBlob > MakeNormalBlob(SkPaint *paint, sk_sp< SkTypeface > serverTf, bool asPaths, SkScalar textSize, sk_sp< SkTypeface > clientTf=nullptr)
SK_SPI bool readStrikeData(const volatile void *memory, size_t memorySize)
sk_sp< SkTypeface > retrieveTypefaceUsingServerIDForTest(SkTypefaceID) const
sk_sp< sktext::gpu::Slug > deserializeSlugForTest(const void *data, size_t size) const
void setMaxEntriesInDescriptorMapForTesting(size_t count)
SK_SPI void writeStrikeData(std::vector< uint8_t > *memory)
SK_API std::unique_ptr< SkCanvas > makeAnalysisCanvas(int width, int height, const SkSurfaceProps &props, sk_sp< SkColorSpace > colorSpace, bool DFTSupport, bool DFTPerspSupport=true)
size_t remoteStrikeMapSizeForTesting() const
static bool ShouldDrawAsPath(const SkPaint &paint, const SkFont &font, const SkMatrix &matrix)
static sk_sp< SkTextBlob > MakeFromText(const void *text, size_t byteLength, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
static sk_sp< SkTextBlob > Deserialize(const void *data, size_t size, const SkDeserialProcs &procs)
static std::optional< SkTypefaceProxyPrototype > MakeFromBuffer(SkReadBuffer &buffer)
SkTypefaceID remoteTypefaceID() const
SkTypefaceID uniqueID() const
static sk_sp< SkTypeface > Make()
bool isSDFT(SkScalar approximateDeviceTextSize, const SkPaint &paint, const SkMatrix &matrix) const
static sk_sp< Slug > ConvertBlob(SkCanvas *canvas, const SkTextBlob &blob, SkPoint origin, const SkPaint &paint)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
font
Font Metadata and Metrics.
bool IsRenderingContext(skgpu::ContextType type)
SIN Vec< N, float > abs(const Vec< N, float > &x)
SkDeserialTypefaceProc fTypefaceProc
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static SkRect MakeIWH(int w, int h)
constexpr float width() const
static constexpr SkRect MakeWH(float w, float h)
SkSerialTypefaceProc fTypefaceProc
std::shared_ptr< const fml::Mapping > data