OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrLayerCache.h" | 8 #include "GrLayerCache.h" |
9 #include "GrLayerHoister.h" | 9 #include "GrLayerHoister.h" |
10 #include "GrRecordReplaceDraw.h" | 10 #include "GrRecordReplaceDraw.h" |
11 | 11 |
12 #include "SkCanvas.h" | 12 #include "SkCanvas.h" |
13 #include "SkGrPixelRef.h" | 13 #include "SkGrPixelRef.h" |
14 #include "SkRecordDraw.h" | 14 #include "SkRecordDraw.h" |
15 #include "SkSurface.h" | 15 #include "SkSurface.h" |
16 | 16 |
17 // Create the layer information for the hoisted layer and secure the | 17 // Create the layer information for the hoisted layer and secure the |
18 // required texture/render target resources. | 18 // required texture/render target resources. |
19 static void prepare_for_hoisting(GrLayerCache* layerCache, | 19 static void prepare_for_hoisting(GrLayerCache* layerCache, |
20 const SkPicture* topLevelPicture, | 20 const SkPicture* topLevelPicture, |
21 const GrAccelData::SaveLayerInfo& info, | 21 const GrAccelData::SaveLayerInfo& info, |
22 const SkIRect& layerRect, | 22 const SkIRect& layerRect, |
23 SkTDArray<GrHoistedLayer>* atlased, | 23 SkTDArray<GrHoistedLayer>* needRendering, |
24 SkTDArray<GrHoistedLayer>* nonAtlased, | 24 SkTDArray<GrHoistedLayer>* recycled, |
25 SkTDArray<GrHoistedLayer>* recycled) { | 25 bool attemptToAtlas) { |
26 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture; | 26 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture; |
27 | 27 |
28 SkMatrix combined = SkMatrix::Concat(info.fPreMat, info.fLocalMat); | 28 SkMatrix combined = SkMatrix::Concat(info.fPreMat, info.fLocalMat); |
29 | 29 |
30 GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(), | 30 GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(), |
31 info.fSaveLayerOpID, | 31 info.fSaveLayerOpID, |
32 info.fRestoreOpID, | 32 info.fRestoreOpID, |
33 layerRect, | 33 layerRect, |
34 combined, | 34 combined, |
35 info.fPaint); | 35 info.fPaint); |
36 GrTextureDesc desc; | 36 GrTextureDesc desc; |
37 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 37 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
38 desc.fWidth = layerRect.width(); | 38 desc.fWidth = layerRect.width(); |
39 desc.fHeight = layerRect.height(); | 39 desc.fHeight = layerRect.height(); |
40 desc.fConfig = kSkia8888_GrPixelConfig; | 40 desc.fConfig = kSkia8888_GrPixelConfig; |
41 // TODO: need to deal with sample count | 41 // TODO: need to deal with sample count |
42 | 42 |
43 | 43 bool locked, needsRendering; |
44 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested || | 44 if (attemptToAtlas) { |
45 (layer->paint() && layer->paint()->getImageFilter())
; | 45 locked = layerCache->tryToAtlas(layer, desc, &needsRendering); |
46 | 46 } else { |
47 bool needsRendering = layerCache->lock(layer, desc, disallowAtlasing); | 47 locked = layerCache->lock(layer, desc, &needsRendering); |
48 if (NULL == layer->texture()) { | 48 } |
| 49 if (!locked) { |
49 // GPU resources could not be secured for the hoisting of this layer | 50 // GPU resources could not be secured for the hoisting of this layer |
50 return; | 51 return; |
51 } | 52 } |
52 | 53 |
| 54 if (attemptToAtlas) { |
| 55 SkASSERT(layer->isAtlased()); |
| 56 } |
| 57 |
53 GrHoistedLayer* hl; | 58 GrHoistedLayer* hl; |
54 | 59 |
55 if (needsRendering) { | 60 if (needsRendering) { |
56 if (layer->isAtlased()) { | 61 if (!attemptToAtlas) { |
57 hl = atlased->append(); | 62 SkASSERT(!layer->isAtlased()); |
58 } else { | |
59 hl = nonAtlased->append(); | |
60 } | 63 } |
| 64 hl = needRendering->append(); |
61 } else { | 65 } else { |
62 hl = recycled->append(); | 66 hl = recycled->append(); |
63 } | 67 } |
64 | 68 |
65 layerCache->addUse(layer); | 69 layerCache->addUse(layer); |
66 hl->fLayer = layer; | 70 hl->fLayer = layer; |
67 hl->fPicture = pict; | 71 hl->fPicture = pict; |
68 hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop); | 72 hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop); |
69 hl->fLocalMat = info.fLocalMat; | 73 hl->fLocalMat = info.fLocalMat; |
70 hl->fPreMat = info.fPreMat; | 74 hl->fPreMat = info.fPreMat; |
71 } | 75 } |
72 | 76 |
73 // Return true if any layers are suitable for hoisting | 77 // Atlased layers must be small enough to fit in the atlas, not have a |
74 bool GrLayerHoister::FindLayersToHoist(GrContext* context, | 78 // paint with an image filter and be neither nested nor nesting. |
| 79 // TODO: allow leaf nested layers to appear in the atlas. |
| 80 void GrLayerHoister::FindLayersToAtlas(GrContext* context, |
75 const SkPicture* topLevelPicture, | 81 const SkPicture* topLevelPicture, |
76 const SkRect& query, | 82 const SkRect& query, |
77 SkTDArray<GrHoistedLayer>* atlased, | 83 SkTDArray<GrHoistedLayer>* atlased, |
78 SkTDArray<GrHoistedLayer>* nonAtlased, | |
79 SkTDArray<GrHoistedLayer>* recycled) { | 84 SkTDArray<GrHoistedLayer>* recycled) { |
80 GrLayerCache* layerCache = context->getLayerCache(); | 85 GrLayerCache* layerCache = context->getLayerCache(); |
81 | 86 |
82 layerCache->processDeletedPictures(); | 87 layerCache->processDeletedPictures(); |
83 | 88 |
84 SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); | 89 SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); |
85 | 90 |
86 const SkPicture::AccelData* topLevelData = topLevelPicture->EXPERIMENTAL_get
AccelData(key); | 91 const SkPicture::AccelData* topLevelData = topLevelPicture->EXPERIMENTAL_get
AccelData(key); |
87 if (!topLevelData) { | 92 if (!topLevelData) { |
88 return false; | 93 return; |
89 } | 94 } |
90 | 95 |
91 const GrAccelData *topLevelGPUData = static_cast<const GrAccelData*>(topLeve
lData); | 96 const GrAccelData *topLevelGPUData = static_cast<const GrAccelData*>(topLeve
lData); |
92 if (0 == topLevelGPUData->numSaveLayers()) { | 97 if (0 == topLevelGPUData->numSaveLayers()) { |
93 return false; | 98 return; |
94 } | 99 } |
95 | 100 |
96 bool anyHoisted = false; | |
97 | |
98 // The layer hoisting code will pre-render and cache an entire layer if most | |
99 // of it is being used (~70%) and it will fit in a texture. This is to allow | |
100 // such layers to be re-used for different clips/tiles. | |
101 // Small layers will additionally be atlased. | |
102 // The only limitation right now is that nested layers are currently not hoi
sted. | |
103 // Parent layers are hoisted but are never atlased (so that we never swap | |
104 // away from the atlas rendertarget when generating the hoisted layers). | |
105 | |
106 atlased->setReserve(atlased->count() + topLevelGPUData->numSaveLayers()); | 101 atlased->setReserve(atlased->count() + topLevelGPUData->numSaveLayers()); |
107 | 102 |
108 // Find and prepare for hoisting all the layers that intersect the query rec
t | |
109 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) { | 103 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) { |
| 104 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo(
i); |
110 | 105 |
111 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo(
i); | 106 // TODO: ignore perspective projected layers here? |
| 107 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested || |
| 108 (info.fPaint && info.fPaint->getImageFilter()); |
| 109 |
| 110 if (disallowAtlasing) { |
| 111 continue; |
| 112 } |
112 | 113 |
113 SkRect layerRect = SkRect::Make(info.fBounds); | 114 SkRect layerRect = SkRect::Make(info.fBounds); |
114 if (!layerRect.intersect(query)) { | 115 if (!layerRect.intersect(query)) { |
115 continue; | 116 continue; |
116 } | 117 } |
117 | 118 |
118 SkIRect ir; | 119 SkIRect ir; |
119 layerRect.roundOut(&ir); | 120 layerRect.roundOut(&ir); |
120 | 121 |
121 // TODO: ignore perspective projected layers here! | 122 if (!GrLayerCache::PlausiblyAtlasable(ir.width(), ir.height())) { |
122 // TODO: once this code is more stable unsuitable layers can | |
123 // just be omitted during the optimization stage | |
124 if (info.fIsNested) { | |
125 continue; | 123 continue; |
126 } | 124 } |
127 | 125 |
128 prepare_for_hoisting(layerCache, topLevelPicture, info, ir, atlased, non
Atlased, recycled); | 126 prepare_for_hoisting(layerCache, topLevelPicture, info, ir, atlased, rec
ycled, true); |
129 anyHoisted = true; | |
130 } | 127 } |
131 | 128 |
132 return anyHoisted; | 129 } |
| 130 |
| 131 void GrLayerHoister::FindLayersToHoist(GrContext* context, |
| 132 const SkPicture* topLevelPicture, |
| 133 const SkRect& query, |
| 134 SkTDArray<GrHoistedLayer>* needRendering, |
| 135 SkTDArray<GrHoistedLayer>* recycled) { |
| 136 GrLayerCache* layerCache = context->getLayerCache(); |
| 137 |
| 138 layerCache->processDeletedPictures(); |
| 139 |
| 140 SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); |
| 141 |
| 142 const SkPicture::AccelData* topLevelData = topLevelPicture->EXPERIMENTAL_get
AccelData(key); |
| 143 if (!topLevelData) { |
| 144 return; |
| 145 } |
| 146 |
| 147 const GrAccelData *topLevelGPUData = static_cast<const GrAccelData*>(topLeve
lData); |
| 148 if (0 == topLevelGPUData->numSaveLayers()) { |
| 149 return; |
| 150 } |
| 151 |
| 152 // Find and prepare for hoisting all the layers that intersect the query rec
t |
| 153 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) { |
| 154 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo(
i); |
| 155 if (info.fIsNested) { |
| 156 // Parent layers are currently hoisted while nested layers are not. |
| 157 continue; |
| 158 } |
| 159 |
| 160 SkRect layerRect = SkRect::Make(info.fBounds); |
| 161 if (!layerRect.intersect(query)) { |
| 162 continue; |
| 163 } |
| 164 |
| 165 SkIRect ir; |
| 166 layerRect.roundOut(&ir); |
| 167 |
| 168 prepare_for_hoisting(layerCache, topLevelPicture, info, ir, |
| 169 needRendering, recycled, false); |
| 170 } |
133 } | 171 } |
134 | 172 |
135 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { | 173 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { |
136 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); | 174 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
137 result->setInfo(info); | 175 result->setInfo(info); |
138 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); | 176 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); |
139 } | 177 } |
140 | 178 |
141 static void convert_layers_to_replacements(const SkTDArray<GrHoistedLayer>& laye
rs, | 179 void GrLayerHoister::ConvertLayersToReplacements(const SkTDArray<GrHoistedLayer>
& layers, |
142 GrReplacements* replacements) { | 180 GrReplacements* replacements) { |
143 // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? | 181 // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? |
144 for (int i = 0; i < layers.count(); ++i) { | 182 for (int i = 0; i < layers.count(); ++i) { |
145 GrCachedLayer* layer = layers[i].fLayer; | 183 GrCachedLayer* layer = layers[i].fLayer; |
146 const SkPicture* picture = layers[i].fPicture; | 184 const SkPicture* picture = layers[i].fPicture; |
147 | 185 |
148 SkMatrix combined = SkMatrix::Concat(layers[i].fPreMat, layers[i].fLocal
Mat); | 186 SkMatrix combined = SkMatrix::Concat(layers[i].fPreMat, layers[i].fLocal
Mat); |
149 | 187 |
150 GrReplacements::ReplacementInfo* layerInfo = | 188 GrReplacements::ReplacementInfo* layerInfo = |
151 replacements->newReplacement(picture->uniqueID(), | 189 replacements->newReplacement(picture->uniqueID(), |
152 layer->start(), | 190 layer->start(), |
(...skipping 14 matching lines...) Expand all Loading... |
167 ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint(
))) | 205 ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint(
))) |
168 : NULL; | 206 : NULL; |
169 | 207 |
170 layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft, | 208 layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft, |
171 layers[i].fLayer->rect().fTop, | 209 layers[i].fLayer->rect().fTop, |
172 layers[i].fLayer->rect().width()
, | 210 layers[i].fLayer->rect().width()
, |
173 layers[i].fLayer->rect().height(
)); | 211 layers[i].fLayer->rect().height(
)); |
174 } | 212 } |
175 } | 213 } |
176 | 214 |
177 void GrLayerHoister::DrawLayers(GrContext* context, | 215 void GrLayerHoister::DrawLayersToAtlas(GrContext* context, |
178 const SkTDArray<GrHoistedLayer>& atlased, | 216 const SkTDArray<GrHoistedLayer>& atlased)
{ |
179 const SkTDArray<GrHoistedLayer>& nonAtlased, | |
180 const SkTDArray<GrHoistedLayer>& recycled, | |
181 GrReplacements* replacements) { | |
182 // Render the atlased layers that require it | |
183 if (atlased.count() > 0) { | 217 if (atlased.count() > 0) { |
184 // All the atlased layers are rendered into the same GrTexture | 218 // All the atlased layers are rendered into the same GrTexture |
185 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 219 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
186 atlased[0].fLayer->texture()->asRenderTa
rget(), NULL)); | 220 atlased[0].fLayer->texture()->asRenderTa
rget(), NULL)); |
187 | 221 |
188 SkCanvas* atlasCanvas = surface->getCanvas(); | 222 SkCanvas* atlasCanvas = surface->getCanvas(); |
189 | 223 |
190 SkPaint clearPaint; | 224 SkPaint clearPaint; |
191 clearPaint.setColor(SK_ColorTRANSPARENT); | 225 clearPaint.setColor(SK_ColorTRANSPARENT); |
192 clearPaint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref
(); | 226 clearPaint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref
(); |
(...skipping 10 matching lines...) Expand all Loading... |
203 | 237 |
204 // Add a rect clip to make sure the rendering doesn't | 238 // Add a rect clip to make sure the rendering doesn't |
205 // extend beyond the boundaries of the atlased sub-rect | 239 // extend beyond the boundaries of the atlased sub-rect |
206 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), | 240 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
207 SkIntToScalar(layer->rect().fTop), | 241 SkIntToScalar(layer->rect().fTop), |
208 SkIntToScalar(layer->rect().width())
, | 242 SkIntToScalar(layer->rect().width())
, |
209 SkIntToScalar(layer->rect().height()
)); | 243 SkIntToScalar(layer->rect().height()
)); |
210 atlasCanvas->clipRect(bound); | 244 atlasCanvas->clipRect(bound); |
211 | 245 |
212 // Since 'clear' doesn't respect the clip we need to draw a rect | 246 // Since 'clear' doesn't respect the clip we need to draw a rect |
213 // TODO: ensure none of the atlased layers contain a clear call! | |
214 atlasCanvas->drawRect(bound, clearPaint); | 247 atlasCanvas->drawRect(bound, clearPaint); |
215 | 248 |
216 // info.fCTM maps the layer's top/left to the origin. | 249 // '-offset' maps the layer's top/left to the origin. |
217 // Since this layer is atlased, the top/left corner needs | 250 // Since this layer is atlased, the top/left corner needs |
218 // to be offset to the correct location in the backing texture. | 251 // to be offset to the correct location in the backing texture. |
219 SkMatrix initialCTM; | 252 SkMatrix initialCTM; |
220 initialCTM.setTranslate(SkIntToScalar(-offset.fX), | 253 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-of
fset.fY)); |
221 SkIntToScalar(-offset.fY)); | 254 initialCTM.preTranslate(bound.fLeft, bound.fTop); |
222 initialCTM.postTranslate(bound.fLeft, bound.fTop); | 255 initialCTM.preConcat(atlased[i].fPreMat); |
223 initialCTM.postConcat(atlased[i].fPreMat); | |
224 | 256 |
225 atlasCanvas->translate(SkIntToScalar(-offset.fX), | 257 atlasCanvas->setMatrix(initialCTM); |
226 SkIntToScalar(-offset.fY)); | |
227 atlasCanvas->translate(bound.fLeft, bound.fTop); | |
228 atlasCanvas->concat(atlased[i].fPreMat); | |
229 atlasCanvas->concat(atlased[i].fLocalMat); | 258 atlasCanvas->concat(atlased[i].fLocalMat); |
230 | 259 |
231 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound, | 260 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound, |
232 layer->start()+1, layer->stop(), initialCTM); | 261 layer->start() + 1, layer->stop(), initialCTM); |
233 | 262 |
234 atlasCanvas->restore(); | 263 atlasCanvas->restore(); |
235 } | 264 } |
236 | 265 |
237 atlasCanvas->flush(); | 266 atlasCanvas->flush(); |
238 } | 267 } |
| 268 } |
239 | 269 |
240 // Render the non-atlased layers that require it | 270 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
er>& layers) { |
241 for (int i = 0; i < nonAtlased.count(); ++i) { | 271 for (int i = 0; i < layers.count(); ++i) { |
242 GrCachedLayer* layer = nonAtlased[i].fLayer; | 272 GrCachedLayer* layer = layers[i].fLayer; |
243 const SkPicture* pict = nonAtlased[i].fPicture; | 273 const SkPicture* pict = layers[i].fPicture; |
244 const SkIPoint& offset = nonAtlased[i].fOffset; | 274 const SkIPoint& offset = layers[i].fOffset; |
245 | 275 |
246 // Each non-atlased layer has its own GrTexture | 276 // Each non-atlased layer has its own GrTexture |
247 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 277 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
248 layer->texture()->asRenderTarget(), NULL
)); | 278 layer->texture()->asRenderTarget(), NULL
)); |
249 | 279 |
250 SkCanvas* layerCanvas = surface->getCanvas(); | 280 SkCanvas* layerCanvas = surface->getCanvas(); |
251 | 281 |
252 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); | 282 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); |
253 | 283 |
254 // Add a rect clip to make sure the rendering doesn't | 284 // Add a rect clip to make sure the rendering doesn't |
255 // extend beyond the boundaries of the atlased sub-rect | 285 // extend beyond the boundaries of the layer |
256 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), | 286 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
257 SkIntToScalar(layer->rect().fTop), | 287 SkIntToScalar(layer->rect().fTop), |
258 SkIntToScalar(layer->rect().width()), | 288 SkIntToScalar(layer->rect().width()), |
259 SkIntToScalar(layer->rect().height())); | 289 SkIntToScalar(layer->rect().height())); |
260 | 290 |
261 layerCanvas->clipRect(bound); // TODO: still useful? | 291 layerCanvas->clipRect(bound); |
262 | 292 |
263 layerCanvas->clear(SK_ColorTRANSPARENT); | 293 layerCanvas->clear(SK_ColorTRANSPARENT); |
264 | 294 |
265 SkMatrix initialCTM; | 295 SkMatrix initialCTM; |
266 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset
.fY)); | 296 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset
.fY)); |
267 initialCTM.postConcat(nonAtlased[i].fPreMat); | 297 initialCTM.preConcat(layers[i].fPreMat); |
268 | 298 |
269 layerCanvas->translate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.
fY)); | 299 layerCanvas->setMatrix(initialCTM); |
270 layerCanvas->concat(nonAtlased[i].fPreMat); | 300 layerCanvas->concat(layers[i].fLocalMat); |
271 layerCanvas->concat(nonAtlased[i].fLocalMat); | |
272 | 301 |
273 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound, | 302 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound, |
274 layer->start()+1, layer->stop(), initialCTM); | 303 layer->start()+1, layer->stop(), initialCTM); |
275 | 304 |
276 layerCanvas->flush(); | 305 layerCanvas->flush(); |
277 } | 306 } |
278 | |
279 convert_layers_to_replacements(atlased, replacements); | |
280 convert_layers_to_replacements(nonAtlased, replacements); | |
281 convert_layers_to_replacements(recycled, replacements); | |
282 } | 307 } |
283 | 308 |
284 void GrLayerHoister::UnlockLayers(GrContext* context, | 309 void GrLayerHoister::UnlockLayers(GrContext* context, |
285 const SkTDArray<GrHoistedLayer>& atlased, | 310 const SkTDArray<GrHoistedLayer>& layers) { |
286 const SkTDArray<GrHoistedLayer>& nonAtlased, | |
287 const SkTDArray<GrHoistedLayer>& recycled) { | |
288 GrLayerCache* layerCache = context->getLayerCache(); | 311 GrLayerCache* layerCache = context->getLayerCache(); |
289 | 312 |
290 for (int i = 0; i < atlased.count(); ++i) { | 313 for (int i = 0; i < layers.count(); ++i) { |
291 layerCache->removeUse(atlased[i].fLayer); | 314 layerCache->removeUse(layers[i].fLayer); |
292 } | |
293 | |
294 for (int i = 0; i < nonAtlased.count(); ++i) { | |
295 layerCache->removeUse(nonAtlased[i].fLayer); | |
296 } | |
297 | |
298 for (int i = 0; i < recycled.count(); ++i) { | |
299 layerCache->removeUse(recycled[i].fLayer); | |
300 } | 315 } |
301 | 316 |
302 #if DISABLE_CACHING | 317 #if DISABLE_CACHING |
303 // This code completely clears out the atlas. It is required when | 318 // This code completely clears out the atlas. It is required when |
304 // caching is disabled so the atlas doesn't fill up and force more | 319 // caching is disabled so the atlas doesn't fill up and force more |
305 // free floating layers | 320 // free floating layers |
306 layerCache->purgeAll(); | 321 layerCache->purgeAll(); |
307 #endif | 322 #endif |
308 | 323 |
309 SkDEBUGCODE(layerCache->validate();) | 324 SkDEBUGCODE(layerCache->validate();) |
310 } | 325 } |
311 | 326 |
OLD | NEW |