aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/atlastext/SkInternalAtlasTextContext.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-11-19 13:20:13 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-19 18:55:18 +0000
commitcbcb0a12ad0068b820c28178e8aa141166febd1f (patch)
tree120917b5961b8a043894b95811eec1f8f6379b25 /src/atlastext/SkInternalAtlasTextContext.cpp
parentb07b06e14819c7bfb9da87dd754aca1239045af4 (diff)
Revert "Revert "Add Atlas Text interface for rendering SDF glyphs.""
This reverts commit 9c2202ffc22b4293b48a4edeafa1b5d2bab8bb83. Bug: skia: Change-Id: I482ddf74f8e40d3d0908c840ba5c6ff981ccefbd Reviewed-on: https://skia-review.googlesource.com/73345 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/atlastext/SkInternalAtlasTextContext.cpp')
-rw-r--r--src/atlastext/SkInternalAtlasTextContext.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/atlastext/SkInternalAtlasTextContext.cpp b/src/atlastext/SkInternalAtlasTextContext.cpp
new file mode 100644
index 0000000000..8be7e1fb67
--- /dev/null
+++ b/src/atlastext/SkInternalAtlasTextContext.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkInternalAtlasTextContext.h"
+#include "GrContext.h"
+#include "SkAtlasTextContext.h"
+#include "SkAtlasTextRenderer.h"
+#include "text/GrAtlasGlyphCache.h"
+
+SkAtlasTextRenderer* SkGetAtlasTextRendererFromInternalContext(
+ class SkInternalAtlasTextContext& internal) {
+ return internal.renderer();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+std::unique_ptr<SkInternalAtlasTextContext> SkInternalAtlasTextContext::Make(
+ sk_sp<SkAtlasTextRenderer> renderer) {
+ return std::unique_ptr<SkInternalAtlasTextContext>(
+ new SkInternalAtlasTextContext(std::move(renderer)));
+}
+
+SkInternalAtlasTextContext::SkInternalAtlasTextContext(sk_sp<SkAtlasTextRenderer> renderer)
+ : fRenderer(std::move(renderer)) {
+ GrContextOptions options;
+ options.fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo;
+ options.fMinDistanceFieldFontSize = 0.f;
+ options.fGlyphsAsPathsFontSize = SK_ScalarInfinity;
+ fGrContext = GrContext::MakeMock(nullptr, options);
+}
+
+SkInternalAtlasTextContext::~SkInternalAtlasTextContext() {
+ if (fDistanceFieldAtlas.fProxy) {
+ SkASSERT(1 == fGrContext->getAtlasGlyphCache()->getAtlasPageCount(kA8_GrMaskFormat));
+ fRenderer->deleteTexture(fDistanceFieldAtlas.fTextureHandle);
+ }
+}
+
+GrAtlasGlyphCache* SkInternalAtlasTextContext::atlasGlyphCache() {
+ return fGrContext->getAtlasGlyphCache();
+}
+
+GrTextBlobCache* SkInternalAtlasTextContext::textBlobCache() {
+ return fGrContext->getTextBlobCache();
+}
+
+GrDeferredUploadToken SkInternalAtlasTextContext::addInlineUpload(
+ GrDeferredTextureUploadFn&& upload) {
+ auto token = this->nextDrawToken();
+ fInlineUploads.append(&fArena, InlineUpload{std::move(upload), token});
+ return token;
+}
+
+GrDeferredUploadToken SkInternalAtlasTextContext::addASAPUpload(
+ GrDeferredTextureUploadFn&& upload) {
+ fASAPUploads.append(&fArena, std::move(upload));
+ return this->nextTokenToFlush();
+}
+
+void SkInternalAtlasTextContext::recordDraw(const void* srcVertexData, int glyphCnt,
+ void* targetHandle) {
+ auto vertexDataSize = sizeof(SkAtlasTextRenderer::SDFVertex) * 4 * glyphCnt;
+ auto vertexData = fArena.makeArrayDefault<char>(vertexDataSize);
+ memcpy(vertexData, srcVertexData, vertexDataSize);
+ for (int i = 0; i < 4 * glyphCnt; ++i) {
+ auto* vertex = reinterpret_cast<SkAtlasTextRenderer::SDFVertex*>(vertexData) + i;
+ // GrAtlasTextContext encodes a texture index into the lower bit of each texture coord.
+ // This isn't expected by SkAtlasTextRenderer subclasses.
+ vertex->fTextureCoord.fX /= 2;
+ vertex->fTextureCoord.fY /= 2;
+ }
+ fDraws.append(&fArena, Draw{glyphCnt, this->issueDrawToken(), targetHandle, vertexData});
+}
+
+void SkInternalAtlasTextContext::flush() {
+ auto* atlasGlyphCache = fGrContext->getAtlasGlyphCache();
+ if (!fDistanceFieldAtlas.fProxy) {
+ SkASSERT(1 == atlasGlyphCache->getAtlasPageCount(kA8_GrMaskFormat));
+ fDistanceFieldAtlas.fProxy = atlasGlyphCache->getProxies(kA8_GrMaskFormat)->get();
+ fDistanceFieldAtlas.fTextureHandle =
+ fRenderer->createTexture(SkAtlasTextRenderer::AtlasFormat::kA8,
+ fDistanceFieldAtlas.fProxy->width(),
+ fDistanceFieldAtlas.fProxy->height());
+ }
+ GrDeferredTextureUploadWritePixelsFn writePixelsFn =
+ [this](GrTextureProxy* proxy, int left, int top, int width, int height,
+ GrPixelConfig config, const void* data, size_t rowBytes) -> bool {
+ SkASSERT(kAlpha_8_GrPixelConfig == config);
+ SkASSERT(proxy == this->fDistanceFieldAtlas.fProxy);
+ void* handle = fDistanceFieldAtlas.fTextureHandle;
+ this->fRenderer->setTextureData(handle, data, left, top, width, height, rowBytes);
+ return true;
+ };
+ for (const auto& upload : fASAPUploads) {
+ upload(writePixelsFn);
+ }
+ auto draw = fDraws.begin();
+ auto inlineUpload = fInlineUploads.begin();
+ while (draw != fDraws.end()) {
+ while (inlineUpload != fInlineUploads.end() && inlineUpload->fToken == draw->fToken) {
+ inlineUpload->fUpload(writePixelsFn);
+ ++inlineUpload;
+ }
+ auto vertices = reinterpret_cast<const SkAtlasTextRenderer::SDFVertex*>(draw->fVertexData);
+ fRenderer->drawSDFGlyphs(draw->fTargetHandle, fDistanceFieldAtlas.fTextureHandle, vertices,
+ draw->fGlyphCnt);
+ ++draw;
+ }
+ fASAPUploads.reset();
+ fInlineUploads.reset();
+ fDraws.reset();
+ fArena.reset();
+}