Consolidate all the id handling and caching code.
BUG=skia:7515
Change-Id: Iab31e8cadfaa1ce09d85aab9cc84a3e614ea5e45
Reviewed-on: https://skia-review.googlesource.com/100420
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp
new file mode 100644
index 0000000..a2044ff
--- /dev/null
+++ b/src/core/SkRemoteGlyphCache.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkRemoteGlyphCache.h"
+
+struct WireTypeface {
+ // std::thread::id thread_id; // TODO:need to figure a good solution
+ SkFontID typeface_id;
+ SkFontStyle style;
+ bool is_fixed;
+};
+
+void SkRemoteGlyphCacheRenderer::prepareSerializeProcs(SkSerialProcs* procs) {
+ auto encode = [](SkTypeface* tf, void* ctx) {
+ return reinterpret_cast<SkRemoteGlyphCacheRenderer*>(ctx)->encodeTypeface(tf);
+ };
+ procs->fTypefaceProc = encode;
+ procs->fTypefaceCtx = this;
+}
+
+SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext(
+ const SkScalerContextRecDescriptor& desc, SkFontID typefaceId)
+{
+ auto scaler = fScalerContextMap.find(desc);
+ if (scaler == nullptr) {
+ auto typefaceIter = fTypefaceMap.find(typefaceId);
+ if (typefaceIter == nullptr) {
+ // TODO: handle this with some future fallback strategy.
+ SK_ABORT("unknown type face");
+ // Should never happen
+ return nullptr;
+ }
+ auto tf = typefaceIter->get();
+ SkScalerContextEffects effects;
+ auto mapSc = tf->createScalerContext(effects, &desc.desc(), false);
+ scaler = fScalerContextMap.set(desc, std::move(mapSc));
+ }
+ return scaler->get();
+}
+
+sk_sp<SkData> SkRemoteGlyphCacheRenderer::encodeTypeface(SkTypeface* tf) {
+ WireTypeface wire = {
+ SkTypeface::UniqueID(tf),
+ tf->fontStyle(),
+ tf->isFixedPitch()
+ };
+ auto typeFace = fTypefaceMap.find(SkTypeface::UniqueID(tf));
+ if (typeFace == nullptr) {
+ fTypefaceMap.set(SkTypeface::UniqueID(tf), sk_ref_sp(tf));
+ }
+ // Can this be done with no copy?
+ return SkData::MakeWithCopy(&wire, sizeof(wire));
+}
+
+SkRemoteGlyphCacheGPU::SkRemoteGlyphCacheGPU(
+ std::unique_ptr<SkRemoteScalerContext> remoteScalerContext)
+ : fRemoteScalerContext{std::move(remoteScalerContext)} { }
+
+void SkRemoteGlyphCacheGPU::prepareDeserializeProcs(SkDeserialProcs* procs) {
+ auto decode = [](const void* buf, size_t len, void* ctx) {
+ return reinterpret_cast<SkRemoteGlyphCacheGPU*>(ctx)->decodeTypeface(buf, len);
+ };
+ procs->fTypefaceProc = decode;
+ procs->fTypefaceCtx = this;
+}
+
+sk_sp<SkTypeface> SkRemoteGlyphCacheGPU::decodeTypeface(const void* buf, size_t len) {
+ WireTypeface wire;
+ if (len < sizeof(wire)) {
+ SK_ABORT("Incomplete transfer");
+ return nullptr;
+ }
+ memcpy(&wire, buf, sizeof(wire));
+ auto typeFace = fMapIdToTypeface.find(wire.typeface_id);
+ if (typeFace == nullptr) {
+
+ auto newTypeface = sk_make_sp<SkTypefaceProxy>(
+ wire.typeface_id,
+ wire.style,
+ wire.is_fixed,
+ fRemoteScalerContext.get());
+
+ typeFace = fMapIdToTypeface.set(wire.typeface_id, newTypeface);
+ }
+ return *typeFace;
+}
+
+