Make SkStrikeCache::Node be SkStrike.
SkStrike becomes SkScalerCache. It will eventually externalize
the memory accounting to SkStrikeCache::Node because the amount of
memory used by the scaler cache, and the overall strike cache memory
usage must be kept in sync.
Change-Id: Ia889f057d8138ec7f22f996e7ebb9d2441dea4ee
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271018
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/bench/PathTextBench.cpp b/bench/PathTextBench.cpp
index 846f049..43f43d7 100644
--- a/bench/PathTextBench.cpp
+++ b/bench/PathTextBench.cpp
@@ -10,7 +10,7 @@
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/utils/SkRandom.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "tools/ToolUtils.h"
diff --git a/bench/SkGlyphCacheBench.cpp b/bench/SkGlyphCacheBench.cpp
index 725cedc..5704a74 100644
--- a/bench/SkGlyphCacheBench.cpp
+++ b/bench/SkGlyphCacheBench.cpp
@@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "bench/Benchmark.h"
#include "include/core/SkCanvas.h"
diff --git a/gn/core.gni b/gn/core.gni
index c3a4471..743ea25 100644
--- a/gn/core.gni
+++ b/gn/core.gni
@@ -323,6 +323,8 @@
"$_src/core/SkRuntimeEffect.cpp",
"$_src/core/SkRWBuffer.cpp",
"$_src/core/SkScalar.cpp",
+ "$_src/core/SkScalerCache.cpp",
+ "$_src/core/SkScalerCache.h",
"$_src/core/SkScalerContext.cpp",
"$_src/core/SkScalerContext.h",
"$_src/core/SkScaleToSides.h",
@@ -349,8 +351,6 @@
"$_src/core/SkSpriteBlitter.h",
"$_src/core/SkStream.cpp",
"$_src/core/SkStreamPriv.h",
- "$_src/core/SkStrike.cpp",
- "$_src/core/SkStrike.h",
"$_src/core/SkStrikeCache.cpp",
"$_src/core/SkStrikeCache.h",
"$_src/core/SkStrikeForGPU.h",
diff --git a/gn/tests.gni b/gn/tests.gni
index c681a15..3c35994 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -253,7 +253,7 @@
"$_tests/SkSLSPIRVTest.cpp",
"$_tests/SkShaperJSONWriterTest.cpp",
"$_tests/SkSharedMutexTest.cpp",
- "$_tests/SkStrikeTest.cpp",
+ "$_tests/SkScalerCacheTest.cpp",
"$_tests/SkUTFTest.cpp",
"$_tests/SkVMTest.cpp",
"$_tests/SkVxTest.cpp",
diff --git a/samplecode/SamplePathText.cpp b/samplecode/SamplePathText.cpp
index 54f49b3..c9504ae 100644
--- a/samplecode/SamplePathText.cpp
+++ b/samplecode/SamplePathText.cpp
@@ -10,7 +10,7 @@
#include "include/core/SkPath.h"
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTaskGroup.h"
diff --git a/src/core/SkDraw_text.cpp b/src/core/SkDraw_text.cpp
index d192952..73e2722 100644
--- a/src/core/SkDraw_text.cpp
+++ b/src/core/SkDraw_text.cpp
@@ -9,8 +9,8 @@
#include "src/core/SkFontPriv.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkRasterClip.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkScalerContext.h"
-#include "src/core/SkStrike.h"
#include "src/core/SkUtils.h"
#include <climits>
diff --git a/src/core/SkFont.cpp b/src/core/SkFont.cpp
index b0de674..8f09ac1 100644
--- a/src/core/SkFont.cpp
+++ b/src/core/SkFont.cpp
@@ -13,8 +13,8 @@
#include "src/core/SkDraw.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkPaintDefaults.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkScalerContext.h"
-#include "src/core/SkStrike.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTLazy.h"
diff --git a/src/core/SkGlyph.h b/src/core/SkGlyph.h
index 048c953..773dad6 100644
--- a/src/core/SkGlyph.h
+++ b/src/core/SkGlyph.h
@@ -17,7 +17,6 @@
#include "src/core/SkMask.h"
class SkArenaAlloc;
-class SkStrike;
class SkScalerContext;
// needs to be != to any valid SkMask::Format
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index e85fb37..7a6a427 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -13,7 +13,7 @@
#include "include/private/SkTo.h"
#include "src/core/SkDevice.h"
#include "src/core/SkFontPriv.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTextBlobPriv.h"
diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp
index f9f361f..29c986f 100644
--- a/src/core/SkGlyphRunPainter.cpp
+++ b/src/core/SkGlyphRunPainter.cpp
@@ -29,7 +29,7 @@
#include "src/core/SkEnumerate.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkRasterClip.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeForGPU.h"
#include "src/core/SkStrikeSpec.h"
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp
index 46f09b1..211344e 100644
--- a/src/core/SkRemoteGlyphCache.cpp
+++ b/src/core/SkRemoteGlyphCache.cpp
@@ -19,8 +19,8 @@
#include "src/core/SkDraw.h"
#include "src/core/SkEnumerate.h"
#include "src/core/SkGlyphRun.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkSpan.h"
-#include "src/core/SkStrike.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkTLazy.h"
#include "src/core/SkTraceEvent.h"
diff --git a/src/core/SkRemoteGlyphCache.h b/src/core/SkRemoteGlyphCache.h
index 4a3bd36..3155b87 100644
--- a/src/core/SkRemoteGlyphCache.h
+++ b/src/core/SkRemoteGlyphCache.h
@@ -35,7 +35,6 @@
enum SkAxisAlignment : uint32_t;
class SkDescriptor;
class SkAutoDescriptor;
-class SkStrike;
struct SkPackedGlyphID;
enum SkScalerContextFlags : uint32_t;
class SkStrikeCache;
diff --git a/src/core/SkStrike.cpp b/src/core/SkScalerCache.cpp
similarity index 82%
rename from src/core/SkStrike.cpp
rename to src/core/SkScalerCache.cpp
index 2435993..d994485 100644
--- a/src/core/SkStrike.cpp
+++ b/src/core/SkScalerCache.cpp
@@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPath.h"
@@ -27,7 +27,7 @@
return answer;
}
-SkStrike::SkStrike(
+SkScalerCache::SkScalerCache(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkFontMetrics* fontMetrics)
@@ -46,14 +46,14 @@
#endif
// -- glyph creation -------------------------------------------------------------------------------
-SkGlyph* SkStrike::makeGlyph(SkPackedGlyphID packedGlyphID) {
+SkGlyph* SkScalerCache::makeGlyph(SkPackedGlyphID packedGlyphID) {
fMemoryUsed += sizeof(SkGlyph);
SkGlyph* glyph = fAlloc.make<SkGlyph>(packedGlyphID);
fGlyphMap.set(glyph);
return glyph;
}
-SkGlyph* SkStrike::glyph(SkPackedGlyphID packedGlyphID) {
+SkGlyph* SkScalerCache::glyph(SkPackedGlyphID packedGlyphID) {
VALIDATE();
SkGlyph* glyph = fGlyphMap.findOrNull(packedGlyphID);
if (glyph == nullptr) {
@@ -63,14 +63,14 @@
return glyph;
}
-const SkPath* SkStrike::preparePath(SkGlyph* glyph) {
+const SkPath* SkScalerCache::preparePath(SkGlyph* glyph) {
if (glyph->setPath(&fAlloc, fScalerContext.get())) {
fMemoryUsed += glyph->path()->approximateBytesUsed();
}
return glyph->path();
}
-const SkPath* SkStrike::preparePath(SkGlyph* glyph, const SkPath* path) {
+const SkPath* SkScalerCache::preparePath(SkGlyph* glyph, const SkPath* path) {
SkAutoMutexExclusive lock{fMu};
if (glyph->setPath(&fAlloc, path)) {
fMemoryUsed += glyph->path()->approximateBytesUsed();
@@ -78,20 +78,20 @@
return glyph->path();
}
-const SkDescriptor& SkStrike::getDescriptor() const {
+const SkDescriptor& SkScalerCache::getDescriptor() const {
return *fDesc.getDesc();
}
-int SkStrike::countCachedGlyphs() const {
+int SkScalerCache::countCachedGlyphs() const {
SkAutoMutexExclusive lock(fMu);
return fGlyphMap.count();
}
-SkGlyph* SkStrike::internalGlyphOrNull(SkPackedGlyphID id) const {
+SkGlyph* SkScalerCache::internalGlyphOrNull(SkPackedGlyphID id) const {
return fGlyphMap.findOrNull(id);
}
-SkSpan<const SkGlyph*> SkStrike::internalPrepare(
+SkSpan<const SkGlyph*> SkScalerCache::internalPrepare(
SkSpan<const SkGlyphID> glyphIDs, PathDetail pathDetail, const SkGlyph** results) {
const SkGlyph** cursor = results;
for (auto glyphID : glyphIDs) {
@@ -105,14 +105,14 @@
return {results, glyphIDs.size()};
}
-const void* SkStrike::prepareImage(SkGlyph* glyph) {
+const void* SkScalerCache::prepareImage(SkGlyph* glyph) {
if (glyph->setImage(&fAlloc, fScalerContext.get())) {
fMemoryUsed += glyph->imageSize();
}
return glyph->image();
}
-SkGlyph* SkStrike::mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph& from) {
+SkGlyph* SkScalerCache::mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph& from) {
SkAutoMutexExclusive lock{fMu};
SkGlyph* glyph = fGlyphMap.findOrNull(toID);
if (glyph == nullptr) {
@@ -124,20 +124,20 @@
return glyph;
}
-SkSpan<const SkGlyph*> SkStrike::metrics(SkSpan<const SkGlyphID> glyphIDs,
+SkSpan<const SkGlyph*> SkScalerCache::metrics(SkSpan<const SkGlyphID> glyphIDs,
const SkGlyph* results[]) {
SkAutoMutexExclusive lock{fMu};
return this->internalPrepare(glyphIDs, kMetricsOnly, results);
}
-SkSpan<const SkGlyph*> SkStrike::preparePaths(SkSpan<const SkGlyphID> glyphIDs,
+SkSpan<const SkGlyph*> SkScalerCache::preparePaths(SkSpan<const SkGlyphID> glyphIDs,
const SkGlyph* results[]) {
SkAutoMutexExclusive lock{fMu};
return this->internalPrepare(glyphIDs, kMetricsAndPath, results);
}
SkSpan<const SkGlyph*>
-SkStrike::prepareImages(SkSpan<const SkPackedGlyphID> glyphIDs, const SkGlyph* results[]) {
+SkScalerCache::prepareImages(SkSpan<const SkPackedGlyphID> glyphIDs, const SkGlyph* results[]) {
const SkGlyph** cursor = results;
SkAutoMutexExclusive lock{fMu};
for (auto glyphID : glyphIDs) {
@@ -150,7 +150,7 @@
}
template <typename Fn>
-void SkStrike::commonFilterLoop(SkDrawableGlyphBuffer* drawables, Fn&& fn) {
+void SkScalerCache::commonFilterLoop(SkDrawableGlyphBuffer* drawables, Fn&& fn) {
for (auto [i, packedID, pos] : SkMakeEnumerate(drawables->input())) {
if (SkScalarsAreFinite(pos.x(), pos.y())) {
SkGlyph* glyph = this->glyph(packedID);
@@ -161,7 +161,7 @@
}
}
-void SkStrike::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer* drawables) {
+void SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer* drawables) {
SkAutoMutexExclusive lock{fMu};
this->commonFilterLoop(drawables,
[&](size_t i, SkGlyph* glyph, SkPoint pos) SK_REQUIRES(fMu) {
@@ -173,12 +173,12 @@
}
// Note: this does not actually fill out the image. That happens at atlas building time.
-void SkStrike::prepareForMaskDrawing(
+void SkScalerCache::prepareForMaskDrawing(
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) {
SkAutoMutexExclusive lock{fMu};
this->commonFilterLoop(drawables,
[&](size_t i, SkGlyph* glyph, SkPoint pos) {
- if (CanDrawAsMask(*glyph)) {
+ if (SkStrikeForGPU::CanDrawAsMask(*glyph)) {
drawables->push_back(glyph, i);
} else {
rejects->reject(i);
@@ -186,12 +186,12 @@
});
}
-void SkStrike::prepareForSDFTDrawing(
+void SkScalerCache::prepareForSDFTDrawing(
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) {
SkAutoMutexExclusive lock{fMu};
this->commonFilterLoop(drawables,
[&](size_t i, SkGlyph* glyph, SkPoint pos) {
- if (CanDrawAsSDFT(*glyph)) {
+ if (SkStrikeForGPU::CanDrawAsSDFT(*glyph)) {
drawables->push_back(glyph, i);
} else {
rejects->reject(i);
@@ -199,7 +199,7 @@
});
}
-void SkStrike::prepareForPathDrawing(
+void SkScalerCache::prepareForPathDrawing(
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) {
SkAutoMutexExclusive lock{fMu};
this->commonFilterLoop(drawables,
@@ -220,12 +220,12 @@
});
}
-void SkStrike::findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
+void SkScalerCache::findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
SkGlyph* glyph, SkScalar* array, int* count) {
glyph->ensureIntercepts(bounds, scale, xPos, array, count, &fAlloc);
}
-void SkStrike::dump() const {
+void SkScalerCache::dump() const {
SkAutoMutexExclusive lock{fMu};
const SkTypeface* face = fScalerContext->getTypeface();
const SkScalerContextRec& rec = fScalerContext->getRec();
@@ -243,10 +243,8 @@
SkDebugf("%s\n", msg.c_str());
}
-void SkStrike::onAboutToExitScope() { }
-
#ifdef SK_DEBUG
-void SkStrike::forceValidate() const {
+void SkScalerCache::forceValidate() const {
SkAutoMutexExclusive lock{fMu};
size_t memoryUsed = sizeof(*this);
fGlyphMap.foreach ([&memoryUsed](const SkGlyph* glyphPtr) {
@@ -261,7 +259,7 @@
SkASSERT(fMemoryUsed == memoryUsed);
}
-void SkStrike::validate() const {
+void SkScalerCache::validate() const {
#ifdef SK_DEBUG_GLYPH_CACHE
forceValidate();
#endif
diff --git a/src/core/SkStrike.h b/src/core/SkScalerCache.h
similarity index 90%
rename from src/core/SkStrike.h
rename to src/core/SkScalerCache.h
index e468ff2..f211532 100644
--- a/src/core/SkStrike.h
+++ b/src/core/SkScalerCache.h
@@ -23,11 +23,11 @@
// This class represents a strike: a specific combination of typeface, size, matrix, etc., and
// holds the glyphs for that strike.
-class SkStrike final : public SkStrikeForGPU {
+class SkScalerCache {
public:
- SkStrike(const SkDescriptor& desc,
- std::unique_ptr<SkScalerContext> scaler,
- const SkFontMetrics* metrics = nullptr);
+ SkScalerCache(const SkDescriptor& desc,
+ std::unique_ptr<SkScalerContext> scaler,
+ const SkFontMetrics* metrics = nullptr);
// Lookup (or create if needed) the toGlyph using toID. If that glyph is not initialized with
// an image, then use the information in from to initialize the width, height top, left,
@@ -51,11 +51,6 @@
return fFontMetrics;
}
- const SkGlyphPositionRoundingSpec& roundingSpec() const override {
- return fRoundingSpec;
- }
-
- const SkDescriptor& getDescriptor() const override;
SkSpan<const SkGlyph*> metrics(SkSpan<const SkGlyphID> glyphIDs,
const SkGlyph* results[]) SK_EXCLUDES(fMu);
@@ -68,16 +63,21 @@
void prepareForDrawingMasksCPU(SkDrawableGlyphBuffer* drawables) SK_EXCLUDES(fMu);
+ // SkStrikeForGPU APIs
+ const SkGlyphPositionRoundingSpec& roundingSpec() const {
+ return fRoundingSpec;
+ }
+
+ const SkDescriptor& getDescriptor() const;
+
void prepareForMaskDrawing(
- SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) override SK_EXCLUDES(fMu);
+ SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) SK_EXCLUDES(fMu);
void prepareForSDFTDrawing(
- SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) override SK_EXCLUDES(fMu);
+ SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) SK_EXCLUDES(fMu);
void prepareForPathDrawing(
- SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) override SK_EXCLUDES(fMu);
-
- void onAboutToExitScope() override;
+ SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) SK_EXCLUDES(fMu);
/** Return the approx RAM usage for this cache. */
size_t getMemoryUsed() const SK_EXCLUDES(fMu) {
@@ -98,7 +98,7 @@
class AutoValidate : SkNoncopyable {
public:
- AutoValidate(const SkStrike* cache) : fCache(cache) {
+ AutoValidate(const SkScalerCache* cache) : fCache(cache) {
if (fCache) {
fCache->validate();
}
@@ -112,7 +112,7 @@
fCache = nullptr;
}
private:
- const SkStrike* fCache;
+ const SkScalerCache* fCache;
};
private:
@@ -173,7 +173,7 @@
SkArenaAlloc fAlloc SK_GUARDED_BY(fMu) {kMinAllocAmount};
// Tracks (approx) how much ram is tied-up in this strike.
- size_t fMemoryUsed SK_GUARDED_BY(fMu) {sizeof(SkStrike)};
+ size_t fMemoryUsed SK_GUARDED_BY(fMu) {sizeof(SkScalerCache)};
};
#endif // SkStrike_DEFINED
diff --git a/src/core/SkStrikeCache.cpp b/src/core/SkStrikeCache.cpp
index 986e7a1..7c793fb 100644
--- a/src/core/SkStrikeCache.cpp
+++ b/src/core/SkStrikeCache.cpp
@@ -16,52 +16,7 @@
#include "include/private/SkMutex.h"
#include "include/private/SkTemplates.h"
#include "src/core/SkGlyphRunPainter.h"
-#include "src/core/SkStrike.h"
-
-class SkStrikeCache::Node final : public SkRefCnt, public SkStrikeForGPU {
-public:
- Node(SkStrikeCache* strikeCache,
- const SkDescriptor& desc,
- std::unique_ptr<SkScalerContext> scaler,
- const SkFontMetrics* metrics,
- std::unique_ptr<SkStrikePinner> pinner)
- : fStrikeCache{strikeCache}
- , fStrike{desc, std::move(scaler), metrics}
- , fPinner{std::move(pinner)} {}
-
- const SkGlyphPositionRoundingSpec& roundingSpec() const override {
- return fStrike.roundingSpec();
- }
-
- const SkDescriptor& getDescriptor() const override {
- return fStrike.getDescriptor();
- }
-
- void prepareForMaskDrawing(
- SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
- fStrike.prepareForMaskDrawing(drawbles, rejects);
- }
-
- void prepareForSDFTDrawing(
- SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
- fStrike.prepareForSDFTDrawing(drawbles, rejects);
- }
-
- void prepareForPathDrawing(
- SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
- fStrike.prepareForPathDrawing(drawbles, rejects);
- }
-
- void onAboutToExitScope() override {
- fStrikeCache->attachNode(this);
- }
-
- SkStrikeCache* const fStrikeCache;
- Node* fNext{nullptr};
- Node* fPrev{nullptr};
- SkStrike fStrike;
- std::unique_ptr<SkStrikePinner> fPinner;
-};
+#include "src/core/SkScalerCache.h"
bool gSkUseThreadLocalStrikeCaches_IAcknowledgeThisIsIncrediblyExperimental = false;
@@ -76,35 +31,35 @@
return cache;
}
-SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(SkStrikeCache::Node* node)
- : fNode{node} {}
+SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(SkStrikeCache::Strike* strike)
+ : fStrike{strike} {}
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr()
- : fNode{nullptr} {}
+ : fStrike{nullptr} {}
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(ExclusiveStrikePtr&& o)
- : fNode{o.fNode} {
- o.fNode = nullptr;
+ : fStrike{o.fStrike} {
+ o.fStrike = nullptr;
}
SkStrikeCache::ExclusiveStrikePtr&
SkStrikeCache::ExclusiveStrikePtr::operator = (ExclusiveStrikePtr&& o) {
- if (fNode != nullptr) {
- fNode->fStrikeCache->attachNode(fNode);
+ if (fStrike != nullptr) {
+ fStrike->fStrikeCache->attachStrike(fStrike);
}
- fNode = o.fNode;
- o.fNode = nullptr;
+ fStrike = o.fStrike;
+ o.fStrike = nullptr;
return *this;
}
SkStrikeCache::ExclusiveStrikePtr::~ExclusiveStrikePtr() {
- if (fNode != nullptr) {
- fNode->fStrikeCache->attachNode(fNode);
+ if (fStrike != nullptr) {
+ fStrike->fStrikeCache->attachStrike(fStrike);
}
}
SkStrike* SkStrikeCache::ExclusiveStrikePtr::get() const {
- return &fNode->fStrike;
+ return fStrike;
}
SkStrike* SkStrikeCache::ExclusiveStrikePtr::operator -> () const {
@@ -116,28 +71,28 @@
}
SkStrikeCache::ExclusiveStrikePtr::operator bool () const {
- return fNode != nullptr;
+ return fStrike != nullptr;
}
bool operator == (const SkStrikeCache::ExclusiveStrikePtr& lhs,
const SkStrikeCache::ExclusiveStrikePtr& rhs) {
- return lhs.fNode == rhs.fNode;
+ return lhs.fStrike == rhs.fStrike;
}
bool operator == (const SkStrikeCache::ExclusiveStrikePtr& lhs, decltype(nullptr)) {
- return lhs.fNode == nullptr;
+ return lhs.fStrike == nullptr;
}
bool operator == (decltype(nullptr), const SkStrikeCache::ExclusiveStrikePtr& rhs) {
- return nullptr == rhs.fNode;
+ return nullptr == rhs.fStrike;
}
SkStrikeCache::~SkStrikeCache() {
- Node* node = fHead;
- while (node) {
- Node* next = node->fNext;
- node->unref();
- node = next;
+ Strike* strike = fHead;
+ while (strike) {
+ Strike* next = strike->fNext;
+ strike->unref();
+ strike = next;
}
}
@@ -149,13 +104,13 @@
auto SkStrikeCache::findOrCreateStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
- const SkTypeface& typeface) -> Node* {
- Node* node = this->findAndDetachStrike(desc);
- if (node == nullptr) {
+ const SkTypeface& typeface) -> Strike* {
+ Strike* strike = this->findAndDetachStrike(desc);
+ if (strike == nullptr) {
auto scaler = typeface.createScalerContext(effects, &desc);
- node = this->createStrike(desc, std::move(scaler));
+ strike = this->createStrike(desc, std::move(scaler));
}
- return node;
+ return strike;
}
SkScopedStrikeForGPU SkStrikeCache::findOrCreateScopedStrike(const SkDescriptor& desc,
@@ -177,8 +132,8 @@
int counter = 0;
- auto visitor = [&counter](const SkStrike& cache) {
- const SkScalerContextRec& rec = cache.getScalerContext()->getRec();
+ auto visitor = [&counter](const Strike& strike) {
+ const SkScalerContextRec& rec = strike.fScalerCache.getScalerContext()->getRec();
SkDebugf("index %d\n", counter);
SkDebugf("%s", rec.dump().c_str());
@@ -206,9 +161,9 @@
return;
}
- auto visitor = [&dump](const SkStrike& cache) {
- const SkTypeface* face = cache.getScalerContext()->getTypeface();
- const SkScalerContextRec& rec = cache.getScalerContext()->getRec();
+ auto visitor = [&dump](const Strike& strike) {
+ const SkTypeface* face = strike.fScalerCache.getScalerContext()->getTypeface();
+ const SkScalerContextRec& rec = strike.fScalerCache.getScalerContext()->getRec();
SkString fontName;
face->getFamilyName(&fontName);
@@ -220,12 +175,13 @@
}
SkString dumpName = SkStringPrintf(
- "%s/%s_%d/%p", gGlyphCacheDumpName, fontName.c_str(), rec.fFontID, &cache);
+ "%s/%s_%d/%p", gGlyphCacheDumpName, fontName.c_str(), rec.fFontID, &strike);
dump->dumpNumericValue(dumpName.c_str(),
- "size", "bytes", cache.getMemoryUsed());
+ "size", "bytes", strike.fScalerCache.getMemoryUsed());
dump->dumpNumericValue(dumpName.c_str(),
- "glyph_count", "objects", cache.countCachedGlyphs());
+ "glyph_count", "objects",
+ strike.fScalerCache.countCachedGlyphs());
dump->setMemoryBacking(dumpName.c_str(), "malloc", nullptr);
};
@@ -233,16 +189,16 @@
}
-void SkStrikeCache::attachNode(Node* node) {
- if (node == nullptr) {
+void SkStrikeCache::attachStrike(Strike* strike) {
+ if (strike == nullptr) {
return;
}
SkAutoSpinlock ac(fLock);
this->validate();
- node->fStrike.validate();
+ strike->fScalerCache.validate();
- this->internalAttachToHead(node);
+ this->internalAttachToHead(strike);
this->internalPurge();
}
@@ -250,13 +206,13 @@
return SkExclusiveStrikePtr(this->findAndDetachStrike(desc));
}
-auto SkStrikeCache::findAndDetachStrike(const SkDescriptor& desc) -> Node* {
+auto SkStrikeCache::findAndDetachStrike(const SkDescriptor& desc) -> Strike* {
SkAutoSpinlock ac(fLock);
- for (Node* node = fHead; node != nullptr; node = node->fNext) {
- if (node->fStrike.getDescriptor() == desc) {
- this->internalDetachCache(node);
- return node;
+ for (Strike* strike = fHead; strike != nullptr; strike = strike->fNext) {
+ if (strike->fScalerCache.getDescriptor() == desc) {
+ this->internalDetachStrike(strike);
+ return strike;
}
}
@@ -277,8 +233,8 @@
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
SkFontMetrics* maybeMetrics,
- std::unique_ptr<SkStrikePinner> pinner) -> Node* {
- return new Node{this, desc, std::move(scaler), maybeMetrics, std::move(pinner)};
+ std::unique_ptr<SkStrikePinner> pinner) -> Strike* {
+ return new Strike{this, desc, std::move(scaler), maybeMetrics, std::move(pinner)};
}
void SkStrikeCache::purgeAll() {
@@ -350,13 +306,13 @@
return prevLimit;
}
-void SkStrikeCache::forEachStrike(std::function<void(const SkStrike&)> visitor) const {
+void SkStrikeCache::forEachStrike(std::function<void(const Strike&)> visitor) const {
SkAutoSpinlock ac(fLock);
this->validate();
- for (Node* node = fHead; node != nullptr; node = node->fNext) {
- visitor(node->fStrike);
+ for (Strike* strike = fHead; strike != nullptr; strike = strike->fNext) {
+ visitor(*strike);
}
}
@@ -390,18 +346,18 @@
// Start at the tail and proceed backwards deleting; the list is in LRU
// order, with unimportant entries at the tail.
- Node* node = fTail;
- while (node != nullptr && (bytesFreed < bytesNeeded || countFreed < countNeeded)) {
- Node* prev = node->fPrev;
+ Strike* strike = fTail;
+ while (strike != nullptr && (bytesFreed < bytesNeeded || countFreed < countNeeded)) {
+ Strike* prev = strike->fPrev;
// Only delete if the strike is not pinned.
- if (node->fPinner == nullptr || node->fPinner->canDelete()) {
- bytesFreed += node->fStrike.getMemoryUsed();
+ if (strike->fPinner == nullptr || strike->fPinner->canDelete()) {
+ bytesFreed += strike->fScalerCache.getMemoryUsed();
countFreed += 1;
- this->internalDetachCache(node);
- node->unref();
+ this->internalDetachStrike(strike);
+ strike->unref();
}
- node = prev;
+ strike = prev;
}
this->validate();
@@ -416,38 +372,38 @@
return bytesFreed;
}
-void SkStrikeCache::internalAttachToHead(Node* node) {
- SkASSERT(nullptr == node->fPrev && nullptr == node->fNext);
+void SkStrikeCache::internalAttachToHead(Strike* strike) {
+ SkASSERT(nullptr == strike->fPrev && nullptr == strike->fNext);
if (fHead) {
- fHead->fPrev = node;
- node->fNext = fHead;
+ fHead->fPrev = strike;
+ strike->fNext = fHead;
}
- fHead = node;
+ fHead = strike;
if (fTail == nullptr) {
- fTail = node;
+ fTail = strike;
}
fCacheCount += 1;
- fTotalMemoryUsed += node->fStrike.getMemoryUsed();
+ fTotalMemoryUsed += strike->fScalerCache.getMemoryUsed();
}
-void SkStrikeCache::internalDetachCache(Node* node) {
+void SkStrikeCache::internalDetachStrike(Strike* strike) {
SkASSERT(fCacheCount > 0);
fCacheCount -= 1;
- fTotalMemoryUsed -= node->fStrike.getMemoryUsed();
+ fTotalMemoryUsed -= strike->fScalerCache.getMemoryUsed();
- if (node->fPrev) {
- node->fPrev->fNext = node->fNext;
+ if (strike->fPrev) {
+ strike->fPrev->fNext = strike->fNext;
} else {
- fHead = node->fNext;
+ fHead = strike->fNext;
}
- if (node->fNext) {
- node->fNext->fPrev = node->fPrev;
+ if (strike->fNext) {
+ strike->fNext->fPrev = strike->fPrev;
} else {
- fTail = node->fPrev;
+ fTail = strike->fPrev;
}
- node->fPrev = node->fNext = nullptr;
+ strike->fPrev = strike->fNext = nullptr;
}
void SkStrikeCache::ValidateGlyphCacheDataSize() {
@@ -459,7 +415,7 @@
#ifdef SK_DEBUG
void SkStrikeCache::validateGlyphCacheDataSize() const {
this->forEachStrike(
- [](const SkStrike& cache) { cache.forceValidate();
+ [](const Strike& strike) { strike.fScalerCache.forceValidate();
});
}
#endif
@@ -469,11 +425,11 @@
size_t computedBytes = 0;
int computedCount = 0;
- const Node* node = fHead;
- while (node != nullptr) {
- computedBytes += node->fStrike.getMemoryUsed();
+ const Strike* strike = fHead;
+ while (strike != nullptr) {
+ computedBytes += strike->fScalerCache.getMemoryUsed();
computedCount += 1;
- node = node->fNext;
+ strike = strike->fNext;
}
// Can't use SkASSERTF because it looses thread annotations.
diff --git a/src/core/SkStrikeCache.h b/src/core/SkStrikeCache.h
index 89035bd..e589d00 100644
--- a/src/core/SkStrikeCache.h
+++ b/src/core/SkStrikeCache.h
@@ -14,7 +14,7 @@
#include "include/private/SkSpinlock.h"
#include "include/private/SkTemplates.h"
#include "src/core/SkDescriptor.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
class SkTraceMemoryDump;
@@ -39,15 +39,102 @@
};
class SkStrikeCache final : public SkStrikeForGPUCacheInterface {
- class Node;
-
public:
SkStrikeCache() = default;
~SkStrikeCache() override;
+ class Strike final : public SkRefCnt, public SkStrikeForGPU {
+ public:
+ Strike(SkStrikeCache* strikeCache,
+ const SkDescriptor& desc,
+ std::unique_ptr<SkScalerContext> scaler,
+ const SkFontMetrics* metrics,
+ std::unique_ptr<SkStrikePinner> pinner)
+ : fStrikeCache{strikeCache}
+ , fScalerCache{desc, std::move(scaler), metrics}
+ , fPinner{std::move(pinner)} {}
+
+ SkGlyph* mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph& from) {
+ return fScalerCache.mergeGlyphAndImage(toID, from);
+ }
+
+ const SkPath* preparePath(SkGlyph* glyph, const SkPath* path) {
+ return fScalerCache.preparePath(glyph, path);
+ }
+
+ SkScalerContext* getScalerContext() const {
+ return fScalerCache.getScalerContext();
+ }
+
+ int countCachedGlyphs() {
+ return fScalerCache.countCachedGlyphs();
+ }
+
+ void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
+ SkGlyph* glyph, SkScalar* array, int* count) {
+ fScalerCache.findIntercepts(bounds, scale, xPos, glyph, array, count);
+ }
+
+ const SkFontMetrics& getFontMetrics() const {
+ return fScalerCache.getFontMetrics();
+ }
+
+ SkSpan<const SkGlyph*> metrics(SkSpan<const SkGlyphID> glyphIDs,
+ const SkGlyph* results[]) {
+ return fScalerCache.metrics(glyphIDs, results);
+ }
+
+ SkSpan<const SkGlyph*> preparePaths(SkSpan<const SkGlyphID> glyphIDs,
+ const SkGlyph* results[]) {
+ return fScalerCache.preparePaths(glyphIDs, results);
+ }
+
+ SkSpan<const SkGlyph*> prepareImages(SkSpan<const SkPackedGlyphID> glyphIDs,
+ const SkGlyph* results[]) {
+ return fScalerCache.prepareImages(glyphIDs, results);
+ }
+
+ void prepareForDrawingMasksCPU(SkDrawableGlyphBuffer* drawables) {
+ return fScalerCache.prepareForDrawingMasksCPU(drawables);
+ }
+
+ const SkGlyphPositionRoundingSpec& roundingSpec() const override {
+ return fScalerCache.roundingSpec();
+ }
+
+ const SkDescriptor& getDescriptor() const override {
+ return fScalerCache.getDescriptor();
+ }
+
+ void prepareForMaskDrawing(
+ SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
+ fScalerCache.prepareForMaskDrawing(drawbles, rejects);
+ }
+
+ void prepareForSDFTDrawing(
+ SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
+ fScalerCache.prepareForSDFTDrawing(drawbles, rejects);
+ }
+
+ void prepareForPathDrawing(
+ SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
+ fScalerCache.prepareForPathDrawing(drawbles, rejects);
+ }
+
+ void onAboutToExitScope() override {
+ fStrikeCache->attachStrike(this);
+ }
+
+ SkStrikeCache* const fStrikeCache;
+ Strike* fNext{nullptr};
+ Strike* fPrev{nullptr};
+ SkScalerCache fScalerCache;
+ std::unique_ptr<SkStrikePinner> fPinner;
+ }; // Strike
+
class ExclusiveStrikePtr {
public:
- explicit ExclusiveStrikePtr(Node*);
+ explicit ExclusiveStrikePtr(Strike*);
ExclusiveStrikePtr();
ExclusiveStrikePtr(const ExclusiveStrikePtr&) = delete;
ExclusiveStrikePtr& operator = (const ExclusiveStrikePtr&) = delete;
@@ -55,16 +142,16 @@
ExclusiveStrikePtr& operator = (ExclusiveStrikePtr&&);
~ExclusiveStrikePtr();
- SkStrike* get() const;
- SkStrike* operator -> () const;
- SkStrike& operator * () const;
+ Strike* get() const;
+ Strike* operator -> () const;
+ Strike& operator * () const;
explicit operator bool () const;
friend bool operator == (const ExclusiveStrikePtr&, const ExclusiveStrikePtr&);
friend bool operator == (const ExclusiveStrikePtr&, decltype(nullptr));
friend bool operator == (decltype(nullptr), const ExclusiveStrikePtr&);
private:
- Node* fNode;
+ Strike* fStrike;
};
static SkStrikeCache* GlobalStrikeCache();
@@ -121,39 +208,40 @@
void validate() const {}
#endif
- Node* findAndDetachStrike(const SkDescriptor&) SK_EXCLUDES(fLock);
- Node* createStrike(
+ Strike* findAndDetachStrike(const SkDescriptor&) SK_EXCLUDES(fLock);
+ Strike* createStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
SkFontMetrics* maybeMetrics = nullptr,
std::unique_ptr<SkStrikePinner> = nullptr);
- Node* findOrCreateStrike(
+ Strike* findOrCreateStrike(
const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) SK_EXCLUDES(fLock);
- void attachNode(Node* node) SK_EXCLUDES(fLock);
+ void attachStrike(Strike* strike) SK_EXCLUDES(fLock);
// The following methods can only be called when mutex is already held.
- void internalDetachCache(Node*) SK_REQUIRES(fLock);
- void internalAttachToHead(Node*) SK_REQUIRES(fLock);
+ void internalDetachStrike(Strike* strike) SK_REQUIRES(fLock);
+ void internalAttachToHead(Strike* strike) SK_REQUIRES(fLock);
// Checkout budgets, modulated by the specified min-bytes-needed-to-purge,
// and attempt to purge caches to match.
// Returns number of bytes freed.
size_t internalPurge(size_t minBytesNeeded = 0) SK_REQUIRES(fLock);
- void forEachStrike(std::function<void(const SkStrike&)> visitor) const;
+ void forEachStrike(std::function<void(const Strike&)> visitor) const;
mutable SkSpinlock fLock;
- Node* fHead SK_GUARDED_BY(fLock) {nullptr};
- Node* fTail SK_GUARDED_BY(fLock) {nullptr};
- size_t fCacheSizeLimit{SK_DEFAULT_FONT_CACHE_LIMIT};
- size_t fTotalMemoryUsed SK_GUARDED_BY(fLock) {0};
- int32_t fCacheCountLimit{SK_DEFAULT_FONT_CACHE_COUNT_LIMIT};
- int32_t fCacheCount SK_GUARDED_BY(fLock) {0};
- int32_t fPointSizeLimit{SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT};
+ Strike* fHead SK_GUARDED_BY(fLock) {nullptr};
+ Strike* fTail SK_GUARDED_BY(fLock) {nullptr};
+ size_t fCacheSizeLimit{SK_DEFAULT_FONT_CACHE_LIMIT};
+ size_t fTotalMemoryUsed SK_GUARDED_BY(fLock) {0};
+ int32_t fCacheCountLimit{SK_DEFAULT_FONT_CACHE_COUNT_LIMIT};
+ int32_t fCacheCount SK_GUARDED_BY(fLock) {0};
+ int32_t fPointSizeLimit{SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT};
};
using SkExclusiveStrikePtr = SkStrikeCache::ExclusiveStrikePtr;
+using SkStrike = SkStrikeCache::Strike;
#endif // SkStrikeCache_DEFINED
diff --git a/src/core/SkTypeface_remote.cpp b/src/core/SkTypeface_remote.cpp
index 7ae809a..21a4fc8 100644
--- a/src/core/SkTypeface_remote.cpp
+++ b/src/core/SkTypeface_remote.cpp
@@ -7,7 +7,7 @@
#include "include/core/SkPaint.h"
#include "src/core/SkRemoteGlyphCache.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkTraceEvent.h"
#include "src/core/SkTypeface_remote.h"
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index bb7554e..880dd43 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -32,8 +32,8 @@
#include "src/core/SkImageFilter_Base.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkRasterClip.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkScopeExit.h"
-#include "src/core/SkStrike.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTextFormatParams.h"
#include "src/core/SkXfermodeInterpretation.h"
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index 4fa981b..9869591 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -30,8 +30,8 @@
#include "src/core/SkGlyph.h"
#include "src/core/SkImagePriv.h"
#include "src/core/SkMask.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkScalerContext.h"
-#include "src/core/SkStrike.h"
#include "src/core/SkStrikeSpec.h"
#include "src/pdf/SkPDFBitmap.h"
#include "src/pdf/SkPDFDocumentPriv.h"
diff --git a/src/pdf/SkPDFFont.h b/src/pdf/SkPDFFont.h
index f047aa1..2c3c858 100644
--- a/src/pdf/SkPDFFont.h
+++ b/src/pdf/SkPDFFont.h
@@ -18,7 +18,6 @@
#include <vector>
class SkPDFDocument;
-class SkStrike;
class SkString;
/** \class SkPDFFont
diff --git a/src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp b/src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp
index 210202d..fdda294 100644
--- a/src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp
+++ b/src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp
@@ -9,7 +9,7 @@
#include "include/core/SkPaint.h"
#include "include/private/SkTo.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/pdf/SkPDFGlyphUse.h"
diff --git a/src/pdf/SkPDFMakeCIDGlyphWidthsArray.h b/src/pdf/SkPDFMakeCIDGlyphWidthsArray.h
index 041fe28..fd541c2 100644
--- a/src/pdf/SkPDFMakeCIDGlyphWidthsArray.h
+++ b/src/pdf/SkPDFMakeCIDGlyphWidthsArray.h
@@ -9,7 +9,6 @@
#include "src/pdf/SkPDFTypes.h"
-class SkStrike;
class SkPDFGlyphUse;
class SkTypeface;
diff --git a/tests/SkRemoteGlyphCacheTest.cpp b/tests/SkRemoteGlyphCacheTest.cpp
index 64cc8b3..96f94d7 100644
--- a/tests/SkRemoteGlyphCacheTest.cpp
+++ b/tests/SkRemoteGlyphCacheTest.cpp
@@ -11,7 +11,7 @@
#include "include/private/SkMutex.h"
#include "src/core/SkDraw.h"
#include "src/core/SkRemoteGlyphCache.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkSurfacePriv.h"
diff --git a/tests/SkStrikeTest.cpp b/tests/SkScalerCacheTest.cpp
similarity index 89%
rename from tests/SkStrikeTest.cpp
rename to tests/SkScalerCacheTest.cpp
index f7876e0..20480f4 100644
--- a/tests/SkStrikeTest.cpp
+++ b/tests/SkScalerCacheTest.cpp
@@ -7,7 +7,7 @@
#include "include/core/SkFont.h"
#include "include/core/SkTypeface.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTaskGroup.h"
#include "tests/Test.h"
@@ -27,7 +27,7 @@
std::atomic<int> fThreadCount;
};
-DEF_TEST(SkStrikeMultiThread, Reporter) {
+DEF_TEST(SkScalerCacheMultiThread, Reporter) {
sk_sp<SkTypeface> typeface =
ToolUtils::create_portable_typeface("serif", SkFontStyle::Italic());
static constexpr int kThreadCount = 4;
@@ -59,7 +59,7 @@
SkScalerContextEffects effects;
std::unique_ptr<SkScalerContext> ctx{
typeface->createScalerContext(effects, &strikeSpec.descriptor())};
- SkStrike strike{strikeSpec.descriptor(), std::move(ctx)};
+ SkScalerCache scalerCache{strikeSpec.descriptor(), std::move(ctx)};
auto perThread = [&](int threadIndex) {
barrier.waitForAll();
@@ -73,8 +73,8 @@
rejects.setSource(local);
drawable.startDevice(rejects.source(), {0, 0}, SkMatrix::I(),
- strike.roundingSpec());
- strike.prepareForMaskDrawing(&drawable, &rejects);
+ scalerCache.roundingSpec());
+ scalerCache.prepareForMaskDrawing(&drawable, &rejects);
rejects.flipRejectsToSource();
drawable.reset();
}