aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/gpu.gni6
-rw-r--r--include/gpu/GrContext.h6
-rw-r--r--src/atlastext/SkAtlasTextTarget.cpp11
-rw-r--r--src/atlastext/SkInternalAtlasTextContext.cpp16
-rw-r--r--src/atlastext/SkInternalAtlasTextContext.h4
-rw-r--r--src/gpu/GrContext.cpp33
-rw-r--r--src/gpu/GrContextPriv.h14
-rw-r--r--src/gpu/GrDrawOpAtlas.cpp3
-rw-r--r--src/gpu/GrOpFlushState.cpp9
-rw-r--r--src/gpu/GrOpFlushState.h6
-rw-r--r--src/gpu/GrProxyProvider.h3
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp35
-rw-r--r--src/gpu/ops/GrAtlasTextOp.h24
-rw-r--r--src/gpu/ops/GrMeshDrawOp.h5
-rw-r--r--src/gpu/text/GrAtlasGlyphCache.h270
-rw-r--r--src/gpu/text/GrAtlasManager.cpp222
-rw-r--r--src/gpu/text/GrAtlasManager.h155
-rw-r--r--src/gpu/text/GrAtlasTextBlob.cpp21
-rw-r--r--src/gpu/text/GrAtlasTextBlob.h24
-rw-r--r--src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp29
-rw-r--r--src/gpu/text/GrAtlasTextContext.cpp121
-rw-r--r--src/gpu/text/GrAtlasTextContext.h27
-rw-r--r--src/gpu/text/GrGlyphCache.cpp (renamed from src/gpu/text/GrAtlasGlyphCache.cpp)191
-rw-r--r--src/gpu/text/GrGlyphCache.h148
-rw-r--r--src/gpu/text/GrTextUtils.h2
-rw-r--r--tests/DrawOpAtlasTest.cpp2
-rw-r--r--tools/gpu/GrTest.cpp10
27 files changed, 788 insertions, 609 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni
index a34e62b6b4..27a50a9a70 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -392,8 +392,8 @@ skia_gpu_sources = [
"$_src/gpu/effects/GrYUVtoRGBEffect.h",
# text
- "$_src/gpu/text/GrAtlasGlyphCache.cpp",
- "$_src/gpu/text/GrAtlasGlyphCache.h",
+ "$_src/gpu/text/GrAtlasManager.cpp",
+ "$_src/gpu/text/GrAtlasManager.h",
"$_src/gpu/text/GrAtlasTextBlob.cpp",
"$_src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp",
"$_src/gpu/text/GrAtlasTextBlob.h",
@@ -401,6 +401,8 @@ skia_gpu_sources = [
"$_src/gpu/text/GrAtlasTextContext.h",
"$_src/gpu/text/GrDistanceFieldAdjustTable.cpp",
"$_src/gpu/text/GrDistanceFieldAdjustTable.h",
+ "$_src/gpu/text/GrGlyphCache.cpp",
+ "$_src/gpu/text/GrGlyphCache.h",
"$_src/gpu/text/GrTextBlobCache.cpp",
"$_src/gpu/text/GrTextBlobCache.h",
"$_src/gpu/text/GrTextUtils.cpp",
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 914983c2ec..ff4ec5f677 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -16,7 +16,7 @@
#include "../private/GrSingleOwner.h"
#include "GrContextOptions.h"
-class GrAtlasGlyphCache;
+class GrAtlasManager;
class GrBackendFormat;
class GrBackendSemaphore;
class GrContextPriv;
@@ -25,6 +25,7 @@ class GrDrawingManager;
struct GrDrawOpAtlasConfig;
class GrFragmentProcessor;
struct GrGLInterface;
+class GrGlyphCache;
class GrGpu;
class GrIndexBuffer;
struct GrMockOptions;
@@ -366,7 +367,8 @@ private:
sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy;
- GrAtlasGlyphCache* fAtlasGlyphCache;
+ GrGlyphCache* fGlyphCache;
+ GrAtlasManager* fFullAtlasManager;
std::unique_ptr<GrTextBlobCache> fTextBlobCache;
bool fDisableGpuYUVConversion;
diff --git a/src/atlastext/SkAtlasTextTarget.cpp b/src/atlastext/SkAtlasTextTarget.cpp
index f553ffad96..9da5fd1e3d 100644
--- a/src/atlastext/SkAtlasTextTarget.cpp
+++ b/src/atlastext/SkAtlasTextTarget.cpp
@@ -181,20 +181,17 @@ void GrAtlasTextOp::finalizeForTextTarget(uint32_t color, const GrCaps& caps) {
void GrAtlasTextOp::executeForTextTarget(SkAtlasTextTarget* target) {
FlushInfo flushInfo;
- SkAutoGlyphCache glyphCache;
+ SkAutoGlyphCache autoGlyphCache;
auto& context = target->context()->internal();
- auto atlasGlyphCache = context.grContext()->contextPriv().getAtlasGlyphCache();
+ auto glyphCache = context.grContext()->contextPriv().getGlyphCache();
+ auto fullAtlasManager = context.grContext()->contextPriv().getFullAtlasManager();
auto resourceProvider = context.grContext()->contextPriv().resourceProvider();
- auto drawingManager = context.grContext()->contextPriv().drawingManager();
-
- GrOnFlushResourceProvider onFlushResourceProvider(drawingManager);
- atlasGlyphCache->preFlush(&onFlushResourceProvider, nullptr, 0, nullptr);
for (int i = 0; i < fGeoCount; ++i) {
GrAtlasTextBlob::VertexRegenerator regenerator(
resourceProvider, fGeoData[i].fBlob, fGeoData[i].fRun, fGeoData[i].fSubRun,
fGeoData[i].fViewMatrix, fGeoData[i].fX, fGeoData[i].fY, fGeoData[i].fColor,
- &context, atlasGlyphCache, &glyphCache);
+ &context, glyphCache, fullAtlasManager, &autoGlyphCache);
GrAtlasTextBlob::VertexRegenerator::Result result;
do {
result = regenerator.regenerate();
diff --git a/src/atlastext/SkInternalAtlasTextContext.cpp b/src/atlastext/SkInternalAtlasTextContext.cpp
index fcb4130665..1e9cbf3079 100644
--- a/src/atlastext/SkInternalAtlasTextContext.cpp
+++ b/src/atlastext/SkInternalAtlasTextContext.cpp
@@ -10,7 +10,7 @@
#include "GrContextPriv.h"
#include "SkAtlasTextContext.h"
#include "SkAtlasTextRenderer.h"
-#include "text/GrAtlasGlyphCache.h"
+#include "text/GrGlyphCache.h"
SkAtlasTextRenderer* SkGetAtlasTextRendererFromInternalContext(
class SkInternalAtlasTextContext& internal) {
@@ -38,17 +38,17 @@ SkInternalAtlasTextContext::SkInternalAtlasTextContext(sk_sp<SkAtlasTextRenderer
SkInternalAtlasTextContext::~SkInternalAtlasTextContext() {
if (fDistanceFieldAtlas.fProxy) {
#ifdef SK_DEBUG
- auto atlasGlyphCache = fGrContext->contextPriv().getAtlasGlyphCache();
+ auto restrictedAtlasManager = fGrContext->contextPriv().getRestrictedAtlasManager();
unsigned int numProxies;
- atlasGlyphCache->getProxies(kA8_GrMaskFormat, &numProxies);
+ restrictedAtlasManager->getProxies(kA8_GrMaskFormat, &numProxies);
SkASSERT(1 == numProxies);
#endif
fRenderer->deleteTexture(fDistanceFieldAtlas.fTextureHandle);
}
}
-GrAtlasGlyphCache* SkInternalAtlasTextContext::atlasGlyphCache() {
- return fGrContext->contextPriv().getAtlasGlyphCache();
+GrGlyphCache* SkInternalAtlasTextContext::glyphCache() {
+ return fGrContext->contextPriv().getGlyphCache();
}
GrTextBlobCache* SkInternalAtlasTextContext::textBlobCache() {
@@ -86,11 +86,11 @@ void SkInternalAtlasTextContext::recordDraw(const void* srcVertexData, int glyph
}
void SkInternalAtlasTextContext::flush() {
- auto* atlasGlyphCache = fGrContext->contextPriv().getAtlasGlyphCache();
+ auto* restrictedAtlasManager = fGrContext->contextPriv().getRestrictedAtlasManager();
if (!fDistanceFieldAtlas.fProxy) {
unsigned int numProxies;
- fDistanceFieldAtlas.fProxy = atlasGlyphCache->getProxies(kA8_GrMaskFormat,
- &numProxies)->get();
+ fDistanceFieldAtlas.fProxy = restrictedAtlasManager->getProxies(kA8_GrMaskFormat,
+ &numProxies)->get();
SkASSERT(1 == numProxies);
fDistanceFieldAtlas.fTextureHandle =
fRenderer->createTexture(SkAtlasTextRenderer::AtlasFormat::kA8,
diff --git a/src/atlastext/SkInternalAtlasTextContext.h b/src/atlastext/SkInternalAtlasTextContext.h
index cdba3ad8b0..22cda5ca51 100644
--- a/src/atlastext/SkInternalAtlasTextContext.h
+++ b/src/atlastext/SkInternalAtlasTextContext.h
@@ -13,8 +13,8 @@
#include "SkArenaAllocList.h"
#include "SkRefCnt.h"
-class GrAtlasGlyphCache;
class GrContext;
+class GrGlyphCache;
class GrTextBlobCache;
class SkAtlasTextRenderer;
@@ -33,7 +33,7 @@ public:
SkAtlasTextRenderer* renderer() const { return fRenderer.get(); }
GrContext* grContext() const { return fGrContext.get(); }
- GrAtlasGlyphCache* atlasGlyphCache();
+ GrGlyphCache* glyphCache();
GrTextBlobCache* textBlobCache();
const GrTokenTracker* tokenTracker() final { return &fTokenTracker; }
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 74fbe10ac1..8ccbb2b754 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -77,6 +77,7 @@ public:
GrDDLContext(GrContextThreadSafeProxy* proxy) : INHERITED(proxy) {}
protected:
+ // DDL TODO: grab a GrRestrictedAtlasManager from the proxy
private:
typedef GrContext INHERITED;
@@ -218,7 +219,8 @@ GrContext::GrContext(GrBackend backend)
fResourceCache = nullptr;
fResourceProvider = nullptr;
fProxyProvider = nullptr;
- fAtlasGlyphCache = nullptr;
+ fGlyphCache = nullptr;
+ fFullAtlasManager = nullptr;
}
GrContext::GrContext(GrContextThreadSafeProxy* proxy)
@@ -228,7 +230,8 @@ GrContext::GrContext(GrContextThreadSafeProxy* proxy)
fResourceCache = nullptr;
fResourceProvider = nullptr;
fProxyProvider = nullptr;
- fAtlasGlyphCache = nullptr;
+ fGlyphCache = nullptr;
+ fFullAtlasManager = nullptr;
}
bool GrContext::init(const GrContextOptions& options) {
@@ -293,9 +296,17 @@ bool GrContext::init(const GrContextOptions& options) {
} else {
allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
}
- fAtlasGlyphCache = new GrAtlasGlyphCache(fProxyProvider, options.fGlyphCacheTextureMaximumBytes,
- allowMultitexturing);
- this->contextPriv().addOnFlushCallbackObject(fAtlasGlyphCache);
+
+ fGlyphCache = new GrGlyphCache;
+
+ // DDL TODO: in DDL-mode grab a GrRestrictedAtlasManager from the thread-proxy and
+ // do not add an onFlushCB
+ fFullAtlasManager = new GrAtlasManager(fProxyProvider, fGlyphCache,
+ options.fGlyphCacheTextureMaximumBytes,
+ allowMultitexturing);
+ this->contextPriv().addOnFlushCallbackObject(fFullAtlasManager);
+
+ fGlyphCache->setGlyphSizeLimit(fFullAtlasManager->getGlyphSizeLimit());
fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB,
this, this->uniqueID(), SkToBool(fGpu)));
@@ -327,7 +338,8 @@ GrContext::~GrContext() {
delete fResourceProvider;
delete fResourceCache;
delete fProxyProvider;
- delete fAtlasGlyphCache;
+ delete fGlyphCache;
+ delete fFullAtlasManager;
}
sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
@@ -386,7 +398,8 @@ void GrContext::abandonContext() {
fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
- fAtlasGlyphCache->freeAll();
+ fGlyphCache->freeAll();
+ fFullAtlasManager->freeAll();
fTextBlobCache->freeAll();
}
@@ -405,7 +418,8 @@ void GrContext::releaseResourcesAndAbandonContext() {
fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
- fAtlasGlyphCache->freeAll();
+ fGlyphCache->freeAll();
+ fFullAtlasManager->freeAll();
fTextBlobCache->freeAll();
}
@@ -419,7 +433,8 @@ void GrContext::freeGpuResources() {
this->flush();
- fAtlasGlyphCache->freeAll();
+ fGlyphCache->freeAll();
+ fFullAtlasManager->freeAll();
fDrawingManager->freeGpuResources();
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index a2a45b5007..c2e525d9b9 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -10,6 +10,7 @@
#include "GrContext.h"
#include "GrSurfaceContext.h"
+#include "text/GrAtlasManager.h"
class GrBackendRenderTarget;
class GrOnFlushCallbackObject;
@@ -187,8 +188,19 @@ public:
GrGpu* getGpu() { return fContext->fGpu.get(); }
const GrGpu* getGpu() const { return fContext->fGpu.get(); }
- GrAtlasGlyphCache* getAtlasGlyphCache() { return fContext->fAtlasGlyphCache; }
+ GrGlyphCache* getGlyphCache() { return fContext->fGlyphCache; }
GrTextBlobCache* getTextBlobCache() { return fContext->fTextBlobCache.get(); }
+ GrRestrictedAtlasManager* getRestrictedAtlasManager() { return fContext->fFullAtlasManager; }
+
+ // This accessor should only ever be called by the GrOpFlushState.
+ GrAtlasManager* getFullAtlasManager() {
+ if (fContext->fResourceProvider) {
+ // Disallow access to the full atlasManager when recording DDLs
+ return fContext->fFullAtlasManager;
+ }
+
+ return nullptr;
+ }
void moveOpListsToDDL(SkDeferredDisplayList*);
void copyOpListsFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest);
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 3fd3110dcc..56dfcef56d 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -14,6 +14,7 @@
#include "GrRectanizer.h"
#include "GrProxyProvider.h"
#include "GrResourceProvider.h"
+#include "GrSurfaceProxyPriv.h"
#include "GrTexture.h"
#include "GrTracing.h"
@@ -336,8 +337,8 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider,
// With c+14 we could move sk_sp into lambda to only ref once.
sk_sp<Plot> plotsp(SkRef(newPlot.get()));
- SkASSERT(fProxies[pageIdx]->priv().isInstantiated());
GrTextureProxy* proxy = fProxies[pageIdx].get();
+ SkASSERT(proxy->priv().isInstantiated());
GrDeferredUploadToken lastUploadToken = target->addInlineUpload(
[plotsp, proxy](GrDeferredTextureUploadWritePixelsFn& writePixels) {
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 06a05c6bb3..53986c5f6a 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -7,6 +7,7 @@
#include "GrOpFlushState.h"
+#include "GrContextPriv.h"
#include "GrDrawOpAtlas.h"
#include "GrGpu.h"
#include "GrResourceProvider.h"
@@ -191,3 +192,11 @@ void GrOpFlushState::putBackVertices(int vertices, size_t vertexStride) {
GrAppliedClip GrOpFlushState::detachAppliedClip() {
return fOpArgs->fAppliedClip ? std::move(*fOpArgs->fAppliedClip) : GrAppliedClip();
}
+
+GrGlyphCache* GrOpFlushState::glyphCache() const {
+ return fGpu->getContext()->contextPriv().getGlyphCache();
+}
+
+GrAtlasManager* GrOpFlushState::fullAtlasManager() const {
+ return fGpu->getContext()->contextPriv().getFullAtlasManager();
+}
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index 1f77c25cb7..ad33a98e2d 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -90,6 +90,12 @@ public:
const GrCaps& caps() const final;
GrResourceProvider* resourceProvider() const final { return fResourceProvider; }
+ GrGlyphCache* glyphCache() const final;
+
+ // At this point we know we're flushing so full access to the GrAtlasManager is required (and
+ // permissible).
+ GrAtlasManager* fullAtlasManager() const final;
+
private:
/** GrMeshDrawOp::Target override. */
SkArenaAlloc* pipelineArena() override { return &fArena; }
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index dfd06dfe80..254686a613 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -8,13 +8,13 @@
#ifndef GrProxyProvider_DEFINED
#define GrProxyProvider_DEFINED
+#include "GrCaps.h"
#include "GrResourceKey.h"
#include "GrTextureProxy.h"
#include "GrTypes.h"
#include "SkRefCnt.h"
#include "SkTDynamicHash.h"
-class GrCaps;
class GrResourceProvider;
class GrSingleOwner;
class GrBackendRenderTarget;
@@ -207,6 +207,7 @@ public:
void processInvalidProxyUniqueKey(const GrUniqueKey&, GrTextureProxy*, bool invalidateSurface);
const GrCaps* caps() const { return fCaps.get(); }
+ sk_sp<const GrCaps> refCaps() const { return fCaps; }
void abandon() {
fResourceCache = nullptr;
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 952b3ba5ad..8f0c555295 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -16,7 +16,8 @@
#include "SkPoint3.h"
#include "effects/GrBitmapTextGeoProc.h"
#include "effects/GrDistanceFieldGeoProc.h"
-#include "text/GrAtlasGlyphCache.h"
+#include "text/GrAtlasManager.h"
+#include "text/GrGlyphCache.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -53,9 +54,12 @@ void GrAtlasTextOp::init() {
void GrAtlasTextOp::visitProxies(const VisitProxyFunc& func) const {
fProcessors.visitProxies(func);
+ // We need to visit the atlasManager's proxies because, although the atlasManager explicitly
+ // manages their lifetimes, if they fail to allocate the draws that reference them need to
+ // be dropped.
unsigned int numProxies;
- const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(this->maskFormat(),
- &numProxies);
+ const sk_sp<GrTextureProxy>* proxies = fRestrictedAtlasManager->getProxies(
+ this->maskFormat(), &numProxies);
for (unsigned int i = 0; i < numProxies; ++i) {
if (proxies[i]) {
func(proxies[i].get());
@@ -232,10 +236,15 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
return;
}
+ GrAtlasManager* fullAtlasManager = target->fullAtlasManager();
+ SkASSERT(fRestrictedAtlasManager == fullAtlasManager);
+ GrGlyphCache* glyphCache = target->glyphCache();
+
GrMaskFormat maskFormat = this->maskFormat();
unsigned int atlasPageCount;
- const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(maskFormat, &atlasPageCount);
+ const sk_sp<GrTextureProxy>* proxies = fullAtlasManager->getProxies(maskFormat,
+ &atlasPageCount);
if (!proxies[0]) {
SkDebugf("Could not allocate backing texture for atlas\n");
return;
@@ -246,7 +255,7 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
target->makePipeline(fSRGBFlags, std::move(fProcessors), target->detachAppliedClip());
SkDEBUGCODE(bool dfPerspective = false);
if (this->usesDistanceFields()) {
- flushInfo.fGeometryProcessor = this->setupDfProcessor();
+ flushInfo.fGeometryProcessor = this->setupDfProcessor(fullAtlasManager);
SkDEBUGCODE(dfPerspective = fGeoData[0].fViewMatrix.hasPerspective());
} else {
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
@@ -272,14 +281,15 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
char* currVertex = reinterpret_cast<char*>(vertices);
- SkAutoGlyphCache glyphCache;
+ SkAutoGlyphCache autoGlyphCache;
// each of these is a SubRun
for (int i = 0; i < fGeoCount; i++) {
const Geometry& args = fGeoData[i];
Blob* blob = args.fBlob;
GrAtlasTextBlob::VertexRegenerator regenerator(
resourceProvider, blob, args.fRun, args.fSubRun, args.fViewMatrix, args.fX, args.fY,
- args.fColor, target->deferredUploadTarget(), fFontCache, &glyphCache);
+ args.fColor, target->deferredUploadTarget(), glyphCache, fullAtlasManager,
+ &autoGlyphCache);
GrAtlasTextBlob::VertexRegenerator::Result result;
do {
result = regenerator.regenerate();
@@ -319,11 +329,14 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
}
void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const {
+ auto fullAtlasManager = target->fullAtlasManager();
+ SkASSERT(fRestrictedAtlasManager == fullAtlasManager);
+
GrGeometryProcessor* gp = flushInfo->fGeometryProcessor.get();
GrMaskFormat maskFormat = this->maskFormat();
unsigned int numProxies;
- const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(maskFormat, &numProxies);
+ const sk_sp<GrTextureProxy>* proxies = fullAtlasManager->getProxies(maskFormat, &numProxies);
if (gp->numTextureSamplers() != (int) numProxies) {
// During preparation the number of atlas pages has increased.
// Update the proxies used in the GP to match.
@@ -427,9 +440,11 @@ bool GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
// TODO trying to figure out why lcd is so whack
// (see comments in GrAtlasTextContext::ComputeCanonicalColor)
-sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor() const {
+sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(
+ GrRestrictedAtlasManager* restrictedAtlasManager) const {
unsigned int numProxies;
- const sk_sp<GrTextureProxy>* p = fFontCache->getProxies(this->maskFormat(), &numProxies);
+ const sk_sp<GrTextureProxy>* p = restrictedAtlasManager->getProxies(this->maskFormat(),
+ &numProxies);
bool isLCD = this->isLCD();
SkMatrix localMatrix = SkMatrix::I();
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index dbdce387ec..ae1c95b56e 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -11,6 +11,7 @@
#include "ops/GrMeshDrawOp.h"
#include "text/GrAtlasTextContext.h"
#include "text/GrDistanceFieldAdjustTable.h"
+#include "text/GrGlyphCache.h"
class SkAtlasTextTarget;
@@ -39,11 +40,12 @@ public:
GrColor fColor;
};
- static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrPaint&& paint, GrMaskFormat maskFormat,
- int glyphCount, GrAtlasGlyphCache* fontCache) {
- std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
+ static std::unique_ptr<GrAtlasTextOp> MakeBitmap(
+ GrPaint&& paint, GrMaskFormat maskFormat,
+ int glyphCount, GrRestrictedAtlasManager* restrictedAtlasManager) {
+ std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(restrictedAtlasManager,
+ std::move(paint)));
- op->fFontCache = fontCache;
switch (maskFormat) {
case kA8_GrMaskFormat:
op->fMaskType = kGrayscaleCoverageMask_MaskType;
@@ -58,18 +60,17 @@ public:
op->fNumGlyphs = glyphCount;
op->fGeoCount = 1;
op->fLuminanceColor = 0;
- op->fFontCache = fontCache;
return op;
}
static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
- GrPaint&& paint, int glyphCount, GrAtlasGlyphCache* fontCache,
+ GrPaint&& paint, int glyphCount, GrRestrictedAtlasManager* restrictedAtlasManager,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
bool useGammaCorrectDistanceTable, SkColor luminanceColor, bool isLCD, bool useBGR,
bool isAntiAliased) {
- std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
+ std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(restrictedAtlasManager,
+ std::move(paint)));
- op->fFontCache = fontCache;
op->fMaskType = !isAntiAliased ? kAliasedDistanceField_MaskType
: isLCD ? (useBGR ? kLCDBGRDistanceField_MaskType
: kLCDDistanceField_MaskType)
@@ -120,8 +121,9 @@ private:
// The minimum number of Geometry we will try to allocate.
static constexpr auto kMinGeometryAllocated = 12;
- GrAtlasTextOp(GrPaint&& paint)
+ GrAtlasTextOp(GrRestrictedAtlasManager* restrictedAtlasManager, GrPaint&& paint)
: INHERITED(ClassID())
+ , fRestrictedAtlasManager(restrictedAtlasManager)
, fGeoDataAllocSize(kMinGeometryAllocated)
, fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
, fProcessors(std::move(paint)) {}
@@ -174,8 +176,9 @@ private:
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override;
- sk_sp<GrGeometryProcessor> setupDfProcessor() const;
+ sk_sp<GrGeometryProcessor> setupDfProcessor(GrRestrictedAtlasManager*) const;
+ GrRestrictedAtlasManager* fRestrictedAtlasManager;
SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
int fGeoDataAllocSize;
uint32_t fSRGBFlags;
@@ -185,7 +188,6 @@ private:
int fGeoCount;
int fNumGlyphs;
MaskType fMaskType;
- GrAtlasGlyphCache* fFontCache;
// Distance field properties
sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
SkColor fLuminanceColor;
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index 1b8831cfe8..766fd23ce5 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -15,7 +15,9 @@
#include "SkTLList.h"
+class GrAtlasManager;
class GrCaps;
+class GrGlyphCache;
class GrOpFlushState;
/**
@@ -152,6 +154,9 @@ public:
virtual GrResourceProvider* resourceProvider() const = 0;
+ virtual GrGlyphCache* glyphCache() const = 0;
+ virtual GrAtlasManager* fullAtlasManager() const = 0;
+
virtual const GrCaps& caps() const = 0;
virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
diff --git a/src/gpu/text/GrAtlasGlyphCache.h b/src/gpu/text/GrAtlasGlyphCache.h
deleted file mode 100644
index 84b7d1b249..0000000000
--- a/src/gpu/text/GrAtlasGlyphCache.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrAtlasGlyphCache_DEFINED
-#define GrAtlasGlyphCache_DEFINED
-
-#include "GrCaps.h"
-#include "GrDrawOpAtlas.h"
-#include "GrGlyph.h"
-#include "GrOnFlushResourceProvider.h"
-#include "SkArenaAlloc.h"
-#include "SkGlyphCache.h"
-#include "SkTDynamicHash.h"
-
-class GrAtlasGlyphCache;
-class GrGpu;
-
-/**
- * The GrAtlasTextStrike manages a pool of CPU backing memory for GrGlyphs. This backing memory
- * is indexed by a PackedID and SkGlyphCache. The SkGlyphCache is what actually creates the mask.
- * The GrAtlasTextStrike may outlive the generating SkGlyphCache. However, it retains a copy
- * of it's SkDescriptor as a key to access (or regenerate) the SkGlyphCache. GrAtlasTextStrike are
- * created by and owned by a GrAtlasGlyphCache.
- */
-class GrAtlasTextStrike : public SkNVRefCnt<GrAtlasTextStrike> {
-public:
- GrAtlasTextStrike(const SkDescriptor& fontScalerKey);
- ~GrAtlasTextStrike();
-
- inline GrGlyph* getGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
- SkGlyphCache* cache) {
- GrGlyph* glyph = fCache.find(packed);
- if (nullptr == glyph) {
- glyph = this->generateGlyph(skGlyph, packed, cache);
- }
- return glyph;
- }
-
- // This variant of the above function is called by GrAtlasTextOp. At this point, it is possible
- // that the maskformat of the glyph differs from what we expect. In these cases we will just
- // draw a clear square.
- // skbug:4143 crbug:510931
- inline GrGlyph* getGlyph(GrGlyph::PackedID packed,
- GrMaskFormat expectedMaskFormat,
- SkGlyphCache* cache) {
- GrGlyph* glyph = fCache.find(packed);
- if (nullptr == glyph) {
- // We could return this to the caller, but in practice it adds code complexity for
- // potentially little benefit(ie, if the glyph is not in our font cache, then its not
- // in the atlas and we're going to be doing a texture upload anyways).
- const SkGlyph& skGlyph = GrToSkGlyph(cache, packed);
- glyph = this->generateGlyph(skGlyph, packed, cache);
- glyph->fMaskFormat = expectedMaskFormat;
- }
- return glyph;
- }
-
- // returns true if glyph successfully added to texture atlas, false otherwise. If the glyph's
- // mask format has changed, then addGlyphToAtlas will draw a clear box. This will almost never
- // happen.
- // TODO we can handle some of these cases if we really want to, but the long term solution is to
- // get the actual glyph image itself when we get the glyph metrics.
- bool addGlyphToAtlas(GrResourceProvider*, GrDeferredUploadTarget*, GrAtlasGlyphCache*, GrGlyph*,
- SkGlyphCache*, GrMaskFormat expectedMaskFormat);
-
- // testing
- int countGlyphs() const { return fCache.count(); }
-
- // remove any references to this plot
- void removeID(GrDrawOpAtlas::AtlasID);
-
- // If a TextStrike is abandoned by the cache, then the caller must get a new strike
- bool isAbandoned() const { return fIsAbandoned; }
-
- static const SkDescriptor& GetKey(const GrAtlasTextStrike& ts) {
- return *ts.fFontScalerKey.getDesc();
- }
-
- static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
-
-private:
- SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
- SkAutoDescriptor fFontScalerKey;
- SkArenaAlloc fPool{512};
-
- int fAtlasedGlyphs;
- bool fIsAbandoned;
-
- static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, GrGlyph::PackedID id) {
- return cache->getGlyphIDMetrics(GrGlyph::UnpackID(id),
- GrGlyph::UnpackFixedX(id),
- GrGlyph::UnpackFixedY(id));
- }
-
- GrGlyph* generateGlyph(const SkGlyph&, GrGlyph::PackedID, SkGlyphCache*);
-
- friend class GrAtlasGlyphCache;
-};
-
-/**
- * GrAtlasGlyphCache manages strikes which are indexed by a SkGlyphCache. These strikes can then be
- * used to generate individual Glyph Masks. The GrAtlasGlyphCache also manages GrDrawOpAtlases,
- * though this is more or less transparent to the client(aside from atlasGeneration, described
- * below).
- */
-class GrAtlasGlyphCache : public GrOnFlushCallbackObject {
-public:
- GrAtlasGlyphCache(GrProxyProvider*, float maxTextureBytes,
- GrDrawOpAtlas::AllowMultitexturing);
- ~GrAtlasGlyphCache() override;
- // The user of the cache may hold a long-lived ref to the returned strike. However, actions by
- // another client of the cache may cause the strike to be purged while it is still reffed.
- // Therefore, the caller must check GrAtlasTextStrike::isAbandoned() if there are other
- // interactions with the cache since the strike was received.
- inline GrAtlasTextStrike* getStrike(const SkGlyphCache* cache) {
- GrAtlasTextStrike* strike = fCache.find(cache->getDescriptor());
- if (nullptr == strike) {
- strike = this->generateStrike(cache);
- }
- return strike;
- }
-
- void freeAll();
-
- // if getProxies returns nullptr, the client must not try to use other functions on the
- // GrAtlasGlyphCache which use the atlas. This function *must* be called first, before other
- // functions which use the atlas.
- const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numProxies) {
- SkASSERT(numProxies);
-
- if (this->initAtlas(format)) {
- *numProxies = this->getAtlas(format)->numActivePages();
- return this->getAtlas(format)->getProxies();
- }
- *numProxies = 0;
- return nullptr;
- }
-
- SkScalar getGlyphSizeLimit() const { return fGlyphSizeLimit; }
-
- bool hasGlyph(GrGlyph* glyph) {
- SkASSERT(glyph);
- return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
- }
-
- // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store,
- // the client must pass in the current op token along with the GrGlyph.
- // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
- // For convenience, this function will also set the use token for the current glyph if required
- // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
- void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater* updater, GrGlyph* glyph,
- GrDeferredUploadToken token) {
- SkASSERT(glyph);
- updater->add(glyph->fID);
- this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token);
- }
-
- void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater,
- GrDeferredUploadToken token,
- GrMaskFormat format) {
- this->getAtlas(format)->setLastUseTokenBulk(updater, token);
- }
-
- // add to texture atlas that matches this format
- bool addToAtlas(GrResourceProvider* resourceProvider, GrAtlasTextStrike* strike,
- GrDrawOpAtlas::AtlasID* id,
- GrDeferredUploadTarget* target, GrMaskFormat format, int width, int height,
- const void* image, SkIPoint16* loc) {
- fPreserveStrike = strike;
- return this->getAtlas(format)->addToAtlas(resourceProvider, id, target,
- width, height, image, loc);
- }
-
- // Some clients may wish to verify the integrity of the texture backing store of the
- // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
- // changes every time something is removed from the texture backing store.
- uint64_t atlasGeneration(GrMaskFormat format) const {
- return this->getAtlas(format)->atlasGeneration();
- }
-
- // GrOnFlushCallbackObject overrides
-
- void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
- SkTArray<sk_sp<GrRenderTargetContext>>*) override {
- for (int i = 0; i < kMaskFormatCount; ++i) {
- if (fAtlases[i]) {
- fAtlases[i]->instantiate(onFlushResourceProvider);
- }
- }
- }
-
- void postFlush(GrDeferredUploadToken startTokenForNextFlush, const uint32_t*, int) override {
- for (int i = 0; i < kMaskFormatCount; ++i) {
- if (fAtlases[i]) {
- fAtlases[i]->compact(startTokenForNextFlush);
- }
- }
- }
-
- // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active
- // OnFlushCallbackObject list
- bool retainOnFreeGpuResources() override { return true; }
-
- ///////////////////////////////////////////////////////////////////////////
- // Functions intended debug only
-#ifdef SK_DEBUG
- void dump(GrContext*) const;
-#endif
-
- void setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]);
-
-private:
- static GrPixelConfig MaskFormatToPixelConfig(GrMaskFormat format, const GrCaps& caps) {
- switch (format) {
- case kA8_GrMaskFormat:
- return kAlpha_8_GrPixelConfig;
- case kA565_GrMaskFormat:
- return kRGB_565_GrPixelConfig;
- case kARGB_GrMaskFormat:
- return caps.srgbSupport() ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
- default:
- SkDEBUGFAIL("unsupported GrMaskFormat");
- return kAlpha_8_GrPixelConfig;
- }
- }
-
- // There is a 1:1 mapping between GrMaskFormats and atlas indices
- static int MaskFormatToAtlasIndex(GrMaskFormat format) {
- static const int sAtlasIndices[] = {
- kA8_GrMaskFormat,
- kA565_GrMaskFormat,
- kARGB_GrMaskFormat,
- };
- static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");
-
- SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
- return sAtlasIndices[format];
- }
-
- bool initAtlas(GrMaskFormat);
-
- GrAtlasTextStrike* generateStrike(const SkGlyphCache* cache) {
- GrAtlasTextStrike* strike = new GrAtlasTextStrike(cache->getDescriptor());
- fCache.add(strike);
- return strike;
- }
-
- GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
- int atlasIndex = MaskFormatToAtlasIndex(format);
- SkASSERT(fAtlases[atlasIndex]);
- return fAtlases[atlasIndex].get();
- }
-
- static void HandleEviction(GrDrawOpAtlas::AtlasID, void*);
-
- using StrikeHash = SkTDynamicHash<GrAtlasTextStrike, SkDescriptor>;
- GrProxyProvider* fProxyProvider;
- StrikeHash fCache;
- GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
- std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
- GrAtlasTextStrike* fPreserveStrike;
- GrDrawOpAtlasConfig fAtlasConfigs[kMaskFormatCount];
- SkScalar fGlyphSizeLimit;
-};
-
-#endif
diff --git a/src/gpu/text/GrAtlasManager.cpp b/src/gpu/text/GrAtlasManager.cpp
new file mode 100644
index 0000000000..6e227a94a2
--- /dev/null
+++ b/src/gpu/text/GrAtlasManager.cpp
@@ -0,0 +1,222 @@
+/*
+ * 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 "GrAtlasManager.h"
+
+#include "GrCaps.h"
+#include "GrGlyph.h"
+#include "GrGlyphCache.h"
+#include "GrProxyProvider.h"
+
+GrRestrictedAtlasManager::GrRestrictedAtlasManager(
+ sk_sp<const GrCaps> caps,
+ float maxTextureBytes,
+ GrDrawOpAtlas::AllowMultitexturing allowMultitexturing)
+ : fCaps(std::move(caps))
+ , fAllowMultitexturing(allowMultitexturing) {
+ // Calculate RGBA size. Must be between 512 x 256 and MaxTextureSize x MaxTextureSize / 2
+ int log2MaxTextureSize = SkPrevLog2(fCaps->maxTextureSize());
+ int log2MaxDim = 9;
+ for (; log2MaxDim <= log2MaxTextureSize; ++log2MaxDim) {
+ int maxDim = 1 << log2MaxDim;
+ int minDim = 1 << (log2MaxDim - 1);
+
+ if (maxDim * minDim * 4 >= maxTextureBytes) break;
+ }
+
+ int log2MinDim = log2MaxDim - 1;
+ int maxDim = 1 << log2MaxDim;
+ int minDim = 1 << log2MinDim;
+ // Plots are either 256 or 512.
+ int maxPlot = SkTMin(512, SkTMax(256, 1 << (log2MaxDim - 2)));
+ int minPlot = SkTMin(512, SkTMax(256, 1 << (log2MaxDim - 3)));
+
+ // Setup default atlas configs. The A8 atlas uses maxDim for both width and height, as the A8
+ // format is already very compact.
+ fAtlasConfigs[kA8_GrMaskFormat].fWidth = maxDim;
+ fAtlasConfigs[kA8_GrMaskFormat].fHeight = maxDim;
+ fAtlasConfigs[kA8_GrMaskFormat].fPlotWidth = maxPlot;
+ fAtlasConfigs[kA8_GrMaskFormat].fPlotHeight = minPlot;
+
+ // A565 and ARGB use maxDim x minDim.
+ fAtlasConfigs[kA565_GrMaskFormat].fWidth = minDim;
+ fAtlasConfigs[kA565_GrMaskFormat].fHeight = maxDim;
+ fAtlasConfigs[kA565_GrMaskFormat].fPlotWidth = minPlot;
+ fAtlasConfigs[kA565_GrMaskFormat].fPlotHeight = minPlot;
+
+ fAtlasConfigs[kARGB_GrMaskFormat].fWidth = minDim;
+ fAtlasConfigs[kARGB_GrMaskFormat].fHeight = maxDim;
+ fAtlasConfigs[kARGB_GrMaskFormat].fPlotWidth = minPlot;
+ fAtlasConfigs[kARGB_GrMaskFormat].fPlotHeight = minPlot;
+
+ fGlyphSizeLimit = minPlot;
+}
+
+GrRestrictedAtlasManager::~GrRestrictedAtlasManager() {
+}
+
+static GrPixelConfig mask_format_to_pixel_config(GrMaskFormat format, const GrCaps& caps) {
+ switch (format) {
+ case kA8_GrMaskFormat:
+ return kAlpha_8_GrPixelConfig;
+ case kA565_GrMaskFormat:
+ return kRGB_565_GrPixelConfig;
+ case kARGB_GrMaskFormat:
+ return caps.srgbSupport() ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
+ default:
+ SkDEBUGFAIL("unsupported GrMaskFormat");
+ return kAlpha_8_GrPixelConfig;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+GrAtlasManager::GrAtlasManager(GrProxyProvider* proxyProvider, GrGlyphCache* glyphCache,
+ float maxTextureBytes,
+ GrDrawOpAtlas::AllowMultitexturing allowMultitexturing)
+ : INHERITED(proxyProvider->refCaps(), maxTextureBytes, allowMultitexturing)
+ , fProxyProvider(proxyProvider)
+ , fGlyphCache(glyphCache) {
+}
+
+void GrAtlasManager::freeAll() {
+ for (int i = 0; i < kMaskFormatCount; ++i) {
+ fAtlases[i] = nullptr;
+ }
+}
+
+bool GrAtlasManager::hasGlyph(GrGlyph* glyph) {
+ SkASSERT(glyph);
+ return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
+}
+
+// add to texture atlas that matches this format
+bool GrAtlasManager::addToAtlas(GrResourceProvider* resourceProvider,
+ GrGlyphCache* glyphCache,
+ GrAtlasTextStrike* strike, GrDrawOpAtlas::AtlasID* id,
+ GrDeferredUploadTarget* target, GrMaskFormat format,
+ int width, int height, const void* image, SkIPoint16* loc) {
+ glyphCache->setStrikeToPreserve(strike);
+ return this->getAtlas(format)->addToAtlas(resourceProvider, id, target, width, height,
+ image, loc);
+}
+
+void GrAtlasManager::addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater* updater,
+ GrGlyph* glyph,
+ GrDeferredUploadToken token) {
+ SkASSERT(glyph);
+ updater->add(glyph->fID);
+ this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token);
+}
+
+#ifdef SK_DEBUG
+#include "GrContextPriv.h"
+#include "GrSurfaceProxy.h"
+#include "GrSurfaceContext.h"
+#include "GrTextureProxy.h"
+
+#include "SkBitmap.h"
+#include "SkImageEncoder.h"
+#include "SkStream.h"
+#include <stdio.h>
+
+/**
+ * Write the contents of the surface proxy to a PNG. Returns true if successful.
+ * @param filename Full path to desired file
+ */
+static bool save_pixels(GrContext* context, GrSurfaceProxy* sProxy, const char* filename) {
+ if (!sProxy) {
+ return false;
+ }
+
+ SkImageInfo ii = SkImageInfo::Make(sProxy->width(), sProxy->height(),
+ kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ SkBitmap bm;
+ if (!bm.tryAllocPixels(ii)) {
+ return false;
+ }
+
+ sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext(
+ sk_ref_sp(sProxy)));
+ if (!sContext || !sContext->asTextureProxy()) {
+ return false;
+ }
+
+ bool result = sContext->readPixels(ii, bm.getPixels(), bm.rowBytes(), 0, 0);
+ if (!result) {
+ SkDebugf("------ failed to read pixels for %s\n", filename);
+ return false;
+ }
+
+ // remove any previous version of this file
+ remove(filename);
+
+ SkFILEWStream file(filename);
+ if (!file.isValid()) {
+ SkDebugf("------ failed to create file: %s\n", filename);
+ remove(filename); // remove any partial file
+ return false;
+ }
+
+ if (!SkEncodeImage(&file, bm, SkEncodedImageFormat::kPNG, 100)) {
+ SkDebugf("------ failed to encode %s\n", filename);
+ remove(filename); // remove any partial file
+ return false;
+ }
+
+ return true;
+}
+
+void GrAtlasManager::dump(GrContext* context) const {
+ static int gDumpCount = 0;
+ for (int i = 0; i < kMaskFormatCount; ++i) {
+ if (fAtlases[i]) {
+ const sk_sp<GrTextureProxy>* proxies = fAtlases[i]->getProxies();
+ for (uint32_t pageIdx = 0; pageIdx < fAtlases[i]->numActivePages(); ++pageIdx) {
+ SkASSERT(proxies[pageIdx]);
+ SkString filename;
+#ifdef SK_BUILD_FOR_ANDROID
+ filename.printf("/sdcard/fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
+#else
+ filename.printf("fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
+#endif
+
+ save_pixels(context, proxies[pageIdx].get(), filename.c_str());
+ }
+ }
+ }
+ ++gDumpCount;
+}
+#endif
+
+void GrAtlasManager::setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]) {
+ // Delete any old atlases.
+ // This should be safe to do as long as we are not in the middle of a flush.
+ for (int i = 0; i < kMaskFormatCount; i++) {
+ fAtlases[i] = nullptr;
+ }
+ memcpy(fAtlasConfigs, configs, sizeof(fAtlasConfigs));
+}
+
+bool GrAtlasManager::initAtlas(GrMaskFormat format) {
+ int index = MaskFormatToAtlasIndex(format);
+ if (!fAtlases[index]) {
+ GrPixelConfig config = mask_format_to_pixel_config(format, *fCaps);
+ int width = fAtlasConfigs[index].fWidth;
+ int height = fAtlasConfigs[index].fHeight;
+ int numPlotsX = fAtlasConfigs[index].numPlotsX();
+ int numPlotsY = fAtlasConfigs[index].numPlotsY();
+
+ fAtlases[index] = GrDrawOpAtlas::Make(fProxyProvider, config, width, height,
+ numPlotsX, numPlotsY, fAllowMultitexturing,
+ &GrGlyphCache::HandleEviction,
+ fGlyphCache);
+ if (!fAtlases[index]) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/src/gpu/text/GrAtlasManager.h b/src/gpu/text/GrAtlasManager.h
new file mode 100644
index 0000000000..4629cb173b
--- /dev/null
+++ b/src/gpu/text/GrAtlasManager.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrAtlasManager_DEFINED
+#define GrAtlasManager_DEFINED
+
+#include "GrDrawOpAtlas.h"
+#include "GrOnFlushResourceProvider.h"
+
+class GrAtlasGlypCache;
+class GrAtlasTextStrike;
+struct GrGlyph;
+
+ /** The GrAtlasManager classes manage the lifetime of and access to GrDrawOpAtlases.
+ * The restricted version is available at op creation time and only allows basic access
+ * to the proxies (so the created ops can reference them). The full GrAtlasManager class
+ * is only available at flush time and only via the GrOpFlushState.
+ *
+ * This organization implies that all of the advanced atlasManager functionality (i.e.,
+ * adding glyphs to the atlas) are only available at flush time.
+ */
+class GrRestrictedAtlasManager : public GrOnFlushCallbackObject {
+public:
+ GrRestrictedAtlasManager(sk_sp<const GrCaps>, float maxTextureBytes,
+ GrDrawOpAtlas::AllowMultitexturing);
+ ~GrRestrictedAtlasManager() override;
+
+ // if getProxies returns nullptr, the client must not try to use other functions on the
+ // GrGlyphCache which use the atlas. This function *must* be called first, before other
+ // functions which use the atlas.
+ const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numProxies) {
+ if (this->initAtlas(format)) {
+ *numProxies = this->getAtlas(format)->numActivePages();
+ return this->getAtlas(format)->getProxies();
+ }
+ *numProxies = 0;
+ return nullptr;
+ }
+
+ SkScalar getGlyphSizeLimit() const { return fGlyphSizeLimit; }
+
+protected:
+ // There is a 1:1 mapping between GrMaskFormats and atlas indices
+ static int MaskFormatToAtlasIndex(GrMaskFormat format) {
+ static const int sAtlasIndices[] = {
+ kA8_GrMaskFormat,
+ kA565_GrMaskFormat,
+ kARGB_GrMaskFormat,
+ };
+ static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");
+
+ SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
+ return sAtlasIndices[format];
+ }
+
+ GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
+ int atlasIndex = MaskFormatToAtlasIndex(format);
+ SkASSERT(fAtlases[atlasIndex]);
+ return fAtlases[atlasIndex].get();
+ }
+
+ sk_sp<const GrCaps> fCaps;
+ GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
+ std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
+ GrDrawOpAtlasConfig fAtlasConfigs[kMaskFormatCount];
+ SkScalar fGlyphSizeLimit;
+
+private:
+ virtual bool initAtlas(GrMaskFormat) = 0;
+
+ typedef GrOnFlushCallbackObject INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+class GrAtlasManager : public GrRestrictedAtlasManager {
+public:
+ GrAtlasManager(GrProxyProvider*, GrGlyphCache*,
+ float maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing);
+
+ void freeAll();
+
+ bool hasGlyph(GrGlyph* glyph);
+
+ // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store,
+ // the client must pass in the current op token along with the GrGlyph.
+ // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
+ // For convenience, this function will also set the use token for the current glyph if required
+ // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
+ void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*,
+ GrDeferredUploadToken);
+
+ void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater,
+ GrDeferredUploadToken token,
+ GrMaskFormat format) {
+ this->getAtlas(format)->setLastUseTokenBulk(updater, token);
+ }
+
+ // add to texture atlas that matches this format
+ bool addToAtlas(GrResourceProvider*, GrGlyphCache*, GrAtlasTextStrike*,
+ GrDrawOpAtlas::AtlasID*, GrDeferredUploadTarget*, GrMaskFormat,
+ int width, int height, const void* image, SkIPoint16* loc);
+
+ // Some clients may wish to verify the integrity of the texture backing store of the
+ // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
+ // changes every time something is removed from the texture backing store.
+ uint64_t atlasGeneration(GrMaskFormat format) const {
+ return this->getAtlas(format)->atlasGeneration();
+ }
+
+ // GrOnFlushCallbackObject overrides
+
+ void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
+ SkTArray<sk_sp<GrRenderTargetContext>>*) override {
+ for (int i = 0; i < kMaskFormatCount; ++i) {
+ if (fAtlases[i]) {
+ fAtlases[i]->instantiate(onFlushResourceProvider);
+ }
+ }
+ }
+
+ void postFlush(GrDeferredUploadToken startTokenForNextFlush,
+ const uint32_t* opListIDs, int numOpListIDs) override {
+ for (int i = 0; i < kMaskFormatCount; ++i) {
+ if (fAtlases[i]) {
+ fAtlases[i]->compact(startTokenForNextFlush);
+ }
+ }
+ }
+
+ // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active
+ // OnFlushCallbackObject list
+ bool retainOnFreeGpuResources() override { return true; }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Functions intended debug only
+#ifdef SK_DEBUG
+ void dump(GrContext* context) const;
+#endif
+
+ void setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]);
+
+private:
+ bool initAtlas(GrMaskFormat) override;
+
+ GrProxyProvider* fProxyProvider;
+ GrGlyphCache* fGlyphCache;
+
+ typedef GrRestrictedAtlasManager INHERITED;
+};
+
+#endif // GrAtlasManager_DEFINED
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 90bcf5a224..35e783019f 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -250,8 +250,8 @@ inline std::unique_ptr<GrAtlasTextOp> GrAtlasTextBlob::makeOp(
const Run::SubRunInfo& info, int glyphCount, uint16_t run, uint16_t subRun,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkIRect& clipRect,
const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
- const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache,
- GrTextUtils::Target* target) {
+ const GrDistanceFieldAdjustTable* distanceAdjustTable,
+ GrRestrictedAtlasManager* restrictedAtlasManager, GrTextUtils::Target* target) {
GrMaskFormat format = info.maskFormat();
GrPaint grPaint;
@@ -260,11 +260,12 @@ inline std::unique_ptr<GrAtlasTextOp> GrAtlasTextBlob::makeOp(
if (info.drawAsDistanceFields()) {
bool useBGR = SkPixelGeometryIsBGR(props.pixelGeometry());
op = GrAtlasTextOp::MakeDistanceField(
- std::move(grPaint), glyphCount, cache, distanceAdjustTable,
+ std::move(grPaint), glyphCount, restrictedAtlasManager, distanceAdjustTable,
target->colorSpaceInfo().isGammaCorrect(), paint.luminanceColor(),
info.hasUseLCDText(), useBGR, info.isAntiAliased());
} else {
- op = GrAtlasTextOp::MakeBitmap(std::move(grPaint), format, glyphCount, cache);
+ op = GrAtlasTextOp::MakeBitmap(std::move(grPaint), format,
+ glyphCount, restrictedAtlasManager);
}
GrAtlasTextOp::Geometry& geometry = op->geometry();
geometry.fViewMatrix = viewMatrix;
@@ -300,8 +301,8 @@ static void calculate_translation(bool applyVM,
}
}
-void GrAtlasTextBlob::flush(GrAtlasGlyphCache* atlasGlyphCache, GrTextUtils::Target* target,
- const SkSurfaceProps& props,
+void GrAtlasTextBlob::flush(GrRestrictedAtlasManager* restrictedAtlasManager,
+ GrTextUtils::Target* target, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
const GrTextUtils::Paint& paint, const GrClip& clip,
const SkMatrix& viewMatrix, const SkIRect& clipBounds,
@@ -376,7 +377,7 @@ void GrAtlasTextBlob::flush(GrAtlasGlyphCache* atlasGlyphCache, GrTextUtils::Tar
if (submitOp) {
auto op = this->makeOp(info, glyphCount, runIndex, subRun, viewMatrix, x, y,
clipRect, std::move(paint), props, distanceAdjustTable,
- atlasGlyphCache, target);
+ restrictedAtlasManager, target);
if (op) {
if (skipClip) {
target->addDrawOp(GrNoClip(), std::move(op));
@@ -394,12 +395,12 @@ void GrAtlasTextBlob::flush(GrAtlasGlyphCache* atlasGlyphCache, GrTextUtils::Tar
std::unique_ptr<GrDrawOp> GrAtlasTextBlob::test_makeOp(
int glyphCount, uint16_t run, uint16_t subRun, const SkMatrix& viewMatrix,
SkScalar x, SkScalar y, const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
- const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache,
- GrTextUtils::Target* target) {
+ const GrDistanceFieldAdjustTable* distanceAdjustTable,
+ GrRestrictedAtlasManager* restrictedAtlasManager, GrTextUtils::Target* target) {
const GrAtlasTextBlob::Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
SkIRect emptyRect = SkIRect::MakeEmpty();
return this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, emptyRect, paint, props,
- distanceAdjustTable, cache, target);
+ distanceAdjustTable, restrictedAtlasManager, target);
}
void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlob& r) {
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 0fae3cd8c7..9f91cae957 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -8,9 +8,9 @@
#ifndef GrAtlasTextBlob_DEFINED
#define GrAtlasTextBlob_DEFINED
-#include "GrAtlasGlyphCache.h"
#include "GrColor.h"
#include "GrDrawOpAtlas.h"
+#include "GrGlyphCache.h"
#include "GrMemoryPool.h"
#include "GrTextUtils.h"
#include "SkDescriptor.h"
@@ -22,8 +22,13 @@
#include "SkSurfaceProps.h"
#include "SkTInternalLList.h"
+class GrAtlasManager;
struct GrDistanceFieldAdjustTable;
+struct GrGlyph;
+class GrGlyphCache;
class GrMemoryPool;
+class GrRestrictedAtlasManager;
+
class SkDrawFilter;
class SkTextBlob;
class SkTextBlobRunIterator;
@@ -201,7 +206,7 @@ public:
bool mustRegenerate(const GrTextUtils::Paint&, const SkMaskFilterBase::BlurRec& blurRec,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
- void flush(GrAtlasGlyphCache*, GrTextUtils::Target*, const SkSurfaceProps& props,
+ void flush(GrRestrictedAtlasManager*, GrTextUtils::Target*, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
const GrTextUtils::Paint& paint, const GrClip& clip,
const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
@@ -276,8 +281,8 @@ public:
std::unique_ptr<GrDrawOp> test_makeOp(int glyphCount, uint16_t run, uint16_t subRun,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
const GrTextUtils::Paint&, const SkSurfaceProps&,
- const GrDistanceFieldAdjustTable*, GrAtlasGlyphCache*,
- GrTextUtils::Target*);
+ const GrDistanceFieldAdjustTable*,
+ GrRestrictedAtlasManager*, GrTextUtils::Target*);
private:
GrAtlasTextBlob()
@@ -506,9 +511,8 @@ private:
inline std::unique_ptr<GrAtlasTextOp> makeOp(
const Run::SubRunInfo& info, int glyphCount, uint16_t run, uint16_t subRun,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkIRect& clipRect,
- const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
- const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache,
- GrTextUtils::Target*);
+ const GrTextUtils::Paint&, const SkSurfaceProps&,
+ const GrDistanceFieldAdjustTable*, GrRestrictedAtlasManager* , GrTextUtils::Target*);
struct StrokeInfo {
SkScalar fFrameWidth;
@@ -562,7 +566,8 @@ public:
*/
VertexRegenerator(GrResourceProvider*, GrAtlasTextBlob*, int runIdx, int subRunIdx,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y, GrColor color,
- GrDeferredUploadTarget*, GrAtlasGlyphCache*, SkAutoGlyphCache*);
+ GrDeferredUploadTarget*, GrGlyphCache*, GrAtlasManager*,
+ SkAutoGlyphCache*);
struct Result {
/**
@@ -593,7 +598,8 @@ private:
const SkMatrix& fViewMatrix;
GrAtlasTextBlob* fBlob;
GrDeferredUploadTarget* fUploadTarget;
- GrAtlasGlyphCache* fGlyphCache;
+ GrGlyphCache* fGlyphCache;
+ GrAtlasManager* fFullAtlasManager;
SkAutoGlyphCache* fLazyCache;
Run* fRun;
Run::SubRunInfo* fSubRun;
diff --git a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
index 500ae31703..54001c2628 100644
--- a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
+++ b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "GrAtlasManager.h"
#include "GrAtlasTextBlob.h"
#include "GrTextUtils.h"
#include "SkDistanceFieldGen.h"
@@ -193,13 +194,14 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri
Regenerator::VertexRegenerator(GrResourceProvider* resourceProvider, GrAtlasTextBlob* blob,
int runIdx, int subRunIdx,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y, GrColor color,
- GrDeferredUploadTarget* uploadTarget, GrAtlasGlyphCache* glyphCache,
- SkAutoGlyphCache* lazyCache)
+ GrDeferredUploadTarget* uploadTarget, GrGlyphCache* glyphCache,
+ GrAtlasManager* fullAtlasManager, SkAutoGlyphCache* lazyCache)
: fResourceProvider(resourceProvider)
, fViewMatrix(viewMatrix)
, fBlob(blob)
, fUploadTarget(uploadTarget)
, fGlyphCache(glyphCache)
+ , fFullAtlasManager(fullAtlasManager)
, fLazyCache(lazyCache)
, fRun(&blob->fRuns[runIdx])
, fSubRun(&blob->fRuns[runIdx].fSubRunInfo[subRunIdx])
@@ -207,7 +209,7 @@ Regenerator::VertexRegenerator(GrResourceProvider* resourceProvider, GrAtlasText
// Compute translation if any
fSubRun->computeTranslation(fViewMatrix, x, y, &fTransX, &fTransY);
- // Because the GrAtlasGlyphCache may evict the strike a blob depends on using for
+ // Because the GrGlyphCache may evict the strike a blob depends on using for
// generating its texture coords, we have to track whether or not the strike has
// been abandoned. If it hasn't been abandoned, then we can use the GrGlyph*s as is
// otherwise we have to get the new strike, and use that to get the correct glyphs.
@@ -275,16 +277,17 @@ Regenerator::Result Regenerator::doRegen() {
glyph = fBlob->fGlyphs[glyphOffset];
SkASSERT(glyph && glyph->fMaskFormat == fSubRun->maskFormat());
- if (!fGlyphCache->hasGlyph(glyph) &&
- !strike->addGlyphToAtlas(fResourceProvider, fUploadTarget, fGlyphCache, glyph,
+ if (!fFullAtlasManager->hasGlyph(glyph) &&
+ !strike->addGlyphToAtlas(fResourceProvider, fUploadTarget, fGlyphCache,
+ fFullAtlasManager, glyph,
fLazyCache->get(), fSubRun->maskFormat())) {
fBrokenRun = glyphIdx > 0;
result.fFinished = false;
return result;
}
auto tokenTracker = fUploadTarget->tokenTracker();
- fGlyphCache->addGlyphToBulkAndSetUseToken(fSubRun->bulkUseToken(), glyph,
- tokenTracker->nextDrawToken());
+ fFullAtlasManager->addGlyphToBulkAndSetUseToken(fSubRun->bulkUseToken(), glyph,
+ tokenTracker->nextDrawToken());
}
regen_vertices<regenPos, regenCol, regenTexCoords>(currVertex, glyph, vertexStride,
@@ -302,14 +305,14 @@ Regenerator::Result Regenerator::doRegen() {
fSubRun->setStrike(strike);
}
fSubRun->setAtlasGeneration(fBrokenRun
- ? GrDrawOpAtlas::kInvalidAtlasGeneration
- : fGlyphCache->atlasGeneration(fSubRun->maskFormat()));
+ ? GrDrawOpAtlas::kInvalidAtlasGeneration
+ : fFullAtlasManager->atlasGeneration(fSubRun->maskFormat()));
}
return result;
}
Regenerator::Result Regenerator::regenerate() {
- uint64_t currentAtlasGen = fGlyphCache->atlasGeneration(fSubRun->maskFormat());
+ uint64_t currentAtlasGen = fFullAtlasManager->atlasGeneration(fSubRun->maskFormat());
// If regenerate() is called multiple times then the atlas gen may have changed. So we check
// this each time.
if (fSubRun->atlasGeneration() != currentAtlasGen) {
@@ -352,9 +355,9 @@ Regenerator::Result Regenerator::regenerate() {
// set use tokens for all of the glyphs in our subrun. This is only valid if we
// have a valid atlas generation
- fGlyphCache->setUseTokenBulk(*fSubRun->bulkUseToken(),
- fUploadTarget->tokenTracker()->nextDrawToken(),
- fSubRun->maskFormat());
+ fFullAtlasManager->setUseTokenBulk(*fSubRun->bulkUseToken(),
+ fUploadTarget->tokenTracker()->nextDrawToken(),
+ fSubRun->maskFormat());
return result;
}
}
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index 06282e103e..aadc2dc0c1 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -118,7 +118,8 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t
drawFilter);
SkScalerContextFlags scalerContextFlags = ComputeScalerContextFlags(target->colorSpaceInfo());
- auto atlasGlyphCache = context->contextPriv().getAtlasGlyphCache();
+ auto glyphCache = context->contextPriv().getGlyphCache();
+ auto restrictedAtlasManager = context->contextPriv().getRestrictedAtlasManager();
GrTextBlobCache* textBlobCache = context->contextPriv().getTextBlobCache();
if (canCache) {
@@ -151,7 +152,7 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t
// but we'd have to clear the subrun information
textBlobCache->remove(cacheBlob.get());
cacheBlob = textBlobCache->makeCachedBlob(blob, key, blurRec, skPaint);
- this->regenerateTextBlob(cacheBlob.get(), atlasGlyphCache,
+ this->regenerateTextBlob(cacheBlob.get(), glyphCache,
*context->caps()->shaderCaps(), paint, scalerContextFlags,
viewMatrix, props, blob, x, y, drawFilter);
} else {
@@ -163,7 +164,7 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t
GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob);
sk_sp<GrAtlasTextBlob> sanityBlob(textBlobCache->makeBlob(glyphCount, runCount));
sanityBlob->setupKey(key, blurRec, skPaint);
- this->regenerateTextBlob(sanityBlob.get(), atlasGlyphCache,
+ this->regenerateTextBlob(sanityBlob.get(), glyphCache,
*context->caps()->shaderCaps(), paint, scalerContextFlags,
viewMatrix, props, blob, x, y, drawFilter);
GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob);
@@ -175,17 +176,17 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t
} else {
cacheBlob = textBlobCache->makeBlob(blob);
}
- this->regenerateTextBlob(cacheBlob.get(), atlasGlyphCache,
+ this->regenerateTextBlob(cacheBlob.get(), glyphCache,
*context->caps()->shaderCaps(), paint, scalerContextFlags,
viewMatrix, props, blob, x, y, drawFilter);
}
- cacheBlob->flush(atlasGlyphCache, target, props, fDistanceAdjustTable.get(), paint,
+ cacheBlob->flush(restrictedAtlasManager, target, props, fDistanceAdjustTable.get(), paint,
clip, viewMatrix, clipBounds, x, y);
}
void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
- GrAtlasGlyphCache* fontCache,
+ GrGlyphCache* glyphCache,
const GrShaderCaps& shaderCaps,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
@@ -211,21 +212,21 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
if (this->canDrawAsDistanceFields(runPaint, viewMatrix, props, shaderCaps)) {
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning: {
- this->drawDFText(cacheBlob, run, fontCache, props, runPaint, scalerContextFlags,
+ this->drawDFText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
viewMatrix, (const char*)it.glyphs(), textLen, x + offset.x(),
y + offset.y());
break;
}
case SkTextBlob::kHorizontal_Positioning: {
SkPoint dfOffset = SkPoint::Make(x, y + offset.y());
- this->drawDFPosText(cacheBlob, run, fontCache, props, runPaint,
+ this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
textLen, it.pos(), 1, dfOffset);
break;
}
case SkTextBlob::kFull_Positioning: {
SkPoint dfOffset = SkPoint::Make(x, y);
- this->drawDFPosText(cacheBlob, run, fontCache, props, runPaint,
+ this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
textLen, it.pos(), 2, dfOffset);
break;
@@ -234,17 +235,17 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
} else {
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
- DrawBmpText(cacheBlob, run, fontCache, props, runPaint, scalerContextFlags,
+ DrawBmpText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
viewMatrix, (const char*)it.glyphs(), textLen, x + offset.x(),
y + offset.y());
break;
case SkTextBlob::kHorizontal_Positioning:
- DrawBmpPosText(cacheBlob, run, fontCache, props, runPaint, scalerContextFlags,
+ DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1,
SkPoint::Make(x, y + offset.y()));
break;
case SkTextBlob::kFull_Positioning:
- DrawBmpPosText(cacheBlob, run, fontCache, props, runPaint, scalerContextFlags,
+ DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2,
SkPoint::Make(x, y));
break;
@@ -255,7 +256,7 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
inline sk_sp<GrAtlasTextBlob>
GrAtlasTextContext::makeDrawTextBlob(GrTextBlobCache* blobCache,
- GrAtlasGlyphCache* fontCache,
+ GrGlyphCache* glyphCache,
const GrShaderCaps& shaderCaps,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
@@ -272,10 +273,10 @@ GrAtlasTextContext::makeDrawTextBlob(GrTextBlobCache* blobCache,
blob->setRunPaintFlags(0, paint.skPaint().getFlags());
if (this->canDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps)) {
- this->drawDFText(blob.get(), 0, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ this->drawDFText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
text, byteLength, x, y);
} else {
- DrawBmpText(blob.get(), 0, fontCache, props, paint, scalerContextFlags, viewMatrix, text,
+ DrawBmpText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix, text,
byteLength, x, y);
}
return blob;
@@ -283,7 +284,7 @@ GrAtlasTextContext::makeDrawTextBlob(GrTextBlobCache* blobCache,
inline sk_sp<GrAtlasTextBlob>
GrAtlasTextContext::makeDrawPosTextBlob(GrTextBlobCache* blobCache,
- GrAtlasGlyphCache* fontCache,
+ GrGlyphCache* glyphCache,
const GrShaderCaps& shaderCaps,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
@@ -302,11 +303,11 @@ GrAtlasTextContext::makeDrawPosTextBlob(GrTextBlobCache* blobCache,
blob->setRunPaintFlags(0, paint.skPaint().getFlags());
if (this->canDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps)) {
- this->drawDFPosText(blob.get(), 0, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ this->drawDFPosText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
text, byteLength, pos, scalarsPerPosition, offset);
} else {
- DrawBmpPosText(blob.get(), 0, fontCache, props, paint, scalerContextFlags, viewMatrix, text,
- byteLength, pos, scalarsPerPosition, offset);
+ DrawBmpPosText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
+ text, byteLength, pos, scalarsPerPosition, offset);
}
return blob;
}
@@ -320,17 +321,18 @@ void GrAtlasTextContext::drawText(GrContext* context, GrTextUtils::Target* targe
return;
}
- auto atlasGlyphCache = context->contextPriv().getAtlasGlyphCache();
+ auto glyphCache = context->contextPriv().getGlyphCache();
+ auto restrictedAtlasManager = context->contextPriv().getRestrictedAtlasManager();
auto textBlobCache = context->contextPriv().getTextBlobCache();
GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo());
sk_sp<GrAtlasTextBlob> blob(
- this->makeDrawTextBlob(textBlobCache, atlasGlyphCache,
+ this->makeDrawTextBlob(textBlobCache, glyphCache,
*context->caps()->shaderCaps(), paint,
ComputeScalerContextFlags(target->colorSpaceInfo()),
viewMatrix, props, text, byteLength, x, y));
if (blob) {
- blob->flush(atlasGlyphCache, target, props, fDistanceAdjustTable.get(), paint,
+ blob->flush(restrictedAtlasManager, target, props, fDistanceAdjustTable.get(), paint,
clip, viewMatrix, regionClipBounds, x, y);
}
}
@@ -346,22 +348,23 @@ void GrAtlasTextContext::drawPosText(GrContext* context, GrTextUtils::Target* ta
return;
}
- auto atlasGlyphCache = context->contextPriv().getAtlasGlyphCache();
+ auto glyphCache = context->contextPriv().getGlyphCache();
+ auto restrictedAtlasManager = context->contextPriv().getRestrictedAtlasManager();
auto textBlobCache = context->contextPriv().getTextBlobCache();
sk_sp<GrAtlasTextBlob> blob(this->makeDrawPosTextBlob(
- textBlobCache, atlasGlyphCache,
+ textBlobCache, glyphCache,
*context->caps()->shaderCaps(), paint,
ComputeScalerContextFlags(target->colorSpaceInfo()), viewMatrix, props, text,
byteLength, pos, scalarsPerPosition, offset));
if (blob) {
- blob->flush(atlasGlyphCache, target, props, fDistanceAdjustTable.get(), paint,
+ blob->flush(restrictedAtlasManager, target, props, fDistanceAdjustTable.get(), paint,
clip, viewMatrix, regionClipBounds, offset.fX, offset.fY);
}
}
void GrAtlasTextContext::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
+ GrGlyphCache* glyphCache, const SkSurfaceProps& props,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix, const char text[],
@@ -377,7 +380,7 @@ void GrAtlasTextContext::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
blob->setHasBitmap();
if (SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix)) {
- DrawBmpTextAsPaths(blob, runIndex, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ DrawBmpTextAsPaths(blob, runIndex, glyphCache, props, paint, scalerContextFlags, viewMatrix,
text, byteLength, x, y);
return;
}
@@ -387,7 +390,7 @@ void GrAtlasTextContext::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
viewMatrix, paint.skPaint().getTextAlign(), cache,
[&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
position += rounding;
- BmpAppendGlyph(blob, runIndex, fontCache, &currStrike,
+ BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike,
glyph, SkScalarFloorToScalar(position.fX),
SkScalarFloorToScalar(position.fY),
paint.filteredPremulColor(), cache,
@@ -398,7 +401,7 @@ void GrAtlasTextContext::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
}
void GrAtlasTextContext::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
+ GrGlyphCache* glyphCache, const SkSurfaceProps& props,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix,
@@ -416,7 +419,7 @@ void GrAtlasTextContext::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
blob->setHasBitmap();
if (SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix)) {
- DrawBmpPosTextAsPaths(blob, runIndex, fontCache, props, paint, scalerContextFlags,
+ DrawBmpPosTextAsPaths(blob, runIndex, glyphCache, props, paint, scalerContextFlags,
viewMatrix, text, byteLength, pos, scalarsPerPosition, offset);
return;
}
@@ -429,7 +432,7 @@ void GrAtlasTextContext::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
scalarsPerPosition, paint.skPaint().getTextAlign(), cache,
[&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
position += rounding;
- BmpAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph,
+ BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph,
SkScalarFloorToScalar(position.fX),
SkScalarFloorToScalar(position.fY),
paint.filteredPremulColor(), cache, SK_Scalar1);
@@ -439,7 +442,7 @@ void GrAtlasTextContext::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
}
void GrAtlasTextContext::DrawBmpTextAsPaths(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache,
+ GrGlyphCache* glyphCache,
const SkSurfaceProps& props,
const GrTextUtils::Paint& origPaint,
SkScalerContextFlags scalerContextFlags,
@@ -457,7 +460,7 @@ void GrAtlasTextContext::DrawBmpTextAsPaths(GrAtlasTextBlob* blob, int runIndex,
GrTextUtils::PathTextIter iter(text, byteLength, pathPaint, true);
FallbackTextHelper fallbackTextHelper(viewMatrix, pathPaint.getTextSize(),
- fontCache->getGlyphSizeLimit(),
+ glyphCache->getGlyphSizeLimit(),
iter.getPathScale());
const SkGlyph* iterGlyph;
@@ -474,11 +477,11 @@ void GrAtlasTextContext::DrawBmpTextAsPaths(GrAtlasTextBlob* blob, int runIndex,
lastText = iter.getText();
}
- fallbackTextHelper.drawText(blob, runIndex, fontCache, props, origPaint, scalerContextFlags);
+ fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, origPaint, scalerContextFlags);
}
void GrAtlasTextContext::DrawBmpPosTextAsPaths(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache,
+ GrGlyphCache* glyphCache,
const SkSurfaceProps& props,
const GrTextUtils::Paint& origPaint,
SkScalerContextFlags scalerContextFlags,
@@ -497,7 +500,7 @@ void GrAtlasTextContext::DrawBmpPosTextAsPaths(GrAtlasTextBlob* blob, int runInd
SkPaint pathPaint(origPaint);
SkScalar matrixScale = pathPaint.setupForAsPaths();
FallbackTextHelper fallbackTextHelper(viewMatrix, pathPaint.getTextSize(), matrixScale,
- fontCache->getGlyphSizeLimit());
+ glyphCache->getGlyphSizeLimit());
// Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
pathPaint.setStyle(SkPaint::kFill_Style);
@@ -534,23 +537,23 @@ void GrAtlasTextContext::DrawBmpPosTextAsPaths(GrAtlasTextBlob* blob, int runInd
pos += scalarsPerPosition;
}
- fallbackTextHelper.drawText(blob, runIndex, fontCache, props, origPaint, scalerContextFlags);
+ fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, origPaint, scalerContextFlags);
}
void GrAtlasTextContext::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, GrAtlasTextStrike** strike,
+ GrGlyphCache* grGlyphCache, GrAtlasTextStrike** strike,
const SkGlyph& skGlyph, SkScalar sx, SkScalar sy,
- GrColor color, SkGlyphCache* glyphCache,
+ GrColor color, SkGlyphCache* skGlyphCache,
SkScalar textRatio) {
if (!*strike) {
- *strike = fontCache->getStrike(glyphCache);
+ *strike = grGlyphCache->getStrike(skGlyphCache);
}
GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
skGlyph.getSubXFixed(),
skGlyph.getSubYFixed(),
GrGlyph::kCoverage_MaskStyle);
- GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, glyphCache);
+ GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, skGlyphCache);
if (!glyph) {
return;
}
@@ -570,7 +573,7 @@ void GrAtlasTextContext::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
SkRect glyphRect = SkRect::MakeXYWH(sx + dx, sy + dy, width, height);
- blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, glyphCache, skGlyph, sx, sy,
+ blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, skGlyphCache, skGlyph, sx, sy,
textRatio, true);
}
@@ -670,7 +673,7 @@ void GrAtlasTextContext::initDistanceFieldPaint(GrAtlasTextBlob* blob,
}
void GrAtlasTextContext::drawDFText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
+ GrGlyphCache* glyphCache, const SkSurfaceProps& props,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix, const char text[],
@@ -740,12 +743,12 @@ void GrAtlasTextContext::drawDFText(GrAtlasTextBlob* blob, int runIndex,
y -= alignY;
SkPoint offset = SkPoint::Make(x, y);
- this->drawDFPosText(blob, runIndex, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ this->drawDFPosText(blob, runIndex, glyphCache, props, paint, scalerContextFlags, viewMatrix,
text, byteLength, positions.begin(), 2, offset);
}
void GrAtlasTextContext::drawDFPosText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
+ GrGlyphCache* glyphCache, const SkSurfaceProps& props,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix, const char text[],
@@ -771,7 +774,7 @@ void GrAtlasTextContext::drawDFPosText(GrAtlasTextBlob* blob, int runIndex,
FallbackTextHelper fallbackTextHelper(viewMatrix,
paint.skPaint().getTextSize(),
- fontCache->getGlyphSizeLimit(),
+ glyphCache->getGlyphSizeLimit(),
textRatio);
GrAtlasTextStrike* currStrike = nullptr;
@@ -800,7 +803,7 @@ void GrAtlasTextContext::drawDFPosText(GrAtlasTextBlob* blob, int runIndex,
SkFloatToScalar(glyph.fAdvanceY) * alignMul * textRatio;
if (glyph.fMaskFormat != SkMask::kARGB32_Format) {
- DfAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph, glyphPos.fX,
+ DfAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph, glyphPos.fX,
glyphPos.fY, paint.filteredPremulColor(), cache, textRatio);
} else {
// can't append color glyph to SDF batch, send to fallback
@@ -812,25 +815,24 @@ void GrAtlasTextContext::drawDFPosText(GrAtlasTextBlob* blob, int runIndex,
SkGlyphCache::AttachCache(cache);
- fallbackTextHelper.drawText(blob, runIndex, fontCache, props, paint,
- scalerContextFlags);
+ fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, paint, scalerContextFlags);
}
// TODO: merge with BmpAppendGlyph
void GrAtlasTextContext::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* cache, GrAtlasTextStrike** strike,
+ GrGlyphCache* grGlyphCache, GrAtlasTextStrike** strike,
const SkGlyph& skGlyph, SkScalar sx, SkScalar sy,
- GrColor color, SkGlyphCache* glyphCache,
+ GrColor color, SkGlyphCache* skGlyphCache,
SkScalar textRatio) {
if (!*strike) {
- *strike = cache->getStrike(glyphCache);
+ *strike = grGlyphCache->getStrike(skGlyphCache);
}
GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
skGlyph.getSubXFixed(),
skGlyph.getSubYFixed(),
GrGlyph::kDistance_MaskStyle);
- GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, glyphCache);
+ GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, skGlyphCache);
if (!glyph) {
return;
}
@@ -846,7 +848,7 @@ void GrAtlasTextContext::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
height *= textRatio;
SkRect glyphRect = SkRect::MakeXYWH(sx + dx, sy + dy, width, height);
- blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, glyphCache, skGlyph, sx, sy,
+ blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, skGlyphCache, skGlyph, sx, sy,
textRatio, false);
}
@@ -871,7 +873,7 @@ void GrAtlasTextContext::FallbackTextHelper::appendText(const SkGlyph& glyph, in
}
void GrAtlasTextContext::FallbackTextHelper::drawText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache,
+ GrGlyphCache* glyphCache,
const SkSurfaceProps& props,
const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags) {
@@ -909,7 +911,7 @@ void GrAtlasTextContext::FallbackTextHelper::drawText(GrAtlasTextBlob* blob, int
SkPoint* glyphPos = fFallbackPos.begin();
while (text < stop) {
const SkGlyph& glyph = glyphCacheProc(cache, &text);
- GrAtlasTextContext::BmpAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph,
+ GrAtlasTextContext::BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph,
glyphPos->fX, glyphPos->fY, textColor,
cache, textRatio);
glyphPos++;
@@ -962,18 +964,19 @@ GR_DRAW_OP_TEST_DEFINE(GrAtlasTextOp) {
SkScalar x = SkIntToScalar(xInt);
SkScalar y = SkIntToScalar(yInt);
- auto atlasGlyphCache = context->contextPriv().getAtlasGlyphCache();
+ auto glyphCache = context->contextPriv().getGlyphCache();
+ auto restrictedAtlasManager = context->contextPriv().getRestrictedAtlasManager();
// right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to
// test the text op with this unit test, that is okay.
sk_sp<GrAtlasTextBlob> blob(gTextContext->makeDrawTextBlob(
- context->contextPriv().getTextBlobCache(), atlasGlyphCache,
+ context->contextPriv().getTextBlobCache(), glyphCache,
*context->caps()->shaderCaps(), utilsPaint,
GrAtlasTextContext::kTextBlobOpScalerContextFlags, viewMatrix, gSurfaceProps, text,
static_cast<size_t>(textLen), x, y));
return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, gSurfaceProps,
- gTextContext->dfAdjustTable(), atlasGlyphCache,
+ gTextContext->dfAdjustTable(), restrictedAtlasManager,
rtc->textTarget());
}
diff --git a/src/gpu/text/GrAtlasTextContext.h b/src/gpu/text/GrAtlasTextContext.h
index 207dd67206..37b7de5357 100644
--- a/src/gpu/text/GrAtlasTextContext.h
+++ b/src/gpu/text/GrAtlasTextContext.h
@@ -74,9 +74,8 @@ private:
}
void appendText(const SkGlyph& glyph, int count, const char* text, SkPoint glyphPos);
- void drawText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
- const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags);
+ void drawText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&,
+ const GrTextUtils::Paint&, SkScalerContextFlags);
private:
SkTDArray<char> fFallbackTxt;
@@ -96,7 +95,7 @@ private:
// Determines if we need to use fake gamma (and contrast boost):
static SkScalerContextFlags ComputeScalerContextFlags(const GrColorSpaceInfo&);
void regenerateTextBlob(GrAtlasTextBlob* bmp,
- GrAtlasGlyphCache*,
+ GrGlyphCache*,
const GrShaderCaps&,
const GrTextUtils::Paint&,
SkScalerContextFlags scalerContextFlags,
@@ -107,7 +106,7 @@ private:
static bool HasLCD(const SkTextBlob*);
- sk_sp<GrAtlasTextBlob> makeDrawTextBlob(GrTextBlobCache*, GrAtlasGlyphCache*,
+ sk_sp<GrAtlasTextBlob> makeDrawTextBlob(GrTextBlobCache*, GrGlyphCache*,
const GrShaderCaps&,
const GrTextUtils::Paint&,
SkScalerContextFlags scalerContextFlags,
@@ -116,7 +115,7 @@ private:
const char text[], size_t byteLength,
SkScalar x, SkScalar y) const;
- sk_sp<GrAtlasTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrAtlasGlyphCache*,
+ sk_sp<GrAtlasTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrGlyphCache*,
const GrShaderCaps&,
const GrTextUtils::Paint&,
SkScalerContextFlags scalerContextFlags,
@@ -128,24 +127,24 @@ private:
const SkPoint& offset) const;
// Functions for appending BMP text to GrAtlasTextBlob
- static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, SkScalar x, SkScalar y);
- static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset);
- static void DrawBmpTextAsPaths(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ static void DrawBmpTextAsPaths(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix, const char text[],
size_t byteLength, SkScalar x, SkScalar y);
- static void DrawBmpPosTextAsPaths(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ static void DrawBmpPosTextAsPaths(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix,
@@ -157,12 +156,12 @@ private:
bool canDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
const SkSurfaceProps& props, const GrShaderCaps& caps) const;
- void drawDFText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*, const SkSurfaceProps&,
+ void drawDFText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&,
const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x,
SkScalar y) const;
- void drawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*,
+ void drawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix, const char text[],
@@ -174,11 +173,11 @@ private:
SkScalar* textRatio,
const SkMatrix& viewMatrix) const;
- static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
GrAtlasTextStrike**, const SkGlyph&, SkScalar sx, SkScalar sy,
GrColor color, SkGlyphCache*, SkScalar textRatio);
- static void DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ static void DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
GrAtlasTextStrike**, const SkGlyph&, SkScalar sx, SkScalar sy,
GrColor color, SkGlyphCache* cache, SkScalar textRatio);
diff --git a/src/gpu/text/GrAtlasGlyphCache.cpp b/src/gpu/text/GrGlyphCache.cpp
index f7b1e1269a..d4440897bc 100644
--- a/src/gpu/text/GrAtlasGlyphCache.cpp
+++ b/src/gpu/text/GrGlyphCache.cpp
@@ -5,81 +5,19 @@
* found in the LICENSE file.
*/
-#include "GrAtlasGlyphCache.h"
-#include "GrContext.h"
+#include "GrAtlasManager.h"
#include "GrDistanceFieldGenFromVector.h"
-#include "GrGpu.h"
-#include "GrProxyProvider.h"
-#include "GrRectanizer.h"
+#include "GrGlyphCache.h"
#include "SkAutoMalloc.h"
#include "SkDistanceFieldGen.h"
-#include "SkMathPriv.h"
-#include "SkString.h"
-
-bool GrAtlasGlyphCache::initAtlas(GrMaskFormat format) {
- int index = MaskFormatToAtlasIndex(format);
- if (!fAtlases[index]) {
- GrPixelConfig config = MaskFormatToPixelConfig(format, *fProxyProvider->caps());
- int width = fAtlasConfigs[index].fWidth;
- int height = fAtlasConfigs[index].fHeight;
- int numPlotsX = fAtlasConfigs[index].numPlotsX();
- int numPlotsY = fAtlasConfigs[index].numPlotsY();
-
- fAtlases[index] = GrDrawOpAtlas::Make(fProxyProvider, config, width, height,
- numPlotsX, numPlotsY, fAllowMultitexturing,
- &GrAtlasGlyphCache::HandleEviction, (void*)this);
- if (!fAtlases[index]) {
- return false;
- }
- }
- return true;
-}
-GrAtlasGlyphCache::GrAtlasGlyphCache(GrProxyProvider* proxyProvider, float maxTextureBytes,
- GrDrawOpAtlas::AllowMultitexturing allowMultitexturing)
- : fProxyProvider(proxyProvider)
- , fAllowMultitexturing(allowMultitexturing)
- , fPreserveStrike(nullptr) {
- // Calculate RGBA size. Must be between 512 x 256 and MaxTextureSize x MaxTextureSize / 2
- int log2MaxTextureSize = SkPrevLog2(fProxyProvider->caps()->maxTextureSize());
- int log2MaxDim = 9;
- for (; log2MaxDim <= log2MaxTextureSize; ++log2MaxDim) {
- int maxDim = 1 << log2MaxDim;
- int minDim = 1 << (log2MaxDim - 1);
-
- if (maxDim * minDim * 4 >= maxTextureBytes) break;
- }
-
- int log2MinDim = log2MaxDim - 1;
- int maxDim = 1 << log2MaxDim;
- int minDim = 1 << log2MinDim;
- // Plots are either 256 or 512.
- int maxPlot = SkTMin(512, SkTMax(256, 1 << (log2MaxDim - 2)));
- int minPlot = SkTMin(512, SkTMax(256, 1 << (log2MaxDim - 3)));
-
- // Setup default atlas configs. The A8 atlas uses maxDim for both width and height, as the A8
- // format is already very compact.
- fAtlasConfigs[kA8_GrMaskFormat].fWidth = maxDim;
- fAtlasConfigs[kA8_GrMaskFormat].fHeight = maxDim;
- fAtlasConfigs[kA8_GrMaskFormat].fPlotWidth = maxPlot;
- fAtlasConfigs[kA8_GrMaskFormat].fPlotHeight = minPlot;
-
- // A565 and ARGB use maxDim x minDim.
- fAtlasConfigs[kA565_GrMaskFormat].fWidth = minDim;
- fAtlasConfigs[kA565_GrMaskFormat].fHeight = maxDim;
- fAtlasConfigs[kA565_GrMaskFormat].fPlotWidth = minPlot;
- fAtlasConfigs[kA565_GrMaskFormat].fPlotHeight = minPlot;
-
- fAtlasConfigs[kARGB_GrMaskFormat].fWidth = minDim;
- fAtlasConfigs[kARGB_GrMaskFormat].fHeight = maxDim;
- fAtlasConfigs[kARGB_GrMaskFormat].fPlotWidth = minPlot;
- fAtlasConfigs[kARGB_GrMaskFormat].fPlotHeight = minPlot;
-
- fGlyphSizeLimit = minPlot;
+GrGlyphCache::GrGlyphCache()
+ : fPreserveStrike(nullptr)
+ , fGlyphSizeLimit(0) {
}
-GrAtlasGlyphCache::~GrAtlasGlyphCache() {
+GrGlyphCache::~GrGlyphCache() {
StrikeHash::Iter iter(&fCache);
while (!iter.done()) {
(*iter).fIsAbandoned = true;
@@ -88,7 +26,7 @@ GrAtlasGlyphCache::~GrAtlasGlyphCache() {
}
}
-void GrAtlasGlyphCache::freeAll() {
+void GrGlyphCache::freeAll() {
StrikeHash::Iter iter(&fCache);
while (!iter.done()) {
(*iter).fIsAbandoned = true;
@@ -96,120 +34,26 @@ void GrAtlasGlyphCache::freeAll() {
++iter;
}
fCache.rewind();
- for (int i = 0; i < kMaskFormatCount; ++i) {
- fAtlases[i] = nullptr;
- }
}
-void GrAtlasGlyphCache::HandleEviction(GrDrawOpAtlas::AtlasID id, void* ptr) {
- GrAtlasGlyphCache* fontCache = reinterpret_cast<GrAtlasGlyphCache*>(ptr);
+void GrGlyphCache::HandleEviction(GrDrawOpAtlas::AtlasID id, void* ptr) {
+ GrGlyphCache* glyphCache = reinterpret_cast<GrGlyphCache*>(ptr);
- StrikeHash::Iter iter(&fontCache->fCache);
+ StrikeHash::Iter iter(&glyphCache->fCache);
for (; !iter.done(); ++iter) {
GrAtlasTextStrike* strike = &*iter;
strike->removeID(id);
// clear out any empty strikes. We will preserve the strike whose call to addToAtlas
// triggered the eviction
- if (strike != fontCache->fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
- fontCache->fCache.remove(GrAtlasTextStrike::GetKey(*strike));
+ if (strike != glyphCache->fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
+ glyphCache->fCache.remove(GrAtlasTextStrike::GetKey(*strike));
strike->fIsAbandoned = true;
strike->unref();
}
}
}
-#ifdef SK_DEBUG
-#include "GrContextPriv.h"
-#include "GrSurfaceProxy.h"
-#include "GrSurfaceContext.h"
-#include "GrTextureProxy.h"
-
-#include "SkBitmap.h"
-#include "SkImageEncoder.h"
-#include "SkStream.h"
-#include <stdio.h>
-
-/**
- * Write the contents of the surface proxy to a PNG. Returns true if successful.
- * @param filename Full path to desired file
- */
-static bool save_pixels(GrContext* context, GrSurfaceProxy* sProxy, const char* filename) {
- if (!sProxy) {
- return false;
- }
-
- SkImageInfo ii = SkImageInfo::Make(sProxy->width(), sProxy->height(),
- kRGBA_8888_SkColorType, kPremul_SkAlphaType);
- SkBitmap bm;
- if (!bm.tryAllocPixels(ii)) {
- return false;
- }
-
- sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext(
- sk_ref_sp(sProxy)));
- if (!sContext || !sContext->asTextureProxy()) {
- return false;
- }
-
- bool result = sContext->readPixels(ii, bm.getPixels(), bm.rowBytes(), 0, 0);
- if (!result) {
- SkDebugf("------ failed to read pixels for %s\n", filename);
- return false;
- }
-
- // remove any previous version of this file
- remove(filename);
-
- SkFILEWStream file(filename);
- if (!file.isValid()) {
- SkDebugf("------ failed to create file: %s\n", filename);
- remove(filename); // remove any partial file
- return false;
- }
-
- if (!SkEncodeImage(&file, bm, SkEncodedImageFormat::kPNG, 100)) {
- SkDebugf("------ failed to encode %s\n", filename);
- remove(filename); // remove any partial file
- return false;
- }
-
- return true;
-}
-
-void GrAtlasGlyphCache::dump(GrContext* context) const {
- static int gDumpCount = 0;
- for (int i = 0; i < kMaskFormatCount; ++i) {
- if (fAtlases[i]) {
- const sk_sp<GrTextureProxy>* proxies = fAtlases[i]->getProxies();
- for (uint32_t pageIdx = 0; pageIdx < fAtlases[i]->numActivePages(); ++pageIdx) {
- SkASSERT(proxies[pageIdx]);
- SkString filename;
-#ifdef SK_BUILD_FOR_ANDROID
- filename.printf("/sdcard/fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
-#else
- filename.printf("fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
-#endif
-
- save_pixels(context, proxies[pageIdx].get(), filename.c_str());
- }
- }
- }
- ++gDumpCount;
-}
-#endif
-
-void GrAtlasGlyphCache::setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]) {
- // Delete any old atlases.
- // This should be safe to do as long as we are not in the middle of a flush.
- for (int i = 0; i < kMaskFormatCount; i++) {
- fAtlases[i] = nullptr;
- }
- memcpy(fAtlasConfigs, configs, sizeof(fAtlasConfigs));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
static inline GrMaskFormat get_packed_glyph_mask_format(const SkGlyph& glyph) {
SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
switch (format) {
@@ -450,7 +294,8 @@ void GrAtlasTextStrike::removeID(GrDrawOpAtlas::AtlasID id) {
bool GrAtlasTextStrike::addGlyphToAtlas(GrResourceProvider* resourceProvider,
GrDeferredUploadTarget* target,
- GrAtlasGlyphCache* atlasGlyphCache,
+ GrGlyphCache* glyphCache,
+ GrAtlasManager* fullAtlasManager,
GrGlyph* glyph,
SkGlyphCache* cache,
GrMaskFormat expectedMaskFormat) {
@@ -477,10 +322,10 @@ bool GrAtlasTextStrike::addGlyphToAtlas(GrResourceProvider* resourceProvider,
}
}
- bool success = atlasGlyphCache->addToAtlas(resourceProvider, this, &glyph->fID, target,
- expectedMaskFormat,
- glyph->width(), glyph->height(),
- storage.get(), &glyph->fAtlasLocation);
+ bool success = fullAtlasManager->addToAtlas(resourceProvider, glyphCache, this,
+ &glyph->fID, target, expectedMaskFormat,
+ glyph->width(), glyph->height(),
+ storage.get(), &glyph->fAtlasLocation);
if (success) {
SkASSERT(GrDrawOpAtlas::kInvalidAtlasID != glyph->fID);
fAtlasedGlyphs++;
diff --git a/src/gpu/text/GrGlyphCache.h b/src/gpu/text/GrGlyphCache.h
new file mode 100644
index 0000000000..169e4b30a5
--- /dev/null
+++ b/src/gpu/text/GrGlyphCache.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrAtlasGlyphCache_DEFINED
+#define GrAtlasGlyphCache_DEFINED
+
+#include "GrDrawOpAtlas.h"
+#include "GrGlyph.h"
+#include "SkArenaAlloc.h"
+#include "SkGlyphCache.h"
+#include "SkTDynamicHash.h"
+
+class GrGlyphCache;
+class GrAtlasManager;
+class GrGpu;
+
+/**
+ * The GrAtlasTextStrike manages a pool of CPU backing memory for GrGlyphs. This backing memory
+ * is indexed by a PackedID and SkGlyphCache. The SkGlyphCache is what actually creates the mask.
+ * The GrAtlasTextStrike may outlive the generating SkGlyphCache. However, it retains a copy
+ * of it's SkDescriptor as a key to access (or regenerate) the SkGlyphCache. GrAtlasTextStrike are
+ * created by and owned by a GrGlyphCache.
+ */
+class GrAtlasTextStrike : public SkNVRefCnt<GrAtlasTextStrike> {
+public:
+ GrAtlasTextStrike(const SkDescriptor& fontScalerKey);
+ ~GrAtlasTextStrike();
+
+ inline GrGlyph* getGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
+ SkGlyphCache* cache) {
+ GrGlyph* glyph = fCache.find(packed);
+ if (nullptr == glyph) {
+ glyph = this->generateGlyph(skGlyph, packed, cache);
+ }
+ return glyph;
+ }
+
+ // This variant of the above function is called by GrAtlasTextOp. At this point, it is possible
+ // that the maskformat of the glyph differs from what we expect. In these cases we will just
+ // draw a clear square.
+ // skbug:4143 crbug:510931
+ inline GrGlyph* getGlyph(GrGlyph::PackedID packed,
+ GrMaskFormat expectedMaskFormat,
+ SkGlyphCache* cache) {
+ GrGlyph* glyph = fCache.find(packed);
+ if (nullptr == glyph) {
+ // We could return this to the caller, but in practice it adds code complexity for
+ // potentially little benefit(ie, if the glyph is not in our font cache, then its not
+ // in the atlas and we're going to be doing a texture upload anyways).
+ const SkGlyph& skGlyph = GrToSkGlyph(cache, packed);
+ glyph = this->generateGlyph(skGlyph, packed, cache);
+ glyph->fMaskFormat = expectedMaskFormat;
+ }
+ return glyph;
+ }
+
+ // returns true if glyph successfully added to texture atlas, false otherwise. If the glyph's
+ // mask format has changed, then addGlyphToAtlas will draw a clear box. This will almost never
+ // happen.
+ // TODO we can handle some of these cases if we really want to, but the long term solution is to
+ // get the actual glyph image itself when we get the glyph metrics.
+ bool addGlyphToAtlas(GrResourceProvider*, GrDeferredUploadTarget*, GrGlyphCache*,
+ GrAtlasManager*, GrGlyph*,
+ SkGlyphCache*, GrMaskFormat expectedMaskFormat);
+
+ // testing
+ int countGlyphs() const { return fCache.count(); }
+
+ // remove any references to this plot
+ void removeID(GrDrawOpAtlas::AtlasID);
+
+ // If a TextStrike is abandoned by the cache, then the caller must get a new strike
+ bool isAbandoned() const { return fIsAbandoned; }
+
+ static const SkDescriptor& GetKey(const GrAtlasTextStrike& ts) {
+ return *ts.fFontScalerKey.getDesc();
+ }
+
+ static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
+
+private:
+ SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
+ SkAutoDescriptor fFontScalerKey;
+ SkArenaAlloc fPool{512};
+
+ int fAtlasedGlyphs;
+ bool fIsAbandoned;
+
+ static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, GrGlyph::PackedID id) {
+ return cache->getGlyphIDMetrics(GrGlyph::UnpackID(id),
+ GrGlyph::UnpackFixedX(id),
+ GrGlyph::UnpackFixedY(id));
+ }
+
+ GrGlyph* generateGlyph(const SkGlyph&, GrGlyph::PackedID, SkGlyphCache*);
+
+ friend class GrGlyphCache;
+};
+
+/**
+ * GrGlyphCache manages strikes which are indexed by a SkGlyphCache. These strikes can then be
+ * used to generate individual Glyph Masks.
+ */
+class GrGlyphCache {
+public:
+ GrGlyphCache();
+ ~GrGlyphCache();
+
+ void setGlyphSizeLimit(SkScalar sizeLimit) { fGlyphSizeLimit = sizeLimit; }
+ SkScalar getGlyphSizeLimit() const { return fGlyphSizeLimit; }
+
+ void setStrikeToPreserve(GrAtlasTextStrike* strike) { fPreserveStrike = strike; }
+
+ // The user of the cache may hold a long-lived ref to the returned strike. However, actions by
+ // another client of the cache may cause the strike to be purged while it is still reffed.
+ // Therefore, the caller must check GrAtlasTextStrike::isAbandoned() if there are other
+ // interactions with the cache since the strike was received.
+ inline GrAtlasTextStrike* getStrike(const SkGlyphCache* cache) {
+ GrAtlasTextStrike* strike = fCache.find(cache->getDescriptor());
+ if (nullptr == strike) {
+ strike = this->generateStrike(cache);
+ }
+ return strike;
+ }
+
+ void freeAll();
+
+ static void HandleEviction(GrDrawOpAtlas::AtlasID, void*);
+
+private:
+ GrAtlasTextStrike* generateStrike(const SkGlyphCache* cache) {
+ GrAtlasTextStrike* strike = new GrAtlasTextStrike(cache->getDescriptor());
+ fCache.add(strike);
+ return strike;
+ }
+
+ using StrikeHash = SkTDynamicHash<GrAtlasTextStrike, SkDescriptor>;
+
+ StrikeHash fCache;
+ GrAtlasTextStrike* fPreserveStrike;
+ SkScalar fGlyphSizeLimit;
+};
+
+#endif
diff --git a/src/gpu/text/GrTextUtils.h b/src/gpu/text/GrTextUtils.h
index 5fe38fe773..69421c2474 100644
--- a/src/gpu/text/GrTextUtils.h
+++ b/src/gpu/text/GrTextUtils.h
@@ -16,13 +16,13 @@
#include "SkTextToPathIter.h"
#include "SkTLazy.h"
-class GrAtlasGlyphCache;
class GrAtlasTextBlob;
class GrAtlasTextOp;
class GrAtlasTextStrike;
class GrClip;
class GrColorSpaceXform;
class GrContext;
+class GrGlyphCache;
class GrPaint;
class GrShaderCaps;
class SkColorSpace;
diff --git a/tests/DrawOpAtlasTest.cpp b/tests/DrawOpAtlasTest.cpp
index a34618e38f..7e35a07726 100644
--- a/tests/DrawOpAtlasTest.cpp
+++ b/tests/DrawOpAtlasTest.cpp
@@ -11,7 +11,7 @@
#include "GrContextPriv.h"
#include "Test.h"
-#include "text/GrAtlasGlyphCache.h"
+#include "text/GrGlyphCache.h"
static const int kNumPlots = 2;
static const int kPlotSize = 32;
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index c6d3bbe2ef..c483a22aac 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -26,7 +26,7 @@
#include "SkMathPriv.h"
#include "SkString.h"
#include "ops/GrMeshDrawOp.h"
-#include "text/GrAtlasGlyphCache.h"
+#include "text/GrGlyphCache.h"
#include "text/GrTextBlobCache.h"
namespace GrTest {
@@ -94,7 +94,7 @@ void GrContext::setTextBlobCacheLimit_ForTesting(size_t bytes) {
}
void GrContext::setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs) {
- fAtlasGlyphCache->setAtlasSizes_ForTesting(configs);
+ fFullAtlasManager->setAtlasSizes_ForTesting(configs);
}
///////////////////////////////////////////////////////////////////////////////
@@ -147,11 +147,11 @@ void GrContext::printGpuStats() const {
SkDebugf("%s", out.c_str());
}
-sk_sp<SkImage> GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format, uint32_t index) {
- GrAtlasGlyphCache* cache = this->contextPriv().getAtlasGlyphCache();
+sk_sp<SkImage> GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format, unsigned int index) {
+ auto restrictedAtlasManager = this->contextPriv().getRestrictedAtlasManager();
unsigned int numProxies;
- const sk_sp<GrTextureProxy>* proxies = cache->getProxies(format, &numProxies);
+ const sk_sp<GrTextureProxy>* proxies = restrictedAtlasManager->getProxies(format, &numProxies);
if (index >= numProxies || !proxies[index]) {
return nullptr;
}