Move StrikeCache and TextBlobCache to RecordingContext

TBR=bsalomon@google.com
Change-Id: I09a918eee4fab2091b0cbbbe83bc66418e43045e
Reviewed-on: https://skia-review.googlesource.com/c/193471
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Robert Phillips 2019-02-21 16:11:41 -05:00 committed by Skia Commit-Bot
parent bce7d86270
commit 2184fb7bbd
7 changed files with 69 additions and 45 deletions

View File

@ -26,7 +26,6 @@ class GrContextThreadSafeProxy;
class GrDrawingManager; class GrDrawingManager;
class GrFragmentProcessor; class GrFragmentProcessor;
struct GrGLInterface; struct GrGLInterface;
class GrStrikeCache;
class GrGpu; class GrGpu;
struct GrMockOptions; struct GrMockOptions;
class GrPath; class GrPath;
@ -37,7 +36,6 @@ class GrSamplerState;
class GrSkSLFPFactoryCache; class GrSkSLFPFactoryCache;
class GrSurfaceProxy; class GrSurfaceProxy;
class GrSwizzle; class GrSwizzle;
class GrTextBlobCache;
class GrTextContext; class GrTextContext;
class GrTextureProxy; class GrTextureProxy;
struct GrVkBackendContext; struct GrVkBackendContext;
@ -310,9 +308,6 @@ private:
GrResourceCache* fResourceCache; GrResourceCache* fResourceCache;
GrResourceProvider* fResourceProvider; GrResourceProvider* fResourceProvider;
GrStrikeCache* fGlyphCache;
std::unique_ptr<GrTextBlobCache> fTextBlobCache;
bool fDidTestPMConversions; bool fDidTestPMConversions;
// true if the PM/UPM conversion succeeded; false otherwise // true if the PM/UPM conversion succeeded; false otherwise
bool fPMUPMConversionsRoundTrip; bool fPMUPMConversionsRoundTrip;
@ -337,12 +332,6 @@ private:
*/ */
bool validPMUPMConversionExists(); bool validPMUPMConversionExists();
/**
* A callback similar to the above for use by the TextBlobCache
* TODO move textblob draw calls below context so we can use the call above.
*/
static void TextBlobCacheOverBudgetCB(void* data);
typedef GrRecordingContext INHERITED; typedef GrRecordingContext INHERITED;
}; };

View File

@ -15,6 +15,8 @@ class GrDrawingManager;
class GrOnFlushCallbackObject; class GrOnFlushCallbackObject;
class GrOpMemoryPool; class GrOpMemoryPool;
class GrRecordingContextPriv; class GrRecordingContextPriv;
class GrStrikeCache;
class GrTextBlobCache;
class SK_API GrRecordingContext : public GrImageContext { class SK_API GrRecordingContext : public GrImageContext {
public: public:
@ -38,6 +40,10 @@ protected:
sk_sp<GrOpMemoryPool> refOpMemoryPool(); sk_sp<GrOpMemoryPool> refOpMemoryPool();
GrOpMemoryPool* opMemoryPool(); GrOpMemoryPool* opMemoryPool();
GrStrikeCache* getGlyphCache() { return fGlyphCache.get(); }
GrTextBlobCache* getTextBlobCache();
const GrTextBlobCache* getTextBlobCache() const;
/** /**
* Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.) * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.)
* *
@ -100,8 +106,12 @@ protected:
private: private:
// All the GrOp-derived classes use this pool. // All the GrOp-derived classes use this pool.
sk_sp<GrOpMemoryPool> fOpMemoryPool; sk_sp<GrOpMemoryPool> fOpMemoryPool;
GrAuditTrail fAuditTrail;
std::unique_ptr<GrStrikeCache> fGlyphCache;
std::unique_ptr<GrTextBlobCache> fTextBlobCache;
GrAuditTrail fAuditTrail;
typedef GrImageContext INHERITED; typedef GrImageContext INHERITED;
}; };

View File

@ -49,7 +49,6 @@ GrContext::GrContext(GrBackendApi backend, const GrContextOptions& options, int3
: INHERITED(backend, options, contextID) { : INHERITED(backend, options, contextID) {
fResourceCache = nullptr; fResourceCache = nullptr;
fResourceProvider = nullptr; fResourceProvider = nullptr;
fGlyphCache = nullptr;
} }
GrContext::~GrContext() { GrContext::~GrContext() {
@ -60,7 +59,6 @@ GrContext::~GrContext() {
} }
delete fResourceProvider; delete fResourceProvider;
delete fResourceCache; delete fResourceCache;
delete fGlyphCache;
} }
bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) { bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
@ -73,6 +71,8 @@ bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFac
} }
SkASSERT(this->caps()); SkASSERT(this->caps());
SkASSERT(this->getGlyphCache());
SkASSERT(this->getTextBlobCache());
if (fGpu) { if (fGpu) {
fResourceCache = new GrResourceCache(this->caps(), this->singleOwner(), this->contextID()); fResourceCache = new GrResourceCache(this->caps(), this->singleOwner(), this->contextID());
@ -121,10 +121,6 @@ bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFac
this->options().fSortRenderTargets, this->options().fSortRenderTargets,
this->options().fReduceOpListSplitting)); this->options().fReduceOpListSplitting));
fGlyphCache = new GrStrikeCache(this->caps(), this->options().fGlyphCacheTextureMaximumBytes);
fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this, this->contextID()));
// DDL TODO: we need to think through how the task group & persistent cache // DDL TODO: we need to think through how the task group & persistent cache
// get passed on to/shared between all the DDLRecorders created with this context. // get passed on to/shared between all the DDLRecorders created with this context.
if (this->options().fExecutor) { if (this->options().fExecutor) {
@ -164,9 +160,6 @@ void GrContext::abandonContext() {
fResourceCache->abandonAll(); fResourceCache->abandonAll();
fGpu->disconnect(GrGpu::DisconnectType::kAbandon); fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
fGlyphCache->freeAll();
fTextBlobCache->freeAll();
} }
void GrContext::releaseResourcesAndAbandonContext() { void GrContext::releaseResourcesAndAbandonContext() {
@ -186,9 +179,6 @@ void GrContext::releaseResourcesAndAbandonContext() {
fResourceCache->releaseAll(); fResourceCache->releaseAll();
fGpu->disconnect(GrGpu::DisconnectType::kCleanup); fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
fGlyphCache->freeAll();
fTextBlobCache->freeAll();
} }
void GrContext::resetGLTextureBindings() { void GrContext::resetGLTextureBindings() {
@ -206,7 +196,9 @@ void GrContext::resetContext(uint32_t state) {
void GrContext::freeGpuResources() { void GrContext::freeGpuResources() {
ASSERT_SINGLE_OWNER ASSERT_SINGLE_OWNER
fGlyphCache->freeAll(); // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
// Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
this->getGlyphCache()->freeAll();
this->drawingManager()->freeGpuResources(); this->drawingManager()->freeGpuResources();
@ -217,7 +209,10 @@ void GrContext::purgeUnlockedResources(bool scratchResourcesOnly) {
ASSERT_SINGLE_OWNER ASSERT_SINGLE_OWNER
fResourceCache->purgeUnlockedResources(scratchResourcesOnly); fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
fResourceCache->purgeAsNeeded(); fResourceCache->purgeAsNeeded();
fTextBlobCache->purgeStaleBlobs();
// The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
// place to purge stale blobs
this->getTextBlobCache()->purgeStaleBlobs();
} }
void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) { void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
@ -232,7 +227,9 @@ void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
ccpr->purgeCacheEntriesOlderThan(this->proxyProvider(), purgeTime); ccpr->purgeCacheEntriesOlderThan(this->proxyProvider(), purgeTime);
} }
fTextBlobCache->purgeStaleBlobs(); // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
// place to purge stale blobs
this->getTextBlobCache()->purgeStaleBlobs();
} }
void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) { void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
@ -274,18 +271,6 @@ int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void GrContext::TextBlobCacheOverBudgetCB(void* data) {
SkASSERT(data);
// TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
// GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
// to below the GrContext level, but this is not trivial because they call drawPath on
// SkGpuDevice.
GrContext* context = reinterpret_cast<GrContext*>(data);
context->flush();
}
////////////////////////////////////////////////////////////////////////////////
void GrContext::flush() { void GrContext::flush() {
ASSERT_SINGLE_OWNER ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED RETURN_IF_ABANDONED
@ -373,6 +358,6 @@ void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
ASSERT_SINGLE_OWNER ASSERT_SINGLE_OWNER
fResourceCache->dumpMemoryStatistics(traceMemoryDump); fResourceCache->dumpMemoryStatistics(traceMemoryDump);
traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes", traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
fTextBlobCache->usedBytes()); this->getTextBlobCache()->usedBytes());
} }

View File

@ -765,7 +765,7 @@ void GrContextPriv::printGpuStats() const {
} }
void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) { void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) {
fContext->fTextBlobCache->setBudget(bytes); fContext->priv().getTextBlobCache()->setBudget(bytes);
} }
sk_sp<SkImage> GrContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index) { sk_sp<SkImage> GrContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index) {

View File

@ -68,6 +68,9 @@ public:
sk_sp<GrOpMemoryPool> refOpMemoryPool(); sk_sp<GrOpMemoryPool> refOpMemoryPool();
GrOpMemoryPool* opMemoryPool() { return fContext->opMemoryPool(); } GrOpMemoryPool* opMemoryPool() { return fContext->opMemoryPool(); }
GrStrikeCache* getGlyphCache() { return fContext->getGlyphCache(); }
GrTextBlobCache* getTextBlobCache() { return fContext->getTextBlobCache(); }
/** /**
* Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.) * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.)
* *
@ -265,9 +268,6 @@ public:
GrGpu* getGpu() { return fContext->fGpu.get(); } GrGpu* getGpu() { return fContext->fGpu.get(); }
const GrGpu* getGpu() const { return fContext->fGpu.get(); } const GrGpu* getGpu() const { return fContext->fGpu.get(); }
GrStrikeCache* getGlyphCache() { return fContext->fGlyphCache; }
GrTextBlobCache* getTextBlobCache() { return fContext->fTextBlobCache.get(); }
// This accessor should only ever be called by the GrOpFlushState. // This accessor should only ever be called by the GrOpFlushState.
GrAtlasManager* getAtlasManager() { GrAtlasManager* getAtlasManager() {
return fContext->onGetAtlasManager(); return fContext->onGetAtlasManager();

View File

@ -16,6 +16,7 @@
#include "GrSkSLFPFactoryCache.h" #include "GrSkSLFPFactoryCache.h"
#include "GrTextureContext.h" #include "GrTextureContext.h"
#include "SkGr.h" #include "SkGr.h"
#include "text/GrTextBlobCache.h"
#define ASSERT_SINGLE_OWNER_PRIV \ #define ASSERT_SINGLE_OWNER_PRIV \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());) SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
@ -28,17 +29,45 @@ GrRecordingContext::GrRecordingContext(GrBackendApi backend,
GrRecordingContext::~GrRecordingContext() { } GrRecordingContext::~GrRecordingContext() { }
/**
* TODO: move textblob draw calls below context (see comment below)
*/
static void textblobcache_overbudget_CB(void* data) {
SkASSERT(data);
GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
GrContext* direct = context->priv().asDirectContext();
if (!direct) {
return;
}
// TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
// GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
// to below the GrContext level, but this is not trivial because they call drawPath on
// SkGpuDevice.
direct->flush();
}
bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) { bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) {
if (!INHERITED::init(std::move(caps), std::move(cache))) { if (!INHERITED::init(std::move(caps), std::move(cache))) {
return false; return false;
} }
fGlyphCache.reset(new GrStrikeCache(this->caps(),
this->options().fGlyphCacheTextureMaximumBytes));
fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
this->contextID()));
return true; return true;
} }
void GrRecordingContext::abandonContext() { void GrRecordingContext::abandonContext() {
INHERITED::abandonContext(); INHERITED::abandonContext();
fGlyphCache->freeAll();
fTextBlobCache->freeAll();
} }
sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() { sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
@ -57,6 +86,14 @@ GrOpMemoryPool* GrRecordingContext::opMemoryPool() {
return this->refOpMemoryPool().get(); return this->refOpMemoryPool().get();
} }
GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
return fTextBlobCache.get();
}
const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
return fTextBlobCache.get();
}
void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject); this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
} }

View File

@ -52,6 +52,9 @@ public:
sk_sp<GrOpMemoryPool> refOpMemoryPool(); sk_sp<GrOpMemoryPool> refOpMemoryPool();
GrOpMemoryPool* opMemoryPool() { return fContext->opMemoryPool(); } GrOpMemoryPool* opMemoryPool() { return fContext->opMemoryPool(); }
GrStrikeCache* getGlyphCache() { return fContext->getGlyphCache(); }
GrTextBlobCache* getTextBlobCache() { return fContext->getTextBlobCache(); }
/** /**
* Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.) * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.)
* *