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