Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions
SkStrikeTest.cpp File Reference
#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkExecutor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkMutex.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkArenaAlloc.h"
#include "src/base/SkZip.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMask.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkStrike.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTaskGroup.h"
#include "src/core/SkWriteBuffer.h"
#include "src/text/StrikeForGPU.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <memory>
#include <tuple>
#include <vector>

Go to the source code of this file.

Classes

class  Barrier
 
class  SkGlyphTestPeer
 
class  SkStrikeTestingPeer
 

Functions

static std::tuple< SkZip< const SkPackedGlyphID, const SkPoint >, SkZip< SkGlyphID, SkPoint >, SkRectprepare_for_mask_drawing (StrikeForGPU *strike, SkZip< const SkGlyphID, const SkPoint > source, SkZip< SkPackedGlyphID, SkPoint > acceptedBuffer, SkZip< SkGlyphID, SkPoint > rejectedBuffer)
 
 DEF_TEST (SkStrikeMultiThread, Reporter)
 
 DEF_TEST (SkStrike_FlattenByType, reporter)
 

Function Documentation

◆ DEF_TEST() [1/2]

DEF_TEST ( SkStrike_FlattenByType  ,
reporter   
)

Definition at line 198 of file SkStrikeTest.cpp.

198 {
199 std::vector<SkGlyph> imagesToSend;
200 std::vector<SkGlyph> pathsToSend;
201 std::vector<SkGlyph> drawablesToSend;
202 SkArenaAlloc alloc{256};
203
204 // Make a mask glyph and put it in the glyphs to send.
205 const SkPackedGlyphID maskPackedGlyphID((SkGlyphID)10);
206 SkGlyph maskGlyph{maskPackedGlyphID};
207 SkGlyphTestPeer::SetGlyph(&maskGlyph);
208
209 static constexpr uint8_t X = 0xff;
210 static constexpr uint8_t O = 0x00;
211 uint8_t imageData[][8] = {
212 {X,X,X,X,X,X,X,X},
213 {X,O,O,O,O,O,O,X},
214 {X,O,O,O,O,O,O,X},
215 {X,O,O,O,O,O,O,X},
216 {X,O,O,X,X,O,O,X},
217 {X,O,O,O,O,O,O,X},
218 {X,O,O,O,O,O,O,X},
219 {X,O,O,O,O,O,O,X},
220 {X,X,X,X,X,X,X,X},
221 };
222 maskGlyph.setImage(&alloc, imageData);
223 imagesToSend.emplace_back(maskGlyph);
224
225 // Make a path glyph and put it in the glyphs to send.
226 const SkPackedGlyphID pathPackedGlyphID((SkGlyphID)11);
227 SkGlyph pathGlyph{pathPackedGlyphID};
228 SkGlyphTestPeer::SetGlyph(&pathGlyph);
229 SkPath path;
230 path.addRect(pathGlyph.rect());
231 pathGlyph.setPath(&alloc, &path, false);
232 pathsToSend.emplace_back(pathGlyph);
233
234 // Make a drawable glyph and put it in the glyphs to send.
235 const SkPackedGlyphID drawablePackedGlyphID((SkGlyphID)12);
236 SkGlyph drawableGlyph{drawablePackedGlyphID};
237 SkGlyphTestPeer::SetGlyph(&drawableGlyph);
238 class TestDrawable final : public SkDrawable {
239 public:
240 TestDrawable(SkRect rect) : fRect(rect) {}
241
242 private:
243 const SkRect fRect;
244 SkRect onGetBounds() override { return fRect; }
245 size_t onApproximateBytesUsed() override {
246 return 0;
247 }
248 void onDraw(SkCanvas* canvas) override {
250 canvas->drawRect(fRect, paint);
251 }
252 };
253
254 sk_sp<SkDrawable> drawable = sk_make_sp<TestDrawable>(drawableGlyph.rect());
255 REPORTER_ASSERT(reporter, !drawableGlyph.setDrawableHasBeenCalled());
256 drawableGlyph.setDrawable(&alloc, drawable);
257 REPORTER_ASSERT(reporter, drawableGlyph.setDrawableHasBeenCalled());
258 REPORTER_ASSERT(reporter, drawableGlyph.drawable() != nullptr);
259 drawablesToSend.emplace_back(drawableGlyph);
260
261 // Test the FlattenGlyphsByType method.
262 SkBinaryWriteBuffer writeBuffer({});
263 SkStrike::FlattenGlyphsByType(writeBuffer, imagesToSend, pathsToSend, drawablesToSend);
264 auto data = writeBuffer.snapshotAsData();
265
266 // Make a strike to merge into.
267 SkStrikeCache strikeCache;
268 auto dstTypeface = ToolUtils::CreateTestTypeface("monospace", SkFontStyle());
269 SkFont font{dstTypeface};
271 sk_sp<SkStrike> strike = spec.findOrCreateStrike(&strikeCache);
272
273 // Test the mergeFromBuffer method.
274 SkReadBuffer readBuffer{data->data(), data->size()};
275 strike->mergeFromBuffer(readBuffer);
276
277 // Check mask glyph.
278 SkGlyph* dstMaskGlyph = SkStrikeTestingPeer::GetGlyph(strike.get(), maskPackedGlyphID);
279 REPORTER_ASSERT(reporter, maskGlyph.rect() == dstMaskGlyph->rect());
281 REPORTER_ASSERT(reporter, dstMaskGlyph->image() != nullptr);
282
283 // Check path glyph.
284 SkGlyph* dstPathGlyph = SkStrikeTestingPeer::GetGlyph(strike.get(), pathPackedGlyphID);
285 REPORTER_ASSERT(reporter, pathGlyph.rect() == dstPathGlyph->rect());
287 REPORTER_ASSERT(reporter, dstPathGlyph->path() != nullptr);
288
289 // Check drawable glyph.
290 SkGlyph* dstDrawableGlyph = SkStrikeTestingPeer::GetGlyph(strike.get(),drawablePackedGlyphID);
291 REPORTER_ASSERT(reporter, drawableGlyph.rect() == dstDrawableGlyph->rect());
293 REPORTER_ASSERT(reporter, dstDrawableGlyph->drawable() != nullptr);
294}
SkRect fRect
reporter
uint16_t SkGlyphID
Definition SkTypes.h:179
static const SkScalar X
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
void drawRect(const SkRect &rect, const SkPaint &paint)
virtual SkRect onGetBounds()=0
virtual void onDraw(SkCanvas *)=0
virtual size_t onApproximateBytesUsed()
static void SetGlyph(SkGlyph *glyph)
bool setPathHasBeenCalled() const
Definition SkGlyph.h:486
bool setDrawableHasBeenCalled() const
Definition SkGlyph.h:495
bool setImageHasBeenCalled() const
Definition SkGlyph.h:459
const SkPath * path() const
Definition SkGlyph.cpp:284
SkRect rect() const
Definition SkGlyph.h:506
SkDrawable * drawable() const
Definition SkGlyph.cpp:327
const void * image() const
Definition SkGlyph.h:465
static SkStrikeSpec MakeWithNoDevice(const SkFont &font, const SkPaint *paint=nullptr)
sk_sp< SkStrike > findOrCreateStrike() const
static SkGlyph * GetGlyph(SkStrike *strike, SkPackedGlyphID packedID)
static void FlattenGlyphsByType(SkWriteBuffer &buffer, SkSpan< SkGlyph > images, SkSpan< SkGlyph > paths, SkSpan< SkGlyph > drawables)
Definition SkStrike.cpp:87
T * get() const
Definition SkRefCnt.h:303
const Paint & paint
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
sk_sp< SkTypeface > CreateTestTypeface(const char *name, SkFontStyle style)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
font
Font Metadata and Metrics.

◆ DEF_TEST() [2/2]

DEF_TEST ( SkStrikeMultiThread  ,
Reporter   
)

Definition at line 109 of file SkStrikeTest.cpp.

109 {
110 sk_sp<SkTypeface> typeface =
112 static constexpr int kThreadCount = 4;
113
114 Barrier barrier{kThreadCount};
115
116 SkFont font;
118 font.setSubpixel(true);
119 font.setTypeface(typeface);
120
121 SkGlyphID glyphs['z'];
122 SkPoint pos['z'];
123 for (int c = ' '; c < 'z'; c++) {
124 glyphs[c] = font.unicharToGlyph(c);
125 pos[c] = {30.0f * c + 30, 30.0f};
126 }
127 constexpr size_t glyphCount = 'z' - ' ';
128 auto data = SkMakeZip(glyphs, pos).subspan(SkTo<int>(' '), glyphCount);
129
130 SkPaint defaultPaint;
132 font, defaultPaint, SkSurfaceProps(0, kUnknown_SkPixelGeometry),
134
135 SkStrikeCache strikeCache;
136
137 // Make our own executor so the --threads parameter doesn't mess things up.
139 for (int tries = 0; tries < 100; tries++) {
140 SkStrike strike{&strikeCache, strikeSpec, strikeSpec.createScalerContext(), nullptr,
141 nullptr};
142
143 auto perThread = [&](int threadIndex) {
144 barrier.waitForAll();
145
146 auto local = data.subspan(threadIndex * 2, data.size() - kThreadCount * 2);
147 for (int i = 0; i < 100; i++) {
148 // Accepted buffers.
149 STArray<64, SkPackedGlyphID> acceptedPackedGlyphIDs;
150 STArray<64, SkPoint> acceptedPositions;
151 STArray<64, SkMask::Format> acceptedFormats;
152 acceptedPackedGlyphIDs.resize(glyphCount);
153 acceptedPositions.resize(glyphCount);
154 const auto acceptedBuffer = SkMakeZip(acceptedPackedGlyphIDs, acceptedPositions);
155
156 // Rejected buffers.
157 STArray<64, SkGlyphID> rejectedGlyphIDs;
158 STArray<64, SkPoint> rejectedPositions;
159 rejectedGlyphIDs.resize(glyphCount);
160 rejectedPositions.resize(glyphCount);
161 const auto rejectedBuffer = SkMakeZip(rejectedGlyphIDs, rejectedPositions);
162
164
165 auto [accepted, rejected, bounds] =
166 prepare_for_mask_drawing(&strike, source, acceptedBuffer, rejectedBuffer);
167 source = rejected;
168 }
169 };
170
171 SkTaskGroup(*executor).batch(kThreadCount, perThread);
172 }
173}
uint16_t glyphs[5]
SkPoint pos
static std::tuple< SkZip< const SkPackedGlyphID, const SkPoint >, SkZip< SkGlyphID, SkPoint >, SkRect > prepare_for_mask_drawing(StrikeForGPU *strike, SkZip< const SkGlyphID, const SkPoint > source, SkZip< SkPackedGlyphID, SkPoint > acceptedBuffer, SkZip< SkGlyphID, SkPoint > rejectedBuffer)
@ kUnknown_SkPixelGeometry
constexpr auto SkMakeZip(Ts &&... ts)
Definition SkZip.h:212
static std::unique_ptr< SkExecutor > MakeFIFOThreadPool(int threads=0, bool allowBorrowing=true)
static constexpr SkFontStyle Italic()
Definition SkFontStyle.h:72
@ kAntiAlias
may have transparent pixels on glyph edges
static const SkMatrix & I()
static SkStrikeSpec MakeMask(const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix)
std::unique_ptr< SkScalerContext > createScalerContext() const
void batch(int N, std::function< void(int)> fn)
Definition SkZip.h:25
void resize(size_t count)
Definition SkTArray.h:418
SkBitmap source
Definition examples.cpp:28
static constexpr uint64_t kThreadCount
Optional< SkRect > bounds
Definition SkRecords.h:189
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)

◆ prepare_for_mask_drawing()

static std::tuple< SkZip< const SkPackedGlyphID, const SkPoint >, SkZip< SkGlyphID, SkPoint >, SkRect > prepare_for_mask_drawing ( StrikeForGPU strike,
SkZip< const SkGlyphID, const SkPoint source,
SkZip< SkPackedGlyphID, SkPoint acceptedBuffer,
SkZip< SkGlyphID, SkPoint rejectedBuffer 
)
static

Definition at line 74 of file SkStrikeTest.cpp.

78 {
79 SkGlyphRect boundingRect = skglyph::empty_rect();
80 int acceptedSize = 0,
81 rejectedSize = 0;
83 for (auto [glyphID, pos] : source) {
84 if (!SkIsFinite(pos.x(), pos.y())) {
85 continue;
86 }
87 const SkPackedGlyphID packedID{glyphID};
88 switch (const SkGlyphDigest digest = strike->digestFor(kDirectMask, packedID);
89 digest.actionFor(kDirectMask)) {
90 case GlyphAction::kAccept: {
91 const SkGlyphRect glyphBounds = digest.bounds().offset(pos);
92 boundingRect = skglyph::rect_union(boundingRect, glyphBounds);
93 acceptedBuffer[acceptedSize++] = std::make_tuple(packedID, glyphBounds.leftTop());
94 break;
95 }
96 case GlyphAction::kReject:
97 rejectedBuffer[rejectedSize++] = std::make_tuple(glyphID, pos);
98 break;
99 default:
100 break;
101 }
102 }
103
104 return {acceptedBuffer.first(acceptedSize),
105 rejectedBuffer.first(rejectedSize),
106 boundingRect.rect()};
107}
static bool SkIsFinite(T x, Pack... values)
SkPoint leftTop() const
Definition SkGlyph.h:275
SkRect rect() const
Definition SkGlyph.h:259
SkGlyphRect offset(SkScalar x, SkScalar y) const
Definition SkGlyph.h:262
constexpr SkZip first(size_t n) const
Definition SkZip.h:86
virtual SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID)=0
constexpr float y() const
constexpr float x() const