Convert evict callback from function to interface

This allows me to find uses of the eviction registratoin
easier in my IDE.

Change-Id: I127911f769d90716f6c8bb69d71b2255786aec21
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/265981
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2020-01-22 17:26:56 -05:00 committed by Skia Commit-Bot
parent 7abc7aa2db
commit 1a496c507e
8 changed files with 50 additions and 57 deletions

View File

@ -44,7 +44,7 @@ std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrProxyProvider* proxyProvide
GrColorType colorType, int width, GrColorType colorType, int width,
int height, int plotWidth, int plotHeight, int height, int plotWidth, int plotHeight,
AllowMultitexturing allowMultitexturing, AllowMultitexturing allowMultitexturing,
GrDrawOpAtlas::EvictionFunc func, void* data) { EvictionCallback* evictor) {
if (!format.isValid()) { if (!format.isValid()) {
return nullptr; return nullptr;
} }
@ -56,7 +56,7 @@ std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrProxyProvider* proxyProvide
return nullptr; return nullptr;
} }
atlas->registerEvictionCallback(func, data); atlas->fEvictionCallbacks.emplace_back(evictor);
return atlas; return atlas;
} }
@ -229,9 +229,10 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, const GrBackendForm
} }
inline void GrDrawOpAtlas::processEviction(AtlasID id) { inline void GrDrawOpAtlas::processEviction(AtlasID id) {
for (int i = 0; i < fEvictionCallbacks.count(); i++) { for (auto evictor : fEvictionCallbacks) {
(*fEvictionCallbacks[i].fFunc)(id, fEvictionCallbacks[i].fData); evictor->evict(id);
} }
++fAtlasGeneration; ++fAtlasGeneration;
} }

View File

@ -9,9 +9,9 @@
#define GrDrawOpAtlas_DEFINED #define GrDrawOpAtlas_DEFINED
#include <cmath> #include <cmath>
#include <vector>
#include "include/core/SkSize.h" #include "include/core/SkSize.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkGlyphRunPainter.h" #include "src/core/SkGlyphRunPainter.h"
#include "src/core/SkIPoint16.h" #include "src/core/SkIPoint16.h"
#include "src/core/SkTInternalLList.h" #include "src/core/SkTInternalLList.h"
@ -68,11 +68,15 @@ public:
static const uint64_t kInvalidAtlasGeneration = 0; static const uint64_t kInvalidAtlasGeneration = 0;
/** /**
* A function pointer for use as a callback during eviction. Whenever GrDrawOpAtlas evicts a * An interface for eviction callbacks. Whenever GrDrawOpAtlas evicts a
* specific AtlasID, it will call all of the registered listeners so they can process the * specific AtlasID, it will call all of the registered listeners so they can process the
* eviction. * eviction.
*/ */
typedef void (*EvictionFunc)(GrDrawOpAtlas::AtlasID, void*); class EvictionCallback {
public:
virtual ~EvictionCallback() = default;
virtual void evict(AtlasID id) = 0;
};
/** /**
* Returns a GrDrawOpAtlas. This function can be called anywhere, but the returned atlas * Returns a GrDrawOpAtlas. This function can be called anywhere, but the returned atlas
@ -85,10 +89,8 @@ public:
* @param numPlotsY The number of plots the atlas should be broken up into in the Y * @param numPlotsY The number of plots the atlas should be broken up into in the Y
* direction * direction
* @param allowMultitexturing Can the atlas use more than one texture. * @param allowMultitexturing Can the atlas use more than one texture.
* @param func An eviction function which will be called whenever the atlas has to * @param evictor A pointer to an eviction callback class.
* evict data *
* @param data User supplied data which will be passed into func whenever an
* eviction occurs
* @return An initialized GrDrawOpAtlas, or nullptr if creation fails * @return An initialized GrDrawOpAtlas, or nullptr if creation fails
*/ */
static std::unique_ptr<GrDrawOpAtlas> Make(GrProxyProvider*, static std::unique_ptr<GrDrawOpAtlas> Make(GrProxyProvider*,
@ -97,7 +99,7 @@ public:
int width, int height, int width, int height,
int plotWidth, int plotHeight, int plotWidth, int plotHeight,
AllowMultitexturing allowMultitexturing, AllowMultitexturing allowMultitexturing,
GrDrawOpAtlas::EvictionFunc func, void* data); EvictionCallback* evictor);
/** /**
* Packs a texture atlas index into the signed int16 texture coordinates. * Packs a texture atlas index into the signed int16 texture coordinates.
@ -151,7 +153,7 @@ public:
uint64_t atlasGeneration() const { return fAtlasGeneration; } uint64_t atlasGeneration() const { return fAtlasGeneration; }
inline bool hasID(AtlasID id) { bool hasID(AtlasID id) {
if (kInvalidAtlasID == id) { if (kInvalidAtlasID == id) {
return false; return false;
} }
@ -163,7 +165,7 @@ public:
} }
/** To ensure the atlas does not evict a given entry, the client must set the last use token. */ /** To ensure the atlas does not evict a given entry, the client must set the last use token. */
inline void setLastUseToken(AtlasID id, GrDeferredUploadToken token) { void setLastUseToken(AtlasID id, GrDeferredUploadToken token) {
SkASSERT(this->hasID(id)); SkASSERT(this->hasID(id));
uint32_t plotIdx = GetPlotIndexFromID(id); uint32_t plotIdx = GetPlotIndexFromID(id);
SkASSERT(plotIdx < fNumPlots); SkASSERT(plotIdx < fNumPlots);
@ -174,12 +176,6 @@ public:
plot->setLastUseToken(token); plot->setLastUseToken(token);
} }
inline void registerEvictionCallback(EvictionFunc func, void* userData) {
EvictionData* data = fEvictionCallbacks.append();
data->fFunc = func;
data->fData = userData;
}
uint32_t numActivePages() { return fNumActivePages; } uint32_t numActivePages() { return fNumActivePages; }
/** /**
@ -420,12 +416,7 @@ private:
// nextTokenToFlush() value at the end of the previous flush // nextTokenToFlush() value at the end of the previous flush
GrDeferredUploadToken fPrevFlushToken; GrDeferredUploadToken fPrevFlushToken;
struct EvictionData { std::vector<EvictionCallback*> fEvictionCallbacks;
EvictionFunc fFunc;
void* fData;
};
SkTDArray<EvictionData> fEvictionCallbacks;
struct Page { struct Page {
// allocated array of Plots // allocated array of Plots

View File

@ -138,17 +138,16 @@ public:
// Callback to clear out internal path cache when eviction occurs // Callback to clear out internal path cache when eviction occurs
void GrSmallPathRenderer::HandleEviction(GrDrawOpAtlas::AtlasID id, void* pr) { void GrSmallPathRenderer::evict(GrDrawOpAtlas::AtlasID id) {
GrSmallPathRenderer* dfpr = (GrSmallPathRenderer*)pr;
// remove any paths that use this plot // remove any paths that use this plot
ShapeDataList::Iter iter; ShapeDataList::Iter iter;
iter.init(dfpr->fShapeList, ShapeDataList::Iter::kHead_IterStart); iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
ShapeData* shapeData; ShapeData* shapeData;
while ((shapeData = iter.get())) { while ((shapeData = iter.get())) {
iter.next(); iter.next();
if (id == shapeData->fID) { if (id == shapeData->fID) {
dfpr->fShapeCache.remove(shapeData->fKey); fShapeCache.remove(shapeData->fKey);
dfpr->fShapeList.remove(shapeData); fShapeList.remove(shapeData);
delete shapeData; delete shapeData;
#ifdef DF_PATH_TRACKING #ifdef DF_PATH_TRACKING
++g_NumFreedPaths; ++g_NumFreedPaths;
@ -902,8 +901,7 @@ bool GrSmallPathRenderer::onDrawPath(const DrawPathArgs& args) {
ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT, ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
PLOT_WIDTH, PLOT_HEIGHT, PLOT_WIDTH, PLOT_HEIGHT,
GrDrawOpAtlas::AllowMultitexturing::kYes, GrDrawOpAtlas::AllowMultitexturing::kYes,
&GrSmallPathRenderer::HandleEviction, this);
(void*)this);
if (!fAtlas) { if (!fAtlas) {
return false; return false;
} }
@ -921,9 +919,9 @@ bool GrSmallPathRenderer::onDrawPath(const DrawPathArgs& args) {
#if GR_TEST_UTILS #if GR_TEST_UTILS
struct GrSmallPathRenderer::PathTestStruct { struct GrSmallPathRenderer::PathTestStruct : public GrDrawOpAtlas::EvictionCallback {
PathTestStruct() : fContextID(SK_InvalidGenID), fAtlas(nullptr) {} PathTestStruct() : fContextID(SK_InvalidGenID), fAtlas(nullptr) {}
~PathTestStruct() { this->reset(); } ~PathTestStruct() override { this->reset(); }
void reset() { void reset() {
ShapeDataList::Iter iter; ShapeDataList::Iter iter;
@ -938,17 +936,16 @@ struct GrSmallPathRenderer::PathTestStruct {
fShapeCache.reset(); fShapeCache.reset();
} }
static void HandleEviction(GrDrawOpAtlas::AtlasID id, void* pr) { void evict(GrDrawOpAtlas::AtlasID id) override {
PathTestStruct* dfpr = (PathTestStruct*)pr;
// remove any paths that use this plot // remove any paths that use this plot
ShapeDataList::Iter iter; ShapeDataList::Iter iter;
iter.init(dfpr->fShapeList, ShapeDataList::Iter::kHead_IterStart); iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
ShapeData* shapeData; ShapeData* shapeData;
while ((shapeData = iter.get())) { while ((shapeData = iter.get())) {
iter.next(); iter.next();
if (id == shapeData->fID) { if (id == shapeData->fID) {
dfpr->fShapeCache.remove(shapeData->fKey); fShapeCache.remove(shapeData->fKey);
dfpr->fShapeList.remove(shapeData); fShapeList.remove(shapeData);
delete shapeData; delete shapeData;
} }
} }
@ -991,8 +988,7 @@ GR_DRAW_OP_TEST_DEFINE(SmallPathOp) {
ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT, ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
PLOT_WIDTH, PLOT_HEIGHT, PLOT_WIDTH, PLOT_HEIGHT,
GrDrawOpAtlas::AllowMultitexturing::kYes, GrDrawOpAtlas::AllowMultitexturing::kYes,
&PathTestStruct::HandleEviction, &gTestStruct);
(void*)&gTestStruct);
} }
SkMatrix viewMatrix = GrTest::TestMatrix(random); SkMatrix viewMatrix = GrTest::TestMatrix(random);

View File

@ -22,7 +22,9 @@ class GrRecordingContext;
class ShapeData; class ShapeData;
class ShapeDataKey; class ShapeDataKey;
class GrSmallPathRenderer : public GrPathRenderer, public GrOnFlushCallbackObject { class GrSmallPathRenderer : public GrPathRenderer,
public GrOnFlushCallbackObject,
public GrDrawOpAtlas::EvictionCallback {
public: public:
GrSmallPathRenderer(); GrSmallPathRenderer();
~GrSmallPathRenderer() override; ~GrSmallPathRenderer() override;
@ -71,7 +73,7 @@ private:
bool onDrawPath(const DrawPathArgs&) override; bool onDrawPath(const DrawPathArgs&) override;
static void HandleEviction(GrDrawOpAtlas::AtlasID, void*); void evict(GrDrawOpAtlas::AtlasID) override;
std::unique_ptr<GrDrawOpAtlas> fAtlas; std::unique_ptr<GrDrawOpAtlas> fAtlas;
ShapeCache fShapeCache; ShapeCache fShapeCache;

View File

@ -161,7 +161,7 @@ bool GrAtlasManager::initAtlas(GrMaskFormat format) {
fProxyProvider, format, grColorType, fProxyProvider, format, grColorType,
atlasDimensions.width(), atlasDimensions.height(), atlasDimensions.width(), atlasDimensions.height(),
plotDimensions.width(), plotDimensions.height(), plotDimensions.width(), plotDimensions.height(),
fAllowMultitexturing, &GrStrikeCache::HandleEviction, fGlyphCache); fAllowMultitexturing, fGlyphCache);
if (!fAtlases[index]) { if (!fAtlases[index]) {
return false; return false;
} }

View File

@ -33,16 +33,14 @@ void GrStrikeCache::freeAll() {
fCache.reset(); fCache.reset();
} }
void GrStrikeCache::HandleEviction(GrDrawOpAtlas::AtlasID id, void* ptr) { void GrStrikeCache::evict(GrDrawOpAtlas::AtlasID id) {
GrStrikeCache* grStrikeCache = reinterpret_cast<GrStrikeCache*>(ptr); fCache.mutate([this, id](sk_sp<GrTextStrike>* cacheSlot){
grStrikeCache->fCache.mutate([grStrikeCache, id](sk_sp<GrTextStrike>* cacheSlot){
GrTextStrike* strike = cacheSlot->get(); GrTextStrike* strike = cacheSlot->get();
strike->removeID(id); strike->removeID(id);
// clear out any empty strikes. We will preserve the strike whose call to addToAtlas // clear out any empty strikes. We will preserve the strike whose call to addToAtlas
// triggered the eviction // triggered the eviction
if (strike != grStrikeCache->fPreserveStrike && 0 == strike->fAtlasedGlyphs) { if (strike != fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
strike->fIsAbandoned = true; strike->fIsAbandoned = true;
return false; // Remove this entry from the cache. return false; // Remove this entry from the cache.
} }

View File

@ -84,10 +84,10 @@ private:
* GrStrikeCache manages strikes which are indexed by a SkStrike. These strikes can then be * GrStrikeCache manages strikes which are indexed by a SkStrike. These strikes can then be
* used to generate individual Glyph Masks. * used to generate individual Glyph Masks.
*/ */
class GrStrikeCache { class GrStrikeCache final : public GrDrawOpAtlas::EvictionCallback {
public: public:
GrStrikeCache(const GrCaps* caps, size_t maxTextureBytes); GrStrikeCache(const GrCaps* caps, size_t maxTextureBytes);
~GrStrikeCache(); ~GrStrikeCache() override;
void setStrikeToPreserve(GrTextStrike* strike) { fPreserveStrike = strike; } void setStrikeToPreserve(GrTextStrike* strike) { fPreserveStrike = strike; }
@ -106,7 +106,7 @@ public:
void freeAll(); void freeAll();
static void HandleEviction(GrDrawOpAtlas::AtlasID, void*); void evict(GrDrawOpAtlas::AtlasID id) override;
private: private:
sk_sp<GrTextStrike> generateStrike(const SkDescriptor& desc) { sk_sp<GrTextStrike> generateStrike(const SkDescriptor& desc) {

View File

@ -72,9 +72,12 @@ void GrDrawOpAtlas::setMaxPages_TestingOnly(uint32_t maxPages) {
fMaxPages = maxPages; fMaxPages = maxPages;
} }
void EvictionFunc(GrDrawOpAtlas::AtlasID atlasID, void*) { class DummyEvict : public GrDrawOpAtlas::EvictionCallback {
public:
void evict(GrDrawOpAtlas::AtlasID id) override {
SkASSERT(0); // The unit test shouldn't exercise this code path SkASSERT(0); // The unit test shouldn't exercise this code path
} }
};
static void check(skiatest::Reporter* r, GrDrawOpAtlas* atlas, static void check(skiatest::Reporter* r, GrDrawOpAtlas* atlas,
uint32_t expectedActive, uint32_t expectedMax, int expectedAlloced) { uint32_t expectedActive, uint32_t expectedMax, int expectedAlloced) {
@ -142,6 +145,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BasicDrawOpAtlas, reporter, ctxInfo) {
GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8, GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
GrRenderable::kNo); GrRenderable::kNo);
DummyEvict evictor;
std::unique_ptr<GrDrawOpAtlas> atlas = GrDrawOpAtlas::Make( std::unique_ptr<GrDrawOpAtlas> atlas = GrDrawOpAtlas::Make(
proxyProvider, proxyProvider,
format, format,
@ -149,7 +154,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BasicDrawOpAtlas, reporter, ctxInfo) {
kAtlasSize, kAtlasSize, kAtlasSize, kAtlasSize,
kAtlasSize/kNumPlots, kAtlasSize/kNumPlots, kAtlasSize/kNumPlots, kAtlasSize/kNumPlots,
GrDrawOpAtlas::AllowMultitexturing::kYes, GrDrawOpAtlas::AllowMultitexturing::kYes,
EvictionFunc, nullptr); &evictor);
check(reporter, atlas.get(), 0, 4, 0); check(reporter, atlas.get(), 0, 4, 0);
// Fill up the first level // Fill up the first level