Revert of Adding bulk plot reffer to cached textblobs (patchset #7 id:110001 of https://codereview.chromium.org/1050113004/)

Reason for revert:
Breaks linux builder

Original issue's description:
> Adding bulk plot reffer to cached textblobs
>
> This change will prevent the atlas from evicting glyphs the TextBlob
> needs.
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/7281c61e7bc689d484dcbda49be3cef4ce4f11c2

TBR=bsalomon@google.com,jvanverth@google.com,robertphillips@google.com,joshualitt@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/1061713003
This commit is contained in:
joshualitt 2015-04-07 10:21:27 -07:00 committed by Commit bot
parent 7281c61e7b
commit 3cf9863bb6
7 changed files with 37 additions and 109 deletions

View File

@ -275,7 +275,7 @@ public:
} }
} }
atlas->setLastUseToken(args.fPathData->fID, batchTarget->currentToken()); atlas->setLastRefToken(args.fPathData->fID, batchTarget->currentToken());
// Now set vertices // Now set vertices
intptr_t offset = reinterpret_cast<intptr_t>(vertices); intptr_t offset = reinterpret_cast<intptr_t>(vertices);

View File

@ -821,7 +821,6 @@ public:
GrBatchTextStrike* strike = NULL; GrBatchTextStrike* strike = NULL;
bool brokenRun = false; bool brokenRun = false;
if (regenerateTextureCoords) { if (regenerateTextureCoords) {
info.fBulkUseToken.reset();
desc = run.fDescriptor.getDesc(); desc = run.fDescriptor.getDesc();
cache = SkGlyphCache::DetachCache(run.fTypeface, desc); cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
scaler = GrTextContext::GetGrFontScaler(cache); scaler = GrTextContext::GetGrFontScaler(cache);
@ -847,8 +846,8 @@ public:
scaler); scaler);
SkASSERT(success); SkASSERT(success);
} }
fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseToken, glyph,
batchTarget->currentToken()); fFontCache->setGlyphRefToken(glyph, batchTarget->currentToken());
// Texture coords are the last vertex attribute so we get a pointer to the // Texture coords are the last vertex attribute so we get a pointer to the
// first one and then map with stride in regenerateTextureCoords // first one and then map with stride in regenerateTextureCoords
@ -877,12 +876,6 @@ public:
} }
} else { } else {
instancesToFlush += glyphCount; instancesToFlush += glyphCount;
// set use tokens for all of the glyphs in our subrun. This is only valid if we
// have a valid atlas generation
fFontCache->setUseTokenBulk(info.fBulkUseToken,
batchTarget->currentToken(),
fMaskFormat);
} }
// now copy all vertices // now copy all vertices

View File

@ -10,7 +10,6 @@
#include "GrTextContext.h" #include "GrTextContext.h"
#include "GrBatchAtlas.h"
#include "GrGeometryProcessor.h" #include "GrGeometryProcessor.h"
#include "SkDescriptor.h" #include "SkDescriptor.h"
#include "SkTextBlob.h" #include "SkTextBlob.h"
@ -104,7 +103,6 @@ private:
uint32_t fGlyphEndIndex; uint32_t fGlyphEndIndex;
size_t fVertexStartIndex; size_t fVertexStartIndex;
size_t fVertexEndIndex; size_t fVertexEndIndex;
GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken;
}; };
SkSTArray<1, SubRunInfo, true> fSubRunInfo; SkSTArray<1, SubRunInfo, true> fSubRunInfo;
SkAutoDescriptor fDescriptor; SkAutoDescriptor fDescriptor;

View File

@ -11,6 +11,12 @@
#include "GrRectanizer.h" #include "GrRectanizer.h"
#include "GrTracing.h" #include "GrTracing.h"
// for testing
#define ATLAS_STATS 0
#if ATLAS_STATS
static int g_UploadCount = 0;
#endif
static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset) { static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset) {
loc->fX += offset.fX; loc->fX += offset.fX;
loc->fY += offset.fY; loc->fY += offset.fY;
@ -67,6 +73,10 @@ public:
adjust_for_offset(loc, fOffset); adjust_for_offset(loc, fOffset);
SkDEBUGCODE(fDirty = true;) SkDEBUGCODE(fDirty = true;)
#if ATLAS_STATS
++g_UploadCount;
#endif
return true; return true;
} }
@ -76,15 +86,9 @@ public:
// when we can evict a plot from the cache, ie if the last ref has already flushed through // when we can evict a plot from the cache, ie if the last ref has already flushed through
// the gpu then we can reuse the plot // the gpu then we can reuse the plot
BatchToken lastUploadToken() const { return fLastUpload; } BatchToken lastUploadToken() const { return fLastUpload; }
BatchToken lastUseToken() const { return fLastUse; } BatchToken lastRefToken() const { return fLastRef; }
void setLastUploadToken(BatchToken batchToken) { void setLastUploadToken(BatchToken batchToken) { fLastUpload = batchToken; }
SkASSERT(batchToken >= fLastUpload); void setLastRefToken(BatchToken batchToken) { fLastRef = batchToken; }
fLastUpload = batchToken;
}
void setLastUseToken(BatchToken batchToken) {
SkASSERT(batchToken >= fLastUse);
fLastUse = batchToken;
}
void uploadToTexture(GrBatchTarget::TextureUploader uploader) { void uploadToTexture(GrBatchTarget::TextureUploader uploader) {
// We should only be issuing uploads if we are in fact dirty // We should only be issuing uploads if we are in fact dirty
@ -123,7 +127,7 @@ public:
private: private:
BatchPlot() BatchPlot()
: fLastUpload(0) : fLastUpload(0)
, fLastUse(0) , fLastRef(0)
, fIndex(-1) , fIndex(-1)
, fGenID(-1) , fGenID(-1)
, fID(0) , fID(0)
@ -173,7 +177,7 @@ private:
} }
BatchToken fLastUpload; BatchToken fLastUpload;
BatchToken fLastUse; BatchToken fLastRef;
uint32_t fIndex; uint32_t fIndex;
uint32_t fGenID; uint32_t fGenID;
@ -225,7 +229,6 @@ GrBatchAtlas::GrBatchAtlas(GrTexture* texture, int numPlotsX, int numPlotsY)
, fPlotWidth(texture->width() / numPlotsX) , fPlotWidth(texture->width() / numPlotsX)
, fPlotHeight(texture->height() / numPlotsY) , fPlotHeight(texture->height() / numPlotsY)
, fAtlasGeneration(kInvalidAtlasGeneration + 1) { , fAtlasGeneration(kInvalidAtlasGeneration + 1) {
SkASSERT(fNumPlotsX * fNumPlotsY <= BulkUseTokenUpdater::kMaxPlots);
SkASSERT(fPlotWidth * fNumPlotsX == texture->width()); SkASSERT(fPlotWidth * fNumPlotsX == texture->width());
SkASSERT(fPlotHeight * fNumPlotsY == texture->height()); SkASSERT(fPlotHeight * fNumPlotsY == texture->height());
@ -253,6 +256,10 @@ GrBatchAtlas::GrBatchAtlas(GrTexture* texture, int numPlotsX, int numPlotsY)
GrBatchAtlas::~GrBatchAtlas() { GrBatchAtlas::~GrBatchAtlas() {
SkSafeUnref(fTexture); SkSafeUnref(fTexture);
SkDELETE_ARRAY(fPlotArray); SkDELETE_ARRAY(fPlotArray);
#if ATLAS_STATS
SkDebugf("Num uploads: %d\n", g_UploadCount);
#endif
} }
void GrBatchAtlas::processEviction(AtlasID id) { void GrBatchAtlas::processEviction(AtlasID id) {
@ -306,7 +313,7 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrBatchTarget* batchTarget,
plotIter.init(fPlotList, GrBatchPlotList::Iter::kTail_IterStart); plotIter.init(fPlotList, GrBatchPlotList::Iter::kTail_IterStart);
plot = plotIter.get(); plot = plotIter.get();
SkASSERT(plot); SkASSERT(plot);
if (batchTarget->isIssued(plot->lastUseToken())) { if (batchTarget->isIssued(plot->lastRefToken())) {
this->processEviction(plot->id()); this->processEviction(plot->id());
plot->resetRects(); plot->resetRects();
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc, fBPP * width); SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc, fBPP * width);
@ -322,7 +329,7 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrBatchTarget* batchTarget,
// off the plot(ie let the batch target manage it) and create a new plot in its place in our // off the plot(ie let the batch target manage it) and create a new plot in its place in our
// array. If it is equal to the currentToken, then the caller has to flush draws to the batch // array. If it is equal to the currentToken, then the caller has to flush draws to the batch
// target so we can spin off the plot // target so we can spin off the plot
if (plot->lastUseToken() == batchTarget->currentToken()) { if (plot->lastRefToken() == batchTarget->currentToken()) {
return false; return false;
} }
@ -352,24 +359,14 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrBatchTarget* batchTarget,
} }
bool GrBatchAtlas::hasID(AtlasID id) { bool GrBatchAtlas::hasID(AtlasID id) {
int index = GetIndexFromID(id); int index = this->getIndexFromID(id);
SkASSERT(index < fNumPlotsX * fNumPlotsY); SkASSERT(index < fNumPlotsX * fNumPlotsY);
return fPlotArray[index]->genID() == GetGenerationFromID(id); return fPlotArray[index]->genID() == this->getGenerationFromID(id);
} }
void GrBatchAtlas::setLastUseToken(AtlasID id, BatchToken batchToken) { void GrBatchAtlas::setLastRefToken(AtlasID id, BatchToken batchToken) {
SkASSERT(this->hasID(id)); SkASSERT(this->hasID(id));
int index = GetIndexFromID(id); int index = this->getIndexFromID(id);
SkASSERT(index < fNumPlotsX * fNumPlotsY);
this->makeMRU(fPlotArray[index]); this->makeMRU(fPlotArray[index]);
fPlotArray[index]->setLastUseToken(batchToken); fPlotArray[index]->setLastRefToken(batchToken);
}
void GrBatchAtlas::setLastUseTokenBulk(const BulkUseTokenUpdater& updater, BatchToken batchToken) {
int plotsToUpdateCount = updater.fPlotsToUpdate.count();
for (int i = 0; i < plotsToUpdateCount; i++) {
BatchPlot* plot = fPlotArray[updater.fPlotsToUpdate[i]];
this->makeMRU(plot);
plot->setLastUseToken(batchToken);
}
} }

View File

@ -40,9 +40,6 @@ public:
// the containing GrPlot and absolute location in the backing texture. // the containing GrPlot and absolute location in the backing texture.
// NULL is returned if the subimage cannot fit in the atlas. // NULL is returned if the subimage cannot fit in the atlas.
// If provided, the image data will be written to the CPU-side backing bitmap. // If provided, the image data will be written to the CPU-side backing bitmap.
// NOTE: If the client intends to refer to the atlas, they should immediately call 'setUseToken'
// with the currentToken from the batch target, otherwise the next call to addToAtlas might
// cause an eviction
bool addToAtlas(AtlasID*, GrBatchTarget*, int width, int height, const void* image, bool addToAtlas(AtlasID*, GrBatchTarget*, int width, int height, const void* image,
SkIPoint16* loc); SkIPoint16* loc);
@ -50,61 +47,19 @@ public:
uint64_t atlasGeneration() const { return fAtlasGeneration; } uint64_t atlasGeneration() const { return fAtlasGeneration; }
bool hasID(AtlasID id); bool hasID(AtlasID id);
void setLastRefToken(AtlasID id, BatchToken batchToken);
// To ensure the atlas does not evict a given entry, the client must set the last use token
void setLastUseToken(AtlasID id, BatchToken batchToken);
void registerEvictionCallback(EvictionFunc func, void* userData) { void registerEvictionCallback(EvictionFunc func, void* userData) {
EvictionData* data = fEvictionCallbacks.append(); EvictionData* data = fEvictionCallbacks.append();
data->fFunc = func; data->fFunc = func;
data->fData = userData; data->fData = userData;
} }
/*
* A class which can be handed back to GrBatchAtlas for updating in bulk last use tokens. The
* current max number of plots the GrBatchAtlas can handle is 32, if in the future this is
* insufficient then we can move to a 64 bit int
*/
class BulkUseTokenUpdater {
public:
BulkUseTokenUpdater() : fPlotAlreadyUpdated(0) {}
void add(AtlasID id) {
int index = GrBatchAtlas::GetIndexFromID(id);
if (!this->find(index)) {
this->set(index);
}
}
void reset() {
fPlotsToUpdate.reset();
fPlotAlreadyUpdated = 0;
}
private:
bool find(int index) const {
SkASSERT(index < kMaxPlots);
return (fPlotAlreadyUpdated >> index) & 1;
}
void set(int index) {
SkASSERT(!this->find(index));
fPlotAlreadyUpdated = fPlotAlreadyUpdated | (1 << index);
fPlotsToUpdate.push_back(index);
}
static const int kMaxPlots = 32;
uint32_t fPlotAlreadyUpdated;
SkSTArray<4, int, true> fPlotsToUpdate;
friend class GrBatchAtlas;
};
void setLastUseTokenBulk(const BulkUseTokenUpdater& reffer, BatchToken);
private: private:
static int GetIndexFromID(AtlasID id) { int getIndexFromID(AtlasID id) {
return id & 0xffff; return id & 0xffff;
} }
static int GetGenerationFromID(AtlasID id) { int getGenerationFromID(AtlasID id) {
return (id >> 16) & 0xffff; return (id >> 16) & 0xffff;
} }

View File

@ -128,18 +128,10 @@ bool GrBatchFontCache::hasGlyph(GrGlyph* glyph) {
return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID); return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
} }
void GrBatchFontCache::addGlyphToBulkAndSetUseToken(GrBatchAtlas::BulkUseTokenUpdater* updater, void GrBatchFontCache::setGlyphRefToken(GrGlyph* glyph, GrBatchAtlas::BatchToken batchToken) {
GrGlyph* glyph,
GrBatchAtlas::BatchToken token) {
SkASSERT(glyph); SkASSERT(glyph);
updater->add(glyph->fID); SkASSERT(this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID));
this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token); this->getAtlas(glyph->fMaskFormat)->setLastRefToken(glyph->fID, batchToken);
}
void GrBatchFontCache::setUseTokenBulk(const GrBatchAtlas::BulkUseTokenUpdater& updater,
GrBatchAtlas::BatchToken token,
GrMaskFormat format) {
this->getAtlas(format)->setLastUseTokenBulk(updater, token);
} }
bool GrBatchFontCache::addToAtlas(GrBatchTextStrike* strike, GrBatchAtlas::AtlasID* id, bool GrBatchFontCache::addToAtlas(GrBatchTextStrike* strike, GrBatchAtlas::AtlasID* id,

View File

@ -97,15 +97,8 @@ public:
bool hasGlyph(GrGlyph* glyph); bool hasGlyph(GrGlyph* glyph);
// To ensure the GrBatchAtlas does not evict the Glyph Mask from its texture backing store, // To ensure the GrBatchAtlas does not evict the Glyph Mask from its texture backing store,
// the client must pass in the currentToken from the GrBatchTarget along with the GrGlyph. // the client must pass in the currentToken from the GrBatchTarget along with the GrGlyph
// A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas. void setGlyphRefToken(GrGlyph*, GrBatchAtlas::BatchToken);
// For convenience, this function will also set the use token for the current glyph if required
// NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
void addGlyphToBulkAndSetUseToken(GrBatchAtlas::BulkUseTokenUpdater*, GrGlyph*,
GrBatchAtlas::BatchToken);
void setUseTokenBulk(const GrBatchAtlas::BulkUseTokenUpdater&, GrBatchAtlas::BatchToken,
GrMaskFormat);
// add to texture atlas that matches this format // add to texture atlas that matches this format
bool addToAtlas(GrBatchTextStrike*, GrBatchAtlas::AtlasID*, GrBatchTarget*, bool addToAtlas(GrBatchTextStrike*, GrBatchAtlas::AtlasID*, GrBatchTarget*,