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 "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 | 49 |
50 SkRect layerRect = SkRect::MakeXYWH(SkIntToScalar(info.fOffset.fX), | 50 SkRect layerRect = SkRect::MakeXYWH(SkIntToScalar(info.fOffset.fX), |
51 SkIntToScalar(info.fOffset.fY), | 51 SkIntToScalar(info.fOffset.fY), |
52 SkIntToScalar(info.fSize.fWidth), | 52 SkIntToScalar(info.fSize.fWidth), |
53 SkIntToScalar(info.fSize.fHeight)); | 53 SkIntToScalar(info.fSize.fHeight)); |
54 | 54 |
55 if (!SkRect::Intersects(query, layerRect)) { | 55 if (!SkRect::Intersects(query, layerRect)) { |
56 continue; | 56 continue; |
57 } | 57 } |
58 | 58 |
| 59 // TODO: ignore perspective projected layers here! |
59 // TODO: once this code is more stable unsuitable layers can | 60 // TODO: once this code is more stable unsuitable layers can |
60 // just be omitted during the optimization stage | 61 // just be omitted during the optimization stage |
61 if (!info.fValid || | 62 if (!info.fValid || |
62 kSaveLayerMaxSize < info.fSize.fWidth || | 63 kSaveLayerMaxSize < info.fSize.fWidth || |
63 kSaveLayerMaxSize < info.fSize.fHeight || | 64 kSaveLayerMaxSize < info.fSize.fHeight || |
64 info.fIsNested) { | 65 info.fIsNested) { |
65 continue; | 66 continue; |
66 } | 67 } |
67 | 68 |
68 pullForward[i] = true; | 69 pullForward[i] = true; |
69 anyHoisted = true; | 70 anyHoisted = true; |
70 } | 71 } |
71 | 72 |
72 if (!anyHoisted) { | 73 if (!anyHoisted) { |
73 return false; | 74 return false; |
74 } | 75 } |
75 | 76 |
76 atlased->setReserve(atlased->reserved() + topLevelGPUData->numSaveLayers()); | 77 atlased->setReserve(atlased->reserved() + topLevelGPUData->numSaveLayers()); |
77 | 78 |
78 // Generate the layer and/or ensure it is locked | 79 // Generate the layer and/or ensure it is locked |
79 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) { | 80 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) { |
80 if (pullForward[i]) { | 81 if (pullForward[i]) { |
81 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerI
nfo(i); | 82 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerI
nfo(i); |
82 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPict
ure; | 83 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPict
ure; |
83 | 84 |
84 GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(
), | 85 GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(
), |
85 info.fSaveLayer
OpID, | 86 info.fSaveLayer
OpID, |
86 info.fRestoreOp
ID, | 87 info.fRestoreOp
ID, |
87 info.fOffset, | |
88 info.fOriginXfo
rm, | 88 info.fOriginXfo
rm, |
89 info.fPaint); | 89 info.fPaint); |
90 | 90 |
91 GrTextureDesc desc; | 91 GrTextureDesc desc; |
92 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 92 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
93 desc.fWidth = info.fSize.fWidth; | 93 desc.fWidth = info.fSize.fWidth; |
94 desc.fHeight = info.fSize.fHeight; | 94 desc.fHeight = info.fSize.fHeight; |
95 desc.fConfig = kSkia8888_GrPixelConfig; | 95 desc.fConfig = kSkia8888_GrPixelConfig; |
96 // TODO: need to deal with sample count | 96 // TODO: need to deal with sample count |
97 | 97 |
98 bool needsRendering = layerCache->lock(layer, desc, | 98 bool needsRendering = layerCache->lock(layer, desc, |
99 info.fHasNestedLayers || info
.fIsNested); | 99 info.fHasNestedLayers || info
.fIsNested); |
100 if (NULL == layer->texture()) { | 100 if (NULL == layer->texture()) { |
101 continue; | 101 continue; |
102 } | 102 } |
103 | 103 |
104 if (needsRendering) { | 104 if (needsRendering) { |
105 HoistedLayer* info; | 105 HoistedLayer* hl; |
106 | 106 |
107 if (layer->isAtlased()) { | 107 if (layer->isAtlased()) { |
108 info = atlased->append(); | 108 hl = atlased->append(); |
109 } else { | 109 } else { |
110 info = nonAtlased->append(); | 110 hl = nonAtlased->append(); |
111 } | 111 } |
112 | 112 |
113 info->fLayer = layer; | 113 hl->fLayer = layer; |
114 info->fPicture = pict; | 114 hl->fPicture = pict; |
| 115 hl->fOffset = info.fOffset; |
| 116 hl->fCTM = info.fOriginXform; |
115 } | 117 } |
116 } | 118 } |
117 } | 119 } |
118 | 120 |
119 return anyHoisted; | 121 return anyHoisted; |
120 } | 122 } |
121 | 123 |
122 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { | 124 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { |
123 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); | 125 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
124 result->setInfo(info); | 126 result->setInfo(info); |
125 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); | 127 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); |
126 } | 128 } |
127 | 129 |
128 static void convert_layers_to_replacements(const SkTDArray<GrLayerHoister::Hoist
edLayer>& layers, | 130 static void convert_layers_to_replacements(const SkTDArray<GrLayerHoister::Hoist
edLayer>& layers, |
129 GrReplacements* replacements) { | 131 GrReplacements* replacements) { |
130 // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? | 132 // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? |
131 for (int i = 0; i < layers.count(); ++i) { | 133 for (int i = 0; i < layers.count(); ++i) { |
| 134 GrCachedLayer* layer = layers[i].fLayer; |
| 135 |
132 GrReplacements::ReplacementInfo* layerInfo = replacements->push(); | 136 GrReplacements::ReplacementInfo* layerInfo = replacements->push(); |
133 layerInfo->fStart = layers[i].fLayer->start(); | 137 layerInfo->fStart = layer->start(); |
134 layerInfo->fStop = layers[i].fLayer->stop(); | 138 layerInfo->fStop = layer->stop(); |
135 layerInfo->fPos = layers[i].fLayer->offset();; | 139 layerInfo->fPos = layers[i].fOffset; |
136 | 140 |
137 SkBitmap bm; | 141 SkBitmap bm; |
138 wrap_texture(layers[i].fLayer->texture(), | 142 wrap_texture(layers[i].fLayer->texture(), |
139 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().w
idth() | 143 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().w
idth() |
140 : layers[i].fLayer->texture(
)->width(), | 144 : layers[i].fLayer->texture(
)->width(), |
141 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().h
eight() | 145 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().h
eight() |
142 : layers[i].fLayer->texture(
)->height(), | 146 : layers[i].fLayer->texture(
)->height(), |
143 &bm); | 147 &bm); |
144 layerInfo->fImage = SkImage::NewTexture(bm); | 148 layerInfo->fImage = SkImage::NewTexture(bm); |
145 | 149 |
(...skipping 19 matching lines...) Expand all Loading... |
165 | 169 |
166 SkCanvas* atlasCanvas = surface->getCanvas(); | 170 SkCanvas* atlasCanvas = surface->getCanvas(); |
167 | 171 |
168 SkPaint paint; | 172 SkPaint paint; |
169 paint.setColor(SK_ColorTRANSPARENT); | 173 paint.setColor(SK_ColorTRANSPARENT); |
170 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref(); | 174 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref(); |
171 | 175 |
172 for (int i = 0; i < atlased.count(); ++i) { | 176 for (int i = 0; i < atlased.count(); ++i) { |
173 GrCachedLayer* layer = atlased[i].fLayer; | 177 GrCachedLayer* layer = atlased[i].fLayer; |
174 const SkPicture* pict = atlased[i].fPicture; | 178 const SkPicture* pict = atlased[i].fPicture; |
| 179 const SkIPoint offset = atlased[i].fOffset; |
175 | 180 |
176 atlasCanvas->save(); | 181 atlasCanvas->save(); |
177 | 182 |
178 // Add a rect clip to make sure the rendering doesn't | 183 // Add a rect clip to make sure the rendering doesn't |
179 // extend beyond the boundaries of the atlased sub-rect | 184 // extend beyond the boundaries of the atlased sub-rect |
180 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), | 185 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
181 SkIntToScalar(layer->rect().fTop), | 186 SkIntToScalar(layer->rect().fTop), |
182 SkIntToScalar(layer->rect().width())
, | 187 SkIntToScalar(layer->rect().width())
, |
183 SkIntToScalar(layer->rect().height()
)); | 188 SkIntToScalar(layer->rect().height()
)); |
184 atlasCanvas->clipRect(bound); | 189 atlasCanvas->clipRect(bound); |
185 | 190 |
186 // Since 'clear' doesn't respect the clip we need to draw a rect | 191 // Since 'clear' doesn't respect the clip we need to draw a rect |
187 // TODO: ensure none of the atlased layers contain a clear call! | 192 // TODO: ensure none of the atlased layers contain a clear call! |
188 atlasCanvas->drawRect(bound, paint); | 193 atlasCanvas->drawRect(bound, paint); |
189 | 194 |
190 // info.fCTM maps the layer's top/left to the origin. | 195 // info.fCTM maps the layer's top/left to the origin. |
191 // Since this layer is atlased, the top/left corner needs | 196 // Since this layer is atlased, the top/left corner needs |
192 // to be offset to the correct location in the backing texture. | 197 // to be offset to the correct location in the backing texture. |
193 SkMatrix initialCTM; | 198 SkMatrix initialCTM; |
194 initialCTM.setTranslate(SkIntToScalar(-layer->offset().fX), | 199 initialCTM.setTranslate(SkIntToScalar(-offset.fX), |
195 SkIntToScalar(-layer->offset().fY)); | 200 SkIntToScalar(-offset.fY)); |
196 initialCTM.postTranslate(bound.fLeft, bound.fTop); | 201 initialCTM.postTranslate(bound.fLeft, bound.fTop); |
197 | 202 |
198 atlasCanvas->translate(SkIntToScalar(-layer->offset().fX), | 203 atlasCanvas->translate(SkIntToScalar(-offset.fX), |
199 SkIntToScalar(-layer->offset().fY)); | 204 SkIntToScalar(-offset.fY)); |
200 atlasCanvas->translate(bound.fLeft, bound.fTop); | 205 atlasCanvas->translate(bound.fLeft, bound.fTop); |
201 atlasCanvas->concat(layer->ctm()); | 206 atlasCanvas->concat(atlased[i].fCTM); |
202 | 207 |
203 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound, | 208 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound, |
204 layer->start()+1, layer->stop(), initialCTM); | 209 layer->start()+1, layer->stop(), initialCTM); |
205 | 210 |
206 atlasCanvas->restore(); | 211 atlasCanvas->restore(); |
207 } | 212 } |
208 | 213 |
209 atlasCanvas->flush(); | 214 atlasCanvas->flush(); |
210 } | 215 } |
211 | 216 |
212 // Render the non-atlased layers that require it | 217 // Render the non-atlased layers that require it |
213 for (int i = 0; i < nonAtlased.count(); ++i) { | 218 for (int i = 0; i < nonAtlased.count(); ++i) { |
214 GrCachedLayer* layer = nonAtlased[i].fLayer; | 219 GrCachedLayer* layer = nonAtlased[i].fLayer; |
215 const SkPicture* pict = nonAtlased[i].fPicture; | 220 const SkPicture* pict = nonAtlased[i].fPicture; |
| 221 const SkIPoint offset = nonAtlased[i].fOffset; |
216 | 222 |
217 // Each non-atlased layer has its own GrTexture | 223 // Each non-atlased layer has its own GrTexture |
218 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 224 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
219 layer->texture()->asRenderTarget(), NULL
)); | 225 layer->texture()->asRenderTarget(), NULL
)); |
220 | 226 |
221 SkCanvas* layerCanvas = surface->getCanvas(); | 227 SkCanvas* layerCanvas = surface->getCanvas(); |
222 | 228 |
223 // Add a rect clip to make sure the rendering doesn't | 229 // Add a rect clip to make sure the rendering doesn't |
224 // extend beyond the boundaries of the atlased sub-rect | 230 // extend beyond the boundaries of the atlased sub-rect |
225 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), | 231 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
226 SkIntToScalar(layer->rect().fTop), | 232 SkIntToScalar(layer->rect().fTop), |
227 SkIntToScalar(layer->rect().width()), | 233 SkIntToScalar(layer->rect().width()), |
228 SkIntToScalar(layer->rect().height())); | 234 SkIntToScalar(layer->rect().height())); |
229 | 235 |
230 layerCanvas->clipRect(bound); // TODO: still useful? | 236 layerCanvas->clipRect(bound); // TODO: still useful? |
231 | 237 |
232 layerCanvas->clear(SK_ColorTRANSPARENT); | 238 layerCanvas->clear(SK_ColorTRANSPARENT); |
233 | 239 |
234 SkMatrix initialCTM; | 240 SkMatrix initialCTM; |
235 initialCTM.setTranslate(SkIntToScalar(-layer->offset().fX), | 241 initialCTM.setTranslate(SkIntToScalar(-offset.fX), |
236 SkIntToScalar(-layer->offset().fY)); | 242 SkIntToScalar(-offset.fY)); |
237 | 243 |
238 layerCanvas->translate(SkIntToScalar(-layer->offset().fX), | 244 layerCanvas->translate(SkIntToScalar(-offset.fX), |
239 SkIntToScalar(-layer->offset().fY)); | 245 SkIntToScalar(-offset.fY)); |
240 layerCanvas->concat(layer->ctm()); | 246 layerCanvas->concat(nonAtlased[i].fCTM); |
241 | 247 |
242 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound, | 248 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound, |
243 layer->start()+1, layer->stop(), initialCTM); | 249 layer->start()+1, layer->stop(), initialCTM); |
244 | 250 |
245 layerCanvas->flush(); | 251 layerCanvas->flush(); |
246 } | 252 } |
247 | 253 |
248 convert_layers_to_replacements(atlased, replacements); | 254 convert_layers_to_replacements(atlased, replacements); |
249 convert_layers_to_replacements(nonAtlased, replacements); | 255 convert_layers_to_replacements(nonAtlased, replacements); |
250 } | 256 } |
251 | 257 |
252 static void unlock_layer_in_cache(GrLayerCache* layerCache, | 258 static void unlock_layer_in_cache(GrLayerCache* layerCache, |
253 const SkPicture* picture, | 259 const SkPicture* picture, |
254 GrCachedLayer* layer) { | 260 GrCachedLayer* layer) { |
255 layerCache->unlock(layer); | 261 layerCache->unlock(layer); |
256 | 262 |
257 #if DISABLE_CACHING | 263 #if DISABLE_CACHING |
258 // This code completely clears out the atlas. It is required when | 264 // This code completely clears out the atlas. It is required when |
259 // caching is disabled so the atlas doesn't fill up and force more | 265 // caching is disabled so the atlas doesn't fill up and force more |
260 // free floating layers | 266 // free floating layers |
261 layerCache->purge(picture->uniqueID()); | 267 layerCache->purge(picture->uniqueID()); |
262 #endif | 268 #endif |
263 } | 269 } |
264 | 270 |
265 void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, | 271 void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, |
266 const SkTDArray<HoistedLayer>& atlased, | 272 const SkTDArray<HoistedLayer>& atlased, |
267 const SkTDArray<HoistedLayer>& nonAtlased) { | 273 const SkTDArray<HoistedLayer>& nonAtlased) { |
268 | 274 |
269 for (int i = 0; i < atlased.count(); ++i) { | 275 for (int i = 0; i < atlased.count(); ++i) { |
270 unlock_layer_in_cache(layerCache, atlased[i].fPicture, atlased[i].fLayer
); | 276 unlock_layer_in_cache(layerCache, atlased[i].fPicture, atlased[i].fLayer
); |
271 } | 277 } |
272 | 278 |
273 for (int i = 0; i < nonAtlased.count(); ++i) { | 279 for (int i = 0; i < nonAtlased.count(); ++i) { |
274 unlock_layer_in_cache(layerCache, nonAtlased[i].fPicture, nonAtlased[i].
fLayer); | 280 unlock_layer_in_cache(layerCache, nonAtlased[i].fPicture, nonAtlased[i].
fLayer); |
275 } | 281 } |
276 | 282 |
277 #if DISABLE_CACHING | 283 #if DISABLE_CACHING |
278 // This code completely clears out the atlas. It is required when | 284 // This code completely clears out the atlas. It is required when |
279 // caching is disabled so the atlas doesn't fill up and force more | 285 // caching is disabled so the atlas doesn't fill up and force more |
280 // free floating layers | 286 // free floating layers |
281 layerCache->purgeAll(); | 287 layerCache->purgeAll(); |
282 #endif | 288 #endif |
283 } | 289 } |
284 | 290 |
OLD | NEW |