| Index: src/gpu/GrBatchAtlas.cpp
|
| diff --git a/src/gpu/GrBatchAtlas.cpp b/src/gpu/GrBatchAtlas.cpp
|
| index 9f3c4dd983ca8cbdc67460046f135fb47dece37b..40ab0e6c0e09d562ecc483d6130a2a65db509a41 100644
|
| --- a/src/gpu/GrBatchAtlas.cpp
|
| +++ b/src/gpu/GrBatchAtlas.cpp
|
| @@ -14,8 +14,8 @@
|
|
|
| GrBatchAtlas::BatchPlot::BatchPlot(int index, uint64_t genID, int offX, int offY, int width,
|
| int height, GrPixelConfig config)
|
| - : fLastUpload(0)
|
| - , fLastUse(0)
|
| + : fLastUpload(GrBatchDrawToken::AlreadyFlushedToken())
|
| + , fLastUse(GrBatchDrawToken::AlreadyFlushedToken())
|
| , fIndex(index)
|
| , fGenID(genID)
|
| , fID(CreateId(fIndex, fGenID))
|
| @@ -78,7 +78,7 @@ bool GrBatchAtlas::BatchPlot::addSubImage(int width, int height, const void* ima
|
| return true;
|
| }
|
|
|
| -void GrBatchAtlas::BatchPlot::uploadToTexture(GrBatchUploader::TextureUploader* uploader,
|
| +void GrBatchAtlas::BatchPlot::uploadToTexture(GrDrawBatch::WritePixelsFn& writePixels,
|
| GrTexture* texture) {
|
| // We should only be issuing uploads if we are in fact dirty
|
| SkASSERT(fDirty && fData && texture);
|
| @@ -87,10 +87,8 @@ void GrBatchAtlas::BatchPlot::uploadToTexture(GrBatchUploader::TextureUploader*
|
| const unsigned char* dataPtr = fData;
|
| dataPtr += rowBytes * fDirtyRect.fTop;
|
| dataPtr += fBytesPerPixel * fDirtyRect.fLeft;
|
| - uploader->writeTexturePixels(texture,
|
| - fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop,
|
| - fDirtyRect.width(), fDirtyRect.height(),
|
| - fConfig, dataPtr, rowBytes);
|
| + writePixels(texture, fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop,
|
| + fDirtyRect.width(), fDirtyRect.height(), fConfig, dataPtr, rowBytes);
|
| fDirtyRect.setEmpty();
|
| SkDEBUGCODE(fDirty = false;)
|
| }
|
| @@ -112,28 +110,6 @@ void GrBatchAtlas::BatchPlot::resetRects() {
|
| SkDEBUGCODE(fDirty = false;)
|
| }
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -class GrPlotUploader : public GrBatchUploader {
|
| -public:
|
| - GrPlotUploader(GrBatchAtlas::BatchPlot* plot, GrTexture* texture)
|
| - : INHERITED(plot->lastUploadToken())
|
| - , fPlot(SkRef(plot))
|
| - , fTexture(texture) {
|
| - SkASSERT(plot);
|
| - }
|
| -
|
| - void upload(TextureUploader* uploader) override {
|
| - fPlot->uploadToTexture(uploader, fTexture);
|
| - }
|
| -
|
| -private:
|
| - SkAutoTUnref<GrBatchAtlas::BatchPlot> fPlot;
|
| - GrTexture* fTexture;
|
| -
|
| - typedef GrBatchUploader INHERITED;
|
| -};
|
| -
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| GrBatchAtlas::GrBatchAtlas(GrTexture* texture, int numPlotsX, int numPlotsY)
|
| @@ -185,15 +161,21 @@ inline void GrBatchAtlas::updatePlot(GrDrawBatch::Target* target, AtlasID* id, B
|
| // 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.
|
| // This new update will piggy back on that previously scheduled update.
|
| - if (target->hasTokenBeenFlushed(plot->lastUploadToken())) {
|
| - plot->setLastUploadToken(target->asapToken());
|
| - SkAutoTUnref<GrPlotUploader> uploader(new GrPlotUploader(plot, fTexture));
|
| - target->upload(uploader);
|
| + if (target->hasDrawBeenFlushed(plot->lastUploadToken())) {
|
| + // With c+14 we could move sk_sp into lamba to only ref once.
|
| + sk_sp<BatchPlot> plotsp(SkRef(plot));
|
| + GrTexture* texture = fTexture;
|
| + GrBatchDrawToken lastUploadToken = target->addAsapUpload(
|
| + [plotsp, texture] (GrDrawBatch::WritePixelsFn& writePixels) {
|
| + plotsp->uploadToTexture(writePixels, texture);
|
| + }
|
| + );
|
| + plot->setLastUploadToken(lastUploadToken);
|
| }
|
| *id = plot->id();
|
| }
|
|
|
| -bool GrBatchAtlas::addToAtlas(AtlasID* id, GrDrawBatch::Target* batchTarget,
|
| +bool GrBatchAtlas::addToAtlas(AtlasID* id, GrDrawBatch::Target* target,
|
| int width, int height, const void* image, SkIPoint16* loc) {
|
| // We should already have a texture, TODO clean this up
|
| SkASSERT(fTexture);
|
| @@ -205,7 +187,7 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrDrawBatch::Target* batchTarget,
|
| while ((plot = plotIter.get())) {
|
| SkASSERT(GrBytesPerPixel(fTexture->desc().fConfig) == plot->bpp());
|
| if (plot->addSubImage(width, height, image, loc)) {
|
| - this->updatePlot(batchTarget, id, plot);
|
| + this->updatePlot(target, id, plot);
|
| return true;
|
| }
|
| plotIter.next();
|
| @@ -215,30 +197,26 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrDrawBatch::Target* batchTarget,
|
| // gpu
|
| plot = fPlotList.tail();
|
| SkASSERT(plot);
|
| - if (batchTarget->hasTokenBeenFlushed(plot->lastUseToken())) {
|
| + if (target->hasDrawBeenFlushed(plot->lastUseToken())) {
|
| this->processEviction(plot->id());
|
| plot->resetRects();
|
| SkASSERT(GrBytesPerPixel(fTexture->desc().fConfig) == plot->bpp());
|
| SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
|
| SkASSERT(verify);
|
| - this->updatePlot(batchTarget, id, plot);
|
| + this->updatePlot(target, id, plot);
|
| fAtlasGeneration++;
|
| return true;
|
| }
|
|
|
| - // The least recently used plot hasn't been flushed to the gpu yet, however, if we have flushed
|
| - // it to the batch target than we can reuse it. Our last use token is guaranteed to be less
|
| - // than or equal to the current token. If its 'less than' the current token, than we can spin
|
| - // off the plot (ie let the batch target manage it) and create a new plot in its place in our
|
| - // array. If it is equal to the currentToken, then the caller has to flush draws to the batch
|
| - // target so we can spin off the plot
|
| - if (plot->lastUseToken() == batchTarget->currentToken()) {
|
| + // If this plot has been used in a draw that is currently being prepared by a batch, then we
|
| + // have to fail. This gives the batch 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;
|
| }
|
|
|
| - SkASSERT(plot->lastUseToken() < batchTarget->currentToken());
|
| - SkASSERT(!batchTarget->hasTokenBeenFlushed(batchTarget->currentToken()));
|
| -
|
| SkASSERT(!plot->unique()); // The GrPlotUpdater should have a ref too
|
|
|
| this->processEviction(plot->id());
|
| @@ -253,9 +231,16 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrDrawBatch::Target* batchTarget,
|
|
|
| // Note that this plot will be uploaded inline with the draws whereas the
|
| // one it displaced most likely was uploaded asap.
|
| - newPlot->setLastUploadToken(batchTarget->currentToken());
|
| - SkAutoTUnref<GrPlotUploader> uploader(new GrPlotUploader(newPlot, fTexture));
|
| - batchTarget->upload(uploader);
|
| + // With c+14 we could move sk_sp into lamba to only ref once.
|
| + sk_sp<BatchPlot> plotsp(SkRef(newPlot.get()));
|
| + GrTexture* texture = fTexture;
|
| + GrBatchDrawToken lastUploadToken = target->addInlineUpload(
|
| + [plotsp, texture] (GrDrawBatch::WritePixelsFn& writePixels) {
|
| + plotsp->uploadToTexture(writePixels, texture);
|
| + }
|
| + );
|
| + newPlot->setLastUploadToken(lastUploadToken);
|
| +
|
| *id = newPlot->id();
|
|
|
| fAtlasGeneration++;
|
|
|