Expand PlotLocator into a class
This centralizes the PlotLocator code (esp. the construction & accessors). It also allows just the PlotLocator to be passed to hasID - since the AtlasLocator is overkill for that call.
Change-Id: I424b2d075c40ed46219a623f0c99b3101bc7e043
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282861
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 9ee3760..66c911c 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -127,7 +127,7 @@
, fPlotIndex(plotIndex)
, fGenerationCounter(generationCounter)
, fGenID(fGenerationCounter->next())
- , fPlotLocator(CreatePlotLocator(fPageIndex, fPlotIndex, fGenID))
+ , fPlotLocator(fPageIndex, fPlotIndex, fGenID)
, fData(nullptr)
, fWidth(width)
, fHeight(height)
@@ -222,7 +222,7 @@
fRectanizer.reset();
fGenID = fGenerationCounter->next();
- fPlotLocator = CreatePlotLocator(fPageIndex, fPlotIndex, fGenID);
+ fPlotLocator = PlotLocator(fPageIndex, fPlotIndex, fGenID);
fLastUpload = GrDeferredUploadToken::AlreadyFlushedToken();
fLastUse = GrDeferredUploadToken::AlreadyFlushedToken();
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index d16665e..01e61e7 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -51,25 +51,57 @@
* and passes in the given GrDrawUploadToken.
*/
class GrDrawOpAtlas {
-private:
- static constexpr auto kMaxMultitexturePages = 4;
-
public:
/** Is the atlas allowed to use more than one texture? */
enum class AllowMultitexturing : bool { kNo, kYes };
- static constexpr int kMaxPlots = 32; // restricted by the fPlotAlreadyUpdated bitfield
- // in BulkUseTokenUpdater
+ // These are both restricted by the space they occupy in the PlotLocator.
+ // maxPages is also limited by being crammed into the glyph uvs.
+ // maxPlots is also limited by the fPlotAlreadyUpdated bitfield in BulkUseTokenUpdater
+ static constexpr auto kMaxMultitexturePages = 4;
+ static constexpr int kMaxPlots = 32;
/**
* A PlotLocator specifies the plot and is analogous to a directory path:
* page/plot/plotGeneration
*
* In fact PlotLocator is a portion of a glyph image location in the atlas fully specified by:
- * format/atlasGeneration/page/plot/plotGeneration/(u,v)
+ * format/atlasGeneration/page/plot/plotGeneration/rect
+ *
+ * TODO: Remove the small path renderer's use of the PlotLocator for eviction.
*/
- typedef uint64_t PlotLocator;
- static const uint64_t kInvalidPlotLocator = 0;
+ class PlotLocator {
+ public:
+ PlotLocator(uint32_t pageIdx, uint32_t plotIdx, uint64_t generation)
+ : fGenID(generation)
+ , fPlotIndex(plotIdx)
+ , fPageIndex(pageIdx) {
+ SkASSERT(pageIdx < kMaxMultitexturePages);
+ SkASSERT(plotIdx < kMaxPlots);
+ SkASSERT(generation < ((uint64_t)1 << 48));
+ }
+
+ PlotLocator() : fGenID(0), fPlotIndex(0), fPageIndex(0) {}
+
+ bool isValid() const {
+ return fGenID != 0 || fPlotIndex != 0 || fPageIndex != 0;
+ }
+
+ bool operator==(const PlotLocator& other) const {
+ return fGenID == other.fGenID &&
+ fPlotIndex == other.fPlotIndex &&
+ fPageIndex == other.fPageIndex; }
+
+ uint32_t pageIndex() const { return fPageIndex; }
+ uint32_t plotIndex() const { return fPlotIndex; }
+ uint64_t genID() const { return fGenID; }
+
+ private:
+ uint64_t fGenID:48;
+ uint64_t fPlotIndex:8;
+ uint64_t fPageIndex:8;
+ };
+
static const uint64_t kInvalidAtlasGeneration = 0;
class AtlasLocator {
@@ -79,29 +111,18 @@
// TODO: Remove the small path renderer's use of this for eviction
PlotLocator plotLocator() const { return fPlotLocator; }
- uint32_t pageIndex() const {
- uint32_t pageIndex = fPlotLocator & 0xff;
- SkASSERT(pageIndex < 4);
- return pageIndex;
- }
+ uint32_t pageIndex() const { return fPlotLocator.pageIndex(); }
- uint32_t plotIndex() const {
- uint32_t plotIndex = (fPlotLocator >> 8) & 0xff;
- SkASSERT(plotIndex < kMaxPlots);
- return plotIndex;
- }
+ uint32_t plotIndex() const { return fPlotLocator.plotIndex(); }
- uint64_t genID() const {
- // top 48 bits are reserved for the generation ID
- return (fPlotLocator >> 16) & 0xffffffffffff;
- }
+ uint64_t genID() const { return fPlotLocator.genID(); }
private:
friend class GrDrawOpAtlas;
SkDEBUGCODE(void validate(const GrDrawOpAtlas*) const;)
- PlotLocator fPlotLocator{GrDrawOpAtlas::kInvalidPlotLocator};
+ PlotLocator fPlotLocator;
GrIRect16 fRect{0, 0, 0, 0};
// TODO: the inset to the actual data w/in 'fRect' could also be stored in this class
@@ -116,7 +137,7 @@
class EvictionCallback {
public:
virtual ~EvictionCallback() = default;
- virtual void evict(PlotLocator plotLocator) = 0;
+ virtual void evict(PlotLocator) = 0;
};
/**
@@ -205,21 +226,21 @@
uint64_t atlasGeneration() const { return fAtlasGeneration; }
- bool hasID(const AtlasLocator& atlasLocator) {
- if (kInvalidPlotLocator == atlasLocator.plotLocator()) {
+ bool hasID(const PlotLocator& plotLocator) {
+ if (!plotLocator.isValid()) {
return false;
}
- uint32_t plot = atlasLocator.plotIndex();
- uint32_t page = atlasLocator.pageIndex();
+ uint32_t plot = plotLocator.plotIndex();
+ uint32_t page = plotLocator.pageIndex();
uint64_t plotGeneration = fPages[page].fPlotArray[plot]->genID();
- uint64_t locatorGeneration = atlasLocator.genID();
+ uint64_t locatorGeneration = plotLocator.genID();
return plot < fNumPlots && page < fNumActivePages && plotGeneration == locatorGeneration;
}
/** To ensure the atlas does not evict a given entry, the client must set the last use token. */
void setLastUseToken(const AtlasLocator& atlasLocator, GrDeferredUploadToken token) {
- SkASSERT(this->hasID(atlasLocator));
+ SkASSERT(this->hasID(atlasLocator.plotLocator()));
uint32_t plotIdx = atlasLocator.plotIndex();
SkASSERT(plotIdx < fNumPlots);
uint32_t pageIdx = atlasLocator.pageIndex();
@@ -337,8 +358,8 @@
* if a particular subimage is still present in the atlas.
*/
uint64_t genID() const { return fGenID; }
- GrDrawOpAtlas::PlotLocator plotLocator() const {
- SkASSERT(GrDrawOpAtlas::kInvalidPlotLocator != fPlotLocator);
+ PlotLocator plotLocator() const {
+ SkASSERT(fPlotLocator.isValid());
return fPlotLocator;
}
SkDEBUGCODE(size_t bpp() const { return fBytesPerPixel; })
@@ -379,15 +400,6 @@
fPageIndex, fPlotIndex, fGenerationCounter, fX, fY, fWidth, fHeight, fColorType);
}
- static GrDrawOpAtlas::PlotLocator CreatePlotLocator(
- uint32_t pageIdx, uint32_t plotIdx, uint64_t generation) {
- SkASSERT(pageIdx < (1 << 8));
- SkASSERT(pageIdx < kMaxMultitexturePages);
- SkASSERT(plotIdx < (1 << 8));
- SkASSERT(generation < ((uint64_t)1 << 48));
- return generation << 16 | plotIdx << 8 | pageIdx;
- }
-
GrDeferredUploadToken fLastUpload;
GrDeferredUploadToken fLastUse;
// the number of flushes since this plot has been last used
@@ -399,7 +411,7 @@
};
GenerationCounter* const fGenerationCounter;
uint64_t fGenID;
- GrDrawOpAtlas::PlotLocator fPlotLocator;
+ PlotLocator fPlotLocator;
unsigned char* fData;
const int fWidth;
const int fHeight;
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 82722c9..d958e5f 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -458,7 +458,7 @@
// check to see if df path is cached
ShapeDataKey key(args.fShape, SkScalarCeilToInt(desiredDimension));
shapeData = fShapeCache->find(key);
- if (nullptr == shapeData || !fAtlas->hasID(shapeData->fAtlasLocator)) {
+ if (!shapeData || !fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
// Remove the stale cache entry
if (shapeData) {
fShapeCache->remove(shapeData->fKey);
@@ -483,7 +483,7 @@
// check to see if bitmap path is cached
ShapeDataKey key(args.fShape, args.fViewMatrix);
shapeData = fShapeCache->find(key);
- if (nullptr == shapeData || !fAtlas->hasID(shapeData->fAtlasLocator)) {
+ if (!shapeData || !fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
// Remove the stale cache entry
if (shapeData) {
fShapeCache->remove(shapeData->fKey);
diff --git a/src/gpu/text/GrAtlasManager.cpp b/src/gpu/text/GrAtlasManager.cpp
index 47dae97..c91eab6 100644
--- a/src/gpu/text/GrAtlasManager.cpp
+++ b/src/gpu/text/GrAtlasManager.cpp
@@ -29,7 +29,7 @@
bool GrAtlasManager::hasGlyph(GrMaskFormat format, GrGlyph* glyph) {
SkASSERT(glyph);
- return this->getAtlas(format)->hasID(glyph->fAtlasLocator);
+ return this->getAtlas(format)->hasID(glyph->fAtlasLocator.plotLocator());
}
// add to texture atlas that matches this format