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