Index: src/gpu/GrAtlas.cpp |
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp |
index 0322f70dc07bbb0a2b56cf142575d147deb16512..7ebdf6eb12587952d0d0233a7c28bca2dcdb2e73 100644 |
--- a/src/gpu/GrAtlas.cpp |
+++ b/src/gpu/GrAtlas.cpp |
@@ -21,7 +21,8 @@ |
#endif |
GrPlot::GrPlot() |
- : fID(-1) |
+ : fDrawToken(NULL, 0) |
+ , fID(-1) |
, fTexture(NULL) |
, fRects(NULL) |
, fAtlas(NULL) |
@@ -103,6 +104,36 @@ |
#endif |
return true; |
+} |
+ |
+void GrPlot::uploadToTexture() { |
+ static const float kNearlyFullTolerance = 0.85f; |
+ |
+ // should only do this if batching is enabled |
+ SkASSERT(fBatchUploads); |
+ |
+ if (fDirty) { |
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTexture"); |
+ SkASSERT(fTexture); |
+ // We pass the flag that does not force a flush. We assume our caller is |
+ // smart and hasn't referenced the part of the texture we're about to update |
+ // since the last flush. |
+ size_t rowBytes = fBytesPerPixel*fRects->width(); |
+ const unsigned char* dataPtr = fPlotData; |
+ dataPtr += rowBytes*fDirtyRect.fTop; |
+ dataPtr += fBytesPerPixel*fDirtyRect.fLeft; |
+ fTexture->writePixels(fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop, |
+ fDirtyRect.width(), fDirtyRect.height(), fTexture->config(), dataPtr, |
+ rowBytes, GrContext::kDontFlush_PixelOpsFlag); |
+ fDirtyRect.setEmpty(); |
+ fDirty = false; |
+ // If the Plot is nearly full, anything else we add will probably be small and one |
+ // at a time, so free up the memory and after this upload any new images directly. |
+ if (fRects->percentFull() > kNearlyFullTolerance) { |
+ SkDELETE_ARRAY(fPlotData); |
+ fPlotData = NULL; |
+ } |
+ } |
} |
void GrPlot::resetRects() { |
@@ -227,3 +258,30 @@ |
usage->fPlots.remove(index); |
} |
} |
+ |
+// get a plot that's not being used by the current draw |
+GrPlot* GrAtlas::getUnusedPlot() { |
+ GrPlotList::Iter plotIter; |
+ plotIter.init(fPlotList, GrPlotList::Iter::kTail_IterStart); |
+ GrPlot* plot; |
+ while ((plot = plotIter.get())) { |
+ if (plot->drawToken().isIssued()) { |
+ return plot; |
+ } |
+ plotIter.prev(); |
+ } |
+ |
+ return NULL; |
+} |
+ |
+void GrAtlas::uploadPlotsToTexture() { |
+ if (fBatchUploads) { |
+ GrPlotList::Iter plotIter; |
+ plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart); |
+ GrPlot* plot; |
+ while ((plot = plotIter.get())) { |
+ plot->uploadToTexture(); |
+ plotIter.next(); |
+ } |
+ } |
+} |