diff options
author | 2018-02-07 17:47:59 -0500 | |
---|---|---|
committer | 2018-03-14 18:50:39 +0000 | |
commit | 67c47f23290f3f947f35deb1145883d57d2c8c61 (patch) | |
tree | 32a69de5d6a4fa97ea2a145ea342393406b460c2 /src | |
parent | 8b6a9ae7010b11b9d43d518257d7514619bd0fbb (diff) |
Add glyph cache warming - prototype
A system for prewarming the cache using a single "RPC"
This improve performance by ~5X.
This is a checkin of rough code so I can use small
changes clean it up.
BUG=skia:7515
Change-Id: Id0192b4f533c257b0a7eea0170b1e25c336d6432
Reviewed-on: https://skia-review.googlesource.com/105440
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkRemoteGlyphCache.cpp | 7 | ||||
-rw-r--r-- | src/core/SkRemoteGlyphCache.h | 22 | ||||
-rw-r--r-- | src/core/SkTypeface_remote.cpp | 10 | ||||
-rw-r--r-- | src/core/SkTypeface_remote.h | 23 |
4 files changed, 44 insertions, 18 deletions
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp index 2445f89025..da3a64c894 100644 --- a/src/core/SkRemoteGlyphCache.cpp +++ b/src/core/SkRemoteGlyphCache.cpp @@ -25,6 +25,7 @@ void SkRemoteGlyphCacheRenderer::prepareSerializeProcs(SkSerialProcs* procs) { SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext( const SkScalerContextRecDescriptor& desc, SkFontID typefaceId) { + auto scaler = fScalerContextMap.find(desc); if (scaler == nullptr) { auto typefaceIter = fTypefaceMap.find(typefaceId); @@ -35,6 +36,7 @@ SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext( return nullptr; } auto tf = typefaceIter->get(); + // TODO: make effects really work. SkScalerContextEffects effects; auto mapSc = tf->createScalerContext(effects, &desc.desc(), false); scaler = fScalerContextMap.set(desc, std::move(mapSc)); @@ -68,6 +70,11 @@ void SkRemoteGlyphCacheGPU::prepareDeserializeProcs(SkDeserialProcs* procs) { procs->fTypefaceCtx = this; } +SkTypeface* SkRemoteGlyphCacheGPU::lookupTypeface(SkFontID id) { + auto typeface = fMapIdToTypeface.find(id); + SkASSERT(typeface != nullptr); + return typeface->get(); +} sk_sp<SkTypeface> SkRemoteGlyphCacheGPU::decodeTypeface(const void* buf, size_t len) { WireTypeface wire; diff --git a/src/core/SkRemoteGlyphCache.h b/src/core/SkRemoteGlyphCache.h index 18d2dec2a2..e9afacefd7 100644 --- a/src/core/SkRemoteGlyphCache.h +++ b/src/core/SkRemoteGlyphCache.h @@ -9,6 +9,7 @@ #define SkRemoteGlyphCache_DEFINED #include <memory> +#include <vector> #include "SkData.h" #include "SkDescriptor.h" #include "SkSerialProcs.h" @@ -23,9 +24,13 @@ public: auto desc = reinterpret_cast<SkDescriptor*>(&fDescriptor); desc->init(); desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); + desc->computeChecksum(); SkASSERT(sizeof(fDescriptor) == desc->getLength()); } + explicit SkScalerContextRecDescriptor(const SkDescriptor& desc) + : SkScalerContextRecDescriptor(ExtractRec(desc)) { } + SkScalerContextRecDescriptor& operator=(const SkScalerContextRecDescriptor& rhs) { std::memcpy(&fDescriptor, &rhs.fDescriptor, rhs.desc().getLength()); return *this; @@ -47,6 +52,14 @@ public: } private: + static SkScalerContextRec ExtractRec(const SkDescriptor& desc) { + uint32_t size; + auto recPtr = desc.findEntry(kRec_SkDescriptorTag, &size); + + SkScalerContextRec result; + std::memcpy(&result, recPtr, size); + return result; + } // The system only passes descriptors without effects. That is why it uses a fixed size // descriptor. storageFor is needed because some of the constructors below are private. template <typename T> @@ -70,11 +83,9 @@ private: SkTHashMap<SkFontID, sk_sp<SkTypeface>> fTypefaceMap; - using DescriptorToContextMap = - SkTHashMap< - SkScalerContextRecDescriptor, - std::unique_ptr<SkScalerContext>, - SkScalerContextRecDescriptor::Hash>; + using DescriptorToContextMap = SkTHashMap<SkScalerContextRecDescriptor, + std::unique_ptr<SkScalerContext>, + SkScalerContextRecDescriptor::Hash>; DescriptorToContextMap fScalerContextMap; }; @@ -84,6 +95,7 @@ public: explicit SkRemoteGlyphCacheGPU(std::unique_ptr<SkRemoteScalerContext> remoteScalerContext); void prepareDeserializeProcs(SkDeserialProcs* procs); + SkTypeface* lookupTypeface(SkFontID id); private: sk_sp<SkTypeface> decodeTypeface(const void* buf, size_t len); diff --git a/src/core/SkTypeface_remote.cpp b/src/core/SkTypeface_remote.cpp index e549f3604d..ce3c7f5ba6 100644 --- a/src/core/SkTypeface_remote.cpp +++ b/src/core/SkTypeface_remote.cpp @@ -24,7 +24,6 @@ void SkScalerContextProxy::generateMetrics(SkGlyph* glyph) { } void SkScalerContextProxy::generateImage(const SkGlyph& glyph) { - fRemote->generateImage(*this->typefaceProxy(), this->getRec(), glyph); } void SkScalerContextProxy::generatePath(SkGlyphID glyphID, SkPath* path) { @@ -32,10 +31,13 @@ void SkScalerContextProxy::generatePath(SkGlyphID glyphID, SkPath* path) { } void SkScalerContextProxy::generateFontMetrics(SkPaint::FontMetrics* metrics) { - fRemote->generateFontMetrics(*this->typefaceProxy(), this->getRec(), metrics); + if (!fHaveFontMetrics) { + fRemote->generateFontMetrics(*this->typefaceProxy(), this->getRec(), &fFontMetrics); + } + fHaveFontMetrics = true; + *metrics = fFontMetrics; } SkTypefaceProxy* SkScalerContextProxy::typefaceProxy() { - auto up = this->getTypeface(); - return (SkTypefaceProxy *)up; + return SkTypefaceProxy::DownCast(this->getTypeface()); } diff --git a/src/core/SkTypeface_remote.h b/src/core/SkTypeface_remote.h index b8d972f1c9..750ec21ebe 100644 --- a/src/core/SkTypeface_remote.h +++ b/src/core/SkTypeface_remote.h @@ -12,6 +12,7 @@ #include "SkDescriptor.h" #include "SkFontDescriptor.h" #include "SkFontStyle.h" +#include "SkPaint.h" #include "SkScalerContext.h" #include "SkTypeface.h" @@ -27,14 +28,6 @@ public: const SkTypefaceProxy& tf, const SkScalerContextRec& rec, SkPaint::FontMetrics*) = 0; - virtual void generateMetrics( - const SkTypefaceProxy& tf, - const SkScalerContextRec& rec, - SkGlyph* glyph) = 0; - virtual void generateImage( - const SkTypefaceProxy& tf, - const SkScalerContextRec& rec, - const SkGlyph& glyph) = 0; virtual void generateMetricsAndImage( const SkTypefaceProxy& tf, const SkScalerContextRec& rec, @@ -54,6 +47,11 @@ public: const SkDescriptor* desc, SkRemoteScalerContext* rsc); + void setFontMetrics(const SkPaint::FontMetrics& fontMetrics) { + fFontMetrics = fontMetrics; + fHaveFontMetrics = true; + } + protected: unsigned generateGlyphCount(void) override { SK_ABORT("Should never be called."); return 0;} uint16_t generateCharToGlyph(SkUnichar uni) override { @@ -72,10 +70,13 @@ private: static constexpr size_t kMinGlyphCount = 8; static constexpr size_t kMinGlyphImageSize = 16 /* height */ * 8 /* width */; static constexpr size_t kMinAllocAmount = kMinGlyphImageSize * kMinGlyphCount; - SkArenaAlloc fAlloc{kMinAllocAmount}; SkTypefaceProxy* typefaceProxy(); + + SkArenaAlloc fAlloc{kMinAllocAmount}; SkRemoteScalerContext* const fRemote; + bool fHaveFontMetrics{false}; + SkPaint::FontMetrics fFontMetrics; typedef SkScalerContext INHERITED; }; @@ -90,6 +91,10 @@ public: , fFontId{fontId} , fRsc{rsc} { } SkFontID fontID() const {return fFontId;} + static SkTypefaceProxy* DownCast(SkTypeface* typeface) { + // TODO: how to check the safty of the down cast. + return (SkTypefaceProxy*) typeface; + } protected: int onGetUPEM() const override { SK_ABORT("Should never be called."); return 0; } |