 Chromium Code Reviews
 Chromium Code Reviews Issue 552843004:
  Adding texture uploads without cache for YUV and ETC1  (Closed) 
  Base URL: https://skia.googlesource.com/skia.git@master
    
  
    Issue 552843004:
  Adding texture uploads without cache for YUV and ETC1  (Closed) 
  Base URL: https://skia.googlesource.com/skia.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 "SkGr.h" | 8 #include "SkGr.h" | 
| 9 #include "SkColorFilter.h" | 9 #include "SkColorFilter.h" | 
| 10 #include "SkConfig8888.h" | 10 #include "SkConfig8888.h" | 
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 } | 128 } | 
| 129 }; | 129 }; | 
| 130 | 130 | 
| 131 } // namespace | 131 } // namespace | 
| 132 | 132 | 
| 133 static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { | 133 static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { | 
| 134 SkASSERT(pixelRef); | 134 SkASSERT(pixelRef); | 
| 135 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); | 135 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); | 
| 136 } | 136 } | 
| 137 | 137 | 
| 138 static GrTexture* sk_gr_allocate_texture(GrContext* ctx, | |
| 139 bool cache, | |
| 140 const GrTextureParams* params, | |
| 141 const SkBitmap& bm, | |
| 
robertphillips
2014/09/10 14:18:12
const GrTextureDesc&
 | |
| 142 GrTextureDesc desc, | |
| 143 const void* pixels, | |
| 144 size_t rowBytes) { | |
| 145 GrTexture* result; | |
| 146 if (cache) { | |
| 147 // This texture is likely to be used again so leave it in the cache | |
| 148 GrCacheID cacheID; | |
| 149 generate_bitmap_cache_id(bm, &cacheID); | |
| 150 | |
| 151 GrResourceKey key; | |
| 152 result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &ke y); | |
| 153 if (result) { | |
| 154 add_genID_listener(key, bm.pixelRef()); | |
| 155 } | |
| 156 } else { | |
| 157 // This texture is unlikely to be used again (in its present form) so | |
| 158 // just use a scratch texture. This will remove the texture from the | |
| 159 // cache so no one else can find it. Additionally, once unlocked, the | |
| 160 // scratch texture will go to the end of the list for purging so will | |
| 161 // likely be available for this volatile bitmap the next time around. | |
| 162 result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTe xMatch); | |
| 163 if (pixels) { | |
| 164 result->writePixels(0, 0, bm.width(), bm.height(), desc.fConfig, pix els, rowBytes); | |
| 165 } | |
| 166 } | |
| 167 return result; | |
| 168 } | |
| 169 | |
| 138 #ifndef SK_IGNORE_ETC1_SUPPORT | 170 #ifndef SK_IGNORE_ETC1_SUPPORT | 
| 139 static GrTexture *load_etc1_texture(GrContext* ctx, | 171 static GrTexture *load_etc1_texture(GrContext* ctx, bool cache, | 
| 140 const GrTextureParams* params, | 172 const GrTextureParams* params, | 
| 141 const SkBitmap &bm, GrTextureDesc desc) { | 173 const SkBitmap &bm, GrTextureDesc desc) { | 
| 142 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); | 174 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); | 
| 143 | 175 | 
| 144 // Is this even encoded data? | 176 // Is this even encoded data? | 
| 145 if (NULL == data) { | 177 if (NULL == data) { | 
| 146 return NULL; | 178 return NULL; | 
| 147 } | 179 } | 
| 148 | 180 | 
| 149 // Is this a valid PKM encoded data? | 181 // Is this a valid PKM encoded data? | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 175 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { | 207 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { | 
| 176 return NULL; | 208 return NULL; | 
| 177 } | 209 } | 
| 178 | 210 | 
| 179 bytes = ktx.pixelData(); | 211 bytes = ktx.pixelData(); | 
| 180 desc.fConfig = kETC1_GrPixelConfig; | 212 desc.fConfig = kETC1_GrPixelConfig; | 
| 181 } else { | 213 } else { | 
| 182 return NULL; | 214 return NULL; | 
| 183 } | 215 } | 
| 184 | 216 | 
| 185 // This texture is likely to be used again so leave it in the cache | 217 return sk_gr_allocate_texture(ctx, cache, params, bm, desc, bytes, 0); | 
| 186 GrCacheID cacheID; | |
| 187 generate_bitmap_cache_id(bm, &cacheID); | |
| 188 | |
| 189 GrResourceKey key; | |
| 190 GrTexture* result = ctx->createTexture(params, desc, cacheID, bytes, 0, &key ); | |
| 191 if (result) { | |
| 192 add_genID_listener(key, bm.pixelRef()); | |
| 193 } | |
| 194 return result; | |
| 195 } | 218 } | 
| 196 #endif // SK_IGNORE_ETC1_SUPPORT | 219 #endif // SK_IGNORE_ETC1_SUPPORT | 
| 197 | 220 | 
| 198 static GrTexture *load_yuv_texture(GrContext* ctx, const GrTextureParams* params , | 221 static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa rams* params, | 
| 199 const SkBitmap& bm, const GrTextureDesc& desc ) { | 222 const SkBitmap& bm, const GrTextureDesc& desc ) { | 
| 200 GrTexture* result = NULL; | |
| 201 | |
| 202 SkPixelRef* pixelRef = bm.pixelRef(); | 223 SkPixelRef* pixelRef = bm.pixelRef(); | 
| 203 SkISize yuvSizes[3]; | 224 SkISize yuvSizes[3]; | 
| 204 if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL)) { | 225 if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL)) { | 
| 205 return NULL; | 226 return NULL; | 
| 206 } | 227 } | 
| 207 | 228 | 
| 208 // Allocate the memory for YUV | 229 // Allocate the memory for YUV | 
| 209 size_t totalSize(0); | 230 size_t totalSize(0); | 
| 210 size_t sizes[3], rowBytes[3]; | 231 size_t sizes[3], rowBytes[3]; | 
| 211 for (int i = 0; i < 3; ++i) { | 232 for (int i = 0; i < 3; ++i) { | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 236 yuvDesc.fConfig, planes[i], rowBytes[i])) { | 257 yuvDesc.fConfig, planes[i], rowBytes[i])) { | 
| 237 return NULL; | 258 return NULL; | 
| 238 } | 259 } | 
| 239 } | 260 } | 
| 240 | 261 | 
| 241 GrTextureDesc rtDesc = desc; | 262 GrTextureDesc rtDesc = desc; | 
| 242 rtDesc.fFlags = rtDesc.fFlags | | 263 rtDesc.fFlags = rtDesc.fFlags | | 
| 243 kRenderTarget_GrTextureFlagBit | | 264 kRenderTarget_GrTextureFlagBit | | 
| 244 kNoStencil_GrTextureFlagBit; | 265 kNoStencil_GrTextureFlagBit; | 
| 245 | 266 | 
| 246 // This texture is likely to be used again so leave it in the cache | 267 GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, N ULL, 0); | 
| 247 GrCacheID cacheID; | |
| 248 generate_bitmap_cache_id(bm, &cacheID); | |
| 249 | 268 | 
| 250 GrResourceKey key; | |
| 251 result = ctx->createTexture(params, rtDesc, cacheID, NULL, 0, &key); | |
| 252 GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; | 269 GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; | 
| 253 if (renderTarget) { | 270 if (renderTarget) { | 
| 254 add_genID_listener(key, bm.pixelRef()); | |
| 255 SkAutoTUnref<GrEffect> yuvToRgbEffect(GrYUVtoRGBEffect::Create( | 271 SkAutoTUnref<GrEffect> yuvToRgbEffect(GrYUVtoRGBEffect::Create( | 
| 256 yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].t exture())); | 272 yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].t exture())); | 
| 257 GrPaint paint; | 273 GrPaint paint; | 
| 258 paint.addColorEffect(yuvToRgbEffect); | 274 paint.addColorEffect(yuvToRgbEffect); | 
| 259 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), | 275 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), | 
| 260 SkIntToScalar(yuvSizes[0].fHeight)); | 276 SkIntToScalar(yuvSizes[0].fHeight)); | 
| 261 GrContext::AutoRenderTarget autoRT(ctx, renderTarget); | 277 GrContext::AutoRenderTarget autoRT(ctx, renderTarget); | 
| 262 GrContext::AutoMatrix am; | 278 GrContext::AutoMatrix am; | 
| 263 am.setIdentity(ctx); | 279 am.setIdentity(ctx); | 
| 264 GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); | 280 GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 286 // and paletted textures can't be sub-updated | 302 // and paletted textures can't be sub-updated | 
| 287 if (ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->heig ht())) { | 303 if (ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->heig ht())) { | 
| 288 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig , | 304 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig , | 
| 289 bitmap->width(), bitma p->height()); | 305 bitmap->width(), bitma p->height()); | 
| 290 SkAutoMalloc storage(imageSize); | 306 SkAutoMalloc storage(imageSize); | 
| 291 | 307 | 
| 292 build_compressed_data(storage.get(), origBitmap); | 308 build_compressed_data(storage.get(), origBitmap); | 
| 293 | 309 | 
| 294 // our compressed data will be trimmed, so pass width() for its | 310 // our compressed data will be trimmed, so pass width() for its | 
| 295 // "rowBytes", since they are the same now. | 311 // "rowBytes", since they are the same now. | 
| 296 | 312 return sk_gr_allocate_texture(ctx, cache, params, origBitmap, | 
| 297 if (cache) { | 313 desc, storage.get(), bitmap->width()); | 
| 298 GrCacheID cacheID; | |
| 299 generate_bitmap_cache_id(origBitmap, &cacheID); | |
| 300 | |
| 301 GrResourceKey key; | |
| 302 GrTexture* result = ctx->createTexture(params, desc, cacheID, | |
| 303 storage.get(), bitmap->wi dth(), &key); | |
| 304 if (result) { | |
| 305 add_genID_listener(key, origBitmap.pixelRef()); | |
| 306 } | |
| 307 return result; | |
| 308 } else { | |
| 309 GrTexture* result = ctx->lockAndRefScratchTexture(desc, | |
| 310 GrContext::kExact_Sc ratchTexMatch); | |
| 311 result->writePixels(0, 0, bitmap->width(), | |
| 312 bitmap->height(), desc.fConfig, | |
| 313 storage.get()); | |
| 314 return result; | |
| 315 } | |
| 316 } else { | 314 } else { | 
| 317 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); | 315 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); | 
| 318 // now bitmap points to our temp, which has been promoted to 32bits | 316 // now bitmap points to our temp, which has been promoted to 32bits | 
| 319 bitmap = &tmpBitmap; | 317 bitmap = &tmpBitmap; | 
| 320 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); | 318 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); | 
| 321 } | 319 } | 
| 322 } | 320 } | 
| 323 | 321 | 
| 324 // Is this an ETC1 encoded texture? | 322 // Is this an ETC1 encoded texture? | 
| 325 #ifndef SK_IGNORE_ETC1_SUPPORT | 323 #ifndef SK_IGNORE_ETC1_SUPPORT | 
| 326 else if ( | 324 else if ( | 
| 327 // We do not support scratch ETC1 textures, hence they should all be at least | 325 // We do not support scratch ETC1 textures, hence they should all be at least | 
| 328 // trying to go to the cache. | 326 // trying to go to the cache. | 
| 329 cache | 327 cache | 
| 330 // Make sure that the underlying device supports ETC1 textures before we go ahead | 328 // Make sure that the underlying device supports ETC1 textures before we go ahead | 
| 331 // and check the data. | 329 // and check the data. | 
| 332 && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) | 330 && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) | 
| 333 // If the bitmap had compressed data and was then uncompressed, it'll st ill return | 331 // If the bitmap had compressed data and was then uncompressed, it'll st ill return | 
| 334 // compressed data on 'refEncodedData' and upload it. Probably not good, since if | 332 // compressed data on 'refEncodedData' and upload it. Probably not good, since if | 
| 335 // the bitmap has available pixels, then they might not be what the deco mpressed | 333 // the bitmap has available pixels, then they might not be what the deco mpressed | 
| 336 // data is. | 334 // data is. | 
| 337 && !(bitmap->readyToDraw())) { | 335 && !(bitmap->readyToDraw())) { | 
| 338 GrTexture *texture = load_etc1_texture(ctx, params, *bitmap, desc); | 336 GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc ); | 
| 339 if (texture) { | 337 if (texture) { | 
| 340 return texture; | 338 return texture; | 
| 341 } | 339 } | 
| 342 } | 340 } | 
| 343 #endif // SK_IGNORE_ETC1_SUPPORT | 341 #endif // SK_IGNORE_ETC1_SUPPORT | 
| 344 | 342 | 
| 345 else { | 343 else { | 
| 346 GrTexture *texture = load_yuv_texture(ctx, params, *bitmap, desc); | 344 GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc) ; | 
| 347 if (texture) { | 345 if (texture) { | 
| 348 return texture; | 346 return texture; | 
| 349 } | 347 } | 
| 350 } | 348 } | 
| 351 SkAutoLockPixels alp(*bitmap); | 349 SkAutoLockPixels alp(*bitmap); | 
| 352 if (!bitmap->readyToDraw()) { | 350 if (!bitmap->readyToDraw()) { | 
| 353 return NULL; | 351 return NULL; | 
| 354 } | 352 } | 
| 355 if (cache) { | |
| 356 // This texture is likely to be used again so leave it in the cache | |
| 357 GrCacheID cacheID; | |
| 358 generate_bitmap_cache_id(origBitmap, &cacheID); | |
| 359 | 353 | 
| 360 GrResourceKey key; | 354 return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc, | 
| 361 GrTexture* result = ctx->createTexture(params, desc, cacheID, | 355 bitmap->getPixels(), bitmap->rowBytes()); | 
| 362 bitmap->getPixels(), bitmap->rowB ytes(), &key); | |
| 363 if (result) { | |
| 364 add_genID_listener(key, origBitmap.pixelRef()); | |
| 365 } | |
| 366 return result; | |
| 367 } else { | |
| 368 // This texture is unlikely to be used again (in its present form) so | |
| 369 // just use a scratch texture. This will remove the texture from the | |
| 370 // cache so no one else can find it. Additionally, once unlocked, the | |
| 371 // scratch texture will go to the end of the list for purging so will | |
| 372 // likely be available for this volatile bitmap the next time around. | |
| 373 GrTexture* result = ctx->lockAndRefScratchTexture(desc, GrContext::kExac t_ScratchTexMatch); | |
| 374 result->writePixels(0, 0, | |
| 375 bitmap->width(), bitmap->height(), | |
| 376 desc.fConfig, | |
| 377 bitmap->getPixels(), | |
| 378 bitmap->rowBytes()); | |
| 379 return result; | |
| 380 } | |
| 381 } | 356 } | 
| 382 | 357 | 
| 383 bool GrIsBitmapInCache(const GrContext* ctx, | 358 bool GrIsBitmapInCache(const GrContext* ctx, | 
| 384 const SkBitmap& bitmap, | 359 const SkBitmap& bitmap, | 
| 385 const GrTextureParams* params) { | 360 const GrTextureParams* params) { | 
| 386 GrCacheID cacheID; | 361 GrCacheID cacheID; | 
| 387 generate_bitmap_cache_id(bitmap, &cacheID); | 362 generate_bitmap_cache_id(bitmap, &cacheID); | 
| 388 | 363 | 
| 389 GrTextureDesc desc; | 364 GrTextureDesc desc; | 
| 390 generate_bitmap_texture_desc(bitmap, &desc); | 365 generate_bitmap_texture_desc(bitmap, &desc); | 
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 if (shader->asNewEffect(context, skPaint, NULL, &paintColor, &effect) && effect) { | 573 if (shader->asNewEffect(context, skPaint, NULL, &paintColor, &effect) && effect) { | 
| 599 grPaint->addColorEffect(effect)->unref(); | 574 grPaint->addColorEffect(effect)->unref(); | 
| 600 constantColor = false; | 575 constantColor = false; | 
| 601 } | 576 } | 
| 602 } | 577 } | 
| 603 | 578 | 
| 604 // The grcolor is automatically set when calling asneweffect. | 579 // The grcolor is automatically set when calling asneweffect. | 
| 605 // If the shader can be seen as an effect it returns true and adds its effec t to the grpaint. | 580 // If the shader can be seen as an effect it returns true and adds its effec t to the grpaint. | 
| 606 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint ); | 581 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint ); | 
| 607 } | 582 } | 
| OLD | NEW |