aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-09-12 11:54:11 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-12 17:16:00 +0000
commita950b63b442f1376d022740457b020ada62f6554 (patch)
tree8508e15a8ae8e6edc4fdba2d6e2273b5662e2add /src
parent2ab4b2b871c01aa3dd6d2e43883461c722f01680 (diff)
Add support for additional textures in GrDrawOpAtlas
Step two in supporting growable/shrinkable atlases. Bug: skia:3550 Change-Id: I0cdec2a9f59cc8ced071bfeec2f8ed5a228c4b7a Reviewed-on: https://skia-review.googlesource.com/43260 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrDrawOpAtlas.cpp60
-rw-r--r--src/gpu/GrDrawOpAtlas.h133
-rw-r--r--src/gpu/effects/GrBitmapTextGeoProc.cpp20
-rw-r--r--src/gpu/effects/GrBitmapTextGeoProc.h14
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.cpp92
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.h37
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp23
-rw-r--r--src/gpu/ops/GrAtlasTextOp.h5
-rw-r--r--src/gpu/ops/GrSmallPathRenderer.cpp4
-rw-r--r--src/gpu/text/GrAtlasGlyphCache.cpp14
-rw-r--r--src/gpu/text/GrAtlasGlyphCache.h4
11 files changed, 254 insertions, 152 deletions
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index c962a6168d..bdd07e7c82 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -21,7 +21,7 @@ std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrContext* ctx, GrPixelConfig
void* data) {
std::unique_ptr<GrDrawOpAtlas> atlas(
new GrDrawOpAtlas(ctx, config, width, height, numPlotsX, numPlotsY));
- if (!atlas->getProxy()) {
+ if (!atlas->getProxies()[0]) {
return nullptr;
}
@@ -32,13 +32,14 @@ std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrContext* ctx, GrPixelConfig
////////////////////////////////////////////////////////////////////////////////
-GrDrawOpAtlas::Plot::Plot(int index, uint64_t genID, int offX, int offY, int width, int height,
- GrPixelConfig config)
+GrDrawOpAtlas::Plot::Plot(int pageIndex, int plotIndex, uint64_t genID, int offX, int offY,
+ int width, int height, GrPixelConfig config)
: fLastUpload(GrDrawOpUploadToken::AlreadyFlushedToken())
, fLastUse(GrDrawOpUploadToken::AlreadyFlushedToken())
- , fIndex(index)
+ , fPageIndex(pageIndex)
+ , fPlotIndex(plotIndex)
, fGenID(genID)
- , fID(CreateId(fIndex, fGenID))
+ , fID(CreateId(fPageIndex, fPlotIndex, fGenID))
, fData(nullptr)
, fWidth(width)
, fHeight(height)
@@ -126,7 +127,7 @@ void GrDrawOpAtlas::Plot::resetRects() {
}
fGenID++;
- fID = CreateId(fIndex, fGenID);
+ fID = CreateId(fPageIndex, fPlotIndex, fGenID);
// zero out the plot
if (fData) {
@@ -142,7 +143,6 @@ void GrDrawOpAtlas::Plot::resetRects() {
GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width, int height,
int numPlotsX, int numPlotsY)
: fContext(context)
- , fProxy(nullptr)
, fPixelConfig(config)
, fTextureWidth(width)
, fTextureHeight(height)
@@ -166,7 +166,8 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width
// 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.
- fProxy = GrSurfaceProxy::MakeWrapped(std::move(texture), kTopLeft_GrSurfaceOrigin);
+ fProxies[0] = GrSurfaceProxy::MakeWrapped(std::move(texture),
+ kTopLeft_GrSurfaceOrigin);
}
fPlotWidth = fTextureWidth / numPlotsX;
@@ -176,19 +177,20 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width
SkASSERT(fPlotHeight * numPlotsY == fTextureHeight);
SkDEBUGCODE(fNumPlots = numPlotsX * numPlotsY;)
+ SkDEBUGCODE(fNumPages = 1;)
// set up allocated plots
- fPlotArray.reset(new sk_sp<Plot>[ numPlotsX * numPlotsY ]);
+ fPages[0].fPlotArray.reset(new sk_sp<Plot>[ numPlotsX * numPlotsY ]);
- sk_sp<Plot>* currPlot = fPlotArray.get();
+ 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(index, 1, x, y, fPlotWidth, fPlotHeight, fPixelConfig));
+ new Plot(0, index, 1, x, y, fPlotWidth, fPlotHeight, fPixelConfig));
// build LRU list
- fPlotList.addToHead(currPlot->get());
+ fPages[0].fPlotList.addToHead(currPlot->get());
++currPlot;
}
}
@@ -201,7 +203,8 @@ void GrDrawOpAtlas::processEviction(AtlasID id) {
}
inline bool GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plot* plot) {
- this->makeMRU(plot);
+ int pageIdx = GetPageIndexFromID(plot->id());
+ this->makeMRU(plot, pageIdx);
// If our most recent upload has already occurred then we have to insert a new
// upload. Otherwise, we already have a scheduled upload that hasn't yet ocurred.
@@ -212,11 +215,11 @@ inline bool GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plo
// MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated.
// Once it is deferred more care must be taken upon instantiation failure.
- if (!fProxy->instantiate(fContext->resourceProvider())) {
+ if (!fProxies[pageIdx]->instantiate(fContext->resourceProvider())) {
return false;
}
- GrTextureProxy* proxy = fProxy.get();
+ GrTextureProxy* proxy = fProxies[pageIdx].get();
GrDrawOpUploadToken lastUploadToken = target->addAsapUpload(
[plotsp, proxy] (GrDrawOp::WritePixelsFn& writePixels) {
@@ -231,18 +234,21 @@ 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(fProxy);
+ SkASSERT(fProxies[pageIdx]);
if (width > fPlotWidth || height > fPlotHeight) {
return false;
}
// now look through all allocated plots for one we can share, in Most Recently Refed order
PlotList::Iter plotIter;
- plotIter.init(fPlotList, PlotList::Iter::kHead_IterStart);
+ plotIter.init(fPages[pageIdx].fPlotList, PlotList::Iter::kHead_IterStart);
Plot* plot;
while ((plot = plotIter.get())) {
- SkASSERT(GrBytesPerPixel(fProxy->config()) == plot->bpp());
+ SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
if (plot->addSubImage(width, height, image, loc)) {
return this->updatePlot(target, id, plot);
}
@@ -251,12 +257,12 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width,
// If the above fails, then see if the least recently refed plot has already been flushed to the
// gpu
- plot = fPlotList.tail();
+ plot = fPages[pageIdx].fPlotList.tail();
SkASSERT(plot);
if (target->hasDrawBeenFlushed(plot->lastUseToken())) {
this->processEviction(plot->id());
plot->resetRects();
- SkASSERT(GrBytesPerPixel(fProxy->config()) == plot->bpp());
+ SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
SkASSERT(verify);
if (!this->updatePlot(target, id, plot)) {
@@ -267,6 +273,8 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width,
return true;
}
+ // 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
@@ -277,12 +285,12 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width,
}
this->processEviction(plot->id());
- fPlotList.remove(plot);
- sk_sp<Plot>& newPlot = fPlotArray[plot->index()];
+ fPages[pageIdx].fPlotList.remove(plot);
+ sk_sp<Plot>& newPlot = fPages[pageIdx].fPlotArray[plot->index()];
newPlot.reset(plot->clone());
- fPlotList.addToHead(newPlot.get());
- SkASSERT(GrBytesPerPixel(fProxy->config()) == newPlot->bpp());
+ fPages[pageIdx].fPlotList.addToHead(newPlot.get());
+ SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == newPlot->bpp());
SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, loc);
SkASSERT(verify);
@@ -292,10 +300,10 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width,
sk_sp<Plot> plotsp(SkRef(newPlot.get()));
// MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated.
// Once it is deferred more care must be taken upon instantiation failure.
- if (!fProxy->instantiate(fContext->resourceProvider())) {
+ if (!fProxies[pageIdx]->instantiate(fContext->resourceProvider())) {
return false;
}
- GrTextureProxy* proxy = fProxy.get();
+ GrTextureProxy* proxy = fProxies[pageIdx].get();
GrDrawOpUploadToken lastUploadToken = target->addInlineUpload(
[plotsp, proxy] (GrDrawOp::WritePixelsFn& writePixels) {
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index 03eb8080a4..6d12973f4a 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -89,23 +89,28 @@ public:
SkIPoint16* loc);
GrContext* context() const { return fContext; }
- sk_sp<GrTextureProxy> getProxy() const { return fProxy; }
+ const sk_sp<GrTextureProxy>* getProxies() const { return fProxies; }
uint64_t atlasGeneration() const { return fAtlasGeneration; }
inline bool hasID(AtlasID id) {
- uint32_t index = GetIndexFromID(id);
- SkASSERT(index < fNumPlots);
- return fPlotArray[index]->genID() == GetGenerationFromID(id);
+ uint32_t plot = GetPlotIndexFromID(id);
+ SkASSERT(plot < fNumPlots);
+ uint32_t page = GetPageIndexFromID(id);
+ SkASSERT(page < fNumPages);
+ return fPages[page].fPlotArray[plot]->genID() == GetGenerationFromID(id);
}
/** To ensure the atlas does not evict a given entry, the client must set the last use token. */
inline void setLastUseToken(AtlasID id, GrDrawOpUploadToken token) {
SkASSERT(this->hasID(id));
- uint32_t index = GetIndexFromID(id);
- SkASSERT(index < fNumPlots);
- this->makeMRU(fPlotArray[index].get());
- fPlotArray[index]->setLastUseToken(token);
+ uint32_t plotIdx = GetPlotIndexFromID(id);
+ SkASSERT(plotIdx < fNumPlots);
+ uint32_t pageIdx = GetPageIndexFromID(id);
+ SkASSERT(pageIdx < fNumPages);
+ Plot* plot = fPages[pageIdx].fPlotArray[plotIdx].get();
+ this->makeMRU(plot, pageIdx);
+ plot->setLastUseToken(token);
}
inline void registerEvictionCallback(EvictionFunc func, void* userData) {
@@ -114,47 +119,58 @@ public:
data->fData = userData;
}
+ static constexpr auto kMaxPages = 4;
+
/**
* A class which can be handed back to GrDrawOpAtlas for updating last use tokens in bulk. The
- * current max number of plots the GrDrawOpAtlas can handle is 32. If in the future this is
- * insufficient then we can move to a 64 bit int.
+ * current max number of plots per page the GrDrawOpAtlas 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) {}
+ BulkUseTokenUpdater() {
+ memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated));
+ }
BulkUseTokenUpdater(const BulkUseTokenUpdater& that)
- : fPlotsToUpdate(that.fPlotsToUpdate)
- , fPlotAlreadyUpdated(that.fPlotAlreadyUpdated) {
+ : fPlotsToUpdate(that.fPlotsToUpdate) {
+ memcpy(fPlotAlreadyUpdated, that.fPlotAlreadyUpdated, sizeof(fPlotAlreadyUpdated));
}
void add(AtlasID id) {
- int index = GrDrawOpAtlas::GetIndexFromID(id);
- if (!this->find(index)) {
- this->set(index);
+ int index = GrDrawOpAtlas::GetPlotIndexFromID(id);
+ int pageIdx = GrDrawOpAtlas::GetPageIndexFromID(id);
+ if (!this->find(pageIdx, index)) {
+ this->set(pageIdx, index);
}
}
void reset() {
fPlotsToUpdate.reset();
- fPlotAlreadyUpdated = 0;
+ memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated));
}
+ struct PlotData {
+ PlotData(int pageIdx, int plotIdx) : fPageIndex(pageIdx), fPlotIndex(plotIdx) {}
+ uint32_t fPageIndex;
+ uint32_t fPlotIndex;
+ };
+
private:
- bool find(int index) const {
+ bool find(int pageIdx, int index) const {
SkASSERT(index < kMaxPlots);
- return (fPlotAlreadyUpdated >> index) & 1;
+ return (fPlotAlreadyUpdated[pageIdx] >> index) & 1;
}
- void set(int index) {
- SkASSERT(!this->find(index));
- fPlotAlreadyUpdated = fPlotAlreadyUpdated | (1 << index);
- fPlotsToUpdate.push_back(index);
+ void set(int pageIdx, int index) {
+ SkASSERT(!this->find(pageIdx, index));
+ fPlotAlreadyUpdated[pageIdx] |= (1 << index);
+ fPlotsToUpdate.push_back(PlotData(pageIdx, index));
}
- static const int kMinItems = 4;
- static const int kMaxPlots = 32;
- SkSTArray<kMinItems, int, true> fPlotsToUpdate;
- uint32_t fPlotAlreadyUpdated;
+ static constexpr int kMinItems = 4;
+ static constexpr int kMaxPlots = 32;
+ SkSTArray<kMinItems, PlotData, true> fPlotsToUpdate;
+ uint32_t fPlotAlreadyUpdated[kMaxPages];
friend class GrDrawOpAtlas;
};
@@ -162,13 +178,14 @@ public:
void setLastUseTokenBulk(const BulkUseTokenUpdater& updater, GrDrawOpUploadToken token) {
int count = updater.fPlotsToUpdate.count();
for (int i = 0; i < count; i++) {
- Plot* plot = fPlotArray[updater.fPlotsToUpdate[i]].get();
- this->makeMRU(plot);
+ const BulkUseTokenUpdater::PlotData& pd = updater.fPlotsToUpdate[i];
+ Plot* plot = fPages[pd.fPageIndex].fPlotArray[pd.fPlotIndex].get();
+ this->makeMRU(plot, pd.fPageIndex);
plot->setLastUseToken(token);
}
}
- static const int kGlyphMaxDim = 256;
+ static constexpr auto kGlyphMaxDim = 256;
static bool GlyphTooLargeForAtlas(int width, int height) {
return width > kGlyphMaxDim || height > kGlyphMaxDim;
}
@@ -188,8 +205,8 @@ private:
SK_DECLARE_INTERNAL_LLIST_INTERFACE(Plot);
public:
- /** index() is a unique id for the plot relative to the owning GrAtlas. */
- uint32_t index() const { return fIndex; }
+ /** index() is a unique id for the plot relative to the owning GrAtlas and page. */
+ uint32_t index() const { return fPlotIndex; }
/**
* genID() is incremented when the plot is evicted due to a atlas spill. It is used to know
* if a particular subimage is still present in the atlas.
@@ -219,7 +236,7 @@ private:
void resetRects();
private:
- Plot(int index, uint64_t genID, int offX, int offY, int width, int height,
+ Plot(int pageIndex, int plotIndex, uint64_t genID, int offX, int offY, int width, int height,
GrPixelConfig config);
~Plot() override;
@@ -229,19 +246,25 @@ private:
* the atlas
*/
Plot* clone() const {
- return new Plot(fIndex, fGenID + 1, fX, fY, fWidth, fHeight, fConfig);
+ return new Plot(fPageIndex, fPlotIndex, fGenID + 1, fX, fY, fWidth, fHeight, fConfig);
}
- static GrDrawOpAtlas::AtlasID CreateId(uint32_t index, uint64_t generation) {
- SkASSERT(index < (1 << 16));
+ static GrDrawOpAtlas::AtlasID CreateId(uint32_t pageIdx, uint32_t plotIdx,
+ uint64_t generation) {
+ SkASSERT(pageIdx < (1 << 8));
+ SkASSERT(pageIdx == 0); // for now, we only support one page
+ SkASSERT(plotIdx < (1 << 8));
SkASSERT(generation < ((uint64_t)1 << 48));
- return generation << 16 | index;
+ return generation << 16 | plotIdx << 8 | pageIdx;
}
GrDrawOpUploadToken fLastUpload;
GrDrawOpUploadToken fLastUse;
- const uint32_t fIndex;
+ struct {
+ const uint32_t fPageIndex : 16;
+ const uint32_t fPlotIndex : 16;
+ };
uint64_t fGenID;
GrDrawOpAtlas::AtlasID fID;
unsigned char* fData;
@@ -263,8 +286,12 @@ private:
typedef SkTInternalLList<Plot> PlotList;
- static uint32_t GetIndexFromID(AtlasID id) {
- return id & 0xffff;
+ static uint32_t GetPageIndexFromID(AtlasID id) {
+ return id & 0xff;
+ }
+
+ static uint32_t GetPlotIndexFromID(AtlasID id) {
+ return (id >> 8) & 0xff;
}
// top 48 bits are reserved for the generation ID
@@ -274,19 +301,20 @@ private:
inline bool updatePlot(GrDrawOp::Target*, AtlasID*, Plot*);
- inline void makeMRU(Plot* plot) {
- if (fPlotList.head() == plot) {
+ inline void makeMRU(Plot* plot, int pageIdx) {
+ if (fPages[pageIdx].fPlotList.head() == plot) {
return;
}
- fPlotList.remove(plot);
- fPlotList.addToHead(plot);
+ fPages[pageIdx].fPlotList.remove(plot);
+ fPages[pageIdx].fPlotList.addToHead(plot);
+
+ // TODO: make page MRU
}
inline void processEviction(AtlasID);
GrContext* fContext;
- sk_sp<GrTextureProxy> fProxy;
GrPixelConfig fPixelConfig;
int fTextureWidth;
int fTextureHeight;
@@ -302,10 +330,17 @@ private:
};
SkTDArray<EvictionData> fEvictionCallbacks;
- // allocated array of Plots
- std::unique_ptr<sk_sp<Plot>[]> fPlotArray;
- // LRU list of Plots (MRU at head - LRU at tail)
- PlotList fPlotList;
+
+ struct Page {
+ // allocated array of Plots
+ std::unique_ptr<sk_sp<Plot>[]> fPlotArray;
+ // LRU list of Plots (MRU at head - LRU at tail)
+ PlotList fPlotList;
+ };
+ // proxies kept separate to make it easier to pass them up to client
+ sk_sp<GrTextureProxy> fProxies[kMaxPages];
+ Page fPages[kMaxPages];
+ SkDEBUGCODE(uint32_t fNumPages;)
};
#endif
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 8013d2e4b8..2d665c50cb 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -120,13 +120,13 @@ private:
///////////////////////////////////////////////////////////////////////////////
-GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, sk_sp<GrTextureProxy> proxy,
+GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params, GrMaskFormat format,
const SkMatrix& localMatrix, bool usesLocalCoords)
: fColor(color)
, fLocalMatrix(localMatrix)
, fUsesLocalCoords(usesLocalCoords)
- , fTextureSampler(std::move(proxy), params)
, fInColor(nullptr)
, fMaskFormat(format) {
this->initClassID<GrBitmapTextGeoProc>();
@@ -141,7 +141,12 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, sk_sp<GrTextureProxy> pr
fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
kHigh_GrSLPrecision);
- this->addTextureSampler(&fTextureSampler);
+ 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,
@@ -162,7 +167,12 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
sk_sp<GrGeometryProcessor> GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
: GrProcessorUnitTest::kAlphaTextureIdx;
- sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
+ sk_sp<GrTextureProxy> proxies[kMaxTextures] = {
+ d->textureProxy(texIdx),
+ nullptr,
+ nullptr,
+ nullptr
+ };
GrSamplerState::WrapMode wrapModes[2];
GrTest::TestWrapModes(d->fRandom, wrapModes);
@@ -183,7 +193,7 @@ sk_sp<GrGeometryProcessor> GrBitmapTextGeoProc::TestCreate(GrProcessorTestData*
break;
}
- return GrBitmapTextGeoProc::Make(GrRandomColor(d->fRandom), std::move(proxy), samplerState,
+ return GrBitmapTextGeoProc::Make(GrRandomColor(d->fRandom), proxies, samplerState,
format, GrTest::TestMatrix(d->fRandom),
d->fRandom->nextBool());
}
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h
index c919d1c87b..f8f4d8e5a8 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.h
+++ b/src/gpu/effects/GrBitmapTextGeoProc.h
@@ -21,11 +21,14 @@ class GrInvariantOutput;
*/
class GrBitmapTextGeoProc : public GrGeometryProcessor {
public:
- static sk_sp<GrGeometryProcessor> Make(GrColor color, sk_sp<GrTextureProxy> proxy,
+ static constexpr int kMaxTextures = 4;
+
+ static sk_sp<GrGeometryProcessor> Make(GrColor color,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& p, GrMaskFormat format,
const SkMatrix& localMatrix, bool usesLocalCoords) {
return sk_sp<GrGeometryProcessor>(
- new GrBitmapTextGeoProc(color, std::move(proxy), p, format,
+ new GrBitmapTextGeoProc(color, proxies, p, format,
localMatrix, usesLocalCoords));
}
@@ -47,13 +50,14 @@ public:
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override;
private:
- GrBitmapTextGeoProc(GrColor, sk_sp<GrTextureProxy>, const GrSamplerState& params,
- GrMaskFormat format, const SkMatrix& localMatrix, bool usesLocalCoords);
+ GrBitmapTextGeoProc(GrColor, const sk_sp<GrTextureProxy> proxies[kMaxTextures],
+ const GrSamplerState& params, GrMaskFormat format,
+ const SkMatrix& localMatrix, bool usesLocalCoords);
GrColor fColor;
SkMatrix fLocalMatrix;
bool fUsesLocalCoords;
- TextureSampler fTextureSampler;
+ TextureSampler fTextureSamplers[kMaxTextures];
const Attribute* fInPosition;
const Attribute* fInColor;
const Attribute* fInTextureCoords;
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 953d4cc2bc..66e96199eb 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -228,18 +228,18 @@ private:
///////////////////////////////////////////////////////////////////////////////
-GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color,
- const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
- const GrSamplerState& params,
+GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(
+ GrColor color,
+ const SkMatrix& viewMatrix,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
+ const GrSamplerState& params,
#ifdef SK_GAMMA_APPLY_TO_A8
- float distanceAdjust,
+ float distanceAdjust,
#endif
- uint32_t flags,
- bool usesLocalCoords)
+ uint32_t flags,
+ bool usesLocalCoords)
: fColor(color)
, fViewMatrix(viewMatrix)
- , fTextureSampler(std::move(proxy), params)
#ifdef SK_GAMMA_APPLY_TO_A8
, fDistanceAdjust(distanceAdjust)
#endif
@@ -253,7 +253,12 @@ GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color,
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
kHigh_GrSLPrecision);
- this->addTextureSampler(&fTextureSampler);
+ 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,
@@ -274,7 +279,12 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc);
sk_sp<GrGeometryProcessor> GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorTestData* d) {
int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
: GrProcessorUnitTest::kAlphaTextureIdx;
- sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
+ sk_sp<GrTextureProxy> proxies[kMaxTextures] = {
+ d->textureProxy(texIdx),
+ nullptr,
+ nullptr,
+ nullptr
+ };
GrSamplerState::WrapMode wrapModes[2];
GrTest::TestWrapModes(d->fRandom, wrapModes);
@@ -289,7 +299,7 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorT
}
return GrDistanceFieldA8TextGeoProc::Make(GrRandomColor(d->fRandom),
- GrTest::TestMatrix(d->fRandom), std::move(proxy),
+ GrTest::TestMatrix(d->fRandom), proxies,
samplerState,
#ifdef SK_GAMMA_APPLY_TO_A8
d->fRandom->nextF(),
@@ -474,15 +484,15 @@ private:
};
///////////////////////////////////////////////////////////////////////////////
-GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(GrColor color,
- const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
- const GrSamplerState& params,
- uint32_t flags,
- bool usesLocalCoords)
+GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
+ GrColor color,
+ const SkMatrix& viewMatrix,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
+ const GrSamplerState& params,
+ uint32_t flags,
+ bool usesLocalCoords)
: fColor(color)
, fViewMatrix(viewMatrix)
- , fTextureSampler(std::move(proxy), params)
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
, fInColor(nullptr)
, fUsesLocalCoords(usesLocalCoords) {
@@ -493,7 +503,12 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(GrColor color,
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
kHigh_GrSLPrecision);
- this->addTextureSampler(&fTextureSampler);
+ 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,
@@ -514,7 +529,12 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc);
sk_sp<GrGeometryProcessor> GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTestData* d) {
int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
: GrProcessorUnitTest::kAlphaTextureIdx;
- sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
+ sk_sp<GrTextureProxy> proxies[kMaxTextures] = {
+ d->textureProxy(texIdx),
+ nullptr,
+ nullptr,
+ nullptr
+ };
GrSamplerState::WrapMode wrapModes[2];
GrTest::TestWrapModes(d->fRandom, wrapModes);
@@ -530,7 +550,7 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTes
return GrDistanceFieldPathGeoProc::Make(GrRandomColor(d->fRandom),
GrTest::TestMatrix(d->fRandom),
- std::move(proxy),
+ proxies,
samplerState,
flags,
d->fRandom->nextBool());
@@ -776,15 +796,15 @@ private:
};
///////////////////////////////////////////////////////////////////////////////
-GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(GrColor color,
- const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
- const GrSamplerState& params,
- DistanceAdjust distanceAdjust,
- uint32_t flags, bool usesLocalCoords)
+GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(
+ GrColor color,
+ const SkMatrix& viewMatrix,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
+ const GrSamplerState& params,
+ DistanceAdjust distanceAdjust,
+ uint32_t flags, bool usesLocalCoords)
: fColor(color)
, fViewMatrix(viewMatrix)
- , fTextureSampler(std::move(proxy), params)
, fDistanceAdjust(distanceAdjust)
, fFlags(flags & kLCD_DistanceFieldEffectMask)
, fUsesLocalCoords(usesLocalCoords) {
@@ -795,7 +815,12 @@ GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(GrColor color,
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
kHigh_GrSLPrecision);
- this->addTextureSampler(&fTextureSampler);
+ 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,
@@ -815,7 +840,12 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc);
sk_sp<GrGeometryProcessor> GrDistanceFieldLCDTextGeoProc::TestCreate(GrProcessorTestData* d) {
int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
GrProcessorUnitTest::kAlphaTextureIdx;
- sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
+ sk_sp<GrTextureProxy> proxies[kMaxTextures] = {
+ d->textureProxy(texIdx),
+ nullptr,
+ nullptr,
+ nullptr
+ };
GrSamplerState::WrapMode wrapModes[2];
GrTest::TestWrapModes(d->fRandom, wrapModes);
@@ -830,7 +860,7 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldLCDTextGeoProc::TestCreate(GrProcessor
}
flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
return GrDistanceFieldLCDTextGeoProc::Make(GrRandomColor(d->fRandom),
- GrTest::TestMatrix(d->fRandom), std::move(proxy),
+ GrTest::TestMatrix(d->fRandom), proxies,
samplerState, wa, flags, d->fRandom->nextBool());
}
#endif
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.h b/src/gpu/effects/GrDistanceFieldGeoProc.h
index b1836dd9bb..b5c6f9eea6 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.h
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.h
@@ -50,22 +50,24 @@ enum GrDistanceFieldEffectFlags {
*/
class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor {
public:
+ static constexpr int kMaxTextures = 4;
+
#ifdef SK_GAMMA_APPLY_TO_A8
static sk_sp<GrGeometryProcessor> Make(GrColor color, const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params, float lum, uint32_t flags,
bool usesLocalCoords) {
return sk_sp<GrGeometryProcessor>(
- new GrDistanceFieldA8TextGeoProc(color, viewMatrix, std::move(proxy),
+ new GrDistanceFieldA8TextGeoProc(color, viewMatrix, proxies,
params, lum, flags, usesLocalCoords));
}
#else
static sk_sp<GrGeometryProcessor> Make(GrColor color, const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params, uint32_t flags,
bool usesLocalCoords) {
return sk_sp<GrGeometryProcessor>(
- new GrDistanceFieldA8TextGeoProc(color, viewMatrix, std::move(proxy),
+ new GrDistanceFieldA8TextGeoProc(color, viewMatrix, proxies,
params, flags, usesLocalCoords));
}
#endif
@@ -90,7 +92,8 @@ public:
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
private:
- GrDistanceFieldA8TextGeoProc(GrColor, const SkMatrix& viewMatrix, sk_sp<GrTextureProxy> proxy,
+ GrDistanceFieldA8TextGeoProc(GrColor, const SkMatrix& viewMatrix,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params,
#ifdef SK_GAMMA_APPLY_TO_A8
float distanceAdjust,
@@ -99,7 +102,7 @@ private:
GrColor fColor;
SkMatrix fViewMatrix;
- TextureSampler fTextureSampler;
+ TextureSampler fTextureSamplers[kMaxTextures];
#ifdef SK_GAMMA_APPLY_TO_A8
float fDistanceAdjust;
#endif
@@ -122,12 +125,14 @@ private:
*/
class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
public:
+ static constexpr int kMaxTextures = 4;
+
static sk_sp<GrGeometryProcessor> Make(GrColor color, const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params, uint32_t flags,
bool usesLocalCoords) {
return sk_sp<GrGeometryProcessor>(
- new GrDistanceFieldPathGeoProc(color, viewMatrix, std::move(proxy),
+ new GrDistanceFieldPathGeoProc(color, viewMatrix, proxies,
params, flags, usesLocalCoords));
}
@@ -148,12 +153,13 @@ public:
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
private:
- GrDistanceFieldPathGeoProc(GrColor, const SkMatrix& viewMatrix, sk_sp<GrTextureProxy>,
+ GrDistanceFieldPathGeoProc(GrColor, const SkMatrix& viewMatrix,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState&, uint32_t flags, bool usesLocalCoords);
GrColor fColor;
SkMatrix fViewMatrix;
- TextureSampler fTextureSampler;
+ TextureSampler fTextureSamplers[kMaxTextures];
uint32_t fFlags;
const Attribute* fInPosition;
const Attribute* fInColor;
@@ -188,15 +194,17 @@ public:
}
};
+ static constexpr int kMaxTextures = 4;
+
static sk_sp<GrGeometryProcessor> Make(GrColor color,
const SkMatrix& viewMatrix,
- sk_sp<GrTextureProxy> proxy,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params,
DistanceAdjust distanceAdjust,
uint32_t flags,
bool usesLocalCoords) {
return sk_sp<GrGeometryProcessor>(
- new GrDistanceFieldLCDTextGeoProc(color, viewMatrix, std::move(proxy),
+ new GrDistanceFieldLCDTextGeoProc(color, viewMatrix, proxies,
params, distanceAdjust,
flags, usesLocalCoords));
}
@@ -219,13 +227,14 @@ public:
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
private:
- GrDistanceFieldLCDTextGeoProc(GrColor, const SkMatrix& viewMatrix, sk_sp<GrTextureProxy> proxy,
+ GrDistanceFieldLCDTextGeoProc(GrColor, const SkMatrix& viewMatrix,
+ const sk_sp<GrTextureProxy> proxies[kMaxTextures],
const GrSamplerState& params, DistanceAdjust wa, uint32_t flags,
bool usesLocalCoords);
GrColor fColor;
SkMatrix fViewMatrix;
- TextureSampler fTextureSampler;
+ TextureSampler fTextureSamplers[kMaxTextures];
DistanceAdjust fDistanceAdjust;
uint32_t fFlags;
const Attribute* fInPosition;
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index bfdbfdbeeb..c6ceaac005 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -84,8 +84,8 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
return;
}
- sk_sp<GrTextureProxy> proxy = fFontCache->getProxy(this->maskFormat());
- if (!proxy) {
+ const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(this->maskFormat());
+ if (!proxies[0]) {
SkDebugf("Could not allocate backing texture for atlas\n");
return;
}
@@ -98,10 +98,10 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
if (this->usesDistanceFields()) {
flushInfo.fGeometryProcessor =
this->setupDfProcessor(this->viewMatrix(),
- fLuminanceColor, this->color(), std::move(proxy));
+ fLuminanceColor, this->color(), proxies);
} else {
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
- this->color(), std::move(proxy), GrSamplerState::ClampNearest(), maskFormat,
+ this->color(), proxies, GrSamplerState::ClampNearest(), maskFormat,
localMatrix, this->usesLocalCoords());
}
@@ -218,10 +218,11 @@ bool GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
// TODO just use class params
// TODO trying to figure out why lcd is so whack
-sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(const SkMatrix& viewMatrix,
- SkColor luminanceColor,
- GrColor color,
- sk_sp<GrTextureProxy> proxy) const {
+sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(
+ const SkMatrix& viewMatrix,
+ SkColor luminanceColor,
+ GrColor color,
+ const sk_sp<GrTextureProxy> p[kMaxTextures]) const {
bool isLCD = this->isLCD();
// set up any flags
uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
@@ -247,7 +248,7 @@ sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(const SkMatrix& viewM
GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(
redCorrection, greenCorrection, blueCorrection);
- return GrDistanceFieldLCDTextGeoProc::Make(color, viewMatrix, std::move(proxy),
+ return GrDistanceFieldLCDTextGeoProc::Make(color, viewMatrix, p,
GrSamplerState::ClampBilerp(), widthAdjust,
flags, this->usesLocalCoords());
} else {
@@ -258,11 +259,11 @@ sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(const SkMatrix& viewM
correction = fDistanceAdjustTable->getAdjustment(lum >> kDistanceAdjustLumShift,
fUseGammaCorrectDistanceTable);
}
- return GrDistanceFieldA8TextGeoProc::Make(color, viewMatrix, std::move(proxy),
+ return GrDistanceFieldA8TextGeoProc::Make(color, viewMatrix, p,
GrSamplerState::ClampBilerp(), correction, flags,
this->usesLocalCoords());
#else
- return GrDistanceFieldA8TextGeoProc::Make(color, viewMatrix, std::move(proxy),
+ return GrDistanceFieldA8TextGeoProc::Make(color, viewMatrix, p,
GrSamplerState::ClampBilerp(), flags,
this->usesLocalCoords());
#endif
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index 5c37d45ea2..58e0515127 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -159,9 +159,12 @@ private:
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override;
+ static constexpr auto kMaxTextures = 4;
+
// TODO just use class params
sk_sp<GrGeometryProcessor> setupDfProcessor(const SkMatrix& viewMatrix, SkColor luminanceColor,
- GrColor color, sk_sp<GrTextureProxy> proxy) const;
+ GrColor color,
+ const sk_sp<GrTextureProxy> [kMaxTextures]) const;
// The minimum number of Geometry we will try to allocate.
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index ec63e9ec7d..1c3cbe90fb 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -234,7 +234,7 @@ private:
flags |= fGammaCorrect ? kGammaCorrect_DistanceFieldEffectFlag : 0;
flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make(
- this->color(), this->viewMatrix(), atlas->getProxy(),
+ this->color(), this->viewMatrix(), atlas->getProxies(),
GrSamplerState::ClampBilerp(), flags, fHelper.usesLocalCoords());
} else {
SkMatrix invert;
@@ -249,7 +249,7 @@ private:
}
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
- this->color(), atlas->getProxy(), GrSamplerState::ClampNearest(),
+ this->color(), atlas->getProxies(), GrSamplerState::ClampNearest(),
kA8_GrMaskFormat, invert, fHelper.usesLocalCoords());
}
diff --git a/src/gpu/text/GrAtlasGlyphCache.cpp b/src/gpu/text/GrAtlasGlyphCache.cpp
index 7456a8e4dc..1cf704a10e 100644
--- a/src/gpu/text/GrAtlasGlyphCache.cpp
+++ b/src/gpu/text/GrAtlasGlyphCache.cpp
@@ -176,16 +176,18 @@ void GrAtlasGlyphCache::dump() const {
static int gDumpCount = 0;
for (int i = 0; i < kMaskFormatCount; ++i) {
if (fAtlases[i]) {
- sk_sp<GrTextureProxy> proxy = fAtlases[i]->getProxy();
- if (proxy) {
- SkString filename;
+ const sk_sp<GrTextureProxy>* proxies = fAtlases[i]->getProxies();
+ for (int pageIdx = 0; pageIdx < GrDrawOpAtlas::kMaxPages; ++pageIdx) {
+ if (proxies[pageIdx]) {
+ SkString filename;
#ifdef SK_BUILD_FOR_ANDROID
- filename.printf("/sdcard/fontcache_%d%d.png", gDumpCount, i);
+ filename.printf("/sdcard/fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
#else
- filename.printf("fontcache_%d%d.png", gDumpCount, i);
+ filename.printf("fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
#endif
- save_pixels(fContext, proxy.get(), filename.c_str());
+ save_pixels(fContext, proxies[pageIdx].get(), filename.c_str());
+ }
}
}
}
diff --git a/src/gpu/text/GrAtlasGlyphCache.h b/src/gpu/text/GrAtlasGlyphCache.h
index 167830fb99..81876a01d9 100644
--- a/src/gpu/text/GrAtlasGlyphCache.h
+++ b/src/gpu/text/GrAtlasGlyphCache.h
@@ -129,9 +129,9 @@ public:
// 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.
- sk_sp<GrTextureProxy> getProxy(GrMaskFormat format) {
+ const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format) {
if (this->initAtlas(format)) {
- return this->getAtlas(format)->getProxy();
+ return this->getAtlas(format)->getProxies();
}
return nullptr;
}