Revert "Allow GrDrawOpAtlas to grow as needed"
This reverts commit 03168b8a62
.
Reason for revert: Assert in resetting texture proxies.
Original change's description:
> Allow GrDrawOpAtlas to grow as needed
>
> Bug: skia:3550
> Change-Id: Ib5312c8c06ba8549d90545658df6686c45058255
> Reviewed-on: https://skia-review.googlesource.com/45841
> Commit-Queue: Jim Van Verth <jvanverth@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>
TBR=jvanverth@google.com,robertphillips@google.com
Change-Id: I05e084b4cefa57e558f296d6087d4f03fa16ac81
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:3550
Reviewed-on: https://skia-review.googlesource.com/47140
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
4127456bd6
commit
ad70c41f67
@ -146,8 +146,29 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width
|
||||
, fPixelConfig(config)
|
||||
, fTextureWidth(width)
|
||||
, fTextureHeight(height)
|
||||
, fAtlasGeneration(kInvalidAtlasGeneration + 1)
|
||||
, fNumPages(0) {
|
||||
, fAtlasGeneration(kInvalidAtlasGeneration + 1) {
|
||||
|
||||
GrSurfaceDesc desc;
|
||||
desc.fFlags = kNone_GrSurfaceFlags;
|
||||
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
desc.fWidth = fTextureWidth;
|
||||
desc.fHeight = fTextureHeight;
|
||||
desc.fConfig = fPixelConfig;
|
||||
|
||||
// We don't want to flush the context so we claim we're in the middle of flushing so as to
|
||||
// guarantee we do not recieve a texture with pending IO
|
||||
// TODO: Determine how to avoid having to do this. (https://bug.skia.org/4156)
|
||||
static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
|
||||
sk_sp<GrTexture> texture(context->resourceProvider()->createApproxTexture(desc, kFlags));
|
||||
if (texture) {
|
||||
// MDB TODO: for now, wrap an instantiated texture. Having the deferred instantiation
|
||||
// possess the correct properties (e.g., no pendingIO) should fall out of the system but
|
||||
// should receive special attention.
|
||||
// Note: When switching over to the deferred proxy, use the kExact flag to create
|
||||
// the atlas and assert that the width & height are powers of 2.
|
||||
fProxies[0] = GrSurfaceProxy::MakeWrapped(std::move(texture),
|
||||
kTopLeft_GrSurfaceOrigin);
|
||||
}
|
||||
|
||||
fPlotWidth = fTextureWidth / numPlotsX;
|
||||
fPlotHeight = fTextureHeight / numPlotsY;
|
||||
@ -156,8 +177,23 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width
|
||||
SkASSERT(fPlotHeight * numPlotsY == fTextureHeight);
|
||||
|
||||
SkDEBUGCODE(fNumPlots = numPlotsX * numPlotsY;)
|
||||
SkDEBUGCODE(fNumPages = 1;)
|
||||
|
||||
this->createNewPage();
|
||||
// set up allocated plots
|
||||
fPages[0].fPlotArray.reset(new sk_sp<Plot>[ numPlotsX * numPlotsY ]);
|
||||
|
||||
sk_sp<Plot>* currPlot = fPages[0].fPlotArray.get();
|
||||
for (int y = numPlotsY - 1, r = 0; y >= 0; --y, ++r) {
|
||||
for (int x = numPlotsX - 1, c = 0; x >= 0; --x, ++c) {
|
||||
uint32_t index = r * numPlotsX + c;
|
||||
currPlot->reset(
|
||||
new Plot(0, index, 1, x, y, fPlotWidth, fPlotHeight, fPixelConfig));
|
||||
|
||||
// build LRU list
|
||||
fPages[0].fPlotList.addToHead(currPlot->get());
|
||||
++currPlot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrDrawOpAtlas::processEviction(AtlasID id) {
|
||||
@ -198,83 +234,57 @@ inline bool GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plo
|
||||
|
||||
bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width, int height,
|
||||
const void* image, SkIPoint16* loc) {
|
||||
// Eventually we will iterate through these, for now just use the one.
|
||||
int pageIdx = 0;
|
||||
|
||||
// We should already have a texture, TODO clean this up
|
||||
SkASSERT(fProxies[pageIdx]);
|
||||
if (width > fPlotWidth || height > fPlotHeight) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look through each page to see if we can upload without having to flush
|
||||
// We prioritize this upload to the first pages, not the most recently used, to make it easier
|
||||
// to remove unused pages in reverse page order.
|
||||
for (unsigned int pageIdx = 0; pageIdx < fNumPages; ++pageIdx) {
|
||||
SkASSERT(fProxies[pageIdx]);
|
||||
// look through all allocated plots for one we can share, in Most Recently Refed order
|
||||
PlotList::Iter plotIter;
|
||||
plotIter.init(fPages[pageIdx].fPlotList, PlotList::Iter::kHead_IterStart);
|
||||
Plot* plot;
|
||||
while ((plot = plotIter.get())) {
|
||||
SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
|
||||
if (plot->addSubImage(width, height, image, loc)) {
|
||||
return this->updatePlot(target, id, plot);
|
||||
}
|
||||
plotIter.next();
|
||||
}
|
||||
|
||||
// If the above fails, then see if the least recently refed plot has already been
|
||||
// flushed to the gpu
|
||||
plot = fPages[pageIdx].fPlotList.tail();
|
||||
SkASSERT(plot);
|
||||
if (target->hasDrawBeenFlushed(plot->lastUseToken())) {
|
||||
this->processEviction(plot->id());
|
||||
plot->resetRects();
|
||||
SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
|
||||
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
|
||||
SkASSERT(verify);
|
||||
if (!this->updatePlot(target, id, plot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fAtlasGeneration++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the simple cases fail, try to create a new page and add to it
|
||||
if (this->createNewPage()) {
|
||||
unsigned int pageIdx = fNumPages-1;
|
||||
SkASSERT(fProxies[pageIdx]);
|
||||
Plot* plot = fPages[pageIdx].fPlotList.head();
|
||||
// now look through all allocated plots for one we can share, in Most Recently Refed order
|
||||
PlotList::Iter plotIter;
|
||||
plotIter.init(fPages[pageIdx].fPlotList, PlotList::Iter::kHead_IterStart);
|
||||
Plot* plot;
|
||||
while ((plot = plotIter.get())) {
|
||||
SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
|
||||
if (plot->addSubImage(width, height, image, loc)) {
|
||||
return this->updatePlot(target, id, plot);
|
||||
}
|
||||
|
||||
// we shouldn't get here -- if so, something has gone terribly wrong
|
||||
SkASSERT(false);
|
||||
return false;
|
||||
plotIter.next();
|
||||
}
|
||||
|
||||
// Try to find a plot that we can perform an inline upload to.
|
||||
// We prioritize this upload in reverse order of pages to counterbalance the order above.
|
||||
Plot* plot = nullptr;
|
||||
for (int pageIdx = (int)(fNumPages-1); pageIdx >= 0; --pageIdx) {
|
||||
Plot* currentPlot = fPages[pageIdx].fPlotList.tail();
|
||||
if (currentPlot->lastUseToken() != target->nextDrawToken()) {
|
||||
plot = currentPlot;
|
||||
break;
|
||||
// If the above fails, then see if the least recently refed plot has already been flushed to the
|
||||
// gpu
|
||||
plot = fPages[pageIdx].fPlotList.tail();
|
||||
SkASSERT(plot);
|
||||
if (target->hasDrawBeenFlushed(plot->lastUseToken())) {
|
||||
this->processEviction(plot->id());
|
||||
plot->resetRects();
|
||||
SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
|
||||
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
|
||||
SkASSERT(verify);
|
||||
if (!this->updatePlot(target, id, plot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fAtlasGeneration++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we can't find a plot that is not used in a draw currently being prepared by an op, then
|
||||
// we have to fail. This gives the op a chance to enqueue the draw, and call back into this
|
||||
// function. When that draw is enqueued, the draw token advances, and the subsequent call will
|
||||
// continue past this branch and prepare an inline upload that will occur after the enqueued
|
||||
//draw which references the plot's pre-upload content.
|
||||
if (!plot) {
|
||||
// TODO: at this point try to create a new page and add to it before evicting
|
||||
|
||||
// If this plot has been used in a draw that is currently being prepared by an op, then we have
|
||||
// to fail. This gives the op a chance to enqueue the draw, and call back into this function.
|
||||
// When that draw is enqueued, the draw token advances, and the subsequent call will continue
|
||||
// past this branch and prepare an inline upload that will occur after the enqueued draw which
|
||||
// references the plot's pre-upload content.
|
||||
if (plot->lastUseToken() == target->nextDrawToken()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->processEviction(plot->id());
|
||||
int pageIdx = GetPageIndexFromID(plot->id());
|
||||
fPages[pageIdx].fPlotList.remove(plot);
|
||||
sk_sp<Plot>& newPlot = fPages[pageIdx].fPlotArray[plot->index()];
|
||||
newPlot.reset(plot->clone());
|
||||
@ -307,56 +317,3 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width,
|
||||
fAtlasGeneration++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrDrawOpAtlas::createNewPage() {
|
||||
if (fNumPages == kMaxPages) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrSurfaceDesc desc;
|
||||
desc.fFlags = kNone_GrSurfaceFlags;
|
||||
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
desc.fWidth = fTextureWidth;
|
||||
desc.fHeight = fTextureHeight;
|
||||
desc.fConfig = fPixelConfig;
|
||||
|
||||
// We don't want to flush the context so we claim we're in the middle of flushing so as to
|
||||
// guarantee we do not recieve a texture with pending IO
|
||||
// TODO: Determine how to avoid having to do this. (https://bug.skia.org/4156)
|
||||
static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
|
||||
sk_sp<GrTexture> texture(fContext->resourceProvider()->createApproxTexture(desc, kFlags));
|
||||
if (texture) {
|
||||
// MDB TODO: for now, wrap an instantiated texture. Having the deferred instantiation
|
||||
// possess the correct properties (e.g., no pendingIO) should fall out of the system but
|
||||
// should receive special attention.
|
||||
// Note: When switching over to the deferred proxy, use the kExact flag to create
|
||||
// the atlas and assert that the width & height are powers of 2.
|
||||
fProxies[fNumPages] = GrSurfaceProxy::MakeWrapped(std::move(texture),
|
||||
kTopLeft_GrSurfaceOrigin);
|
||||
}
|
||||
if (!fProxies[fNumPages]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int numPlotsX = fTextureWidth/fPlotWidth;
|
||||
int numPlotsY = fTextureHeight/fPlotHeight;
|
||||
|
||||
// set up allocated plots
|
||||
fPages[fNumPages].fPlotArray.reset(new sk_sp<Plot>[ numPlotsX * numPlotsY ]);
|
||||
|
||||
sk_sp<Plot>* currPlot = fPages[fNumPages].fPlotArray.get();
|
||||
for (int y = numPlotsY - 1, r = 0; y >= 0; --y, ++r) {
|
||||
for (int x = numPlotsX - 1, c = 0; x >= 0; --x, ++c) {
|
||||
uint32_t plotIndex = r * numPlotsX + c;
|
||||
currPlot->reset(new Plot(fNumPages, plotIndex, 1, x, y, fPlotWidth, fPlotHeight,
|
||||
fPixelConfig));
|
||||
|
||||
// build LRU list
|
||||
fPages[fNumPages].fPlotList.addToHead(currPlot->get());
|
||||
++currPlot;
|
||||
}
|
||||
}
|
||||
|
||||
fNumPages++;
|
||||
return true;
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ public:
|
||||
}
|
||||
|
||||
static constexpr auto kMaxPages = 4;
|
||||
uint32_t pageCount() { return fNumPages; }
|
||||
|
||||
/**
|
||||
* A class which can be handed back to GrDrawOpAtlas for updating last use tokens in bulk. The
|
||||
@ -191,10 +190,6 @@ public:
|
||||
return width > kGlyphMaxDim || height > kGlyphMaxDim;
|
||||
}
|
||||
|
||||
static uint32_t GetPageIndexFromID(AtlasID id) {
|
||||
return id & 0xff;
|
||||
}
|
||||
|
||||
private:
|
||||
GrDrawOpAtlas(GrContext*, GrPixelConfig config, int width, int height,
|
||||
int numPlotsX, int numPlotsY);
|
||||
@ -257,7 +252,7 @@ private:
|
||||
static GrDrawOpAtlas::AtlasID CreateId(uint32_t pageIdx, uint32_t plotIdx,
|
||||
uint64_t generation) {
|
||||
SkASSERT(pageIdx < (1 << 8));
|
||||
SkASSERT(pageIdx < kMaxPages);
|
||||
SkASSERT(pageIdx == 0); // for now, we only support one page
|
||||
SkASSERT(plotIdx < (1 << 8));
|
||||
SkASSERT(generation < ((uint64_t)1 << 48));
|
||||
return generation << 16 | plotIdx << 8 | pageIdx;
|
||||
@ -291,6 +286,10 @@ private:
|
||||
|
||||
typedef SkTInternalLList<Plot> PlotList;
|
||||
|
||||
static uint32_t GetPageIndexFromID(AtlasID id) {
|
||||
return id & 0xff;
|
||||
}
|
||||
|
||||
static uint32_t GetPlotIndexFromID(AtlasID id) {
|
||||
return (id >> 8) & 0xff;
|
||||
}
|
||||
@ -313,8 +312,6 @@ private:
|
||||
// TODO: make page MRU
|
||||
}
|
||||
|
||||
bool createNewPage();
|
||||
|
||||
inline void processEviction(AtlasID);
|
||||
|
||||
GrContext* fContext;
|
||||
@ -343,7 +340,7 @@ private:
|
||||
// proxies kept separate to make it easier to pass them up to client
|
||||
sk_sp<GrTextureProxy> fProxies[kMaxPages];
|
||||
Page fPages[kMaxPages];
|
||||
uint32_t fNumPages;
|
||||
SkDEBUGCODE(uint32_t fNumPages;)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -61,7 +61,6 @@ struct GrGlyph {
|
||||
int height() const { return fBounds.height(); }
|
||||
bool isEmpty() const { return fBounds.isEmpty(); }
|
||||
uint16_t glyphID() const { return UnpackID(fPackedID); }
|
||||
uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fID); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -137,10 +137,6 @@ void GrResourceIOProcessor::addImageStorageAccess(const ImageStorageAccess* acce
|
||||
fImageStorageAccesses.push_back(access);
|
||||
}
|
||||
|
||||
void GrResourceIOProcessor::resetTextureSamplers() {
|
||||
fTextureSamplers.reset();
|
||||
}
|
||||
|
||||
void GrResourceIOProcessor::addPendingIOs() const {
|
||||
for (const auto& sampler : fTextureSamplers) {
|
||||
sampler->programProxy()->markPendingIO();
|
||||
|
@ -191,7 +191,6 @@ protected:
|
||||
void addTextureSampler(const TextureSampler*);
|
||||
void addBufferAccess(const BufferAccess*);
|
||||
void addImageStorageAccess(const ImageStorageAccess*);
|
||||
void resetTextureSamplers();
|
||||
|
||||
bool hasSameSamplersAndAccesses(const GrResourceIOProcessor&) const;
|
||||
|
||||
|
@ -47,15 +47,17 @@ static void append_multitexture_lookup(GrGLSLPrimitiveProcessor::EmitArgs& args,
|
||||
const char* coordName,
|
||||
const char* colorName) {
|
||||
// conditionally load from the indexed texture sampler
|
||||
for (int i = 0; i < numTextureSamplers-1; ++i) {
|
||||
args.fFragBuilder->codeAppendf("if (%s == %d) { %s = ", texIdx.fsIn(), i, colorName);
|
||||
args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName, kVec2f_GrSLType);
|
||||
args.fFragBuilder->codeAppend("; } else ");
|
||||
if (numTextureSamplers > 1) {
|
||||
args.fFragBuilder->codeAppendf("if (%s == 0) ", texIdx.fsIn());
|
||||
}
|
||||
args.fFragBuilder->codeAppendf("{ %s = ", colorName);
|
||||
args.fFragBuilder->appendTextureLookup(args.fTexSamplers[numTextureSamplers-1], coordName,
|
||||
kVec2f_GrSLType);
|
||||
args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], coordName, kVec2f_GrSLType);
|
||||
args.fFragBuilder->codeAppend("; }");
|
||||
for (int i = 1; i < numTextureSamplers; ++i) {
|
||||
args.fFragBuilder->codeAppendf("else if (%s == %d) { %s =", texIdx.fsIn(), i, colorName);
|
||||
args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName, kVec2f_GrSLType);
|
||||
args.fFragBuilder->codeAppend("; }");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -149,17 +149,6 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color,
|
||||
}
|
||||
}
|
||||
|
||||
void GrBitmapTextGeoProc::resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState& params) {
|
||||
this->resetTextureSamplers();
|
||||
for (int i = 0; i < kMaxTextures; ++i) {
|
||||
if (proxies[i]) {
|
||||
fTextureSamplers[i].reset(std::move(proxies[i]), params);
|
||||
this->addTextureSampler(&fTextureSamplers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrBitmapTextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
GrGLBitmapTextGeoProc::GenKey(*this, caps, b);
|
||||
|
@ -45,8 +45,6 @@ public:
|
||||
const SkMatrix& localMatrix() const { return fLocalMatrix; }
|
||||
bool usesLocalCoords() const { return fUsesLocalCoords; }
|
||||
|
||||
void resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
|
||||
|
||||
void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override;
|
||||
|
@ -261,17 +261,6 @@ GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(
|
||||
}
|
||||
}
|
||||
|
||||
void GrDistanceFieldA8TextGeoProc::resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState& params) {
|
||||
this->resetTextureSamplers();
|
||||
for (int i = 0; i < kMaxTextures; ++i) {
|
||||
if (proxies[i]) {
|
||||
fTextureSamplers[i].reset(std::move(proxies[i]), params);
|
||||
this->addTextureSampler(&fTextureSamplers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrDistanceFieldA8TextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
GrGLDistanceFieldA8TextGeoProc::GenKey(*this, caps, b);
|
||||
@ -522,17 +511,6 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
|
||||
}
|
||||
}
|
||||
|
||||
void GrDistanceFieldPathGeoProc::resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState& params) {
|
||||
this->resetTextureSamplers();
|
||||
for (int i = 0; i < kMaxTextures; ++i) {
|
||||
if (proxies[i]) {
|
||||
fTextureSamplers[i].reset(std::move(proxies[i]), params);
|
||||
this->addTextureSampler(&fTextureSamplers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrDistanceFieldPathGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
GrGLDistanceFieldPathGeoProc::GenKey(*this, caps, b);
|
||||
@ -845,17 +823,6 @@ GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(
|
||||
}
|
||||
}
|
||||
|
||||
void GrDistanceFieldLCDTextGeoProc::resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState& params) {
|
||||
this->resetTextureSamplers();
|
||||
for (int i = 0; i < kMaxTextures; ++i) {
|
||||
if (proxies[i]) {
|
||||
fTextureSamplers[i].reset(std::move(proxies[i]), params);
|
||||
this->addTextureSampler(&fTextureSamplers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrDistanceFieldLCDTextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
GrGLDistanceFieldLCDTextGeoProc::GenKey(*this, caps, b);
|
||||
|
@ -87,8 +87,6 @@ public:
|
||||
#endif
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
|
||||
void resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
|
||||
|
||||
void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
||||
@ -150,8 +148,6 @@ public:
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
bool usesLocalCoords() const { return fUsesLocalCoords; }
|
||||
|
||||
void resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
|
||||
|
||||
void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
||||
@ -226,8 +222,6 @@ public:
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
bool usesLocalCoords() const { return fUsesLocalCoords; }
|
||||
|
||||
void resetProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
|
||||
|
||||
void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
||||
|
@ -84,26 +84,25 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrMaskFormat maskFormat = this->maskFormat();
|
||||
|
||||
uint32_t atlasPageCount = fFontCache->getAtlasPageCount(maskFormat);
|
||||
const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(maskFormat);
|
||||
if (!atlasPageCount || !proxies[0]) {
|
||||
const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(this->maskFormat());
|
||||
if (!proxies[0]) {
|
||||
SkDebugf("Could not allocate backing texture for atlas\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GrMaskFormat maskFormat = this->maskFormat();
|
||||
|
||||
FlushInfo flushInfo;
|
||||
flushInfo.fPipeline =
|
||||
target->makePipeline(fSRGBFlags, std::move(fProcessors), target->detachAppliedClip());
|
||||
if (this->usesDistanceFields()) {
|
||||
flushInfo.fGeometryProcessor =
|
||||
this->setupDfProcessor(this->viewMatrix(),
|
||||
fLuminanceColor, this->color(), proxies);
|
||||
this->setupDfProcessor(this->viewMatrix(),
|
||||
fLuminanceColor, this->color(), proxies);
|
||||
} else {
|
||||
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
|
||||
this->color(), proxies, GrSamplerState::ClampNearest(), maskFormat,
|
||||
localMatrix, this->usesLocalCoords());
|
||||
this->color(), proxies, GrSamplerState::ClampNearest(), maskFormat,
|
||||
localMatrix, this->usesLocalCoords());
|
||||
}
|
||||
|
||||
flushInfo.fGlyphsToFlush = 0;
|
||||
@ -142,24 +141,6 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
|
||||
currVertex += byteCount;
|
||||
}
|
||||
|
||||
// During preparation the number of atlas pages has increased.
|
||||
// Update the proxies used in the GP to match.
|
||||
if (atlasPageCount != fFontCache->getAtlasPageCount(maskFormat)) {
|
||||
GrGeometryProcessor* gp = flushInfo.fGeometryProcessor.get();
|
||||
if (this->usesDistanceFields()) {
|
||||
if (this->isLCD()) {
|
||||
reinterpret_cast<GrDistanceFieldLCDTextGeoProc*>(gp)->resetProxies(
|
||||
fFontCache->getProxies(maskFormat), GrSamplerState::ClampBilerp());
|
||||
} else {
|
||||
reinterpret_cast<GrDistanceFieldA8TextGeoProc*>(gp)->resetProxies(
|
||||
fFontCache->getProxies(maskFormat), GrSamplerState::ClampBilerp());
|
||||
}
|
||||
} else {
|
||||
reinterpret_cast<GrBitmapTextGeoProc*>(gp)->resetProxies(
|
||||
fFontCache->getProxies(maskFormat), GrSamplerState::ClampNearest());
|
||||
}
|
||||
}
|
||||
|
||||
this->flush(target, &flushInfo);
|
||||
}
|
||||
|
||||
|
@ -238,10 +238,6 @@ private:
|
||||
flushInfo.fPipeline = fHelper.makePipeline(target);
|
||||
// Setup GrGeometryProcessor
|
||||
GrDrawOpAtlas* atlas = fAtlas;
|
||||
uint32_t atlasPageCount = atlas->pageCount();
|
||||
if (!atlasPageCount) {
|
||||
return;
|
||||
}
|
||||
if (fUsesDistanceField) {
|
||||
uint32_t flags = 0;
|
||||
flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
|
||||
@ -389,19 +385,6 @@ private:
|
||||
flushInfo.fInstancesToFlush++;
|
||||
}
|
||||
|
||||
// During preparation the number of atlas pages has increased.
|
||||
// Update the proxies used in the GP to match.
|
||||
if (atlasPageCount != atlas->pageCount()) {
|
||||
GrGeometryProcessor* gp = flushInfo.fGeometryProcessor.get();
|
||||
if (fUsesDistanceField) {
|
||||
reinterpret_cast<GrDistanceFieldPathGeoProc*>(gp)->resetProxies(
|
||||
atlas->getProxies(), GrSamplerState::ClampBilerp());
|
||||
} else {
|
||||
reinterpret_cast<GrBitmapTextGeoProc*>(gp)->resetProxies(
|
||||
atlas->getProxies(), GrSamplerState::ClampNearest());
|
||||
}
|
||||
}
|
||||
|
||||
this->flush(target, &flushInfo);
|
||||
}
|
||||
|
||||
@ -513,17 +496,12 @@ private:
|
||||
shapeData->fBounds.fRight /= scale;
|
||||
shapeData->fBounds.fBottom /= scale;
|
||||
|
||||
// We pack the 2bit page index in the low bit of the u and v texture coords
|
||||
uint16_t pageIndex = GrDrawOpAtlas::GetPageIndexFromID(id);
|
||||
SkASSERT(pageIndex < 4);
|
||||
uint16_t uBit = (pageIndex >> 1) & 0x1;
|
||||
uint16_t vBit = pageIndex & 0x1;
|
||||
shapeData->fTextureCoords.set((atlasLocation.fX+SK_DistanceFieldPad) << 1 | uBit,
|
||||
(atlasLocation.fY+SK_DistanceFieldPad) << 1 | vBit,
|
||||
shapeData->fTextureCoords.set((atlasLocation.fX+SK_DistanceFieldPad) << 1,
|
||||
(atlasLocation.fY+SK_DistanceFieldPad) << 1,
|
||||
(atlasLocation.fX+SK_DistanceFieldPad+
|
||||
devPathBounds.width()) << 1 | uBit,
|
||||
devPathBounds.width()) << 1,
|
||||
(atlasLocation.fY+SK_DistanceFieldPad+
|
||||
devPathBounds.height()) << 1 | vBit);
|
||||
devPathBounds.height()) << 1);
|
||||
|
||||
fShapeCache->add(shapeData);
|
||||
fShapeList->addToTail(shapeData);
|
||||
@ -611,14 +589,9 @@ private:
|
||||
shapeData->fBounds = SkRect::Make(devPathBounds);
|
||||
shapeData->fBounds.offset(-translateX, -translateY);
|
||||
|
||||
// We pack the 2bit page index in the low bit of the u and v texture coords
|
||||
uint16_t pageIndex = GrDrawOpAtlas::GetPageIndexFromID(id);
|
||||
SkASSERT(pageIndex < 4);
|
||||
uint16_t uBit = (pageIndex >> 1) & 0x1;
|
||||
uint16_t vBit = pageIndex & 0x1;
|
||||
shapeData->fTextureCoords.set(atlasLocation.fX << 1 | uBit, atlasLocation.fY << 1 | vBit,
|
||||
(atlasLocation.fX+width) << 1 | uBit,
|
||||
(atlasLocation.fY+height) << 1 | vBit);
|
||||
shapeData->fTextureCoords.set(atlasLocation.fX << 1, atlasLocation.fY << 1,
|
||||
(atlasLocation.fX+width) << 1,
|
||||
(atlasLocation.fY+height) << 1);
|
||||
|
||||
fShapeCache->add(shapeData);
|
||||
fShapeList->addToTail(shapeData);
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
|
||||
void freeAll();
|
||||
|
||||
// if getProxies returns nullptr, the client must not try to use other functions on the
|
||||
// if getProxy returns nullptr, the client must not try to use other functions on the
|
||||
// GrAtlasGlyphCache which use the atlas. This function *must* be called first, before other
|
||||
// functions which use the atlas.
|
||||
const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format) {
|
||||
@ -136,13 +136,6 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t getAtlasPageCount(GrMaskFormat format) {
|
||||
if (this->initAtlas(format)) {
|
||||
return this->getAtlas(format)->pageCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool hasGlyph(GrGlyph* glyph) {
|
||||
SkASSERT(glyph);
|
||||
return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
|
||||
|
@ -39,19 +39,11 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS
|
||||
u1 = u0 + width;
|
||||
v1 = v0 + height;
|
||||
}
|
||||
// We pack the 2bit page index in the low bit of the u and v texture coords
|
||||
uint32_t pageIndex = glyph->pageIndex();
|
||||
SkASSERT(pageIndex < 4);
|
||||
uint16_t uBit = (pageIndex >> 1) & 0x1;
|
||||
uint16_t vBit = pageIndex & 0x1;
|
||||
// shift to make space for index bits
|
||||
u0 <<= 1;
|
||||
u0 |= uBit;
|
||||
v0 <<= 1;
|
||||
v0 |= vBit;
|
||||
u1 <<= 1;
|
||||
u1 |= uBit;
|
||||
v1 <<= 1;
|
||||
v1 |= vBit;
|
||||
}
|
||||
|
||||
// This is a bit wonky, but sometimes we have LCD text, in which case we won't have color
|
||||
|
Loading…
Reference in New Issue
Block a user