Chromium Code Reviews| 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 |