diff options
Diffstat (limited to 'src/gpu/GrBatchAtlas.cpp')
-rw-r--r-- | src/gpu/GrBatchAtlas.cpp | 85 |
1 files changed, 35 insertions, 50 deletions
diff --git a/src/gpu/GrBatchAtlas.cpp b/src/gpu/GrBatchAtlas.cpp index 9f3c4dd983..40ab0e6c0e 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++; |