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

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

Issue 639863005: Track nested picture xform state for layer hoisting (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rename variable (fInitialMat -> fPreMat) Created 6 years, 2 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/GrLayerHoister.h ('k') | src/gpu/GrPictureUtils.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 * 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>* atlased,
24 SkTDArray<GrHoistedLayer>* nonAtlased, 24 SkTDArray<GrHoistedLayer>* nonAtlased,
25 SkTDArray<GrHoistedLayer>* recycled) { 25 SkTDArray<GrHoistedLayer>* recycled) {
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);
29
28 GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(), 30 GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(),
29 info.fSaveLayerOpID, 31 info.fSaveLayerOpID,
30 info.fRestoreOpID, 32 info.fRestoreOpID,
31 layerRect, 33 layerRect,
32 info.fOriginXform, 34 combined,
33 info.fPaint); 35 info.fPaint);
34
35 GrTextureDesc desc; 36 GrTextureDesc desc;
36 desc.fFlags = kRenderTarget_GrTextureFlagBit; 37 desc.fFlags = kRenderTarget_GrTextureFlagBit;
37 desc.fWidth = layerRect.width(); 38 desc.fWidth = layerRect.width();
38 desc.fHeight = layerRect.height(); 39 desc.fHeight = layerRect.height();
39 desc.fConfig = kSkia8888_GrPixelConfig; 40 desc.fConfig = kSkia8888_GrPixelConfig;
40 // TODO: need to deal with sample count 41 // TODO: need to deal with sample count
41 42
42 43
43 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested || 44 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
44 (layer->paint() && layer->paint()->getImageFilter()) ; 45 (layer->paint() && layer->paint()->getImageFilter()) ;
(...skipping 13 matching lines...) Expand all
58 hl = nonAtlased->append(); 59 hl = nonAtlased->append();
59 } 60 }
60 } else { 61 } else {
61 hl = recycled->append(); 62 hl = recycled->append();
62 } 63 }
63 64
64 layerCache->addUse(layer); 65 layerCache->addUse(layer);
65 hl->fLayer = layer; 66 hl->fLayer = layer;
66 hl->fPicture = pict; 67 hl->fPicture = pict;
67 hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop); 68 hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop);
68 hl->fCTM = info.fOriginXform; 69 hl->fLocalMat = info.fLocalMat;
70 hl->fPreMat = info.fPreMat;
69 } 71 }
70 72
71 // Return true if any layers are suitable for hoisting 73 // Return true if any layers are suitable for hoisting
72 bool GrLayerHoister::FindLayersToHoist(GrContext* context, 74 bool GrLayerHoister::FindLayersToHoist(GrContext* context,
73 const SkPicture* topLevelPicture, 75 const SkPicture* topLevelPicture,
74 const SkRect& query, 76 const SkRect& query,
75 SkTDArray<GrHoistedLayer>* atlased, 77 SkTDArray<GrHoistedLayer>* atlased,
76 SkTDArray<GrHoistedLayer>* nonAtlased, 78 SkTDArray<GrHoistedLayer>* nonAtlased,
77 SkTDArray<GrHoistedLayer>* recycled) { 79 SkTDArray<GrHoistedLayer>* recycled) {
78 GrLayerCache* layerCache = context->getLayerCache(); 80 GrLayerCache* layerCache = context->getLayerCache();
(...skipping 27 matching lines...) Expand all
106 // Find and prepare for hoisting all the layers that intersect the query rec t 108 // Find and prepare for hoisting all the layers that intersect the query rec t
107 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) { 109 for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) {
108 110
109 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo( i); 111 const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo( i);
110 112
111 SkRect layerRect = SkRect::Make(info.fBounds); 113 SkRect layerRect = SkRect::Make(info.fBounds);
112 if (!layerRect.intersect(query)) { 114 if (!layerRect.intersect(query)) {
113 continue; 115 continue;
114 } 116 }
115 117
116
117 SkIRect ir; 118 SkIRect ir;
118 layerRect.roundOut(&ir); 119 layerRect.roundOut(&ir);
119 120
120 // TODO: ignore perspective projected layers here! 121 // TODO: ignore perspective projected layers here!
121 // TODO: once this code is more stable unsuitable layers can 122 // TODO: once this code is more stable unsuitable layers can
122 // just be omitted during the optimization stage 123 // just be omitted during the optimization stage
123 if (info.fIsNested) { 124 if (info.fIsNested) {
124 continue; 125 continue;
125 } 126 }
126 127
(...skipping 10 matching lines...) Expand all
137 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); 138 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
138 } 139 }
139 140
140 static void convert_layers_to_replacements(const SkTDArray<GrHoistedLayer>& laye rs, 141 static void convert_layers_to_replacements(const SkTDArray<GrHoistedLayer>& laye rs,
141 GrReplacements* replacements) { 142 GrReplacements* replacements) {
142 // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? 143 // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer?
143 for (int i = 0; i < layers.count(); ++i) { 144 for (int i = 0; i < layers.count(); ++i) {
144 GrCachedLayer* layer = layers[i].fLayer; 145 GrCachedLayer* layer = layers[i].fLayer;
145 const SkPicture* picture = layers[i].fPicture; 146 const SkPicture* picture = layers[i].fPicture;
146 147
148 SkMatrix combined = SkMatrix::Concat(layers[i].fPreMat, layers[i].fLocal Mat);
149
147 GrReplacements::ReplacementInfo* layerInfo = 150 GrReplacements::ReplacementInfo* layerInfo =
148 replacements->newReplacement(picture->uniqueID(), 151 replacements->newReplacement(picture->uniqueID(),
149 layer->start(), 152 layer->start(),
150 layers[i].fCTM); 153 combined);
151 layerInfo->fStop = layer->stop(); 154 layerInfo->fStop = layer->stop();
152 layerInfo->fPos = layers[i].fOffset; 155 layerInfo->fPos = layers[i].fOffset;
153 156
154 SkBitmap bm; 157 SkBitmap bm;
155 wrap_texture(layers[i].fLayer->texture(), 158 wrap_texture(layers[i].fLayer->texture(),
156 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().w idth() 159 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().w idth()
157 : layers[i].fLayer->texture( )->width(), 160 : layers[i].fLayer->texture( )->width(),
158 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().h eight() 161 !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().h eight()
159 : layers[i].fLayer->texture( )->height(), 162 : layers[i].fLayer->texture( )->height(),
160 &bm); 163 &bm);
161 layerInfo->fImage = SkImage::NewTexture(bm); 164 layerInfo->fImage = SkImage::NewTexture(bm);
162 165
163 layerInfo->fPaint = layers[i].fLayer->paint() 166 layerInfo->fPaint = layers[i].fLayer->paint()
164 ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint( ))) 167 ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint( )))
165 : NULL; 168 : NULL;
166 169
167 layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft, 170 layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft,
168 layers[i].fLayer->rect().fTop, 171 layers[i].fLayer->rect().fTop,
169 layers[i].fLayer->rect().width() , 172 layers[i].fLayer->rect().width() ,
170 layers[i].fLayer->rect().height( )); 173 layers[i].fLayer->rect().height( ));
171 } 174 }
172 } 175 }
173 176
174 void GrLayerHoister::DrawLayers(const SkTDArray<GrHoistedLayer>& atlased, 177 void GrLayerHoister::DrawLayers(GrContext* context,
178 const SkTDArray<GrHoistedLayer>& atlased,
175 const SkTDArray<GrHoistedLayer>& nonAtlased, 179 const SkTDArray<GrHoistedLayer>& nonAtlased,
176 const SkTDArray<GrHoistedLayer>& recycled, 180 const SkTDArray<GrHoistedLayer>& recycled,
177 GrReplacements* replacements) { 181 GrReplacements* replacements) {
178 // Render the atlased layers that require it 182 // Render the atlased layers that require it
179 if (atlased.count() > 0) { 183 if (atlased.count() > 0) {
180 // All the atlased layers are rendered into the same GrTexture 184 // All the atlased layers are rendered into the same GrTexture
181 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( 185 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
182 atlased[0].fLayer->texture()->asRenderTa rget(), NULL)); 186 atlased[0].fLayer->texture()->asRenderTa rget(), NULL));
183 187
184 SkCanvas* atlasCanvas = surface->getCanvas(); 188 SkCanvas* atlasCanvas = surface->getCanvas();
185 189
186 SkPaint paint; 190 SkPaint clearPaint;
187 paint.setColor(SK_ColorTRANSPARENT); 191 clearPaint.setColor(SK_ColorTRANSPARENT);
188 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref(); 192 clearPaint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref ();
189 193
190 for (int i = 0; i < atlased.count(); ++i) { 194 for (int i = 0; i < atlased.count(); ++i) {
191 GrCachedLayer* layer = atlased[i].fLayer; 195 const GrCachedLayer* layer = atlased[i].fLayer;
192 const SkPicture* pict = atlased[i].fPicture; 196 const SkPicture* pict = atlased[i].fPicture;
193 const SkIPoint offset = atlased[i].fOffset; 197 const SkIPoint offset = atlased[i].fOffset;
198 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
199
200 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
194 201
195 atlasCanvas->save(); 202 atlasCanvas->save();
196 203
197 // Add a rect clip to make sure the rendering doesn't 204 // Add a rect clip to make sure the rendering doesn't
198 // extend beyond the boundaries of the atlased sub-rect 205 // extend beyond the boundaries of the atlased sub-rect
199 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), 206 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
200 SkIntToScalar(layer->rect().fTop), 207 SkIntToScalar(layer->rect().fTop),
201 SkIntToScalar(layer->rect().width()) , 208 SkIntToScalar(layer->rect().width()) ,
202 SkIntToScalar(layer->rect().height() )); 209 SkIntToScalar(layer->rect().height() ));
203 atlasCanvas->clipRect(bound); 210 atlasCanvas->clipRect(bound);
204 211
205 // Since 'clear' doesn't respect the clip we need to draw a rect 212 // Since 'clear' doesn't respect the clip we need to draw a rect
206 // TODO: ensure none of the atlased layers contain a clear call! 213 // TODO: ensure none of the atlased layers contain a clear call!
207 atlasCanvas->drawRect(bound, paint); 214 atlasCanvas->drawRect(bound, clearPaint);
208 215
209 // info.fCTM maps the layer's top/left to the origin. 216 // info.fCTM maps the layer's top/left to the origin.
210 // Since this layer is atlased, the top/left corner needs 217 // Since this layer is atlased, the top/left corner needs
211 // to be offset to the correct location in the backing texture. 218 // to be offset to the correct location in the backing texture.
212 SkMatrix initialCTM; 219 SkMatrix initialCTM;
213 initialCTM.setTranslate(SkIntToScalar(-offset.fX), 220 initialCTM.setTranslate(SkIntToScalar(-offset.fX),
214 SkIntToScalar(-offset.fY)); 221 SkIntToScalar(-offset.fY));
215 initialCTM.postTranslate(bound.fLeft, bound.fTop); 222 initialCTM.postTranslate(bound.fLeft, bound.fTop);
216 223 initialCTM.postConcat(atlased[i].fPreMat);
224
217 atlasCanvas->translate(SkIntToScalar(-offset.fX), 225 atlasCanvas->translate(SkIntToScalar(-offset.fX),
218 SkIntToScalar(-offset.fY)); 226 SkIntToScalar(-offset.fY));
219 atlasCanvas->translate(bound.fLeft, bound.fTop); 227 atlasCanvas->translate(bound.fLeft, bound.fTop);
220 atlasCanvas->concat(atlased[i].fCTM); 228 atlasCanvas->concat(atlased[i].fPreMat);
229 atlasCanvas->concat(atlased[i].fLocalMat);
221 230
222 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound, 231 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound,
223 layer->start()+1, layer->stop(), initialCTM); 232 layer->start()+1, layer->stop(), initialCTM);
224 233
225 atlasCanvas->restore(); 234 atlasCanvas->restore();
226 } 235 }
227 236
228 atlasCanvas->flush(); 237 atlasCanvas->flush();
229 } 238 }
230 239
231 // Render the non-atlased layers that require it 240 // Render the non-atlased layers that require it
232 for (int i = 0; i < nonAtlased.count(); ++i) { 241 for (int i = 0; i < nonAtlased.count(); ++i) {
233 GrCachedLayer* layer = nonAtlased[i].fLayer; 242 GrCachedLayer* layer = nonAtlased[i].fLayer;
234 const SkPicture* pict = nonAtlased[i].fPicture; 243 const SkPicture* pict = nonAtlased[i].fPicture;
235 const SkIPoint offset = nonAtlased[i].fOffset; 244 const SkIPoint& offset = nonAtlased[i].fOffset;
236 245
237 // Each non-atlased layer has its own GrTexture 246 // Each non-atlased layer has its own GrTexture
238 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( 247 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
239 layer->texture()->asRenderTarget(), NULL )); 248 layer->texture()->asRenderTarget(), NULL ));
240 249
241 SkCanvas* layerCanvas = surface->getCanvas(); 250 SkCanvas* layerCanvas = surface->getCanvas();
242 251
252 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
253
243 // Add a rect clip to make sure the rendering doesn't 254 // Add a rect clip to make sure the rendering doesn't
244 // extend beyond the boundaries of the atlased sub-rect 255 // extend beyond the boundaries of the atlased sub-rect
245 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), 256 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
246 SkIntToScalar(layer->rect().fTop), 257 SkIntToScalar(layer->rect().fTop),
247 SkIntToScalar(layer->rect().width()), 258 SkIntToScalar(layer->rect().width()),
248 SkIntToScalar(layer->rect().height())); 259 SkIntToScalar(layer->rect().height()));
249 260
250 layerCanvas->clipRect(bound); // TODO: still useful? 261 layerCanvas->clipRect(bound); // TODO: still useful?
251 262
252 layerCanvas->clear(SK_ColorTRANSPARENT); 263 layerCanvas->clear(SK_ColorTRANSPARENT);
253 264
254 SkMatrix initialCTM; 265 SkMatrix initialCTM;
255 initialCTM.setTranslate(SkIntToScalar(-offset.fX), 266 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset .fY));
256 SkIntToScalar(-offset.fY)); 267 initialCTM.postConcat(nonAtlased[i].fPreMat);
257 268
258 layerCanvas->translate(SkIntToScalar(-offset.fX), 269 layerCanvas->translate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset. fY));
259 SkIntToScalar(-offset.fY)); 270 layerCanvas->concat(nonAtlased[i].fPreMat);
260 layerCanvas->concat(nonAtlased[i].fCTM); 271 layerCanvas->concat(nonAtlased[i].fLocalMat);
261 272
262 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound, 273 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound,
263 layer->start()+1, layer->stop(), initialCTM); 274 layer->start()+1, layer->stop(), initialCTM);
264 275
265 layerCanvas->flush(); 276 layerCanvas->flush();
266 } 277 }
267 278
268 convert_layers_to_replacements(atlased, replacements); 279 convert_layers_to_replacements(atlased, replacements);
269 convert_layers_to_replacements(nonAtlased, replacements); 280 convert_layers_to_replacements(nonAtlased, replacements);
270 convert_layers_to_replacements(recycled, replacements); 281 convert_layers_to_replacements(recycled, replacements);
(...skipping 20 matching lines...) Expand all
291 #if DISABLE_CACHING 302 #if DISABLE_CACHING
292 // This code completely clears out the atlas. It is required when 303 // This code completely clears out the atlas. It is required when
293 // caching is disabled so the atlas doesn't fill up and force more 304 // caching is disabled so the atlas doesn't fill up and force more
294 // free floating layers 305 // free floating layers
295 layerCache->purgeAll(); 306 layerCache->purgeAll();
296 #endif 307 #endif
297 308
298 SkDEBUGCODE(layerCache->validate();) 309 SkDEBUGCODE(layerCache->validate();)
299 } 310 }
300 311
OLDNEW
« no previous file with comments | « src/gpu/GrLayerHoister.h ('k') | src/gpu/GrPictureUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698