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++; |