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 : fID(-1) |
25 , fTexture(NULL) | 25 , fTexture(nullptr) |
26 , fRects(NULL) | 26 , fRects(nullptr) |
27 , fAtlas(NULL) | 27 , fAtlas(nullptr) |
28 , fBytesPerPixel(1) | 28 , fBytesPerPixel(1) |
29 , fDirty(false) | 29 , fDirty(false) |
30 , fBatchUploads(false) | 30 , fBatchUploads(false) |
31 { | 31 { |
32 fOffset.set(0, 0); | 32 fOffset.set(0, 0); |
33 } | 33 } |
34 | 34 |
35 GrPlot::~GrPlot() { | 35 GrPlot::~GrPlot() { |
36 delete[] fPlotData; | 36 delete[] fPlotData; |
37 fPlotData = NULL; | 37 fPlotData = nullptr; |
38 delete fRects; | 38 delete fRects; |
39 } | 39 } |
40 | 40 |
41 void GrPlot::init(GrAtlas* atlas, int id, int offX, int offY, int width, int hei
ght, size_t bpp, | 41 void GrPlot::init(GrAtlas* atlas, int id, int offX, int offY, int width, int hei
ght, size_t bpp, |
42 bool batchUploads) { | 42 bool batchUploads) { |
43 fID = id; | 43 fID = id; |
44 fRects = GrRectanizer::Factory(width, height); | 44 fRects = GrRectanizer::Factory(width, height); |
45 fAtlas = atlas; | 45 fAtlas = atlas; |
46 fOffset.set(offX * width, offY * height); | 46 fOffset.set(offX * width, offY * height); |
47 fBytesPerPixel = bpp; | 47 fBytesPerPixel = bpp; |
48 fPlotData = NULL; | 48 fPlotData = nullptr; |
49 fDirtyRect.setEmpty(); | 49 fDirtyRect.setEmpty(); |
50 fDirty = false; | 50 fDirty = false; |
51 fBatchUploads = batchUploads; | 51 fBatchUploads = batchUploads; |
52 } | 52 } |
53 | 53 |
54 static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset)
{ | 54 static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset)
{ |
55 loc->fX += offset.fX; | 55 loc->fX += offset.fX; |
56 loc->fY += offset.fY; | 56 loc->fY += offset.fY; |
57 } | 57 } |
58 | 58 |
59 bool GrPlot::addSubImage(int width, int height, const void* image, SkIPoint16* l
oc) { | 59 bool GrPlot::addSubImage(int width, int height, const void* image, SkIPoint16* l
oc) { |
60 float percentFull = fRects->percentFull(); | 60 float percentFull = fRects->percentFull(); |
61 if (!fRects->addRect(width, height, loc)) { | 61 if (!fRects->addRect(width, height, loc)) { |
62 return false; | 62 return false; |
63 } | 63 } |
64 | 64 |
65 // if batching uploads, create backing memory on first use | 65 // if batching uploads, create backing memory on first use |
66 // once the plot is nearly full we will revert to uploading each subimage in
dividually | 66 // once the plot is nearly full we will revert to uploading each subimage in
dividually |
67 int plotWidth = fRects->width(); | 67 int plotWidth = fRects->width(); |
68 int plotHeight = fRects->height(); | 68 int plotHeight = fRects->height(); |
69 if (fBatchUploads && NULL == fPlotData && 0.0f == percentFull) { | 69 if (fBatchUploads && nullptr == fPlotData && 0.0f == percentFull) { |
70 fPlotData = new unsigned char[fBytesPerPixel * plotWidth * plotHeight]; | 70 fPlotData = new unsigned char[fBytesPerPixel * plotWidth * plotHeight]; |
71 memset(fPlotData, 0, fBytesPerPixel*plotWidth*plotHeight); | 71 memset(fPlotData, 0, fBytesPerPixel*plotWidth*plotHeight); |
72 } | 72 } |
73 | 73 |
74 // if we have backing memory, copy to the memory and set for future upload | 74 // if we have backing memory, copy to the memory and set for future upload |
75 if (fPlotData) { | 75 if (fPlotData) { |
76 const unsigned char* imagePtr = (const unsigned char*) image; | 76 const unsigned char* imagePtr = (const unsigned char*) image; |
77 // point ourselves at the right starting spot | 77 // point ourselves at the right starting spot |
78 unsigned char* dataPtr = fPlotData; | 78 unsigned char* dataPtr = fPlotData; |
79 dataPtr += fBytesPerPixel*plotWidth*loc->fY; | 79 dataPtr += fBytesPerPixel*plotWidth*loc->fY; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 GrAtlas::GrAtlas(GrGpu* gpu, GrPixelConfig config, GrSurfaceFlags flags, | 115 GrAtlas::GrAtlas(GrGpu* gpu, GrPixelConfig config, GrSurfaceFlags flags, |
116 const SkISize& backingTextureSize, | 116 const SkISize& backingTextureSize, |
117 int numPlotsX, int numPlotsY, bool batchUploads) { | 117 int numPlotsX, int numPlotsY, bool batchUploads) { |
118 fGpu = SkRef(gpu); | 118 fGpu = SkRef(gpu); |
119 fPixelConfig = config; | 119 fPixelConfig = config; |
120 fFlags = flags; | 120 fFlags = flags; |
121 fBackingTextureSize = backingTextureSize; | 121 fBackingTextureSize = backingTextureSize; |
122 fNumPlotsX = numPlotsX; | 122 fNumPlotsX = numPlotsX; |
123 fNumPlotsY = numPlotsY; | 123 fNumPlotsY = numPlotsY; |
124 fBatchUploads = batchUploads; | 124 fBatchUploads = batchUploads; |
125 fTexture = NULL; | 125 fTexture = nullptr; |
126 | 126 |
127 int textureWidth = fBackingTextureSize.width(); | 127 int textureWidth = fBackingTextureSize.width(); |
128 int textureHeight = fBackingTextureSize.height(); | 128 int textureHeight = fBackingTextureSize.height(); |
129 | 129 |
130 int plotWidth = textureWidth / fNumPlotsX; | 130 int plotWidth = textureWidth / fNumPlotsX; |
131 int plotHeight = textureHeight / fNumPlotsY; | 131 int plotHeight = textureHeight / fNumPlotsY; |
132 | 132 |
133 SkASSERT(plotWidth * fNumPlotsX == textureWidth); | 133 SkASSERT(plotWidth * fNumPlotsX == textureWidth); |
134 SkASSERT(plotHeight * fNumPlotsY == textureHeight); | 134 SkASSERT(plotHeight * fNumPlotsY == textureHeight); |
135 | 135 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 for (int i = usage->fPlots.count()-1; i >= 0; --i) { | 179 for (int i = usage->fPlots.count()-1; i >= 0; --i) { |
180 GrPlot* plot = usage->fPlots[i]; | 180 GrPlot* plot = usage->fPlots[i]; |
181 // client may have plots from more than one atlas, must check for ours b
efore adding | 181 // client may have plots from more than one atlas, must check for ours b
efore adding |
182 if (this == plot->fAtlas && plot->addSubImage(width, height, image, loc)
) { | 182 if (this == plot->fAtlas && plot->addSubImage(width, height, image, loc)
) { |
183 this->makeMRU(plot); | 183 this->makeMRU(plot); |
184 return plot; | 184 return plot; |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 // before we get a new plot, make sure we have a backing texture | 188 // before we get a new plot, make sure we have a backing texture |
189 if (NULL == fTexture) { | 189 if (nullptr == fTexture) { |
190 // TODO: Update this to use the cache rather than directly creating a te
xture. | 190 // TODO: Update this to use the cache rather than directly creating a te
xture. |
191 GrSurfaceDesc desc; | 191 GrSurfaceDesc desc; |
192 desc.fFlags = fFlags; | 192 desc.fFlags = fFlags; |
193 desc.fWidth = fBackingTextureSize.width(); | 193 desc.fWidth = fBackingTextureSize.width(); |
194 desc.fHeight = fBackingTextureSize.height(); | 194 desc.fHeight = fBackingTextureSize.height(); |
195 desc.fConfig = fPixelConfig; | 195 desc.fConfig = fPixelConfig; |
196 | 196 |
197 fTexture = fGpu->createTexture(desc, true, NULL, 0); | 197 fTexture = fGpu->createTexture(desc, true, nullptr, 0); |
198 if (NULL == fTexture) { | 198 if (nullptr == fTexture) { |
199 return NULL; | 199 return nullptr; |
200 } | 200 } |
201 } | 201 } |
202 | 202 |
203 // now look through all allocated plots for one we can share, in MRU order | 203 // now look through all allocated plots for one we can share, in MRU order |
204 GrPlotList::Iter plotIter; | 204 GrPlotList::Iter plotIter; |
205 plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart); | 205 plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart); |
206 GrPlot* plot; | 206 GrPlot* plot; |
207 while ((plot = plotIter.get())) { | 207 while ((plot = plotIter.get())) { |
208 // make sure texture is set for quick lookup | 208 // make sure texture is set for quick lookup |
209 plot->fTexture = fTexture; | 209 plot->fTexture = fTexture; |
210 if (plot->addSubImage(width, height, image, loc)) { | 210 if (plot->addSubImage(width, height, image, loc)) { |
211 this->makeMRU(plot); | 211 this->makeMRU(plot); |
212 // new plot for atlas, put at end of array | 212 // new plot for atlas, put at end of array |
213 SkASSERT(!usage->fPlots.contains(plot)); | 213 SkASSERT(!usage->fPlots.contains(plot)); |
214 *(usage->fPlots.append()) = plot; | 214 *(usage->fPlots.append()) = plot; |
215 return plot; | 215 return plot; |
216 } | 216 } |
217 plotIter.next(); | 217 plotIter.next(); |
218 } | 218 } |
219 | 219 |
220 // If the above fails, then the current plot list has no room | 220 // If the above fails, then the current plot list has no room |
221 return NULL; | 221 return nullptr; |
222 } | 222 } |
223 | 223 |
224 void GrAtlas::RemovePlot(ClientPlotUsage* usage, const GrPlot* plot) { | 224 void GrAtlas::RemovePlot(ClientPlotUsage* usage, const GrPlot* plot) { |
225 int index = usage->fPlots.find(const_cast<GrPlot*>(plot)); | 225 int index = usage->fPlots.find(const_cast<GrPlot*>(plot)); |
226 if (index >= 0) { | 226 if (index >= 0) { |
227 usage->fPlots.remove(index); | 227 usage->fPlots.remove(index); |
228 } | 228 } |
229 } | 229 } |
OLD | NEW |