Consolidate the conversion of plot location to uvs to be w/in GrDrawOpAtlas
Bug: 1056730 Change-Id: Icb3e8e32585d1abc38205e1baf86b5a5291c8d8a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281196 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
9b56cea5fa
commit
6d3bc2951d
@ -24,6 +24,20 @@
|
||||
static bool gDumpAtlasData = false;
|
||||
#endif
|
||||
|
||||
std::array<uint16_t, 4> GrDrawOpAtlas::AtlasLocator::getUVs(int padding) const {
|
||||
|
||||
uint16_t left = fRect.fLeft + padding;
|
||||
uint16_t top = fRect.fTop + padding;
|
||||
uint16_t right = fRect.fRight - padding;
|
||||
uint16_t bottom = fRect.fBottom - padding;
|
||||
|
||||
// We pack the 2bit page index in the low bit of the u and v texture coords
|
||||
uint32_t pageIndex = this->pageIndex();
|
||||
std::tie(left, bottom) = GrDrawOpAtlas::PackIndexInTexCoords(left, bottom, pageIndex);
|
||||
std::tie(right, top) = GrDrawOpAtlas::PackIndexInTexCoords(right, top, pageIndex);
|
||||
return { left, top, right, bottom };
|
||||
}
|
||||
|
||||
// When proxy allocation is deferred until flush time the proxies acting as atlases require
|
||||
// special handling. This is because the usage that can be determined from the ops themselves
|
||||
// isn't sufficient. Independent of the ops there will be ASAP and inline uploads to the
|
||||
@ -125,13 +139,16 @@ GrDrawOpAtlas::Plot::~Plot() {
|
||||
sk_free(fData);
|
||||
}
|
||||
|
||||
bool GrDrawOpAtlas::Plot::addSubImage(int width, int height, const void* image, SkIPoint16* loc) {
|
||||
bool GrDrawOpAtlas::Plot::addSubImage(int width, int height, const void* image, GrIRect16* rect) {
|
||||
SkASSERT(width <= fWidth && height <= fHeight);
|
||||
|
||||
if (!fRectanizer.addRect(width, height, loc)) {
|
||||
SkIPoint16 loc;
|
||||
if (!fRectanizer.addRect(width, height, &loc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*rect = GrIRect16::MakeXYWH(loc.fX, loc.fY, width, height);
|
||||
|
||||
if (!fData) {
|
||||
fData = reinterpret_cast<unsigned char*>(sk_calloc_throw(fBytesPerPixel * fWidth *
|
||||
fHeight));
|
||||
@ -140,8 +157,8 @@ bool GrDrawOpAtlas::Plot::addSubImage(int width, int height, const void* image,
|
||||
const unsigned char* imagePtr = (const unsigned char*)image;
|
||||
// point ourselves at the right starting spot
|
||||
unsigned char* dataPtr = fData;
|
||||
dataPtr += fBytesPerPixel * fWidth * loc->fY;
|
||||
dataPtr += fBytesPerPixel * loc->fX;
|
||||
dataPtr += fBytesPerPixel * fWidth * rect->fTop;
|
||||
dataPtr += fBytesPerPixel * rect->fLeft;
|
||||
// copy into the data buffer, swizzling as we go if this is ARGB data
|
||||
if (4 == fBytesPerPixel && kN32_SkColorType == kBGRA_8888_SkColorType) {
|
||||
for (int i = 0; i < height; ++i) {
|
||||
@ -157,10 +174,9 @@ bool GrDrawOpAtlas::Plot::addSubImage(int width, int height, const void* image,
|
||||
}
|
||||
}
|
||||
|
||||
fDirtyRect.join({loc->fX, loc->fY, loc->fX + width, loc->fY + height});
|
||||
fDirtyRect.join({rect->fLeft, rect->fTop, rect->fRight, rect->fBottom});
|
||||
|
||||
loc->fX += fOffset.fX;
|
||||
loc->fY += fOffset.fY;
|
||||
rect->offset(fOffset.fX, fOffset.fY);
|
||||
SkDEBUGCODE(fDirty = true;)
|
||||
|
||||
return true;
|
||||
@ -244,8 +260,8 @@ inline void GrDrawOpAtlas::processEviction(PlotLocator plotLocator) {
|
||||
}
|
||||
|
||||
inline bool GrDrawOpAtlas::updatePlot(GrDeferredUploadTarget* target,
|
||||
PlotLocator* plotLocator, Plot* plot) {
|
||||
int pageIdx = GetPageIndexFromID(plot->plotLocator());
|
||||
AtlasLocator* atlasLocator, Plot* plot) {
|
||||
int pageIdx = plot->pageIndex();
|
||||
this->makeMRU(plot, pageIdx);
|
||||
|
||||
// If our most recent upload has already occurred then we have to insert a new
|
||||
@ -264,13 +280,13 @@ inline bool GrDrawOpAtlas::updatePlot(GrDeferredUploadTarget* target,
|
||||
});
|
||||
plot->setLastUploadToken(lastUploadToken);
|
||||
}
|
||||
*plotLocator = plot->plotLocator();
|
||||
atlasLocator->fPlotLocator = plot->plotLocator();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrDrawOpAtlas::uploadToPage(const GrCaps& caps, unsigned int pageIdx, PlotLocator* plotLocator,
|
||||
bool GrDrawOpAtlas::uploadToPage(const GrCaps& caps, unsigned int pageIdx,
|
||||
GrDeferredUploadTarget* target, int width, int height,
|
||||
const void* image, SkIPoint16* loc) {
|
||||
const void* image, AtlasLocator* atlasLocator) {
|
||||
SkASSERT(fViews[pageIdx].proxy() && fViews[pageIdx].proxy()->isInstantiated());
|
||||
|
||||
// look through all allocated plots for one we can share, in Most Recently Refed order
|
||||
@ -280,8 +296,8 @@ bool GrDrawOpAtlas::uploadToPage(const GrCaps& caps, unsigned int pageIdx, PlotL
|
||||
for (Plot* plot = plotIter.get(); plot; plot = plotIter.next()) {
|
||||
SkASSERT(caps.bytesPerPixel(fViews[pageIdx].proxy()->backendFormat()) == plot->bpp());
|
||||
|
||||
if (plot->addSubImage(width, height, image, loc)) {
|
||||
return this->updatePlot(target, plotLocator, plot);
|
||||
if (plot->addSubImage(width, height, image, &atlasLocator->fRect)) {
|
||||
return this->updatePlot(target, atlasLocator, plot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,10 +314,9 @@ static constexpr auto kPlotRecentlyUsedCount = 256;
|
||||
static constexpr auto kAtlasRecentlyUsedCount = 1024;
|
||||
|
||||
GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider,
|
||||
PlotLocator* plotLocator,
|
||||
GrDeferredUploadTarget* target,
|
||||
int width, int height,
|
||||
const void* image, SkIPoint16* loc) {
|
||||
int width, int height, const void* image,
|
||||
AtlasLocator* atlasLocator) {
|
||||
if (width > fPlotWidth || height > fPlotHeight) {
|
||||
return ErrorCode::kError;
|
||||
}
|
||||
@ -312,7 +327,7 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP
|
||||
// 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 < fNumActivePages; ++pageIdx) {
|
||||
if (this->uploadToPage(caps, pageIdx, plotLocator, target, width, height, image, loc)) {
|
||||
if (this->uploadToPage(caps, pageIdx, target, width, height, image, atlasLocator)) {
|
||||
return ErrorCode::kSucceeded;
|
||||
}
|
||||
}
|
||||
@ -330,9 +345,10 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP
|
||||
this->processEvictionAndResetRects(plot);
|
||||
SkASSERT(caps.bytesPerPixel(fViews[pageIdx].proxy()->backendFormat()) ==
|
||||
plot->bpp());
|
||||
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
|
||||
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image,
|
||||
&atlasLocator->fRect);
|
||||
SkASSERT(verify);
|
||||
if (!this->updatePlot(target, plotLocator, plot)) {
|
||||
if (!this->updatePlot(target, atlasLocator, plot)) {
|
||||
return ErrorCode::kError;
|
||||
}
|
||||
return ErrorCode::kSucceeded;
|
||||
@ -344,8 +360,8 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP
|
||||
return ErrorCode::kError;
|
||||
}
|
||||
|
||||
if (this->uploadToPage(
|
||||
caps, fNumActivePages-1, plotLocator, target, width, height, image, loc)) {
|
||||
if (this->uploadToPage(caps, fNumActivePages-1, target, width, height, image,
|
||||
atlasLocator)) {
|
||||
return ErrorCode::kSucceeded;
|
||||
} else {
|
||||
// If we fail to upload to a newly activated page then something has gone terribly
|
||||
@ -379,14 +395,14 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP
|
||||
}
|
||||
|
||||
this->processEviction(plot->plotLocator());
|
||||
int pageIdx = GetPageIndexFromID(plot->plotLocator());
|
||||
int pageIdx = plot->pageIndex();
|
||||
fPages[pageIdx].fPlotList.remove(plot);
|
||||
sk_sp<Plot>& newPlot = fPages[pageIdx].fPlotArray[plot->index()];
|
||||
sk_sp<Plot>& newPlot = fPages[pageIdx].fPlotArray[plot->plotIndex()];
|
||||
newPlot.reset(plot->clone());
|
||||
|
||||
fPages[pageIdx].fPlotList.addToHead(newPlot.get());
|
||||
SkASSERT(caps.bytesPerPixel(fViews[pageIdx].proxy()->backendFormat()) == newPlot->bpp());
|
||||
SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, loc);
|
||||
SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, &atlasLocator->fRect);
|
||||
SkASSERT(verify);
|
||||
|
||||
// Note that this plot will be uploaded inline with the draws whereas the
|
||||
@ -403,7 +419,7 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP
|
||||
});
|
||||
newPlot->setLastUploadToken(lastUploadToken);
|
||||
|
||||
*plotLocator = newPlot->plotLocator();
|
||||
atlasLocator->fPlotLocator = newPlot->plotLocator();
|
||||
|
||||
return ErrorCode::kSucceeded;
|
||||
}
|
||||
|
@ -70,6 +70,40 @@ public:
|
||||
static const uint64_t kInvalidPlotLocator = 0;
|
||||
static const uint64_t kInvalidAtlasGeneration = 0;
|
||||
|
||||
class AtlasLocator {
|
||||
public:
|
||||
std::array<uint16_t, 4> getUVs(int padding) const;
|
||||
|
||||
// TODO: Remove the small path renderer's use of this for eviction
|
||||
GrDrawOpAtlas::PlotLocator plotLocator() const { return fPlotLocator; }
|
||||
|
||||
uint32_t pageIndex() const {
|
||||
uint32_t pageIndex = fPlotLocator & 0xff;
|
||||
SkASSERT(pageIndex < 4);
|
||||
return pageIndex;
|
||||
}
|
||||
|
||||
uint32_t plotIndex() const {
|
||||
uint32_t plotIndex = (fPlotLocator >> 8) & 0xff;
|
||||
SkASSERT(plotIndex < kMaxPlots);
|
||||
return plotIndex;
|
||||
}
|
||||
|
||||
uint64_t genID() const {
|
||||
// top 48 bits are reserved for the generation ID
|
||||
return (fPlotLocator >> 16) & 0xffffffffffff;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class GrDrawOpAtlas;
|
||||
|
||||
GrDrawOpAtlas::PlotLocator fPlotLocator{GrDrawOpAtlas::kInvalidPlotLocator};
|
||||
GrIRect16 fRect{0, 0, 0, 0};
|
||||
|
||||
// TODO: the inset to the actual data w/in 'fRect' could also be stored in this class
|
||||
// This would simplify the 'getUVs' call. The valid values would be 0, 1, 2 & 4.
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface for eviction callbacks. Whenever GrDrawOpAtlas evicts a
|
||||
* specific PlotLocator, it will call all of the registered listeners so they can process the
|
||||
@ -160,32 +194,31 @@ public:
|
||||
kTryAgain
|
||||
};
|
||||
|
||||
ErrorCode addToAtlas(GrResourceProvider*, PlotLocator*, GrDeferredUploadTarget*,
|
||||
int width, int height,
|
||||
const void* image, SkIPoint16* loc);
|
||||
ErrorCode addToAtlas(GrResourceProvider*, GrDeferredUploadTarget*,
|
||||
int width, int height, const void* image, AtlasLocator*);
|
||||
|
||||
const GrSurfaceProxyView* getViews() const { return fViews; }
|
||||
|
||||
uint64_t atlasGeneration() const { return fAtlasGeneration; }
|
||||
|
||||
bool hasID(PlotLocator plotLocator) {
|
||||
if (kInvalidPlotLocator == plotLocator) {
|
||||
bool hasID(const AtlasLocator& atlasLocator) {
|
||||
if (kInvalidPlotLocator == atlasLocator.fPlotLocator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t plot = GetPlotIndexFromID(plotLocator);
|
||||
uint32_t page = GetPageIndexFromID(plotLocator);
|
||||
uint32_t plot = atlasLocator.plotIndex();
|
||||
uint32_t page = atlasLocator.pageIndex();
|
||||
uint64_t plotGeneration = fPages[page].fPlotArray[plot]->genID();
|
||||
uint64_t locatorGeneration = GetGenerationFromID(plotLocator);
|
||||
uint64_t locatorGeneration = atlasLocator.genID();
|
||||
return plot < fNumPlots && page < fNumActivePages && plotGeneration == locatorGeneration;
|
||||
}
|
||||
|
||||
/** To ensure the atlas does not evict a given entry, the client must set the last use token. */
|
||||
void setLastUseToken(PlotLocator plotLocator, GrDeferredUploadToken token) {
|
||||
SkASSERT(this->hasID(plotLocator));
|
||||
uint32_t plotIdx = GetPlotIndexFromID(plotLocator);
|
||||
void setLastUseToken(const AtlasLocator& atlasLocator, GrDeferredUploadToken token) {
|
||||
SkASSERT(this->hasID(atlasLocator));
|
||||
uint32_t plotIdx = atlasLocator.plotIndex();
|
||||
SkASSERT(plotIdx < fNumPlots);
|
||||
uint32_t pageIdx = GetPageIndexFromID(plotLocator);
|
||||
uint32_t pageIdx = atlasLocator.pageIndex();
|
||||
SkASSERT(pageIdx < fNumActivePages);
|
||||
Plot* plot = fPages[pageIdx].fPlotArray[plotIdx].get();
|
||||
this->makeMRU(plot, pageIdx);
|
||||
@ -205,17 +238,17 @@ public:
|
||||
memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated));
|
||||
}
|
||||
BulkUseTokenUpdater(const BulkUseTokenUpdater& that)
|
||||
: fPlotsToUpdate(that.fPlotsToUpdate) {
|
||||
: fPlotsToUpdate(that.fPlotsToUpdate) {
|
||||
memcpy(fPlotAlreadyUpdated, that.fPlotAlreadyUpdated, sizeof(fPlotAlreadyUpdated));
|
||||
}
|
||||
|
||||
bool add(PlotLocator plotLocator) {
|
||||
int index = GrDrawOpAtlas::GetPlotIndexFromID(plotLocator);
|
||||
int pageIdx = GrDrawOpAtlas::GetPageIndexFromID(plotLocator);
|
||||
if (this->find(pageIdx, index)) {
|
||||
bool add(const AtlasLocator& atlasLocator) {
|
||||
int plotIdx = atlasLocator.plotIndex();
|
||||
int pageIdx = atlasLocator.pageIndex();
|
||||
if (this->find(pageIdx, plotIdx)) {
|
||||
return false;
|
||||
}
|
||||
this->set(pageIdx, index);
|
||||
this->set(pageIdx, plotIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -266,10 +299,6 @@ public:
|
||||
|
||||
void compact(GrDeferredUploadToken startTokenForNextFlush);
|
||||
|
||||
static uint32_t GetPageIndexFromID(PlotLocator plotLocator) {
|
||||
return plotLocator & 0xff;
|
||||
}
|
||||
|
||||
void instantiate(GrOnFlushResourceProvider*);
|
||||
|
||||
uint32_t maxPages() const {
|
||||
@ -295,8 +324,10 @@ private:
|
||||
SK_DECLARE_INTERNAL_LLIST_INTERFACE(Plot);
|
||||
|
||||
public:
|
||||
/** index() is a unique id for the plot relative to the owning GrAtlas and page. */
|
||||
uint32_t index() const { return fPlotIndex; }
|
||||
uint32_t pageIndex() const { return fPageIndex; }
|
||||
|
||||
/** plotIndex() is a unique id for the plot relative to the owning GrAtlas and page. */
|
||||
uint32_t plotIndex() 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.
|
||||
@ -308,7 +339,7 @@ private:
|
||||
}
|
||||
SkDEBUGCODE(size_t bpp() const { return fBytesPerPixel; })
|
||||
|
||||
bool addSubImage(int width, int height, const void* image, SkIPoint16* loc);
|
||||
bool addSubImage(int width, int height, const void* image, GrIRect16* rect);
|
||||
|
||||
/**
|
||||
* To manage the lifetime of a plot, we use two tokens. We use the last upload token to
|
||||
@ -384,16 +415,7 @@ private:
|
||||
|
||||
typedef SkTInternalLList<Plot> PlotList;
|
||||
|
||||
static uint32_t GetPlotIndexFromID(PlotLocator plotLocator) {
|
||||
return (plotLocator >> 8) & 0xff;
|
||||
}
|
||||
|
||||
// top 48 bits are reserved for the generation ID
|
||||
static uint64_t GetGenerationFromID(PlotLocator plotLocator) {
|
||||
return (plotLocator >> 16) & 0xffffffffffff;
|
||||
}
|
||||
|
||||
inline bool updatePlot(GrDeferredUploadTarget*, PlotLocator*, Plot*);
|
||||
inline bool updatePlot(GrDeferredUploadTarget*, AtlasLocator*, Plot*);
|
||||
|
||||
inline void makeMRU(Plot* plot, int pageIdx) {
|
||||
if (fPages[pageIdx].fPlotList.head() == plot) {
|
||||
@ -407,9 +429,8 @@ private:
|
||||
// the front and remove from the back there is no need for MRU.
|
||||
}
|
||||
|
||||
bool uploadToPage(const GrCaps&, unsigned int pageIdx, PlotLocator* plotLocator,
|
||||
GrDeferredUploadTarget* target, int width, int height, const void* image,
|
||||
SkIPoint16* loc);
|
||||
bool uploadToPage(const GrCaps&, unsigned int pageIdx, GrDeferredUploadTarget*,
|
||||
int width, int height, const void* image, AtlasLocator*);
|
||||
|
||||
bool createPages(GrProxyProvider*, GenerationCounter*);
|
||||
bool activateNewPage(GrResourceProvider*);
|
||||
|
@ -36,20 +36,10 @@ public:
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
GrGlyph(const SkGlyph& skGlyph)
|
||||
: fPackedID{skGlyph.getPackedID()}
|
||||
, fWidthHeight(SkIPoint16::Make(skGlyph.width(), skGlyph.height())) {
|
||||
}
|
||||
GrGlyph(const SkGlyph& skGlyph) : fPackedID(skGlyph.getPackedID()) {}
|
||||
|
||||
int width() const { return fWidthHeight.fX; }
|
||||
int height() const { return fWidthHeight.fY; }
|
||||
uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fPlotLocator); }
|
||||
|
||||
const SkPackedGlyphID fPackedID;
|
||||
const SkIPoint16 fWidthHeight{0, 0};
|
||||
|
||||
SkIPoint16 fAtlasLocation{0, 0};
|
||||
GrDrawOpAtlas::PlotLocator fPlotLocator{GrDrawOpAtlas::kInvalidPlotLocator};
|
||||
const SkPackedGlyphID fPackedID;
|
||||
GrDrawOpAtlas::AtlasLocator fAtlasLocator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -124,6 +124,10 @@ struct GrVertexWriter {
|
||||
return { r.fLeft, r.fTop, r.fRight, r.fBottom };
|
||||
}
|
||||
|
||||
static TriStrip<uint16_t> TriStripFromUVs(const std::array<uint16_t, 4>& rect) {
|
||||
return { rect[0], rect[1], rect[2], rect[3] };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct TriFan { T l, t, r, b; };
|
||||
|
||||
|
@ -60,6 +60,13 @@ struct GrIRect16 {
|
||||
fRight = SkToS16(r.fRight);
|
||||
fBottom = SkToS16(r.fBottom);
|
||||
}
|
||||
|
||||
void offset(int16_t dx, int16_t dy) {
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight += dx;
|
||||
fBottom += dy;
|
||||
}
|
||||
};
|
||||
|
||||
/** Returns true if the rectangles have a nonzero area of overlap. It assumed that rects can be
|
||||
|
@ -116,10 +116,10 @@ private:
|
||||
|
||||
class ShapeData {
|
||||
public:
|
||||
ShapeDataKey fKey;
|
||||
GrDrawOpAtlas::PlotLocator fPlotLocator;
|
||||
SkRect fBounds;
|
||||
GrIRect16 fTextureCoords;
|
||||
ShapeDataKey fKey;
|
||||
SkRect fBounds;
|
||||
GrDrawOpAtlas::AtlasLocator fAtlasLocator;
|
||||
|
||||
SK_DECLARE_INTERNAL_LLIST_INTERFACE(ShapeData);
|
||||
|
||||
static inline const ShapeDataKey& GetKey(const ShapeData& data) {
|
||||
@ -141,7 +141,7 @@ void GrSmallPathRenderer::evict(GrDrawOpAtlas::PlotLocator plotLocator) {
|
||||
ShapeData* shapeData;
|
||||
while ((shapeData = iter.get())) {
|
||||
iter.next();
|
||||
if (plotLocator == shapeData->fPlotLocator) {
|
||||
if (plotLocator == shapeData->fAtlasLocator.plotLocator()) {
|
||||
fShapeCache.remove(shapeData->fKey);
|
||||
fShapeList.remove(shapeData);
|
||||
delete shapeData;
|
||||
@ -214,7 +214,7 @@ GrPathRenderer::CanDrawPath GrSmallPathRenderer::onCanDrawPath(const CanDrawPath
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// padding around path bounds to allow for antialiased pixels
|
||||
static const SkScalar kAntiAliasPad = 1.0f;
|
||||
static const int kAntiAliasPad = 1;
|
||||
|
||||
class GrSmallPathRenderer::SmallPathOp final : public GrMeshDrawOp {
|
||||
private:
|
||||
@ -458,7 +458,7 @@ private:
|
||||
// check to see if df path is cached
|
||||
ShapeDataKey key(args.fShape, SkScalarCeilToInt(desiredDimension));
|
||||
shapeData = fShapeCache->find(key);
|
||||
if (nullptr == shapeData || !fAtlas->hasID(shapeData->fPlotLocator)) {
|
||||
if (nullptr == shapeData || !fAtlas->hasID(shapeData->fAtlasLocator)) {
|
||||
// Remove the stale cache entry
|
||||
if (shapeData) {
|
||||
fShapeCache->remove(shapeData->fKey);
|
||||
@ -483,7 +483,7 @@ private:
|
||||
// check to see if bitmap path is cached
|
||||
ShapeDataKey key(args.fShape, args.fViewMatrix);
|
||||
shapeData = fShapeCache->find(key);
|
||||
if (nullptr == shapeData || !fAtlas->hasID(shapeData->fPlotLocator)) {
|
||||
if (nullptr == shapeData || !fAtlas->hasID(shapeData->fAtlasLocator)) {
|
||||
// Remove the stale cache entry
|
||||
if (shapeData) {
|
||||
fShapeCache->remove(shapeData->fKey);
|
||||
@ -506,7 +506,7 @@ private:
|
||||
|
||||
auto uploadTarget = target->deferredUploadTarget();
|
||||
fAtlas->setLastUseToken(
|
||||
shapeData->fPlotLocator, uploadTarget->tokenTracker()->nextDrawToken());
|
||||
shapeData->fAtlasLocator, uploadTarget->tokenTracker()->nextDrawToken());
|
||||
|
||||
this->writePathVertices(fAtlas, vertices, GrVertexColor(args.fColor, fWideColor),
|
||||
args.fViewMatrix, shapeData);
|
||||
@ -518,13 +518,12 @@ private:
|
||||
|
||||
bool addToAtlas(GrMeshDrawOp::Target* target, FlushInfo* flushInfo, GrDrawOpAtlas* atlas,
|
||||
int width, int height, const void* image,
|
||||
GrDrawOpAtlas::PlotLocator* plotLocator, SkIPoint16* atlasLocation) const {
|
||||
GrDrawOpAtlas::AtlasLocator* atlasLocator) const {
|
||||
auto resourceProvider = target->resourceProvider();
|
||||
auto uploadTarget = target->deferredUploadTarget();
|
||||
|
||||
GrDrawOpAtlas::ErrorCode code = atlas->addToAtlas(resourceProvider, plotLocator,
|
||||
uploadTarget, width, height,
|
||||
image, atlasLocation);
|
||||
GrDrawOpAtlas::ErrorCode code = atlas->addToAtlas(resourceProvider, uploadTarget,
|
||||
width, height, image, atlasLocator);
|
||||
if (GrDrawOpAtlas::ErrorCode::kError == code) {
|
||||
return false;
|
||||
}
|
||||
@ -532,8 +531,8 @@ private:
|
||||
if (GrDrawOpAtlas::ErrorCode::kTryAgain == code) {
|
||||
this->flush(target, flushInfo);
|
||||
|
||||
code = atlas->addToAtlas(resourceProvider, plotLocator, uploadTarget, width, height,
|
||||
image, atlasLocation);
|
||||
code = atlas->addToAtlas(resourceProvider, uploadTarget, width, height,
|
||||
image, atlasLocator);
|
||||
}
|
||||
|
||||
return GrDrawOpAtlas::ErrorCode::kSucceeded == code;
|
||||
@ -560,14 +559,12 @@ private:
|
||||
// get integer boundary
|
||||
SkIRect devPathBounds;
|
||||
scaledBounds.roundOut(&devPathBounds);
|
||||
// pad to allow room for antialiasing
|
||||
const int intPad = SkScalarCeilToInt(kAntiAliasPad);
|
||||
// place devBounds at origin
|
||||
int width = devPathBounds.width() + 2*intPad;
|
||||
int height = devPathBounds.height() + 2*intPad;
|
||||
// place devBounds at origin with padding to allow room for antialiasing
|
||||
int width = devPathBounds.width() + 2 * kAntiAliasPad;
|
||||
int height = devPathBounds.height() + 2 * kAntiAliasPad;
|
||||
devPathBounds = SkIRect::MakeWH(width, height);
|
||||
SkScalar translateX = intPad - dx;
|
||||
SkScalar translateY = intPad - dy;
|
||||
SkScalar translateX = kAntiAliasPad - dx;
|
||||
SkScalar translateY = kAntiAliasPad - dy;
|
||||
|
||||
// draw path to bitmap
|
||||
SkMatrix drawMatrix;
|
||||
@ -623,17 +620,13 @@ private:
|
||||
}
|
||||
|
||||
// add to atlas
|
||||
SkIPoint16 atlasLocation;
|
||||
GrDrawOpAtlas::PlotLocator plotLocator;
|
||||
|
||||
if (!this->addToAtlas(target, flushInfo, atlas,
|
||||
width, height, dfStorage.get(), &plotLocator, &atlasLocation)) {
|
||||
if (!this->addToAtlas(target, flushInfo, atlas, width, height, dfStorage.get(),
|
||||
&shapeData->fAtlasLocator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// add to cache
|
||||
shapeData->fKey.set(shape, dimension);
|
||||
shapeData->fPlotLocator = plotLocator;
|
||||
|
||||
shapeData->fBounds = SkRect::Make(devPathBounds);
|
||||
shapeData->fBounds.offset(-translateX, -translateY);
|
||||
@ -642,20 +635,6 @@ private:
|
||||
shapeData->fBounds.fRight /= scale;
|
||||
shapeData->fBounds.fBottom /= scale;
|
||||
|
||||
// Pack the page index into the u and v texture coords
|
||||
uint16_t pageIndex = GrDrawOpAtlas::GetPageIndexFromID(plotLocator);
|
||||
uint16_t left, top, right, bottom;
|
||||
std::tie(left, top, right, bottom) =
|
||||
std::make_tuple(atlasLocation.fX + SK_DistanceFieldPad,
|
||||
atlasLocation.fY + SK_DistanceFieldPad,
|
||||
atlasLocation.fX + SK_DistanceFieldPad + devPathBounds.width(),
|
||||
atlasLocation.fY + SK_DistanceFieldPad + devPathBounds.height());
|
||||
std::tie(left, top) =
|
||||
GrDrawOpAtlas::PackIndexInTexCoords(left, top, pageIndex);
|
||||
std::tie(right, bottom) =
|
||||
GrDrawOpAtlas::PackIndexInTexCoords(right, bottom, pageIndex);
|
||||
shapeData->fTextureCoords.set(left, top, right, bottom);
|
||||
|
||||
fShapeCache->add(shapeData);
|
||||
fShapeList->addToTail(shapeData);
|
||||
#ifdef DF_PATH_TRACKING
|
||||
@ -686,14 +665,12 @@ private:
|
||||
// get integer boundary
|
||||
SkIRect devPathBounds;
|
||||
shapeDevBounds.roundOut(&devPathBounds);
|
||||
// pad to allow room for antialiasing
|
||||
const int intPad = SkScalarCeilToInt(kAntiAliasPad);
|
||||
// place devBounds at origin
|
||||
int width = devPathBounds.width() + 2 * intPad;
|
||||
int height = devPathBounds.height() + 2 * intPad;
|
||||
// place devBounds at origin with padding to allow room for antialiasing
|
||||
int width = devPathBounds.width() + 2 * kAntiAliasPad;
|
||||
int height = devPathBounds.height() + 2 * kAntiAliasPad;
|
||||
devPathBounds = SkIRect::MakeWH(width, height);
|
||||
SkScalar translateX = intPad - dx;
|
||||
SkScalar translateY = intPad - dy;
|
||||
SkScalar translateX = kAntiAliasPad - dx;
|
||||
SkScalar translateY = kAntiAliasPad - dy;
|
||||
|
||||
SkASSERT(devPathBounds.fLeft == 0);
|
||||
SkASSERT(devPathBounds.fTop == 0);
|
||||
@ -727,33 +704,17 @@ private:
|
||||
draw.drawPathCoverage(path, paint);
|
||||
|
||||
// add to atlas
|
||||
SkIPoint16 atlasLocation;
|
||||
GrDrawOpAtlas::PlotLocator plotLocator;
|
||||
|
||||
if (!this->addToAtlas(target, flushInfo, atlas, dst.width(), dst.height(),
|
||||
dst.addr(), &plotLocator, &atlasLocation)) {
|
||||
if (!this->addToAtlas(target, flushInfo, atlas, dst.width(), dst.height(), dst.addr(),
|
||||
&shapeData->fAtlasLocator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// add to cache
|
||||
shapeData->fKey.set(shape, ctm);
|
||||
shapeData->fPlotLocator = plotLocator;
|
||||
|
||||
shapeData->fBounds = SkRect::Make(devPathBounds);
|
||||
shapeData->fBounds.offset(-translateX, -translateY);
|
||||
|
||||
// Pack the page index into the u and v texture coords
|
||||
uint16_t pageIndex = GrDrawOpAtlas::GetPageIndexFromID(plotLocator);
|
||||
uint16_t left, top, right, bottom;
|
||||
std::tie(left, top, right, bottom) = std::make_tuple(atlasLocation.fX, atlasLocation.fY,
|
||||
atlasLocation.fX+width,
|
||||
atlasLocation.fY+height);
|
||||
std::tie(left, top) =
|
||||
GrDrawOpAtlas::PackIndexInTexCoords(left, top, pageIndex);
|
||||
std::tie(right, bottom) =
|
||||
GrDrawOpAtlas::PackIndexInTexCoords(right, bottom, pageIndex);
|
||||
shapeData->fTextureCoords.set(left, top, right, bottom);
|
||||
|
||||
fShapeCache->add(shapeData);
|
||||
fShapeList->addToTail(shapeData);
|
||||
#ifdef DF_PATH_TRACKING
|
||||
@ -774,12 +735,8 @@ private:
|
||||
}
|
||||
|
||||
// set up texture coordinates
|
||||
GrVertexWriter::TriStrip<uint16_t> texCoords{
|
||||
(uint16_t)shapeData->fTextureCoords.fLeft,
|
||||
(uint16_t)shapeData->fTextureCoords.fTop,
|
||||
(uint16_t)shapeData->fTextureCoords.fRight,
|
||||
(uint16_t)shapeData->fTextureCoords.fBottom
|
||||
};
|
||||
auto texCoords = GrVertexWriter::TriStripFromUVs(shapeData->fAtlasLocator.getUVs(
|
||||
fUsesDistanceField ? SK_DistanceFieldPad : 0));
|
||||
|
||||
if (fUsesDistanceField && !ctm.hasPerspective()) {
|
||||
vertices.writeQuad(GrQuad::MakeFromRect(translatedBounds, ctm),
|
||||
@ -959,7 +916,7 @@ struct GrSmallPathRenderer::PathTestStruct : public GrDrawOpAtlas::EvictionCallb
|
||||
ShapeData* shapeData;
|
||||
while ((shapeData = iter.get())) {
|
||||
iter.next();
|
||||
if (plotLocator == shapeData->fPlotLocator) {
|
||||
if (plotLocator == shapeData->fAtlasLocator.plotLocator()) {
|
||||
fShapeCache.remove(shapeData->fKey);
|
||||
fShapeList.remove(shapeData);
|
||||
delete shapeData;
|
||||
|
@ -30,25 +30,25 @@ void GrAtlasManager::freeAll() {
|
||||
|
||||
bool GrAtlasManager::hasGlyph(GrMaskFormat format, GrGlyph* glyph) {
|
||||
SkASSERT(glyph);
|
||||
return this->getAtlas(format)->hasID(glyph->fPlotLocator);
|
||||
return this->getAtlas(format)->hasID(glyph->fAtlasLocator);
|
||||
}
|
||||
|
||||
// add to texture atlas that matches this format
|
||||
GrDrawOpAtlas::ErrorCode GrAtlasManager::addToAtlas(
|
||||
GrResourceProvider* resourceProvider,
|
||||
GrDrawOpAtlas::PlotLocator* plotLocator,
|
||||
GrDeferredUploadTarget* target, GrMaskFormat format,
|
||||
int width, int height, const void* image, SkIPoint16* loc) {
|
||||
GrDrawOpAtlas::ErrorCode GrAtlasManager::addToAtlas(GrResourceProvider* resourceProvider,
|
||||
GrDeferredUploadTarget* target,
|
||||
GrMaskFormat format,
|
||||
int width, int height, const void* image,
|
||||
GrDrawOpAtlas::AtlasLocator* atlasLocator) {
|
||||
return this->getAtlas(format)->addToAtlas(
|
||||
resourceProvider, plotLocator, target, width, height, image, loc);
|
||||
resourceProvider, target, width, height, image, atlasLocator);
|
||||
}
|
||||
|
||||
void GrAtlasManager::addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater* updater,
|
||||
GrMaskFormat format, GrGlyph* glyph,
|
||||
GrDeferredUploadToken token) {
|
||||
SkASSERT(glyph);
|
||||
if (updater->add(glyph->fPlotLocator)) {
|
||||
this->getAtlas(format)->setLastUseToken(glyph->fPlotLocator, token);
|
||||
if (updater->add(glyph->fAtlasLocator)) {
|
||||
this->getAtlas(format)->setLastUseToken(glyph->fAtlasLocator, token);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,10 +74,9 @@ public:
|
||||
}
|
||||
|
||||
// add to texture atlas that matches this format
|
||||
GrDrawOpAtlas::ErrorCode addToAtlas(
|
||||
GrResourceProvider*,
|
||||
GrDrawOpAtlas::PlotLocator*, GrDeferredUploadTarget*, GrMaskFormat,
|
||||
int width, int height, const void* image, SkIPoint16* loc);
|
||||
GrDrawOpAtlas::ErrorCode addToAtlas(GrResourceProvider*, GrDeferredUploadTarget*, GrMaskFormat,
|
||||
int width, int height, const void* image,
|
||||
GrDrawOpAtlas::AtlasLocator*);
|
||||
|
||||
// Some clients may wish to verify the integrity of the texture backing store of the
|
||||
// GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
|
||||
|
@ -141,32 +141,31 @@ GrTextStrike::GrTextStrike(const SkDescriptor& key)
|
||||
|
||||
GrDrawOpAtlas::ErrorCode GrTextStrike::addGlyphToAtlas(const SkGlyph& skGlyph,
|
||||
GrMaskFormat expectedMaskFormat,
|
||||
bool isScaledGlyph,
|
||||
bool needsPadding,
|
||||
GrResourceProvider* resourceProvider,
|
||||
GrDeferredUploadTarget* target,
|
||||
GrAtlasManager* fullAtlasManager,
|
||||
GrGlyph* grGlyph) {
|
||||
SkASSERT(grGlyph != nullptr);
|
||||
SkASSERT(fCache.findOrNull(grGlyph->fPackedID));
|
||||
SkASSERT(grGlyph->width() == skGlyph.width());
|
||||
SkASSERT(grGlyph->height() == skGlyph.height());
|
||||
SkASSERT(skGlyph.image() != nullptr);
|
||||
|
||||
expectedMaskFormat = fullAtlasManager->resolveMaskFormat(expectedMaskFormat);
|
||||
int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
|
||||
|
||||
bool isSDFGlyph = skGlyph.maskFormat() == SkMask::kSDF_Format;
|
||||
SkDEBUGCODE(bool isSDFGlyph = skGlyph.maskFormat() == SkMask::kSDF_Format;)
|
||||
SkASSERT(!needsPadding || !isSDFGlyph);
|
||||
|
||||
// Add 1 pixel padding around grGlyph if needed.
|
||||
bool addPad = isScaledGlyph && !isSDFGlyph;
|
||||
const int width = addPad ? skGlyph.width() + 2 : skGlyph.width();
|
||||
const int height = addPad ? skGlyph.height() + 2 : skGlyph.height();
|
||||
const int width = needsPadding ? skGlyph.width() + 2 : skGlyph.width();
|
||||
const int height = needsPadding ? skGlyph.height() + 2 : skGlyph.height();
|
||||
int rowBytes = width * bytesPerPixel;
|
||||
size_t size = height * rowBytes;
|
||||
|
||||
// Temporary storage for normalizing grGlyph image.
|
||||
SkAutoSMalloc<1024> storage(size);
|
||||
void* dataPtr = storage.get();
|
||||
if (addPad) {
|
||||
if (needsPadding) {
|
||||
sk_bzero(dataPtr, size);
|
||||
// Advance in one row and one column.
|
||||
dataPtr = (char*)(dataPtr) + rowBytes + bytesPerPixel;
|
||||
@ -174,18 +173,8 @@ GrDrawOpAtlas::ErrorCode GrTextStrike::addGlyphToAtlas(const SkGlyph& skGlyph,
|
||||
|
||||
get_packed_glyph_image(skGlyph, rowBytes, expectedMaskFormat, dataPtr);
|
||||
|
||||
GrDrawOpAtlas::ErrorCode result = fullAtlasManager->addToAtlas(
|
||||
resourceProvider, &grGlyph->fPlotLocator, target, expectedMaskFormat,
|
||||
width, height,
|
||||
storage.get(), &grGlyph->fAtlasLocation);
|
||||
if (GrDrawOpAtlas::ErrorCode::kSucceeded == result) {
|
||||
if (addPad) {
|
||||
grGlyph->fAtlasLocation.fX += 1;
|
||||
grGlyph->fAtlasLocation.fY += 1;
|
||||
}
|
||||
SkASSERT(grGlyph->fPlotLocator != GrDrawOpAtlas::kInvalidPlotLocator);
|
||||
}
|
||||
return result;
|
||||
return fullAtlasManager->addToAtlas(resourceProvider, target, expectedMaskFormat, width, height,
|
||||
storage.get(), &grGlyph->fAtlasLocator);
|
||||
}
|
||||
|
||||
GrGlyph* GrTextStrike::getGlyph(const SkGlyph& skGlyph) {
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
// get the actual glyph image itself when we get the glyph metrics.
|
||||
GrDrawOpAtlas::ErrorCode addGlyphToAtlas(const SkGlyph&,
|
||||
GrMaskFormat expectedMaskFormat,
|
||||
bool isScaledGlyph,
|
||||
bool needsPadding,
|
||||
GrResourceProvider*,
|
||||
GrDeferredUploadTarget*,
|
||||
GrAtlasManager*,
|
||||
|
@ -196,9 +196,13 @@ bool GrTextBlob::SubRun::drawAsDistanceFields() const { return fType == kTransfo
|
||||
bool GrTextBlob::SubRun::drawAsPaths() const { return fType == kTransformedPath; }
|
||||
|
||||
bool GrTextBlob::SubRun::needsTransform() const {
|
||||
return fType == kTransformedPath
|
||||
|| fType == kTransformedMask
|
||||
|| fType == kTransformedSDFT;
|
||||
return fType == kTransformedPath ||
|
||||
fType == kTransformedMask ||
|
||||
fType == kTransformedSDFT;
|
||||
}
|
||||
|
||||
bool GrTextBlob::SubRun::needsPadding() const {
|
||||
return fType == kTransformedPath || fType == kTransformedMask;
|
||||
}
|
||||
|
||||
bool GrTextBlob::SubRun::hasW() const {
|
||||
@ -265,37 +269,21 @@ void GrTextBlob::SubRun::updateTexCoords(int begin, int end) {
|
||||
GrGlyph* glyph = this->fGlyphs[i];
|
||||
SkASSERT(glyph != nullptr);
|
||||
|
||||
int width = glyph->width();
|
||||
int height = glyph->height();
|
||||
uint16_t u0, v0, u1, v1;
|
||||
if (this->drawAsDistanceFields()) {
|
||||
u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset;
|
||||
v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset;
|
||||
u1 = u0 + width - 2 * SK_DistanceFieldInset;
|
||||
v1 = v0 + height - 2 * SK_DistanceFieldInset;
|
||||
} else {
|
||||
u0 = glyph->fAtlasLocation.fX;
|
||||
v0 = glyph->fAtlasLocation.fY;
|
||||
u1 = u0 + width;
|
||||
v1 = v0 + height;
|
||||
}
|
||||
int pad = this->drawAsDistanceFields() ? SK_DistanceFieldInset
|
||||
: (this->needsPadding() ? 1 : 0);
|
||||
std::array<uint16_t, 4> uvs = glyph->fAtlasLocator.getUVs(pad);
|
||||
|
||||
// We pack the 2bit page index in the low bit of the u and v texture coords
|
||||
uint32_t pageIndex = glyph->pageIndex();
|
||||
std::tie(u0, v0) = GrDrawOpAtlas::PackIndexInTexCoords(u0, v0, pageIndex);
|
||||
std::tie(u1, v1) = GrDrawOpAtlas::PackIndexInTexCoords(u1, v1, pageIndex);
|
||||
|
||||
textureCoords[0] = u0;
|
||||
textureCoords[1] = v0;
|
||||
textureCoords[0] = uvs[0];
|
||||
textureCoords[1] = uvs[1];
|
||||
textureCoords = SkTAddOffset<uint16_t>(textureCoords, vertexStride);
|
||||
textureCoords[0] = u0;
|
||||
textureCoords[1] = v1;
|
||||
textureCoords[0] = uvs[0];
|
||||
textureCoords[1] = uvs[3];
|
||||
textureCoords = SkTAddOffset<uint16_t>(textureCoords, vertexStride);
|
||||
textureCoords[0] = u1;
|
||||
textureCoords[1] = v0;
|
||||
textureCoords[0] = uvs[2];
|
||||
textureCoords[1] = uvs[1];
|
||||
textureCoords = SkTAddOffset<uint16_t>(textureCoords, vertexStride);
|
||||
textureCoords[0] = u1;
|
||||
textureCoords[1] = v1;
|
||||
textureCoords[0] = uvs[2];
|
||||
textureCoords[1] = uvs[3];
|
||||
textureCoords = SkTAddOffset<uint16_t>(textureCoords, vertexStride);
|
||||
}
|
||||
}
|
||||
@ -823,10 +811,9 @@ std::tuple<bool, int> GrTextBlob::VertexRegenerator::updateTextureCoordinates(
|
||||
if (skGlyph.image() == nullptr) {
|
||||
return {false, 0};
|
||||
}
|
||||
code = grStrike->addGlyphToAtlas(skGlyph,
|
||||
fSubRun->maskFormat(),
|
||||
fSubRun->needsTransform(),
|
||||
fResourceProvider, fUploadTarget, fFullAtlasManager, grGlyph);
|
||||
code = grStrike->addGlyphToAtlas(skGlyph, fSubRun->maskFormat(),
|
||||
fSubRun->needsPadding(), fResourceProvider,
|
||||
fUploadTarget, fFullAtlasManager, grGlyph);
|
||||
if (code != GrDrawOpAtlas::ErrorCode::kSucceeded) {
|
||||
break;
|
||||
}
|
||||
|
@ -347,6 +347,7 @@ public:
|
||||
bool drawAsDistanceFields() const;
|
||||
bool drawAsPaths() const;
|
||||
bool needsTransform() const;
|
||||
bool needsPadding() const;
|
||||
|
||||
void translateVerticesIfNeeded(const SkMatrix& drawMatrix, SkPoint drawOrigin);
|
||||
void updateVerticesColorIfNeeded(GrColor newColor);
|
||||
|
@ -114,7 +114,7 @@ private:
|
||||
static bool fill_plot(GrDrawOpAtlas* atlas,
|
||||
GrResourceProvider* resourceProvider,
|
||||
GrDeferredUploadTarget* target,
|
||||
GrDrawOpAtlas::PlotLocator* plotLocator,
|
||||
GrDrawOpAtlas::AtlasLocator* atlasLocator,
|
||||
int alpha) {
|
||||
SkImageInfo ii = SkImageInfo::MakeA8(kPlotSize, kPlotSize);
|
||||
|
||||
@ -122,10 +122,9 @@ static bool fill_plot(GrDrawOpAtlas* atlas,
|
||||
data.allocPixels(ii);
|
||||
data.eraseARGB(alpha, 0, 0, 0);
|
||||
|
||||
SkIPoint16 loc;
|
||||
GrDrawOpAtlas::ErrorCode code;
|
||||
code = atlas->addToAtlas(resourceProvider, plotLocator, target, kPlotSize, kPlotSize,
|
||||
data.getAddr(0, 0), &loc);
|
||||
code = atlas->addToAtlas(resourceProvider, target, kPlotSize, kPlotSize,
|
||||
data.getAddr(0, 0), atlasLocator);
|
||||
return GrDrawOpAtlas::ErrorCode::kSucceeded == code;
|
||||
}
|
||||
|
||||
@ -160,10 +159,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BasicDrawOpAtlas, reporter, ctxInfo) {
|
||||
check(reporter, atlas.get(), 0, 4, 0);
|
||||
|
||||
// Fill up the first level
|
||||
GrDrawOpAtlas::PlotLocator plotLocators[kNumPlots * kNumPlots];
|
||||
GrDrawOpAtlas::AtlasLocator atlasLocators[kNumPlots * kNumPlots];
|
||||
for (int i = 0; i < kNumPlots * kNumPlots; ++i) {
|
||||
bool result = fill_plot(
|
||||
atlas.get(), resourceProvider, &uploadTarget, &plotLocators[i], i * 32);
|
||||
atlas.get(), resourceProvider, &uploadTarget, &atlasLocators[i], i * 32);
|
||||
REPORTER_ASSERT(reporter, result);
|
||||
check(reporter, atlas.get(), 1, 4, 1);
|
||||
}
|
||||
@ -172,14 +171,14 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BasicDrawOpAtlas, reporter, ctxInfo) {
|
||||
check(reporter, atlas.get(), 1, 4, 1);
|
||||
|
||||
// Force allocation of a second level
|
||||
GrDrawOpAtlas::PlotLocator plotLocator;
|
||||
bool result = fill_plot(atlas.get(), resourceProvider, &uploadTarget, &plotLocator, 4 * 32);
|
||||
GrDrawOpAtlas::AtlasLocator atlasLocator;
|
||||
bool result = fill_plot(atlas.get(), resourceProvider, &uploadTarget, &atlasLocator, 4 * 32);
|
||||
REPORTER_ASSERT(reporter, result);
|
||||
check(reporter, atlas.get(), 2, 4, 2);
|
||||
|
||||
// Simulate a lot of draws using only the first plot. The last texture should be compacted.
|
||||
for (int i = 0; i < 512; ++i) {
|
||||
atlas->setLastUseToken(plotLocators[0], uploadTarget.tokenTracker()->nextDrawToken());
|
||||
atlas->setLastUseToken(atlasLocators[0], uploadTarget.tokenTracker()->nextDrawToken());
|
||||
uploadTarget.issueDrawToken();
|
||||
uploadTarget.flushToken();
|
||||
atlas->compact(uploadTarget.tokenTracker()->nextTokenToFlush());
|
||||
|
Loading…
Reference in New Issue
Block a user