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:
parent
7abc7aa2db
commit
1a496c507e
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user