aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-02-07 17:47:59 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-14 18:50:39 +0000
commit67c47f23290f3f947f35deb1145883d57d2c8c61 (patch)
tree32a69de5d6a4fa97ea2a145ea342393406b460c2 /src
parent8b6a9ae7010b11b9d43d518257d7514619bd0fbb (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.cpp7
-rw-r--r--src/core/SkRemoteGlyphCache.h22
-rw-r--r--src/core/SkTypeface_remote.cpp10
-rw-r--r--src/core/SkTypeface_remote.h23
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; }