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

View File

@ -9,9 +9,9 @@
#define GrDrawOpAtlas_DEFINED
#include <cmath>
#include <vector>
#include "include/core/SkSize.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkGlyphRunPainter.h"
#include "src/core/SkIPoint16.h"
#include "src/core/SkTInternalLList.h"
@ -68,11 +68,15 @@ public:
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
* 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
@ -85,10 +89,8 @@ public:
* @param numPlotsY The number of plots the atlas should be broken up into in the Y
* direction
* @param allowMultitexturing Can the atlas use more than one texture.
* @param func An eviction function which will be called whenever the atlas has to
* evict data
* @param data User supplied data which will be passed into func whenever an
* eviction occurs
* @param evictor A pointer to an eviction callback class.
*
* @return An initialized GrDrawOpAtlas, or nullptr if creation fails
*/
static std::unique_ptr<GrDrawOpAtlas> Make(GrProxyProvider*,
@ -97,7 +99,7 @@ public:
int width, int height,
int plotWidth, int plotHeight,
AllowMultitexturing allowMultitexturing,
GrDrawOpAtlas::EvictionFunc func, void* data);
EvictionCallback* evictor);
/**
* Packs a texture atlas index into the signed int16 texture coordinates.
@ -151,7 +153,7 @@ public:
uint64_t atlasGeneration() const { return fAtlasGeneration; }
inline bool hasID(AtlasID id) {
bool hasID(AtlasID id) {
if (kInvalidAtlasID == id) {
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. */
inline void setLastUseToken(AtlasID id, GrDeferredUploadToken token) {
void setLastUseToken(AtlasID id, GrDeferredUploadToken token) {
SkASSERT(this->hasID(id));
uint32_t plotIdx = GetPlotIndexFromID(id);
SkASSERT(plotIdx < fNumPlots);
@ -174,12 +176,6 @@ public:
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; }
/**
@ -420,12 +416,7 @@ private:
// nextTokenToFlush() value at the end of the previous flush
GrDeferredUploadToken fPrevFlushToken;
struct EvictionData {
EvictionFunc fFunc;
void* fData;
};
SkTDArray<EvictionData> fEvictionCallbacks;
std::vector<EvictionCallback*> fEvictionCallbacks;
struct Page {
// allocated array of Plots

View File

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

View File

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

View File

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

View File

@ -33,16 +33,14 @@ void GrStrikeCache::freeAll() {
fCache.reset();
}
void GrStrikeCache::HandleEviction(GrDrawOpAtlas::AtlasID id, void* ptr) {
GrStrikeCache* grStrikeCache = reinterpret_cast<GrStrikeCache*>(ptr);
grStrikeCache->fCache.mutate([grStrikeCache, id](sk_sp<GrTextStrike>* cacheSlot){
void GrStrikeCache::evict(GrDrawOpAtlas::AtlasID id) {
fCache.mutate([this, id](sk_sp<GrTextStrike>* cacheSlot){
GrTextStrike* strike = cacheSlot->get();
strike->removeID(id);
// clear out any empty strikes. We will preserve the strike whose call to addToAtlas
// triggered the eviction
if (strike != grStrikeCache->fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
if (strike != fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
strike->fIsAbandoned = true;
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
* used to generate individual Glyph Masks.
*/
class GrStrikeCache {
class GrStrikeCache final : public GrDrawOpAtlas::EvictionCallback {
public:
GrStrikeCache(const GrCaps* caps, size_t maxTextureBytes);
~GrStrikeCache();
~GrStrikeCache() override;
void setStrikeToPreserve(GrTextStrike* strike) { fPreserveStrike = strike; }
@ -106,7 +106,7 @@ public:
void freeAll();
static void HandleEviction(GrDrawOpAtlas::AtlasID, void*);
void evict(GrDrawOpAtlas::AtlasID id) override;
private:
sk_sp<GrTextStrike> generateStrike(const SkDescriptor& desc) {

View File

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