OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
11 #include "GrGpu.h" | 11 #include "GrGpu.h" |
12 #include "GrRectanizer.h" | 12 #include "GrRectanizer.h" |
13 #include "GrTracing.h" | 13 #include "GrTracing.h" |
14 | 14 |
15 /////////////////////////////////////////////////////////////////////////////// | 15 /////////////////////////////////////////////////////////////////////////////// |
16 | 16 |
17 // for testing | 17 // for testing |
18 #define FONT_CACHE_STATS 0 | 18 #define FONT_CACHE_STATS 0 |
19 #if FONT_CACHE_STATS | 19 #if FONT_CACHE_STATS |
20 static int g_UploadCount = 0; | 20 static int g_UploadCount = 0; |
21 #endif | 21 #endif |
22 | 22 |
23 GrPlot::GrPlot() | 23 GrPlot::GrPlot() |
24 : fID(-1) | 24 : fDrawToken(NULL, 0) |
| 25 , fID(-1) |
25 , fTexture(NULL) | 26 , fTexture(NULL) |
26 , fRects(NULL) | 27 , fRects(NULL) |
27 , fAtlas(NULL) | 28 , fAtlas(NULL) |
28 , fBytesPerPixel(1) | 29 , fBytesPerPixel(1) |
29 , fDirty(false) | 30 , fDirty(false) |
30 , fBatchUploads(false) | 31 , fBatchUploads(false) |
31 { | 32 { |
32 fOffset.set(0, 0); | 33 fOffset.set(0, 0); |
33 } | 34 } |
34 | 35 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 adjust_for_offset(loc, fOffset); | 99 adjust_for_offset(loc, fOffset); |
99 } | 100 } |
100 | 101 |
101 #if FONT_CACHE_STATS | 102 #if FONT_CACHE_STATS |
102 ++g_UploadCount; | 103 ++g_UploadCount; |
103 #endif | 104 #endif |
104 | 105 |
105 return true; | 106 return true; |
106 } | 107 } |
107 | 108 |
| 109 void GrPlot::uploadToTexture() { |
| 110 static const float kNearlyFullTolerance = 0.85f; |
| 111 |
| 112 // should only do this if batching is enabled |
| 113 SkASSERT(fBatchUploads); |
| 114 |
| 115 if (fDirty) { |
| 116 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTex
ture"); |
| 117 SkASSERT(fTexture); |
| 118 // We pass the flag that does not force a flush. We assume our caller is |
| 119 // smart and hasn't referenced the part of the texture we're about to up
date |
| 120 // since the last flush. |
| 121 size_t rowBytes = fBytesPerPixel*fRects->width(); |
| 122 const unsigned char* dataPtr = fPlotData; |
| 123 dataPtr += rowBytes*fDirtyRect.fTop; |
| 124 dataPtr += fBytesPerPixel*fDirtyRect.fLeft; |
| 125 fTexture->writePixels(fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirty
Rect.fTop, |
| 126 fDirtyRect.width(), fDirtyRect.height(), fTexture-
>config(), dataPtr, |
| 127 rowBytes, GrContext::kDontFlush_PixelOpsFlag); |
| 128 fDirtyRect.setEmpty(); |
| 129 fDirty = false; |
| 130 // If the Plot is nearly full, anything else we add will probably be sma
ll and one |
| 131 // at a time, so free up the memory and after this upload any new images
directly. |
| 132 if (fRects->percentFull() > kNearlyFullTolerance) { |
| 133 SkDELETE_ARRAY(fPlotData); |
| 134 fPlotData = NULL; |
| 135 } |
| 136 } |
| 137 } |
| 138 |
108 void GrPlot::resetRects() { | 139 void GrPlot::resetRects() { |
109 SkASSERT(fRects); | 140 SkASSERT(fRects); |
110 fRects->reset(); | 141 fRects->reset(); |
111 } | 142 } |
112 | 143 |
113 /////////////////////////////////////////////////////////////////////////////// | 144 /////////////////////////////////////////////////////////////////////////////// |
114 | 145 |
115 GrAtlas::GrAtlas(GrGpu* gpu, GrPixelConfig config, GrSurfaceFlags flags, | 146 GrAtlas::GrAtlas(GrGpu* gpu, GrPixelConfig config, GrSurfaceFlags flags, |
116 const SkISize& backingTextureSize, | 147 const SkISize& backingTextureSize, |
117 int numPlotsX, int numPlotsY, bool batchUploads) { | 148 int numPlotsX, int numPlotsY, bool batchUploads) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 // If the above fails, then the current plot list has no room | 251 // If the above fails, then the current plot list has no room |
221 return NULL; | 252 return NULL; |
222 } | 253 } |
223 | 254 |
224 void GrAtlas::RemovePlot(ClientPlotUsage* usage, const GrPlot* plot) { | 255 void GrAtlas::RemovePlot(ClientPlotUsage* usage, const GrPlot* plot) { |
225 int index = usage->fPlots.find(const_cast<GrPlot*>(plot)); | 256 int index = usage->fPlots.find(const_cast<GrPlot*>(plot)); |
226 if (index >= 0) { | 257 if (index >= 0) { |
227 usage->fPlots.remove(index); | 258 usage->fPlots.remove(index); |
228 } | 259 } |
229 } | 260 } |
| 261 |
| 262 // get a plot that's not being used by the current draw |
| 263 GrPlot* GrAtlas::getUnusedPlot() { |
| 264 GrPlotList::Iter plotIter; |
| 265 plotIter.init(fPlotList, GrPlotList::Iter::kTail_IterStart); |
| 266 GrPlot* plot; |
| 267 while ((plot = plotIter.get())) { |
| 268 if (plot->drawToken().isIssued()) { |
| 269 return plot; |
| 270 } |
| 271 plotIter.prev(); |
| 272 } |
| 273 |
| 274 return NULL; |
| 275 } |
| 276 |
| 277 void GrAtlas::uploadPlotsToTexture() { |
| 278 if (fBatchUploads) { |
| 279 GrPlotList::Iter plotIter; |
| 280 plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart); |
| 281 GrPlot* plot; |
| 282 while ((plot = plotIter.get())) { |
| 283 plot->uploadToTexture(); |
| 284 plotIter.next(); |
| 285 } |
| 286 } |
| 287 } |
OLD | NEW |