| 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 |