aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-11-17 14:18:12 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-17 20:35:06 +0000
commit39631f3df172feb385527a5d125bc53b0bded7e6 (patch)
treef63361075ecc24f709d379c976b080d4d54949aa /src
parente686cc4efadec7606b3df0f1e4133011d68b10b3 (diff)
Add Atlas Text interface for rendering SDF glyphs.
This new API is built upon SDF text atlas code from the GPU backend. Unlike using the GPU backend to draw text, this set of interfaces allows the client to render the SDF glyphs. The client issues text draws to potentially multiple targets and then the client flushes. The client then gets commands from Skia with data to put into a texture atlas and vertices to draw that reference the texture. The client is responsible for creating the texture, uploading the SDF data to the texture, and drawing the vertices provided by Skia. Change-Id: Ie9447e19b85f0ce1c2b942e5216c787a74f335d3 Reviewed-on: https://skia-review.googlesource.com/59360 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/atlastext/SkAtlasTextContext.cpp17
-rw-r--r--src/atlastext/SkAtlasTextTarget.cpp143
-rw-r--r--src/atlastext/SkInternalAtlasTextContext.cpp117
-rw-r--r--src/atlastext/SkInternalAtlasTextContext.h80
-rw-r--r--src/core/SkArenaAlloc.h6
-rw-r--r--src/core/SkArenaAllocList.h79
-rw-r--r--src/gpu/GrOpFlushState.cpp19
-rw-r--r--src/gpu/GrOpFlushState.h58
-rw-r--r--src/gpu/ops/GrAtlasTextOp.h26
9 files changed, 461 insertions, 84 deletions
diff --git a/src/atlastext/SkAtlasTextContext.cpp b/src/atlastext/SkAtlasTextContext.cpp
new file mode 100644
index 0000000000..85e79118ee
--- /dev/null
+++ b/src/atlastext/SkAtlasTextContext.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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 "SkAtlasTextContext.h"
+#include "SkAtlasTextRenderer.h"
+#include "SkInternalAtlasTextContext.h"
+
+sk_sp<SkAtlasTextContext> SkAtlasTextContext::Make(sk_sp<SkAtlasTextRenderer> renderer) {
+ return sk_sp<SkAtlasTextContext>(new SkAtlasTextContext(std::move(renderer)));
+}
+
+SkAtlasTextContext::SkAtlasTextContext(sk_sp<SkAtlasTextRenderer> renderer)
+ : fInternalContext(SkInternalAtlasTextContext::Make(std::move(renderer))) {}
diff --git a/src/atlastext/SkAtlasTextTarget.cpp b/src/atlastext/SkAtlasTextTarget.cpp
new file mode 100644
index 0000000000..57ece37b4f
--- /dev/null
+++ b/src/atlastext/SkAtlasTextTarget.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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 "SkAtlasTextTarget.h"
+#include "GrClip.h"
+#include "SkAtlasTextContext.h"
+#include "SkAtlasTextFont.h"
+#include "SkAtlasTextRenderer.h"
+#include "SkGr.h"
+#include "SkInternalAtlasTextContext.h"
+#include "ops/GrAtlasTextOp.h"
+#include "text/GrAtlasTextContext.h"
+
+SkAtlasTextTarget::SkAtlasTextTarget(sk_sp<SkAtlasTextContext> context, int width, int height,
+ void* handle)
+ : fHandle(handle), fContext(std::move(context)), fWidth(width), fHeight(height) {}
+
+SkAtlasTextTarget::~SkAtlasTextTarget() { fContext->renderer()->targetDeleted(fHandle); }
+
+//////////////////////////////////////////////////////////////////////////////
+
+static const GrColorSpaceInfo kColorSpaceInfo(nullptr, kRGBA_8888_GrPixelConfig);
+
+//////////////////////////////////////////////////////////////////////////////
+
+class SkInternalAtlasTextTarget : public GrTextUtils::Target, public SkAtlasTextTarget {
+public:
+ SkInternalAtlasTextTarget(sk_sp<SkAtlasTextContext> context, int width, int height,
+ void* handle)
+ : GrTextUtils::Target(width, height, kColorSpaceInfo)
+ , SkAtlasTextTarget(std::move(context), width, height, handle) {}
+
+ /** GrTextUtils::Target overrides */
+
+ void addDrawOp(const GrClip&, std::unique_ptr<GrAtlasTextOp> op) override;
+
+ void drawPath(const GrClip&, const SkPath&, const SkPaint&, const SkMatrix& viewMatrix,
+ const SkMatrix* pathMatrix, const SkIRect& clipBounds) override {
+ SkDebugf("Path glyph??");
+ }
+
+ void makeGrPaint(GrMaskFormat, const SkPaint& skPaint, const SkMatrix&,
+ GrPaint* grPaint) override {
+ grPaint->setColor4f(SkColorToPremulGrColor4fLegacy(skPaint.getColor()));
+ }
+
+ /** SkAtlasTextTarget overrides */
+
+ void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, uint32_t color,
+ const SkAtlasTextFont&) override;
+ void flush() override;
+
+private:
+ uint32_t fColor;
+ using SkAtlasTextTarget::fWidth;
+ using SkAtlasTextTarget::fHeight;
+ struct RecordedOp {
+ std::unique_ptr<GrAtlasTextOp> fOp;
+ uint32_t fColor;
+ };
+ SkTArray<RecordedOp, true> fOps;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+std::unique_ptr<SkAtlasTextTarget> SkAtlasTextTarget::Make(sk_sp<SkAtlasTextContext> context,
+ int width, int height, void* handle) {
+ return std::unique_ptr<SkAtlasTextTarget>(
+ new SkInternalAtlasTextTarget(std::move(context), width, height, handle));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include "GrContextPriv.h"
+#include "GrDrawingManager.h"
+
+void SkInternalAtlasTextTarget::drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, uint32_t color, const SkAtlasTextFont& font) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTypeface(font.refTypeface());
+ paint.setTextSize(font.size());
+ paint.setStyle(SkPaint::kFill_Style);
+
+ // TODO: Figure out what if anything to do with these:
+ // Paint setTextEncoding? Font isEnableByteCodeHints()? Font isUseNonLinearMetrics()?
+
+ // The atlas text context does munging of the paint color. We store the client's color here
+ // and the context will write it into the final vertices given to the client's renderer.
+ fColor = color;
+
+ // The pixel geometry here is arbitrary. We don't draw LCD text.
+ SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag, kUnknown_SkPixelGeometry);
+ auto* grContext = this->context()->internal().grContext();
+ auto bounds = SkIRect::MakeWH(fWidth, fHeight);
+ auto atlasTextContext = grContext->contextPriv().drawingManager()->getAtlasTextContext();
+ atlasTextContext->drawText(grContext, this, GrNoClip(), paint, SkMatrix::I(), props,
+ (const char*)text, byteLength, x, y, bounds);
+}
+
+void SkInternalAtlasTextTarget::addDrawOp(const GrClip& clip, std::unique_ptr<GrAtlasTextOp> op) {
+ SkASSERT(clip.quickContains(SkRect::MakeIWH(fWidth, fHeight)));
+ // The SkAtlasTextRenderer currently only handles grayscale SDF glyphs.
+ if (op->maskType() != GrAtlasTextOp::kGrayscaleDistanceField_MaskType) {
+ return;
+ }
+ // TODO: batch ops here.
+ op->visitProxies([](GrSurfaceProxy*) {});
+ fOps.emplace_back(RecordedOp{std::move(op), fColor});
+}
+
+void SkInternalAtlasTextTarget::flush() {
+ for (int i = 0; i < fOps.count(); ++i) {
+ fOps[i].fOp->executeForTextTarget(this, fOps[i].fColor);
+ }
+ this->context()->internal().flush();
+ fOps.reset();
+}
+
+void GrAtlasTextOp::executeForTextTarget(SkAtlasTextTarget* target, uint32_t color) {
+ FlushInfo flushInfo;
+ SkAutoGlyphCache glyphCache;
+ auto& context = target->context()->internal();
+ auto* atlasGlyphCache = context.grContext()->getAtlasGlyphCache();
+ for (int i = 0; i < fGeoCount; ++i) {
+ GrAtlasTextBlob::VertexRegenerator regenerator(
+ fGeoData[i].fBlob, fGeoData[i].fRun, fGeoData[i].fSubRun, fGeoData[i].fViewMatrix,
+ fGeoData[i].fX, fGeoData[i].fY, color, &context, atlasGlyphCache, &glyphCache);
+ GrAtlasTextBlob::VertexRegenerator::Result result;
+ do {
+ result = regenerator.regenerate();
+ context.recordDraw(result.fFirstVertex, result.fGlyphsRegenerated, target->handle());
+ if (!result.fFinished) {
+ // Make space in the atlas so we can continue generating vertices.
+ context.flush();
+ }
+ } while (!result.fFinished);
+ }
+}
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();
+}
diff --git a/src/atlastext/SkInternalAtlasTextContext.h b/src/atlastext/SkInternalAtlasTextContext.h
new file mode 100644
index 0000000000..1bb12cee5a
--- /dev/null
+++ b/src/atlastext/SkInternalAtlasTextContext.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkInternalAtlasTextContext_DEFINED
+#define SkInternalAtlasTextContext_DEFINED
+
+#include "GrDeferredUpload.h"
+#include "SkArenaAlloc.h"
+#include "SkArenaAllocList.h"
+#include "SkRefCnt.h"
+
+class SkAtlasTextRenderer;
+class GrContext;
+class GrAtlasGlyphCache;
+class GrTextBlobCache;
+
+/**
+ * The implementation of SkAtlasTextContext. This exists to hide the details from the public class.
+ * and to be able to use other private types.
+ */
+class SkInternalAtlasTextContext : public GrDeferredUploadTarget {
+public:
+ static std::unique_ptr<SkInternalAtlasTextContext> Make(sk_sp<SkAtlasTextRenderer>);
+
+ ~SkInternalAtlasTextContext() override;
+
+ SkAtlasTextRenderer* renderer() const { return fRenderer.get(); }
+
+ GrContext* grContext() const { return fGrContext.get(); }
+ GrAtlasGlyphCache* atlasGlyphCache();
+ GrTextBlobCache* textBlobCache();
+
+ GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) override;
+
+ GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) override;
+
+ void recordDraw(const void* vertexData, int glyphCnt, void* targetHandle);
+
+ void flush();
+
+private:
+ class DeferredUploader;
+ SkInternalAtlasTextContext() = delete;
+ SkInternalAtlasTextContext(const SkInternalAtlasTextContext&) = delete;
+ SkInternalAtlasTextContext& operator=(const SkInternalAtlasTextContext&) = delete;
+
+ SkInternalAtlasTextContext(sk_sp<SkAtlasTextRenderer>);
+
+ sk_sp<SkAtlasTextRenderer> fRenderer;
+
+ struct AtlasTexture {
+ void* fTextureHandle = nullptr;
+ GrTextureProxy* fProxy = nullptr;
+ };
+
+ struct Draw {
+ int fGlyphCnt;
+ GrDeferredUploadToken fToken;
+ void* fTargetHandle;
+ const void* fVertexData;
+ };
+
+ struct InlineUpload {
+ GrDeferredTextureUploadFn fUpload;
+ GrDeferredUploadToken fToken;
+ };
+
+ SkArenaAllocList<InlineUpload> fInlineUploads;
+ SkArenaAllocList<Draw> fDraws;
+ SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads;
+ SkArenaAlloc fArena{1024 * 40};
+ sk_sp<GrContext> fGrContext;
+ AtlasTexture fDistanceFieldAtlas;
+};
+
+#endif
diff --git a/src/core/SkArenaAlloc.h b/src/core/SkArenaAlloc.h
index 9e971610a6..2f23382ac1 100644
--- a/src/core/SkArenaAlloc.h
+++ b/src/core/SkArenaAlloc.h
@@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
-#ifndef SkFixedAlloc_DEFINED
-#define SkFixedAlloc_DEFINED
+#ifndef SkArenaAlloc_DEFINED
+#define SkArenaAlloc_DEFINED
#include "SkRefCnt.h"
#include "SkTFitsIn.h"
@@ -240,4 +240,4 @@ private:
using INHERITED = SkArenaAlloc;
};
-#endif//SkFixedAlloc_DEFINED
+#endif // SkArenaAlloc_DEFINED
diff --git a/src/core/SkArenaAllocList.h b/src/core/SkArenaAllocList.h
new file mode 100644
index 0000000000..b4e442b0bd
--- /dev/null
+++ b/src/core/SkArenaAllocList.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkArenaAllocList_DEFINED
+#define SkArenaAllocList_DEFINED
+
+#include "SkArenaAlloc.h"
+
+/**
+ * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns
+ * the elements. This supports forward iteration and range based for loops.
+ */
+template <typename T>
+class SkArenaAllocList {
+private:
+ struct Node;
+
+public:
+ SkArenaAllocList() = default;
+
+ void reset() { fHead = fTail = nullptr; }
+
+ template <typename... Args>
+ inline T& append(SkArenaAlloc* arena, Args... args);
+
+ class Iter {
+ public:
+ Iter() = default;
+ inline Iter& operator++();
+ T& operator*() const { return fCurr->fT; }
+ T* operator->() const { return &fCurr->fT; }
+ bool operator==(const Iter& that) const { return fCurr == that.fCurr; }
+ bool operator!=(const Iter& that) const { return !(*this == that); }
+
+ private:
+ friend class SkArenaAllocList;
+ explicit Iter(Node* node) : fCurr(node) {}
+ Node* fCurr = nullptr;
+ };
+
+ Iter begin() { return Iter(fHead); }
+ Iter end() { return Iter(); }
+ Iter tail() { return Iter(fTail); }
+
+private:
+ struct Node {
+ template <typename... Args>
+ Node(Args... args) : fT(std::forward<Args>(args)...) {}
+ T fT;
+ Node* fNext = nullptr;
+ };
+ Node* fHead = nullptr;
+ Node* fTail = nullptr;
+};
+
+template <typename T>
+template <typename... Args>
+T& SkArenaAllocList<T>::append(SkArenaAlloc* arena, Args... args) {
+ SkASSERT(!fHead == !fTail);
+ auto* n = arena->make<Node>(std::forward<Args>(args)...);
+ if (!fTail) {
+ fHead = fTail = n;
+ } else {
+ fTail = fTail->fNext = n;
+ }
+ return fTail->fT;
+}
+
+template <typename T>
+typename SkArenaAllocList<T>::Iter& SkArenaAllocList<T>::Iter::operator++() {
+ fCurr = fCurr->fNext;
+ return *this;
+}
+
+#endif
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 6ac5d13430..5245a9d9b2 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -12,25 +12,6 @@
#include "GrResourceProvider.h"
#include "GrTexture.h"
-template <typename T>
-template <typename... Args>
-T& GrOpFlushState::List<T>::append(SkArenaAlloc* arena, Args... args) {
- SkASSERT(!fHead == !fTail);
- auto* n = arena->make<Node>(std::forward<Args>(args)...);
- if (!fTail) {
- fHead = fTail = n;
- } else {
- fTail = fTail->fNext = n;
- }
- return fTail->fT;
-}
-
-template <typename T>
-typename GrOpFlushState::List<T>::Iter& GrOpFlushState::List<T>::Iter::operator++() {
- fCurr = fCurr->fNext;
- return *this;
-}
-
//////////////////////////////////////////////////////////////////////////////
GrOpFlushState::GrOpFlushState(GrGpu* gpu, GrResourceProvider* resourceProvider)
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index b20098aac7..a9cf9a070f 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -13,6 +13,7 @@
#include "GrBufferAllocPool.h"
#include "GrDeferredUpload.h"
#include "SkArenaAlloc.h"
+#include "SkArenaAllocList.h"
#include "ops/GrMeshDrawOp.h"
class GrGpu;
@@ -110,53 +111,6 @@ private:
uint32_t fOpID;
};
- /**
- * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns
- * the elements. This supports forward iteration and range based for loops.
- */
- template <typename T>
- class List {
- private:
- struct Node;
-
- public:
- List() = default;
-
- void reset() { fHead = fTail = nullptr; }
-
- template <typename... Args>
- T& append(SkArenaAlloc* arena, Args... args);
-
- class Iter {
- public:
- Iter() = default;
- Iter& operator++();
- T& operator*() const { return fCurr->fT; }
- T* operator->() const { return &fCurr->fT; }
- bool operator==(const Iter& that) const { return fCurr == that.fCurr; }
- bool operator!=(const Iter& that) const { return !(*this == that); }
-
- private:
- friend class List;
- explicit Iter(Node* node) : fCurr(node) {}
- Node* fCurr = nullptr;
- };
-
- Iter begin() { return Iter(fHead); }
- Iter end() { return Iter(); }
- Iter tail() { return Iter(fTail); }
-
- private:
- struct Node {
- template <typename... Args>
- Node(Args... args) : fT(std::forward<Args>(args)...) {}
- T fT;
- Node* fNext = nullptr;
- };
- Node* fHead = nullptr;
- Node* fTail = nullptr;
- };
-
// Storage for ops' pipelines, draws, and inline uploads.
SkArenaAlloc fArena{sizeof(GrPipeline) * 100};
@@ -165,9 +119,9 @@ private:
GrIndexBufferAllocPool fIndexPool;
// Data stored on behalf of the ops being flushed.
- List<GrDeferredTextureUploadFn> fAsapUploads;
- List<InlineUpload> fInlineUploads;
- List<Draw> fDraws;
+ SkArenaAllocList<GrDeferredTextureUploadFn> fAsapUploads;
+ SkArenaAllocList<InlineUpload> fInlineUploads;
+ SkArenaAllocList<Draw> fDraws;
// TODO: These should go in the arena. However, GrGpuCommandBuffer and other classes currently
// accept contiguous arrays of meshes.
SkSTArray<16, GrMesh> fMeshes;
@@ -185,9 +139,9 @@ private:
GrGpuCommandBuffer* fCommandBuffer = nullptr;
// Variables that are used to track where we are in lists as ops are executed
- List<Draw>::Iter fCurrDraw;
+ SkArenaAllocList<Draw>::Iter fCurrDraw;
int fCurrMesh;
- List<InlineUpload>::Iter fCurrUpload;
+ SkArenaAllocList<InlineUpload>::Iter fCurrUpload;
};
#endif
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index 240b98b6f0..c8ef643fd2 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -12,6 +12,8 @@
#include "text/GrAtlasTextContext.h"
#include "text/GrDistanceFieldAdjustTable.h"
+class SkAtlasTextTarget;
+
class GrAtlasTextOp final : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
@@ -116,6 +118,20 @@ public:
RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip,
GrPixelConfigIsClamped dstIsClamped) override;
+ enum MaskType {
+ kGrayscaleCoverageMask_MaskType,
+ kLCDCoverageMask_MaskType,
+ kColorBitmapMask_MaskType,
+ kAliasedDistanceField_MaskType,
+ kGrayscaleDistanceField_MaskType,
+ kLCDDistanceField_MaskType,
+ kLCDBGRDistanceField_MaskType,
+ };
+
+ MaskType maskType() const { return fMaskType; }
+
+ void executeForTextTarget(SkAtlasTextTarget*, uint32_t color);
+
private:
// The minimum number of Geometry we will try to allocate.
static constexpr auto kMinGeometryAllocated = 12;
@@ -180,16 +196,6 @@ private:
sk_sp<GrGeometryProcessor> setupDfProcessor() const;
- enum MaskType {
- kGrayscaleCoverageMask_MaskType,
- kLCDCoverageMask_MaskType,
- kColorBitmapMask_MaskType,
- kAliasedDistanceField_MaskType,
- kGrayscaleDistanceField_MaskType,
- kLCDDistanceField_MaskType,
- kLCDBGRDistanceField_MaskType,
- };
-
SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
int fGeoDataAllocSize;
GrColor fColor;