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:
parent
7281c61e7b
commit
3cf9863bb6
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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*,
|
||||||
|
Loading…
Reference in New Issue
Block a user