Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: src/gpu/GrBatchAtlas.cpp

Issue 975303005: Creation of GrBatchAtlas and Distancefieldpathrenderer batch (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: more tidying Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "GrBatchAtlas.h"
10 #include "GrBatchTarget.h"
11 #include "GrGpu.h"
12 #include "GrRectanizer.h"
13 #include "GrTracing.h"
14
15 ///////////////////////////////////////////////////////////////////////////////
16
17 static GrBatchAtlas::AtlasID create_id(int id, int generation) {
18 // Generation ID can roll over because we only check for equality
19 SkASSERT(id < (1 << 16));
20 return id << 16 | generation;
21 }
22
23 // for testing
24 #define FONT_CACHE_STATS 0
bsalomon 2015/03/06 16:34:59 ATLAS_STAST?
joshualitt 2015/03/09 19:45:14 Acknowledged.
25 #if FONT_CACHE_STATS
26 static int g_UploadCount = 0;
27 #endif
28
29 GrBatchPlot::GrBatchPlot()
30 : fLastUpload(0)
31 , fLastRef(0)
32 , fID(-1)
33 , fGeneration(-1)
34 , fPlotData(NULL)
35 , fPlotWidth(0)
36 , fPlotHeight(0)
37 , fX(0)
38 , fY(0)
39 , fGpu(NULL)
40 , fTexture(NULL)
41 , fRects(NULL)
42 , fAtlas(NULL)
43 , fBytesPerPixel(1)
44 #ifdef SK_DEBUG
45 , fDirty(false)
46 #endif
47 {
48 fOffset.set(0, 0);
49 }
50
51 GrBatchPlot::~GrBatchPlot() {
52 SkDELETE_ARRAY(fPlotData);
53 fPlotData = NULL;
54 delete fRects;
55 }
56
57 void GrBatchPlot::init(GrGpu* gpu, GrBatchAtlas* atlas, GrTexture* texture, int id,
58 uint32_t generation,
59 int offX, int offY,
60 int width, int height,
61 size_t bpp) {
62 fID = id;
63 fGeneration = generation;
64 fPlotWidth = width;
65 fPlotHeight = height;
66 fX = offX;
67 fY = offY;
68 fRects = GrRectanizer::Factory(width, height);
69 fGpu = gpu;
70 fAtlas = atlas;
71 fOffset.set(offX * width, offY * height);
72 fBytesPerPixel = bpp;
73 fPlotData = NULL;
74 fDirtyRect.setEmpty();
75 SkDEBUGCODE(fDirty = false;)
76 fTexture = texture;
77
78 // allocate backing store
79 fPlotData = SkNEW_ARRAY(unsigned char, fBytesPerPixel * width * height);
80 memset(fPlotData, 0, fBytesPerPixel * width * height);
81 }
82
83 static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset) {
84 loc->fX += offset.fX;
85 loc->fY += offset.fY;
86 }
87
88 bool GrBatchPlot::addSubImage(int width, int height, const void* image, SkIPoint 16* loc) {
89 if (!fRects->addRect(width, height, loc)) {
90 return false;
91 }
92
93 SkASSERT(fPlotData);
94 const unsigned char* imagePtr = (const unsigned char*)image;
95 // point ourselves at the right starting spot
96 unsigned char* dataPtr = fPlotData;
97 dataPtr += fBytesPerPixel * fPlotWidth * loc->fY;
98 dataPtr += fBytesPerPixel * loc->fX;
99 // copy into the data buffer
100 for (int i = 0; i < height; ++i) {
101 memcpy(dataPtr, imagePtr, fBytesPerPixel * width);
102 dataPtr += fBytesPerPixel * fPlotWidth;
103 imagePtr += fBytesPerPixel * width;
104 }
105
106 fDirtyRect.join(loc->fX, loc->fY, loc->fX + width, loc->fY + height);
107 adjust_for_offset(loc, fOffset);
108 SkDEBUGCODE(fDirty = true;)
109
110 #if FONT_CACHE_STATS
111 ++g_UploadCount;
112 #endif
113
114 return true;
115 }
116
117 void GrBatchPlot::uploadToTexture() {
118 // We should only be issuing uploads if we are in fact dirty
119 SkASSERT(fDirty);
120 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTexture ");
bsalomon 2015/03/06 16:34:59 update string?
joshualitt 2015/03/09 19:45:14 Acknowledged.
121 SkASSERT(fTexture);
122 size_t rowBytes = fBytesPerPixel * fRects->width();
123 const unsigned char* dataPtr = fPlotData;
124 dataPtr += rowBytes * fDirtyRect.fTop;
125 dataPtr += fBytesPerPixel * fDirtyRect.fLeft;
126 fGpu->writeTexturePixels(fTexture,
bsalomon 2015/03/06 16:34:59 I think we really need a constrained API for the u
joshualitt 2015/03/09 19:45:14 Acknowledged.
127 fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyR ect.fTop,
128 fDirtyRect.width(), fDirtyRect.height(),
129 fTexture->config(), dataPtr, rowBytes);
130 fDirtyRect.setEmpty();
131 SkDEBUGCODE(fDirty = false;)
132 }
133
134 void GrBatchPlot::resetRects() {
135 SkASSERT(fRects);
136 fRects->reset();
137 fGeneration++;
138
139 // zero out the plot
140 SkASSERT(fPlotData);
141 memset(fPlotData, 0, fBytesPerPixel * fPlotWidth * fPlotHeight);
142
143 fDirtyRect.setEmpty();
144 SkDEBUGCODE(fDirty = false;)
145 }
146
147 ///////////////////////////////////////////////////////////////////////////////
148
149 GrBatchAtlas::GrBatchAtlas(GrGpu* gpu, GrTexture* texture, int numPlotsX, int nu mPlotsY)
150 : fGpu(gpu)
151 , fTexture(texture)
152 , fNumPlotsX(numPlotsX)
153 , fNumPlotsY(numPlotsY)
154 , fPlotWidth(texture->width() / numPlotsX)
155 , fPlotHeight(texture->height() / numPlotsY) {
156 SkASSERT(fPlotWidth * fNumPlotsX == texture->width());
157 SkASSERT(fPlotHeight * fNumPlotsY == texture->height());
158
159 // We currently do not support compressed atlases...
160 SkASSERT(!GrPixelConfigIsCompressed(texture->desc().fConfig));
161
162 // set up allocated plots
163 fBPP = GrBytesPerPixel(texture->desc().fConfig);
164 fPlotArray = SkNEW_ARRAY(SkAutoTUnref<GrBatchPlot>, (fNumPlotsX * fNumPlotsY ));
165
166 SkAutoTUnref<GrBatchPlot>* currPlot = fPlotArray;
167 for (int y = fNumPlotsY - 1, r = 0; y >= 0; --y, ++r) {
168 for (int x = fNumPlotsX - 1, c = 0; x >= 0; --x, ++c) {
169 int id = r * fNumPlotsX + c;
170 currPlot->reset(SkNEW(GrBatchPlot));
171 (*currPlot)->init(fGpu, this, texture, id, 0, x, y, fPlotWidth, fPlo tHeight, fBPP);
172
173 // build LRU list
174 fPlotList.addToHead(currPlot->get());
175 ++currPlot;
176 }
177 }
178 }
179
180 GrBatchAtlas::~GrBatchAtlas() {
181 SkSafeUnref(fTexture);
182 SkDELETE_ARRAY(fPlotArray);
183
184 #if FONT_CACHE_STATS
185 SkDebugf("Num uploads: %d\n", g_UploadCount);
186 #endif
187 }
188
189 void GrBatchAtlas::makeMRU(GrBatchPlot* plot) {
190 if (fPlotList.head() == plot) {
191 return;
192 }
193
194 fPlotList.remove(plot);
195 fPlotList.addToHead(plot);
196 }
197
198
199 inline void GrBatchAtlas::updatePlot(GrBatchTarget* batchTarget, AtlasID* id, Gr BatchPlot* plot) {
200 this->makeMRU(plot);
201
202 // if we've already issued the last plot upload, then we have to issue a new one. Otherwise we
203 // can just piggyback
bsalomon 2015/03/06 16:34:59 I understand this but might not in a few months...
joshualitt 2015/03/09 19:45:15 Acknowledged.
204 if (batchTarget->isIssued(plot->lastUploadToken())) {
205 plot->setLastUploadToken(batchTarget->asapToken());
206 batchTarget->update(GrPlotUpdater(plot));
207 }
208 *id = create_id(plot->id(), plot->generation());
209 }
210
211 bool GrBatchAtlas::addToAtlas(AtlasID* id, GrBatchTarget* batchTarget,
212 int width, int height, const void* image, SkIPoint 16* loc) {
213 // We should already have a texture, TODO clean this up
214 SkASSERT(fTexture && width < fPlotWidth && height < fPlotHeight);
215
216 // now look through all allocated plots for one we can share, in MRU order
217 GrBatchPlotList::Iter plotIter;
218 plotIter.init(fPlotList, GrBatchPlotList::Iter::kHead_IterStart);
219 GrBatchPlot* plot;
220 while ((plot = plotIter.get())) {
221 if (plot->addSubImage(width, height, image, loc)) {
222 this->updatePlot(batchTarget, id, plot);
223 return true;
224 }
225 plotIter.next();
226 }
227
228 // If the above fails, then find an unused LRU spot
229 plotIter.init(fPlotList, GrBatchPlotList::Iter::kTail_IterStart);
230 while ((plot = plotIter.get())) {
231 if (batchTarget->isIssued(plot->lastRefToken())) {
232 plot->resetRects();
233 SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, l oc);
234 SkASSERT(verify);
235 this->updatePlot(batchTarget, id, plot);
236 return true;
237 }
238 plotIter.prev();
239 }
240
241 // get LRU, queue up an upload. However, if our plot was referenced in this draw, then we can't
Jvsquare 2015/03/06 15:45:36 I don't see where we are queuing up an upload here
joshualitt 2015/03/09 19:45:14 Acknowledged.
242 // reuse it. We return false to force the caller to start a new draw
243 plotIter.init(fPlotList, GrBatchPlotList::Iter::kTail_IterStart);
244 plot = plotIter.get();
245 SkASSERT(plot);
246 if (plot->lastRefToken() == batchTarget->currentToken()) {
247 return false;
248 }
249
250 // Now we have to remove the old plot from the plot list and the plot array and add the new plot
251 int plotID = plot->id();
252 int x = plot->x();
253 int y = plot->y();
254 int generation = plot->generation();
255
256 fPlotList.remove(plot);
257 SkAutoTUnref<GrBatchPlot>& newPlot = fPlotArray[plot->id()];
258 newPlot.reset(SkNEW(GrBatchPlot));
259 newPlot->init(fGpu, this, fTexture, plotID, ++generation, x, y, fPlotWidth, fPlotHeight, fBPP);
260
261 fPlotList.addToHead(newPlot.get());
262 SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, loc);
263 SkASSERT(verify);
264 newPlot->setLastUploadToken(batchTarget->currentToken());
265 batchTarget->update(GrPlotUpdater(newPlot));
bsalomon 2015/03/06 16:34:59 @Jvsquare: I think it is here.
266 *id = create_id(newPlot->id(), newPlot->generation());
267 return true;
268 }
269
270 void GrBatchAtlas::uploadPlotsToTexture() {
271 GrBatchPlotList::Iter plotIter;
272 plotIter.init(fPlotList, GrBatchPlotList::Iter::kHead_IterStart);
273 GrBatchPlot* plot;
274 while ((plot = plotIter.get())) {
275 plot->uploadToTexture();
276 plotIter.next();
277 }
278 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698