Move strike cache backpointer to glyph cache

Change-Id: Ibe53217753d164a13e5666d6444f75a51b7f9c39
Reviewed-on: https://skia-review.googlesource.com/c/170762
Commit-Queue: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Herb Derby 2018-11-13 12:26:10 -05:00 committed by Skia Commit-Bot
parent 7db8068165
commit dcdabf3b37
2 changed files with 106 additions and 38 deletions

View File

@ -10,6 +10,7 @@
#include <cctype> #include <cctype>
#include "SkGlyphCache.h" #include "SkGlyphCache.h"
#include "SkGlyphRunPainter.h"
#include "SkGraphics.h" #include "SkGraphics.h"
#include "SkMutex.h" #include "SkMutex.h"
#include "SkTemplates.h" #include "SkTemplates.h"
@ -17,56 +18,61 @@
#include "SkTypeface.h" #include "SkTypeface.h"
#include "SkPaintPriv.h" #include "SkPaintPriv.h"
SkStrikeCache* SkStrikeCache::GlobalStrikeCache() { class SkStrikeCache::Node final : public SkGlyphCacheInterface {
static auto* cache = new SkStrikeCache; public:
return cache; Node(SkStrikeCache* strikeCache,
} const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkFontMetrics& metrics,
std::unique_ptr<SkStrikePinner> pinner)
: fStrikeCache{strikeCache}
, fCache{desc, std::move(scaler), metrics}
, fPinner{std::move(pinner)} {}
struct SkStrikeCache::Node { SkVector rounding() const override {
Node(const SkDescriptor& desc, return fCache.rounding();
std::unique_ptr<SkScalerContext> scaler, }
const SkFontMetrics& metrics,
std::unique_ptr<SkStrikePinner> pinner)
: fCache{desc, std::move(scaler), metrics}
, fPinner{std::move(pinner)} {}
const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override {
return fCache.getGlyphMetrics(glyphID, position);
}
SkStrikeCache* const fStrikeCache;
Node* fNext{nullptr}; Node* fNext{nullptr};
Node* fPrev{nullptr}; Node* fPrev{nullptr};
SkGlyphCache fCache; SkGlyphCache fCache;
std::unique_ptr<SkStrikePinner> fPinner; std::unique_ptr<SkStrikePinner> fPinner;
}; };
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr( SkStrikeCache* SkStrikeCache::GlobalStrikeCache() {
SkStrikeCache::Node* node, SkStrikeCache* strikeCache) static auto* cache = new SkStrikeCache;
: fNode{node} return cache;
, fStrikeCache{strikeCache} {} }
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(SkStrikeCache::Node* node)
: fNode{node} {}
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr() SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr()
: fNode{nullptr} : fNode{nullptr} {}
, fStrikeCache{nullptr} {}
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(ExclusiveStrikePtr&& o) SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(ExclusiveStrikePtr&& o)
: fNode{o.fNode} : fNode{o.fNode} {
, fStrikeCache{o.fStrikeCache}{
o.fNode = nullptr; o.fNode = nullptr;
o.fStrikeCache = nullptr;
} }
SkStrikeCache::ExclusiveStrikePtr& SkStrikeCache::ExclusiveStrikePtr&
SkStrikeCache::ExclusiveStrikePtr::operator = (ExclusiveStrikePtr&& o) { SkStrikeCache::ExclusiveStrikePtr::operator = (ExclusiveStrikePtr&& o) {
if (fStrikeCache != nullptr) { if (fNode != nullptr) {
fStrikeCache->attachNode(fNode); fNode->fStrikeCache->attachNode(fNode);
} }
fNode = o.fNode; fNode = o.fNode;
fStrikeCache = o.fStrikeCache;
o.fNode = nullptr; o.fNode = nullptr;
o.fStrikeCache = nullptr;
return *this; return *this;
} }
SkStrikeCache::ExclusiveStrikePtr::~ExclusiveStrikePtr() { SkStrikeCache::ExclusiveStrikePtr::~ExclusiveStrikePtr() {
if (fStrikeCache != nullptr) { if (fNode != nullptr) {
fStrikeCache->attachNode(fNode); fNode->fStrikeCache->attachNode(fNode);
} }
} }
@ -138,12 +144,18 @@ SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
SkExclusiveStrikePtr SkStrikeCache::findOrCreateStrikeExclusive( SkExclusiveStrikePtr SkStrikeCache::findOrCreateStrikeExclusive(
const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface) const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface)
{ {
auto cache = this->findStrikeExclusive(desc); return SkExclusiveStrikePtr(this->findOrCreateStrike(desc, effects, typeface));
if (cache == nullptr) { }
auto SkStrikeCache::findOrCreateStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) -> Node* {
Node* node = this->findAndDetachStrike(desc);
if (node == nullptr) {
auto scaler = CreateScalerContext(desc, effects, typeface); auto scaler = CreateScalerContext(desc, effects, typeface);
cache = this->createStrikeExclusive(desc, std::move(scaler)); node = this->createStrike(desc, std::move(scaler));
} }
return cache; return node;
} }
SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive( SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
@ -151,6 +163,25 @@ SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
const SkSurfaceProps& surfaceProps, const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags, SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix) const SkMatrix& deviceMatrix)
{
return SkExclusiveStrikePtr(
GlobalStrikeCache()->findOrCreateStrike(
paint, surfaceProps, scalerContextFlags,deviceMatrix));
}
SkGlyphCacheInterface* SkStrikeCache::findOrCreateGlyphCache(
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix) {
return findOrCreateStrike(paint, surfaceProps, scalerContextFlags, deviceMatrix);
}
auto SkStrikeCache::findOrCreateStrike(
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix) -> Node*
{ {
SkAutoDescriptor ad; SkAutoDescriptor ad;
SkScalerContextEffects effects; SkScalerContextEffects effects;
@ -160,7 +191,7 @@ SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
auto tf = SkPaintPriv::GetTypefaceOrDefault(paint); auto tf = SkPaintPriv::GetTypefaceOrDefault(paint);
return FindOrCreateStrikeExclusive(*desc, effects, *tf); return this->findOrCreateStrike(*desc, effects, *tf);
} }
SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(const SkPaint& paint) { SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(const SkPaint& paint) {
@ -252,18 +283,23 @@ void SkStrikeCache::attachNode(Node* node) {
} }
SkExclusiveStrikePtr SkStrikeCache::findStrikeExclusive(const SkDescriptor& desc) { SkExclusiveStrikePtr SkStrikeCache::findStrikeExclusive(const SkDescriptor& desc) {
return SkExclusiveStrikePtr(this->findAndDetachStrike(desc));
}
auto SkStrikeCache::findAndDetachStrike(const SkDescriptor& desc) -> Node* {
SkAutoExclusive ac(fLock); SkAutoExclusive ac(fLock);
for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) { for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) {
if (node->fCache.getDescriptor() == desc) { if (node->fCache.getDescriptor() == desc) {
this->internalDetachCache(node); this->internalDetachCache(node);
return SkExclusiveStrikePtr(node, this); return node;
} }
} }
return SkExclusiveStrikePtr(); return nullptr;
} }
static bool loose_compare(const SkDescriptor& lhs, const SkDescriptor& rhs) { static bool loose_compare(const SkDescriptor& lhs, const SkDescriptor& rhs) {
uint32_t size; uint32_t size;
auto ptr = lhs.findEntry(kRec_SkDescriptorTag, &size); auto ptr = lhs.findEntry(kRec_SkDescriptorTag, &size);
@ -363,6 +399,15 @@ SkExclusiveStrikePtr SkStrikeCache::createStrikeExclusive(
SkFontMetrics* maybeMetrics, SkFontMetrics* maybeMetrics,
std::unique_ptr<SkStrikePinner> pinner) std::unique_ptr<SkStrikePinner> pinner)
{ {
return SkExclusiveStrikePtr(
this->createStrike(desc, std::move(scaler), maybeMetrics, std::move(pinner)));
}
auto SkStrikeCache::createStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
SkFontMetrics* maybeMetrics,
std::unique_ptr<SkStrikePinner> pinner) -> Node* {
SkFontMetrics fontMetrics; SkFontMetrics fontMetrics;
if (maybeMetrics != nullptr) { if (maybeMetrics != nullptr) {
fontMetrics = *maybeMetrics; fontMetrics = *maybeMetrics;
@ -370,8 +415,7 @@ SkExclusiveStrikePtr SkStrikeCache::createStrikeExclusive(
scaler->getFontMetrics(&fontMetrics); scaler->getFontMetrics(&fontMetrics);
} }
auto* node = new Node(desc, std::move(scaler), fontMetrics, std::move(pinner)); return new Node{this, desc, std::move(scaler), fontMetrics, std::move(pinner)};
return SkExclusiveStrikePtr(node, this);
} }
void SkStrikeCache::purgeAll() { void SkStrikeCache::purgeAll() {

View File

@ -12,6 +12,7 @@
#include <unordered_set> #include <unordered_set>
#include "SkDescriptor.h" #include "SkDescriptor.h"
#include "SkGlyphCache.h"
#include "SkSpinlock.h" #include "SkSpinlock.h"
#include "SkTemplates.h" #include "SkTemplates.h"
@ -39,7 +40,7 @@ public:
}; };
class SkStrikeCache { class SkStrikeCache {
struct Node; class Node;
public: public:
SkStrikeCache() = default; SkStrikeCache() = default;
@ -47,7 +48,7 @@ public:
class ExclusiveStrikePtr { class ExclusiveStrikePtr {
public: public:
explicit ExclusiveStrikePtr(Node*, SkStrikeCache*); explicit ExclusiveStrikePtr(Node*);
ExclusiveStrikePtr(); ExclusiveStrikePtr();
ExclusiveStrikePtr(const ExclusiveStrikePtr&) = delete; ExclusiveStrikePtr(const ExclusiveStrikePtr&) = delete;
ExclusiveStrikePtr& operator = (const ExclusiveStrikePtr&) = delete; ExclusiveStrikePtr& operator = (const ExclusiveStrikePtr&) = delete;
@ -65,13 +66,13 @@ public:
private: private:
Node* fNode; Node* fNode;
SkStrikeCache* fStrikeCache;
}; };
static SkStrikeCache* GlobalStrikeCache(); static SkStrikeCache* GlobalStrikeCache();
static ExclusiveStrikePtr FindStrikeExclusive(const SkDescriptor&); static ExclusiveStrikePtr FindStrikeExclusive(const SkDescriptor&);
ExclusiveStrikePtr findStrikeExclusive(const SkDescriptor&); ExclusiveStrikePtr findStrikeExclusive(const SkDescriptor&);
Node* findAndDetachStrike(const SkDescriptor&);
static ExclusiveStrikePtr CreateStrikeExclusive( static ExclusiveStrikePtr CreateStrikeExclusive(
const SkDescriptor& desc, const SkDescriptor& desc,
@ -85,6 +86,12 @@ public:
SkFontMetrics* maybeMetrics = nullptr, SkFontMetrics* maybeMetrics = nullptr,
std::unique_ptr<SkStrikePinner> = nullptr); std::unique_ptr<SkStrikePinner> = nullptr);
Node* createStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
SkPaint::FontMetrics* maybeMetrics = nullptr,
std::unique_ptr<SkStrikePinner> = nullptr);
static ExclusiveStrikePtr FindOrCreateStrikeExclusive( static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
const SkDescriptor& desc, const SkDescriptor& desc,
const SkScalerContextEffects& effects, const SkScalerContextEffects& effects,
@ -95,6 +102,11 @@ public:
const SkScalerContextEffects& effects, const SkScalerContextEffects& effects,
const SkTypeface& typeface); const SkTypeface& typeface);
Node* findOrCreateStrike(
const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface);
// Routines to find suitable data when working in a remote cache situation. These are // Routines to find suitable data when working in a remote cache situation. These are
// suitable as substitutes for similar calls in SkScalerContext. // suitable as substitutes for similar calls in SkScalerContext.
bool desperationSearchForImage(const SkDescriptor& desc, bool desperationSearchForImage(const SkDescriptor& desc,
@ -108,6 +120,18 @@ public:
SkScalerContextFlags scalerContextFlags, SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix); const SkMatrix& deviceMatrix);
SkGlyphCacheInterface* findOrCreateGlyphCache(
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix);
Node* findOrCreateStrike(
const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& deviceMatrix);
static ExclusiveStrikePtr FindOrCreateStrikeWithNoDeviceExclusive(const SkPaint& paint); static ExclusiveStrikePtr FindOrCreateStrikeWithNoDeviceExclusive(const SkPaint& paint);
static std::unique_ptr<SkScalerContext> CreateScalerContext( static std::unique_ptr<SkScalerContext> CreateScalerContext(