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 "GrGpuResourcePriv.h" | |
10 #include "GrLayerAtlas.h" | 9 #include "GrLayerAtlas.h" |
11 #include "GrRectanizer.h" | 10 #include "GrRectanizer.h" |
12 #include "GrTextureProvider.h" | 11 #include "GrTextureProvider.h" |
13 | 12 |
14 /////////////////////////////////////////////////////////////////////////////// | 13 /////////////////////////////////////////////////////////////////////////////// |
15 GrLayerAtlas::Plot::Plot() | 14 GrLayerAtlas::Plot::Plot() |
16 : fID(-1) | 15 : fID(-1) |
17 , fRects(nullptr) { | 16 , fRects(nullptr) { |
18 fOffset.set(0, 0); | 17 fOffset.set(0, 0); |
19 } | 18 } |
(...skipping 17 matching lines...) Expand all Loading... |
37 loc->fY += fOffset.fY; | 36 loc->fY += fOffset.fY; |
38 return true; | 37 return true; |
39 } | 38 } |
40 | 39 |
41 void GrLayerAtlas::Plot::reset() { | 40 void GrLayerAtlas::Plot::reset() { |
42 SkASSERT(fRects); | 41 SkASSERT(fRects); |
43 fRects->reset(); | 42 fRects->reset(); |
44 } | 43 } |
45 | 44 |
46 /////////////////////////////////////////////////////////////////////////////// | 45 /////////////////////////////////////////////////////////////////////////////// |
47 GR_DECLARE_STATIC_UNIQUE_KEY(gLayerAtlasKey); | |
48 static const GrUniqueKey& get_layer_atlas_key() { | |
49 GR_DEFINE_STATIC_UNIQUE_KEY(gLayerAtlasKey); | |
50 return gLayerAtlasKey; | |
51 } | |
52 | |
53 bool GrLayerAtlas::reattachBackingTexture() { | |
54 SkASSERT(!fTexture); | |
55 | |
56 fTexture.reset(fTexProvider->findAndRefTextureByUniqueKey(get_layer_atlas_ke
y())); | |
57 return SkToBool(fTexture); | |
58 } | |
59 | |
60 void GrLayerAtlas::createBackingTexture() { | |
61 SkASSERT(!fTexture); | |
62 | |
63 GrSurfaceDesc desc; | |
64 desc.fFlags = fFlags; | |
65 desc.fWidth = fBackingTextureSize.width(); | |
66 desc.fHeight = fBackingTextureSize.height(); | |
67 desc.fConfig = fPixelConfig; | |
68 | |
69 fTexture.reset(fTexProvider->createTexture(desc, true, nullptr, 0)); | |
70 | |
71 fTexture->resourcePriv().setUniqueKey(get_layer_atlas_key()); | |
72 } | |
73 | 46 |
74 GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config,
| 47 GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config,
|
75 GrSurfaceFlags flags, | 48 GrSurfaceFlags flags, |
76 const SkISize& backingTextureSize, | 49 const SkISize& backingTextureSize, |
77 int numPlotsX, int numPlotsY) { | 50 int numPlotsX, int numPlotsY) { |
78 fTexProvider = texProvider; | 51 fTexProvider = texProvider; |
79 fPixelConfig = config; | 52 fPixelConfig = config; |
80 fFlags = flags; | 53 fFlags = flags; |
81 fBackingTextureSize = backingTextureSize; | 54 fBackingTextureSize = backingTextureSize; |
| 55 fTexture = nullptr; |
82 | 56 |
83 int textureWidth = fBackingTextureSize.width(); | 57 int textureWidth = fBackingTextureSize.width(); |
84 int textureHeight = fBackingTextureSize.height(); | 58 int textureHeight = fBackingTextureSize.height(); |
85 | 59 |
86 int plotWidth = textureWidth / numPlotsX; | 60 int plotWidth = textureWidth / numPlotsX; |
87 int plotHeight = textureHeight / numPlotsY; | 61 int plotHeight = textureHeight / numPlotsY; |
88 | 62 |
89 SkASSERT(plotWidth * numPlotsX == textureWidth); | 63 SkASSERT(plotWidth * numPlotsX == textureWidth); |
90 SkASSERT(plotHeight * numPlotsY == textureHeight); | 64 SkASSERT(plotHeight * numPlotsY == textureHeight); |
91 | 65 |
92 // We currently do not support compressed atlases... | 66 // We currently do not support compressed atlases... |
93 SkASSERT(!GrPixelConfigIsCompressed(config)); | 67 SkASSERT(!GrPixelConfigIsCompressed(config)); |
94 | 68 |
95 // set up allocated plots | 69 // set up allocated plots |
96 fPlotArray = new Plot[numPlotsX * numPlotsY]; | 70 fPlotArray = new Plot[numPlotsX * numPlotsY]; |
97 | 71 |
98 Plot* currPlot = fPlotArray; | 72 Plot* currPlot = fPlotArray; |
99 for (int y = numPlotsY-1; y >= 0; --y) { | 73 for (int y = numPlotsY-1; y >= 0; --y) { |
100 for (int x = numPlotsX-1; x >= 0; --x) { | 74 for (int x = numPlotsX-1; x >= 0; --x) { |
101 currPlot->init(y*numPlotsX+x, x, y, plotWidth, plotHeight); | 75 currPlot->init(y*numPlotsX+x, x, y, plotWidth, plotHeight); |
102 | 76 |
103 // build LRU list | 77 // build LRU list |
104 fPlotList.addToHead(currPlot); | 78 fPlotList.addToHead(currPlot); |
105 ++currPlot; | 79 ++currPlot; |
106 } | 80 } |
107 } | 81 } |
108 } | 82 } |
109 | 83 |
110 void GrLayerAtlas::resetPlots() { | |
111 PlotIter iter; | |
112 for (Plot* plot = iter.init(fPlotList, PlotIter::kHead_IterStart); plot; plo
t = iter.next()) { | |
113 plot->reset(); | |
114 } | |
115 } | |
116 | |
117 GrLayerAtlas::~GrLayerAtlas() { | 84 GrLayerAtlas::~GrLayerAtlas() { |
| 85 SkSafeUnref(fTexture); |
118 delete[] fPlotArray; | 86 delete[] fPlotArray; |
119 } | 87 } |
120 | 88 |
121 void GrLayerAtlas::makeMRU(Plot* plot) { | 89 void GrLayerAtlas::makeMRU(Plot* plot) { |
122 if (fPlotList.head() == plot) { | 90 if (fPlotList.head() == plot) { |
123 return; | 91 return; |
124 } | 92 } |
125 | 93 |
126 fPlotList.remove(plot); | 94 fPlotList.remove(plot); |
127 fPlotList.addToHead(plot); | 95 fPlotList.addToHead(plot); |
128 }; | 96 }; |
129 | 97 |
130 GrLayerAtlas::Plot* GrLayerAtlas::addToAtlas(ClientPlotUsage* usage, | 98 GrLayerAtlas::Plot* GrLayerAtlas::addToAtlas(ClientPlotUsage* usage, |
131 int width, int height, SkIPoint16*
loc) { | 99 int width, int height, SkIPoint16*
loc) { |
132 // Iterate through the plots currently being used by this client and see if
we can find a hole. | 100 // Iterate through the plots currently being used by this client and see if
we can find a hole. |
133 // The last one was most recently added and probably most empty. | 101 // The last one was most recently added and probably most empty. |
134 // We want to consolidate the uses from individual clients to the same plot(
s) so that | 102 // We want to consolidate the uses from individual clients to the same plot(
s) so that |
135 // when a specific client goes away they are more likely to completely empty
a plot. | 103 // when a specific client goes away they are more likely to completely empty
a plot. |
136 for (int i = usage->numPlots()-1; i >= 0; --i) { | 104 for (int i = usage->numPlots()-1; i >= 0; --i) { |
137 Plot* plot = usage->plot(i); | 105 Plot* plot = usage->plot(i); |
138 if (plot->allocateRect(width, height, loc)) { | 106 if (plot->allocateRect(width, height, loc)) { |
139 this->makeMRU(plot); | 107 this->makeMRU(plot); |
140 return plot; | 108 return plot; |
141 } | 109 } |
142 } | 110 } |
143 | 111 |
144 // before we get a new plot, make sure we have a backing texture | 112 // before we get a new plot, make sure we have a backing texture |
145 if (nullptr == fTexture) { | 113 if (nullptr == fTexture) { |
146 this->createBackingTexture(); | 114 // TODO: Update this to use the cache rather than directly creating a te
xture. |
| 115 GrSurfaceDesc desc; |
| 116 desc.fFlags = fFlags; |
| 117 desc.fWidth = fBackingTextureSize.width(); |
| 118 desc.fHeight = fBackingTextureSize.height(); |
| 119 desc.fConfig = fPixelConfig; |
| 120 |
| 121 fTexture = fTexProvider->createTexture(desc, true, nullptr, 0); |
147 if (nullptr == fTexture) { | 122 if (nullptr == fTexture) { |
148 return nullptr; | 123 return nullptr; |
149 } | 124 } |
150 } | 125 } |
151 | 126 |
152 // Now look through all allocated plots for one we can share, in MRU order | 127 // Now look through all allocated plots for one we can share, in MRU order |
153 // TODO: its seems like traversing from emptiest to fullest would make more
sense | 128 // TODO: its seems like traversing from emptiest to fullest would make more
sense |
154 PlotList::Iter plotIter; | 129 PlotList::Iter plotIter; |
155 plotIter.init(fPlotList, PlotList::Iter::kHead_IterStart); | 130 plotIter.init(fPlotList, PlotList::Iter::kHead_IterStart); |
156 Plot* plot; | 131 Plot* plot; |
157 while ((plot = plotIter.get())) { | 132 while ((plot = plotIter.get())) { |
158 if (plot->allocateRect(width, height, loc)) { | 133 if (plot->allocateRect(width, height, loc)) { |
159 this->makeMRU(plot); | 134 this->makeMRU(plot); |
160 // new plot for atlas, put at end of array | 135 // new plot for atlas, put at end of array |
161 usage->appendPlot(plot); | 136 usage->appendPlot(plot); |
162 return plot; | 137 return plot; |
163 } | 138 } |
164 plotIter.next(); | 139 plotIter.next(); |
165 } | 140 } |
166 | 141 |
167 // If the above fails, then the current plot list has no room | 142 // If the above fails, then the current plot list has no room |
168 return nullptr; | 143 return nullptr; |
169 } | 144 } |
170 | 145 |
OLD | NEW |