diff options
author | Brian Salomon <bsalomon@google.com> | 2017-11-19 13:20:13 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-19 18:55:18 +0000 |
commit | cbcb0a12ad0068b820c28178e8aa141166febd1f (patch) | |
tree | 120917b5961b8a043894b95811eec1f8f6379b25 /src/atlastext/SkInternalAtlasTextContext.cpp | |
parent | b07b06e14819c7bfb9da87dd754aca1239045af4 (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.cpp | 117 |
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(); +} |