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

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

Issue 1225923010: Refugee from Dead Machine 4: MDB Monster Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Last update from dead machine Created 4 years, 7 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
« no previous file with comments | « src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp ('k') | src/gpu/GrAtlasTextContext.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "GrAtlas.h"
10 #include "GrContext.h"
11 #include "GrGpu.h"
12 #include "GrRectanizer.h"
13 #include "GrTracing.h"
14
15 ///////////////////////////////////////////////////////////////////////////////
16
17 // for testing
18 #define FONT_CACHE_STATS 0
19 #if FONT_CACHE_STATS
20 static int g_UploadCount = 0;
21 #endif
22
23 GrPlot::GrPlot()
24 : fID(-1)
25 , fTexture(nullptr)
26 , fRects(nullptr)
27 , fAtlas(nullptr)
28 , fBytesPerPixel(1)
29 , fDirty(false)
30 , fBatchUploads(false)
31 {
32 fOffset.set(0, 0);
33 }
34
35 GrPlot::~GrPlot() {
36 delete[] fPlotData;
37 fPlotData = nullptr;
38 delete fRects;
39 }
40
41 void GrPlot::init(GrAtlas* atlas, int id, int offX, int offY, int width, int hei ght, size_t bpp,
42 bool batchUploads) {
43 fID = id;
44 fRects = GrRectanizer::Factory(width, height);
45 fAtlas = atlas;
46 fOffset.set(offX * width, offY * height);
47 fBytesPerPixel = bpp;
48 fPlotData = nullptr;
49 fDirtyRect.setEmpty();
50 fDirty = false;
51 fBatchUploads = batchUploads;
52 }
53
54 static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset) {
55 loc->fX += offset.fX;
56 loc->fY += offset.fY;
57 }
58
59 bool GrPlot::addSubImage(int width, int height, const void* image, SkIPoint16* l oc) {
60 float percentFull = fRects->percentFull();
61 if (!fRects->addRect(width, height, loc)) {
62 return false;
63 }
64
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
67 int plotWidth = fRects->width();
68 int plotHeight = fRects->height();
69 if (fBatchUploads && nullptr == fPlotData && 0.0f == percentFull) {
70 fPlotData = new unsigned char[fBytesPerPixel * plotWidth * plotHeight];
71 memset(fPlotData, 0, fBytesPerPixel*plotWidth*plotHeight);
72 }
73
74 // if we have backing memory, copy to the memory and set for future upload
75 if (fPlotData) {
76 const unsigned char* imagePtr = (const unsigned char*) image;
77 // point ourselves at the right starting spot
78 unsigned char* dataPtr = fPlotData;
79 dataPtr += fBytesPerPixel*plotWidth*loc->fY;
80 dataPtr += fBytesPerPixel*loc->fX;
81 // copy into the data buffer
82 for (int i = 0; i < height; ++i) {
83 memcpy(dataPtr, imagePtr, fBytesPerPixel*width);
84 dataPtr += fBytesPerPixel*plotWidth;
85 imagePtr += fBytesPerPixel*width;
86 }
87
88 fDirtyRect.join(loc->fX, loc->fY, loc->fX + width, loc->fY + height);
89 adjust_for_offset(loc, fOffset);
90 fDirty = true;
91 // otherwise, just upload the image directly
92 } else if (image) {
93 adjust_for_offset(loc, fOffset);
94 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTex ture");
95 fTexture->writePixels(NULL, loc->fX, loc->fY, width, height, fTexture->c onfig(), image, 0,
96 GrContext::kDontFlush_PixelOpsFlag);
97 } else {
98 adjust_for_offset(loc, fOffset);
99 }
100
101 #if FONT_CACHE_STATS
102 ++g_UploadCount;
103 #endif
104
105 return true;
106 }
107
108 void GrPlot::resetRects() {
109 SkASSERT(fRects);
110 fRects->reset();
111 }
112
113 ///////////////////////////////////////////////////////////////////////////////
114
115 GrAtlas::GrAtlas(GrGpu* gpu, GrPixelConfig config, GrSurfaceFlags flags,
116 const SkISize& backingTextureSize,
117 int numPlotsX, int numPlotsY, bool batchUploads) {
118 fGpu = SkRef(gpu);
119 fPixelConfig = config;
120 fFlags = flags;
121 fBackingTextureSize = backingTextureSize;
122 fNumPlotsX = numPlotsX;
123 fNumPlotsY = numPlotsY;
124 fBatchUploads = batchUploads;
125 fTexture = nullptr;
126
127 int textureWidth = fBackingTextureSize.width();
128 int textureHeight = fBackingTextureSize.height();
129
130 int plotWidth = textureWidth / fNumPlotsX;
131 int plotHeight = textureHeight / fNumPlotsY;
132
133 SkASSERT(plotWidth * fNumPlotsX == textureWidth);
134 SkASSERT(plotHeight * fNumPlotsY == textureHeight);
135
136 // We currently do not support compressed atlases...
137 SkASSERT(!GrPixelConfigIsCompressed(config));
138
139 // set up allocated plots
140 size_t bpp = GrBytesPerPixel(fPixelConfig);
141 fPlotArray = new GrPlot[(fNumPlotsX * fNumPlotsY)];
142
143 GrPlot* currPlot = fPlotArray;
144 for (int y = numPlotsY-1; y >= 0; --y) {
145 for (int x = numPlotsX-1; x >= 0; --x) {
146 currPlot->init(this, y*numPlotsX+x, x, y, plotWidth, plotHeight, bpp , batchUploads);
147
148 // build LRU list
149 fPlotList.addToHead(currPlot);
150 ++currPlot;
151 }
152 }
153 }
154
155 GrAtlas::~GrAtlas() {
156 SkSafeUnref(fTexture);
157 delete[] fPlotArray;
158
159 fGpu->unref();
160 #if FONT_CACHE_STATS
161 SkDebugf("Num uploads: %d\n", g_UploadCount);
162 #endif
163 }
164
165 void GrAtlas::makeMRU(GrPlot* plot) {
166 if (fPlotList.head() == plot) {
167 return;
168 }
169
170 fPlotList.remove(plot);
171 fPlotList.addToHead(plot);
172 };
173
174 GrPlot* GrAtlas::addToAtlas(ClientPlotUsage* usage,
175 int width, int height, const void* image,
176 SkIPoint16* loc) {
177 // iterate through entire plot list for this atlas, see if we can find a hol e
178 // last one was most recently added and probably most empty
179 for (int i = usage->fPlots.count()-1; i >= 0; --i) {
180 GrPlot* plot = usage->fPlots[i];
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) ) {
183 this->makeMRU(plot);
184 return plot;
185 }
186 }
187
188 // before we get a new plot, make sure we have a backing texture
189 if (nullptr == fTexture) {
190 // TODO: Update this to use the cache rather than directly creating a te xture.
191 GrSurfaceDesc desc;
192 desc.fFlags = fFlags;
193 desc.fWidth = fBackingTextureSize.width();
194 desc.fHeight = fBackingTextureSize.height();
195 desc.fConfig = fPixelConfig;
196
197 fTexture = fGpu->createTexture(desc, true, nullptr, 0);
198 if (nullptr == fTexture) {
199 return nullptr;
200 }
201 }
202
203 // now look through all allocated plots for one we can share, in MRU order
204 GrPlotList::Iter plotIter;
205 plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart);
206 GrPlot* plot;
207 while ((plot = plotIter.get())) {
208 // make sure texture is set for quick lookup
209 plot->fTexture = fTexture;
210 if (plot->addSubImage(width, height, image, loc)) {
211 this->makeMRU(plot);
212 // new plot for atlas, put at end of array
213 SkASSERT(!usage->fPlots.contains(plot));
214 *(usage->fPlots.append()) = plot;
215 return plot;
216 }
217 plotIter.next();
218 }
219
220 // If the above fails, then the current plot list has no room
221 return nullptr;
222 }
223
224 void GrAtlas::RemovePlot(ClientPlotUsage* usage, const GrPlot* plot) {
225 int index = usage->fPlots.find(const_cast<GrPlot*>(plot));
226 if (index >= 0) {
227 usage->fPlots.remove(index);
228 }
229 }
OLDNEW
« no previous file with comments | « src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp ('k') | src/gpu/GrAtlasTextContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698