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

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

Issue 269423007: Add CPU backing store for GrAtlas to reduce texture uploads (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Initialize fBatchUploads in GrPlot. Created 6 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/gpu/GrAtlas.h ('k') | src/gpu/GrBitmapTextContext.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13
14 /////////////////////////////////////////////////////////////////////////////// 14 ///////////////////////////////////////////////////////////////////////////////
15 15
16 // for testing 16 // for testing
17 #define FONT_CACHE_STATS 0 17 #define FONT_CACHE_STATS 0
18 #if FONT_CACHE_STATS 18 #if FONT_CACHE_STATS
19 static int g_UploadCount = 0; 19 static int g_UploadCount = 0;
20 #endif 20 #endif
21 21
22 GrPlot::GrPlot() : fDrawToken(NULL, 0) 22 GrPlot::GrPlot() : fDrawToken(NULL, 0)
23 , fTexture(NULL) 23 , fTexture(NULL)
24 , fRects(NULL) 24 , fRects(NULL)
25 , fAtlasMgr(NULL) 25 , fAtlasMgr(NULL)
26 , fBytesPerPixel(1) 26 , fBytesPerPixel(1)
27 , fDirty(false)
28 , fBatchUploads(false)
27 { 29 {
28 fOffset.set(0, 0); 30 fOffset.set(0, 0);
29 } 31 }
30 32
31 GrPlot::~GrPlot() { 33 GrPlot::~GrPlot() {
34 SkDELETE_ARRAY(fPlotData);
35 fPlotData = NULL;
32 delete fRects; 36 delete fRects;
33 } 37 }
34 38
35 void GrPlot::init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, si ze_t bpp) { 39 void GrPlot::init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, si ze_t bpp,
40 bool batchUploads) {
36 fRects = GrRectanizer::Factory(width, height); 41 fRects = GrRectanizer::Factory(width, height);
37 fAtlasMgr = mgr; 42 fAtlasMgr = mgr;
38 fOffset.set(offX * width, offY * height); 43 fOffset.set(offX * width, offY * height);
39 fBytesPerPixel = bpp; 44 fBytesPerPixel = bpp;
45 fPlotData = NULL;
46 fDirtyRect.setEmpty();
47 fDirty = false;
48 fBatchUploads = batchUploads;
40 } 49 }
41 50
42 static inline void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) { 51 static inline void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) {
43 loc->fX += offset.fX; 52 loc->fX += offset.fX;
44 loc->fY += offset.fY; 53 loc->fY += offset.fY;
45 } 54 }
46 55
47 bool GrPlot::addSubImage(int width, int height, const void* image, 56 bool GrPlot::addSubImage(int width, int height, const void* image,
48 GrIPoint16* loc) { 57 GrIPoint16* loc) {
58 float percentFull = fRects->percentFull();
49 if (!fRects->addRect(width, height, loc)) { 59 if (!fRects->addRect(width, height, loc)) {
50 return false; 60 return false;
51 } 61 }
52 62
53 SkAutoSMalloc<1024> storage; 63 // if batching uploads, create backing memory on first use
54 adjust_for_offset(loc, fOffset); 64 // once the plot is nearly full we will revert to uploading each subimage in dividually
55 GrContext* context = fTexture->getContext(); 65 int plotWidth = fRects->width();
56 // We pass the flag that does not force a flush. We assume our caller is 66 int plotHeight = fRects->height();
57 // smart and hasn't referenced the part of the texture we're about to update 67 if (fBatchUploads && NULL == fPlotData && 0.0f == percentFull) {
58 // since the last flush. 68 fPlotData = SkNEW_ARRAY(unsigned char, fBytesPerPixel*plotWidth*plotHeig ht);
59 context->writeTexturePixels(fTexture, 69 memset(fPlotData, 0, fBytesPerPixel*plotWidth*plotHeight);
60 loc->fX, loc->fY, width, height, 70 }
61 fTexture->config(), image, 0, 71
62 GrContext::kDontFlush_PixelOpsFlag); 72 // if we have backing memory, copy to the memory and set for future upload
73 if (NULL != fPlotData) {
74 const unsigned char* imagePtr = (const unsigned char*) image;
75 // point ourselves at the right starting spot
76 unsigned char* dataPtr = fPlotData;
77 dataPtr += fBytesPerPixel*plotWidth*loc->fY;
78 dataPtr += fBytesPerPixel*loc->fX;
79 // copy into the data buffer
80 for (int i = 0; i < height; ++i) {
81 memcpy(dataPtr, imagePtr, fBytesPerPixel*width);
82 dataPtr += fBytesPerPixel*plotWidth;
83 imagePtr += fBytesPerPixel*width;
84 }
85
86 fDirtyRect.join(loc->fX, loc->fY, loc->fX + width, loc->fY + height);
87 adjust_for_offset(loc, fOffset);
88 fDirty = true;
89 // otherwise, just upload the image directly
90 } else {
91 adjust_for_offset(loc, fOffset);
92 GrContext* context = fTexture->getContext();
93 context->writeTexturePixels(fTexture,
94 loc->fX, loc->fY, width, height,
95 fTexture->config(), image, 0,
96 GrContext::kDontFlush_PixelOpsFlag);
97 }
63 98
64 #if FONT_CACHE_STATS 99 #if FONT_CACHE_STATS
65 ++g_UploadCount; 100 ++g_UploadCount;
66 #endif 101 #endif
67 102
68 return true; 103 return true;
69 } 104 }
70 105
106 void GrPlot::uploadToTexture() {
robertphillips 2014/05/14 14:46:19 SkASSERT(fBatchUploads); ?
jvanverth1 2014/05/14 15:01:32 Done.
107 static const float kNearlyFullTolerance = 0.85f;
108
109 if (fDirty) {
110 SkASSERT(NULL != fTexture);
111 GrContext* context = fTexture->getContext();
112 // We pass the flag that does not force a flush. We assume our caller is
113 // smart and hasn't referenced the part of the texture we're about to up date
114 // since the last flush.
115 int rowBytes = fBytesPerPixel*fRects->width();
116 const unsigned char* dataPtr = fPlotData;
117 dataPtr += rowBytes*fDirtyRect.fTop;
118 dataPtr += fBytesPerPixel*fDirtyRect.fLeft;
119 context->writeTexturePixels(fTexture,
120 fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop,
121 fDirtyRect.width(), fDirtyRect.height(),
122 fTexture->config(), dataPtr,
123 rowBytes,
124 GrContext::kDontFlush_PixelOpsFlag);
125 fDirtyRect.setEmpty();
126 fDirty = false;
127 // If the Plot is nearly full, anything else we add will probably be sma ll and one
128 // at a time, so free up the memory and after this upload any new images directly.
129 if (fRects->percentFull() > kNearlyFullTolerance) {
130 SkDELETE_ARRAY(fPlotData);
131 fPlotData = NULL;
132 }
133 }
134 }
135
71 void GrPlot::resetRects() { 136 void GrPlot::resetRects() {
72 SkASSERT(NULL != fRects); 137 SkASSERT(NULL != fRects);
73 fRects->reset(); 138 fRects->reset();
74 } 139 }
75 140
76 /////////////////////////////////////////////////////////////////////////////// 141 ///////////////////////////////////////////////////////////////////////////////
77 142
78 GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config, 143 GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config,
79 const SkISize& backingTextureSize, 144 const SkISize& backingTextureSize,
80 int numPlotsX, int numPlotsY) { 145 int numPlotsX, int numPlotsY, bool batchUploads) {
81 fGpu = SkRef(gpu); 146 fGpu = SkRef(gpu);
82 fPixelConfig = config; 147 fPixelConfig = config;
83 fBackingTextureSize = backingTextureSize; 148 fBackingTextureSize = backingTextureSize;
84 fNumPlotsX = numPlotsX; 149 fNumPlotsX = numPlotsX;
85 fNumPlotsY = numPlotsY; 150 fNumPlotsY = numPlotsY;
151 fBatchUploads = batchUploads;
86 fTexture = NULL; 152 fTexture = NULL;
87 153
88 int plotWidth = fBackingTextureSize.width() / fNumPlotsX; 154 int textureWidth = fBackingTextureSize.width();
89 int plotHeight = fBackingTextureSize.height() / fNumPlotsY; 155 int textureHeight = fBackingTextureSize.height();
90 156
91 SkASSERT(plotWidth * fNumPlotsX == fBackingTextureSize.width()); 157 int plotWidth = textureWidth / fNumPlotsX;
92 SkASSERT(plotHeight * fNumPlotsY == fBackingTextureSize.height()); 158 int plotHeight = textureHeight / fNumPlotsY;
159
160 SkASSERT(plotWidth * fNumPlotsX == textureWidth);
161 SkASSERT(plotHeight * fNumPlotsY == textureHeight);
93 162
94 // set up allocated plots 163 // set up allocated plots
95 size_t bpp = GrBytesPerPixel(fPixelConfig); 164 size_t bpp = GrBytesPerPixel(fPixelConfig);
96 fPlotArray = SkNEW_ARRAY(GrPlot, (fNumPlotsX*fNumPlotsY)); 165 fPlotArray = SkNEW_ARRAY(GrPlot, (fNumPlotsX*fNumPlotsY));
97 166
98 GrPlot* currPlot = fPlotArray; 167 GrPlot* currPlot = fPlotArray;
99 for (int y = numPlotsY-1; y >= 0; --y) { 168 for (int y = numPlotsY-1; y >= 0; --y) {
100 for (int x = numPlotsX-1; x >= 0; --x) { 169 for (int x = numPlotsX-1; x >= 0; --x) {
101 currPlot->init(this, x, y, plotWidth, plotHeight, bpp); 170 currPlot->init(this, x, y, plotWidth, plotHeight, bpp, batchUploads) ;
102 171
103 // build LRU list 172 // build LRU list
104 fPlotList.addToHead(currPlot); 173 fPlotList.addToHead(currPlot);
105 ++currPlot; 174 ++currPlot;
106 } 175 }
107 } 176 }
108 } 177 }
109 178
110 GrAtlasMgr::~GrAtlasMgr() { 179 GrAtlasMgr::~GrAtlasMgr() {
111 SkSafeUnref(fTexture); 180 SkSafeUnref(fTexture);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 GrPlot* plot; 263 GrPlot* plot;
195 while (NULL != (plot = plotIter.get())) { 264 while (NULL != (plot = plotIter.get())) {
196 if (plot->drawToken().isIssued()) { 265 if (plot->drawToken().isIssued()) {
197 return plot; 266 return plot;
198 } 267 }
199 plotIter.prev(); 268 plotIter.prev();
200 } 269 }
201 270
202 return NULL; 271 return NULL;
203 } 272 }
273
274 void GrAtlasMgr::uploadPlotsToTexture() {
275 if (fBatchUploads) {
276 GrPlotList::Iter plotIter;
277 plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart);
278 GrPlot* plot;
279 while (NULL != (plot = plotIter.get())) {
280 plot->uploadToTexture();
281 plotIter.next();
282 }
283 }
284 }
OLDNEW
« no previous file with comments | « src/gpu/GrAtlas.h ('k') | src/gpu/GrBitmapTextContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698