1 /*
2 * Copyright 2018 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "src/core/SkTypeface_remote.h"
9
10 #include "include/core/SkDrawable.h"
11 #include "include/core/SkFontMetrics.h"
12 #include "include/private/base/SkDebug.h"
13 #include "include/private/base/SkMalloc.h"
14 #include "include/private/chromium/SkChromeRemoteGlyphCache.h"
15 #include "src/core/SkGlyph.h"
16 #include "src/core/SkReadBuffer.h"
17 #include "src/core/SkTraceEvent.h"
18 #include "src/core/SkWriteBuffer.h"
19
20 #include <optional>
21 #include <utility>
22
23 class SkArenaAlloc;
24 class SkDescriptor;
25 class SkPath;
26
SkScalerContextProxy(sk_sp<SkTypeface> tf,const SkScalerContextEffects & effects,const SkDescriptor * desc,sk_sp<SkStrikeClient::DiscardableHandleManager> manager)27 SkScalerContextProxy::SkScalerContextProxy(sk_sp<SkTypeface> tf,
28 const SkScalerContextEffects& effects,
29 const SkDescriptor* desc,
30 sk_sp<SkStrikeClient::DiscardableHandleManager> manager)
31 : SkScalerContext{std::move(tf), effects, desc}
32 , fDiscardableManager{std::move(manager)} {}
33
generateMetrics(const SkGlyph & glyph,SkArenaAlloc *)34 SkScalerContext::GlyphMetrics SkScalerContextProxy::generateMetrics(const SkGlyph& glyph,
35 SkArenaAlloc*) {
36 TRACE_EVENT1("skia", "generateMetrics", "rec", TRACE_STR_COPY(this->getRec().dump().c_str()));
37 if (this->getProxyTypeface()->isLogging()) {
38 SkDebugf("GlyphCacheMiss generateMetrics looking for glyph: %x\n generateMetrics: %s\n",
39 glyph.getPackedID().value(), this->getRec().dump().c_str());
40 }
41
42 fDiscardableManager->notifyCacheMiss(
43 SkStrikeClient::CacheMissType::kGlyphMetrics, fRec.fTextSize);
44
45 return {glyph.maskFormat()};
46 }
47
generateImage(const SkGlyph & glyph,void *)48 void SkScalerContextProxy::generateImage(const SkGlyph& glyph, void*) {
49 TRACE_EVENT1("skia", "generateImage", "rec", TRACE_STR_COPY(this->getRec().dump().c_str()));
50 if (this->getProxyTypeface()->isLogging()) {
51 SkDebugf("GlyphCacheMiss generateImage: %s\n", this->getRec().dump().c_str());
52 }
53
54 // There is no desperation search here, because if there was an image to be found it was
55 // copied over with the metrics search.
56 fDiscardableManager->notifyCacheMiss(
57 SkStrikeClient::CacheMissType::kGlyphImage, fRec.fTextSize);
58 }
59
generatePath(const SkGlyph & glyph,SkPath * path,bool * modified)60 bool SkScalerContextProxy::generatePath(const SkGlyph& glyph, SkPath* path, bool* modified) {
61 TRACE_EVENT1("skia", "generatePath", "rec", TRACE_STR_COPY(this->getRec().dump().c_str()));
62 if (this->getProxyTypeface()->isLogging()) {
63 SkDebugf("GlyphCacheMiss generatePath: %s\n", this->getRec().dump().c_str());
64 }
65
66 fDiscardableManager->notifyCacheMiss(
67 SkStrikeClient::CacheMissType::kGlyphPath, fRec.fTextSize);
68 return false;
69 }
70
generateDrawable(const SkGlyph &)71 sk_sp<SkDrawable> SkScalerContextProxy::generateDrawable(const SkGlyph&) {
72 TRACE_EVENT1("skia", "generateDrawable", "rec", TRACE_STR_COPY(this->getRec().dump().c_str()));
73 if (this->getProxyTypeface()->isLogging()) {
74 SkDebugf("GlyphCacheMiss generateDrawable: %s\n", this->getRec().dump().c_str());
75 }
76
77 fDiscardableManager->notifyCacheMiss(
78 SkStrikeClient::CacheMissType::kGlyphDrawable, fRec.fTextSize);
79 return nullptr;
80 }
81
generateFontMetrics(SkFontMetrics * metrics)82 void SkScalerContextProxy::generateFontMetrics(SkFontMetrics* metrics) {
83 TRACE_EVENT1(
84 "skia", "generateFontMetrics", "rec", TRACE_STR_COPY(this->getRec().dump().c_str()));
85 if (this->getProxyTypeface()->isLogging()) {
86 SkDebugf("GlyphCacheMiss generateFontMetrics: %s\n", this->getRec().dump().c_str());
87 }
88
89 // Font metrics aren't really used for render, so just zero out the data and return.
90 fDiscardableManager->notifyCacheMiss(
91 SkStrikeClient::CacheMissType::kFontMetrics, fRec.fTextSize);
92 sk_bzero(metrics, sizeof(*metrics));
93 }
94
95 std::optional<SkTypefaceProxyPrototype>
MakeFromBuffer(SkReadBuffer & buffer)96 SkTypefaceProxyPrototype::MakeFromBuffer(SkReadBuffer& buffer) {
97 SkASSERT(buffer.isValid());
98 const SkTypefaceID typefaceID = buffer.readUInt();
99 const int glyphCount = buffer.readInt();
100 const int32_t styleValue = buffer.read32();
101 const bool isFixedPitch = buffer.readBool();
102 const bool glyphMaskNeedsCurrentColor = buffer.readBool();
103
104 if (buffer.isValid()) {
105 return SkTypefaceProxyPrototype{
106 typefaceID, glyphCount, styleValue, isFixedPitch, glyphMaskNeedsCurrentColor};
107 }
108
109 return std::nullopt;
110 }
111
SkTypefaceProxyPrototype(const SkTypeface & typeface)112 SkTypefaceProxyPrototype::SkTypefaceProxyPrototype(const SkTypeface& typeface)
113 : fServerTypefaceID{typeface.uniqueID()}
114 , fGlyphCount{typeface.countGlyphs()}
115 , fStyleValue{typeface.fontStyle().fValue}
116 , fIsFixedPitch{typeface.isFixedPitch()}
117 , fGlyphMaskNeedsCurrentColor{typeface.glyphMaskNeedsCurrentColor()} {}
118
SkTypefaceProxyPrototype(SkTypefaceID typefaceID,int glyphCount,int32_t styleValue,bool isFixedPitch,bool glyphMaskNeedsCurrentColor)119 SkTypefaceProxyPrototype::SkTypefaceProxyPrototype(SkTypefaceID typefaceID, int glyphCount,
120 int32_t styleValue, bool isFixedPitch,
121 bool glyphMaskNeedsCurrentColor)
122 : fServerTypefaceID {typefaceID}
123 , fGlyphCount{glyphCount}
124 , fStyleValue{styleValue}
125 , fIsFixedPitch{isFixedPitch}
126 , fGlyphMaskNeedsCurrentColor{glyphMaskNeedsCurrentColor} {}
127
flatten(SkWriteBuffer & buffer) const128 void SkTypefaceProxyPrototype::flatten(SkWriteBuffer& buffer) const {
129 buffer.writeUInt(fServerTypefaceID);
130 buffer.writeInt(fGlyphCount);
131 buffer.write32(fStyleValue);
132 buffer.writeBool(fIsFixedPitch);
133 buffer.writeBool(fGlyphMaskNeedsCurrentColor);
134 }
135
136
SkTypefaceProxy(const SkTypefaceProxyPrototype & prototype,sk_sp<SkStrikeClient::DiscardableHandleManager> manager,bool isLogging)137 SkTypefaceProxy::SkTypefaceProxy(const SkTypefaceProxyPrototype& prototype,
138 sk_sp<SkStrikeClient::DiscardableHandleManager> manager,
139 bool isLogging)
140 : SkTypeface{prototype.style(), prototype.fIsFixedPitch}
141 , fTypefaceID{prototype.fServerTypefaceID}
142 , fGlyphCount{prototype.fGlyphCount}
143 , fIsLogging{isLogging}
144 , fGlyphMaskNeedsCurrentColor{prototype.fGlyphMaskNeedsCurrentColor}
145 , fDiscardableManager{std::move(manager)} {}
146
SkTypefaceProxy(SkTypefaceID typefaceID,int glyphCount,const SkFontStyle & style,bool isFixedPitch,bool glyphMaskNeedsCurrentColor,sk_sp<SkStrikeClient::DiscardableHandleManager> manager,bool isLogging)147 SkTypefaceProxy::SkTypefaceProxy(SkTypefaceID typefaceID,
148 int glyphCount,
149 const SkFontStyle& style,
150 bool isFixedPitch,
151 bool glyphMaskNeedsCurrentColor,
152 sk_sp<SkStrikeClient::DiscardableHandleManager> manager,
153 bool isLogging)
154 : SkTypeface{style, isFixedPitch}
155 , fTypefaceID{typefaceID}
156 , fGlyphCount{glyphCount}
157 , fIsLogging{isLogging}
158 , fGlyphMaskNeedsCurrentColor(glyphMaskNeedsCurrentColor)
159 , fDiscardableManager{std::move(manager)} {}
160
getProxyTypeface() const161 SkTypefaceProxy* SkScalerContextProxy::getProxyTypeface() const {
162 return (SkTypefaceProxy*)this->getTypeface();
163 }
164