| 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 | 9 |
| 10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
| 11 #include "GrDrawContext.h" | 11 #include "GrDrawContext.h" |
| 12 #include "GrXferProcessor.h" | 12 #include "GrXferProcessor.h" |
| 13 #include "GrYUVProvider.h" |
| 14 |
| 13 #include "SkColorFilter.h" | 15 #include "SkColorFilter.h" |
| 14 #include "SkConfig8888.h" | 16 #include "SkConfig8888.h" |
| 15 #include "SkCanvas.h" | 17 #include "SkCanvas.h" |
| 16 #include "SkData.h" | 18 #include "SkData.h" |
| 17 #include "SkErrorInternals.h" | 19 #include "SkErrorInternals.h" |
| 18 #include "SkGrPixelRef.h" | 20 #include "SkGrPixelRef.h" |
| 19 #include "SkMessageBus.h" | 21 #include "SkMessageBus.h" |
| 20 #include "SkPixelRef.h" | 22 #include "SkPixelRef.h" |
| 21 #include "SkResourceCache.h" | 23 #include "SkResourceCache.h" |
| 22 #include "SkTextureCompressor.h" | 24 #include "SkTextureCompressor.h" |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 GrUniqueKeyInvalidatedMessage fMsg; | 232 GrUniqueKeyInvalidatedMessage fMsg; |
| 231 | 233 |
| 232 void onChange() override { | 234 void onChange() override { |
| 233 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); | 235 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); |
| 234 } | 236 } |
| 235 }; | 237 }; |
| 236 | 238 |
| 237 } // namespace | 239 } // namespace |
| 238 | 240 |
| 239 | 241 |
| 240 static GrTexture* create_texture_for_bmp(GrContext* ctx, | 242 GrTexture* GrCreateTextureForPixels(GrContext* ctx, |
| 241 const GrUniqueKey& optionalKey, | 243 const GrUniqueKey& optionalKey, |
| 242 GrSurfaceDesc desc, | 244 GrSurfaceDesc desc, |
| 243 SkPixelRef* pixelRefForInvalidationNoti
fication, | 245 SkPixelRef* pixelRefForInvalidationNotificat
ion, |
| 244 const void* pixels, | 246 const void* pixels, |
| 245 size_t rowBytes) { | 247 size_t rowBytes) { |
| 246 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels
, rowBytes); | 248 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels
, rowBytes); |
| 247 if (result && optionalKey.isValid()) { | 249 if (result && optionalKey.isValid()) { |
| 248 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); | 250 if (pixelRefForInvalidationNotification) { |
| 249 pixelRefForInvalidationNotification->addGenIDChangeListener(listener); | 251 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); |
| 252 pixelRefForInvalidationNotification->addGenIDChangeListener(listener
); |
| 253 } |
| 250 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); | 254 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); |
| 251 } | 255 } |
| 252 return result; | 256 return result; |
| 253 } | 257 } |
| 254 | 258 |
| 255 // creates a new texture that is the input texture scaled up. If optionalKey is
valid it will be | 259 // creates a new texture that is the input texture scaled up. If optionalKey is
valid it will be |
| 256 // set on the new texture. stretch controls whether the scaling is done using ne
arest or bilerp | 260 // set on the new texture. stretch controls whether the scaling is done using ne
arest or bilerp |
| 257 // filtering and the size to stretch the texture to. | 261 // filtering and the size to stretch the texture to. |
| 258 GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch, | 262 GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch, |
| 259 SkPixelRef* pixelRef, | 263 SkPixelRef* pixelRef, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 287 if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { | 291 if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { |
| 288 rtDesc.fConfig = kSkia8888_GrPixelConfig; | 292 rtDesc.fConfig = kSkia8888_GrPixelConfig; |
| 289 } else { | 293 } else { |
| 290 return nullptr; | 294 return nullptr; |
| 291 } | 295 } |
| 292 } else { | 296 } else { |
| 293 return nullptr; | 297 return nullptr; |
| 294 } | 298 } |
| 295 } | 299 } |
| 296 | 300 |
| 297 GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc,
pixelRef, nullptr, 0); | 301 SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optional
Key, rtDesc, |
| 298 | 302 pixelRef, nullptr
,0)); |
| 299 if (!stretched) { | 303 if (!stretched) { |
| 300 return nullptr; | 304 return nullptr; |
| 301 } | 305 } |
| 302 GrPaint paint; | 306 GrPaint paint; |
| 303 | 307 |
| 304 // If filtering is not desired then we want to ensure all texels in the resa
mpled image are | 308 // If filtering is not desired then we want to ensure all texels in the resa
mpled image are |
| 305 // copies of texels from the original. | 309 // copies of texels from the original. |
| 306 GrTextureParams params(SkShader::kClamp_TileMode, | 310 GrTextureParams params(SkShader::kClamp_TileMode, |
| 307 Stretch::kBilerp_Type == stretch.fType ? | 311 Stretch::kBilerp_Type == stretch.fType ? |
| 308 GrTextureParams::kBilerp_FilterMode : | 312 GrTextureParams::kBilerp_FilterMode : |
| 309 GrTextureParams::kNone_FilterMode); | 313 GrTextureParams::kNone_FilterMode); |
| 310 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); | 314 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); |
| 311 | 315 |
| 312 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
esc.fHeight)); | 316 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
esc.fHeight)); |
| 313 SkRect localRect = SkRect::MakeWH(1.f, 1.f); | 317 SkRect localRect = SkRect::MakeWH(1.f, 1.f); |
| 314 | 318 |
| 315 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext()); | 319 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext()); |
| 316 if (!drawContext) { | 320 if (!drawContext) { |
| 317 return nullptr; | 321 return nullptr; |
| 318 } | 322 } |
| 319 | 323 |
| 320 drawContext->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOp
en(), paint, | 324 drawContext->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOp
en(), paint, |
| 321 SkMatrix::I(), rect, localRect); | 325 SkMatrix::I(), rect, localRect); |
| 322 | 326 |
| 323 return stretched; | 327 return stretched.detach(); |
| 324 } | 328 } |
| 325 | 329 |
| 330 GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, |
| 331 int expectedW, int expectedH, |
| 332 const void** outStartOfDataToUp
load) { |
| 333 *outStartOfDataToUpload = nullptr; |
| 326 #ifndef SK_IGNORE_ETC1_SUPPORT | 334 #ifndef SK_IGNORE_ETC1_SUPPORT |
| 327 static GrTexture *load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalK
ey, | 335 if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) { |
| 328 const SkBitmap &bm, GrSurfaceDesc desc) { | 336 return kUnknown_GrPixelConfig; |
| 329 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); | |
| 330 | |
| 331 // Is this even encoded data? | |
| 332 if (nullptr == data) { | |
| 333 return nullptr; | |
| 334 } | 337 } |
| 335 | 338 |
| 336 // Is this a valid PKM encoded data? | 339 const uint8_t* bytes = data->bytes(); |
| 337 const uint8_t *bytes = data->bytes(); | 340 if (data->size() > ETC_PKM_HEADER_SIZE && etc1_pkm_is_valid(bytes)) { |
| 338 if (etc1_pkm_is_valid(bytes)) { | |
| 339 uint32_t encodedWidth = etc1_pkm_get_width(bytes); | |
| 340 uint32_t encodedHeight = etc1_pkm_get_height(bytes); | |
| 341 | |
| 342 // Does the data match the dimensions of the bitmap? If not, | 341 // Does the data match the dimensions of the bitmap? If not, |
| 343 // then we don't know how to scale the image to match it... | 342 // then we don't know how to scale the image to match it... |
| 344 if (encodedWidth != static_cast<uint32_t>(bm.width()) || | 343 if (etc1_pkm_get_width(bytes) != (unsigned)expectedW || |
| 345 encodedHeight != static_cast<uint32_t>(bm.height())) { | 344 etc1_pkm_get_height(bytes) != (unsigned)expectedH) |
| 346 return nullptr; | 345 { |
| 346 return kUnknown_GrPixelConfig; |
| 347 } | 347 } |
| 348 | 348 |
| 349 // Everything seems good... skip ahead to the data. | 349 *outStartOfDataToUpload = bytes + ETC_PKM_HEADER_SIZE; |
| 350 bytes += ETC_PKM_HEADER_SIZE; | 350 return kETC1_GrPixelConfig; |
| 351 desc.fConfig = kETC1_GrPixelConfig; | |
| 352 } else if (SkKTXFile::is_ktx(bytes)) { | 351 } else if (SkKTXFile::is_ktx(bytes)) { |
| 353 SkKTXFile ktx(data); | 352 SkKTXFile ktx(data); |
| 354 | 353 |
| 355 // Is it actually an ETC1 texture? | 354 // Is it actually an ETC1 texture? |
| 356 if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { | 355 if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { |
| 357 return nullptr; | 356 return kUnknown_GrPixelConfig; |
| 358 } | 357 } |
| 359 | 358 |
| 360 // Does the data match the dimensions of the bitmap? If not, | 359 // Does the data match the dimensions of the bitmap? If not, |
| 361 // then we don't know how to scale the image to match it... | 360 // then we don't know how to scale the image to match it... |
| 362 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { | 361 if (ktx.width() != expectedW || ktx.height() != expectedH) { |
| 363 return nullptr; | 362 return kUnknown_GrPixelConfig; |
| 364 } | 363 } |
| 365 | 364 |
| 366 bytes = ktx.pixelData(); | 365 *outStartOfDataToUpload = ktx.pixelData(); |
| 367 desc.fConfig = kETC1_GrPixelConfig; | 366 return kETC1_GrPixelConfig; |
| 368 } else { | 367 } |
| 368 #endif |
| 369 return kUnknown_GrPixelConfig; |
| 370 } |
| 371 |
| 372 static GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalK
ey, |
| 373 const SkBitmap &bm, GrSurfaceDesc desc) { |
| 374 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); |
| 375 if (!data) { |
| 369 return nullptr; | 376 return nullptr; |
| 370 } | 377 } |
| 371 | 378 |
| 372 return create_texture_for_bmp(ctx, optionalKey, desc, bm.pixelRef(), bytes,
0); | 379 const void* startOfTexData; |
| 380 desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm.
height(), |
| 381 &startOfTexData); |
| 382 if (kUnknown_GrPixelConfig == desc.fConfig) { |
| 383 return nullptr; |
| 384 } |
| 385 |
| 386 return GrCreateTextureForPixels(ctx, optionalKey, desc, bm.pixelRef(), start
OfTexData, 0); |
| 373 } | 387 } |
| 374 #endif // SK_IGNORE_ETC1_SUPPORT | 388 |
| 389 /* |
| 390 * Once we have made SkImages handle all lazy/deferred/generated content, the Y
UV apis will |
| 391 * be gone from SkPixelRef, and we can remove this subclass entirely. |
| 392 */ |
| 393 class PixelRef_GrYUVProvider : public GrYUVProvider { |
| 394 SkPixelRef* fPR; |
| 395 |
| 396 public: |
| 397 PixelRef_GrYUVProvider(SkPixelRef* pr) : fPR(pr) {} |
| 398 |
| 399 uint32_t onGetID() override { return fPR->getGenerationID(); } |
| 400 bool onGetYUVSizes(SkISize sizes[3]) override { |
| 401 return fPR->getYUV8Planes(sizes, nullptr, nullptr, nullptr); |
| 402 } |
| 403 bool onGetYUVPlanes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], |
| 404 SkYUVColorSpace* space) override { |
| 405 return fPR->getYUV8Planes(sizes, planes, rowBytes, space); |
| 406 } |
| 407 }; |
| 375 | 408 |
| 376 static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe
y, | 409 static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe
y, |
| 377 const SkBitmap& bm, const GrSurfaceDesc& desc
) { | 410 const SkBitmap& bm, const GrSurfaceDesc& desc
) { |
| 378 // Subsets are not supported, the whole pixelRef is loaded when using YUV de
coding | 411 // Subsets are not supported, the whole pixelRef is loaded when using YUV de
coding |
| 379 SkPixelRef* pixelRef = bm.pixelRef(); | 412 SkPixelRef* pixelRef = bm.pixelRef(); |
| 380 if ((nullptr == pixelRef) || | 413 if ((nullptr == pixelRef) || |
| 381 (pixelRef->info().width() != bm.info().width()) || | 414 (pixelRef->info().width() != bm.info().width()) || |
| 382 (pixelRef->info().height() != bm.info().height())) { | 415 (pixelRef->info().height() != bm.info().height())) { |
| 383 return nullptr; | 416 return nullptr; |
| 384 } | 417 } |
| 385 | 418 |
| 386 const bool useCache = optionalKey.isValid(); | 419 const bool useCache = optionalKey.isValid(); |
| 387 SkYUVPlanesCache::Info yuvInfo; | 420 PixelRef_GrYUVProvider provider(pixelRef); |
| 388 SkAutoTUnref<SkCachedData> cachedData; | 421 GrTexture* texture = provider.refAsTexture(ctx, desc, useCache); |
| 389 SkAutoMalloc storage; | 422 if (!texture) { |
| 390 if (useCache) { | |
| 391 cachedData.reset(SkYUVPlanesCache::FindAndRef(pixelRef->getGenerationID(
), &yuvInfo)); | |
| 392 } | |
| 393 | |
| 394 void* planes[3]; | |
| 395 if (cachedData.get()) { | |
| 396 planes[0] = (void*)cachedData->data(); | |
| 397 planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0]; | |
| 398 planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1]; | |
| 399 } else { | |
| 400 // Fetch yuv plane sizes for memory allocation. Here, width and height c
an be | |
| 401 // rounded up to JPEG block size and be larger than the image's width an
d height. | |
| 402 if (!pixelRef->getYUV8Planes(yuvInfo.fSize, nullptr, nullptr, nullptr))
{ | |
| 403 return nullptr; | |
| 404 } | |
| 405 | |
| 406 // Allocate the memory for YUV | |
| 407 size_t totalSize(0); | |
| 408 for (int i = 0; i < 3; ++i) { | |
| 409 yuvInfo.fRowBytes[i] = yuvInfo.fSize[i].fWidth; | |
| 410 yuvInfo.fSizeInMemory[i] = yuvInfo.fRowBytes[i] * yuvInfo.fSize[i].f
Height; | |
| 411 totalSize += yuvInfo.fSizeInMemory[i]; | |
| 412 } | |
| 413 if (useCache) { | |
| 414 cachedData.reset(SkResourceCache::NewCachedData(totalSize)); | |
| 415 planes[0] = cachedData->writable_data(); | |
| 416 } else { | |
| 417 storage.reset(totalSize); | |
| 418 planes[0] = storage.get(); | |
| 419 } | |
| 420 planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0]; | |
| 421 planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1]; | |
| 422 | |
| 423 // Get the YUV planes and update plane sizes to actual image size | |
| 424 if (!pixelRef->getYUV8Planes(yuvInfo.fSize, planes, yuvInfo.fRowBytes, | |
| 425 &yuvInfo.fColorSpace)) { | |
| 426 return nullptr; | |
| 427 } | |
| 428 | |
| 429 if (useCache) { | |
| 430 // Decoding is done, cache the resulting YUV planes | |
| 431 SkYUVPlanesCache::Add(pixelRef->getGenerationID(), cachedData, &yuvI
nfo); | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 GrSurfaceDesc yuvDesc; | |
| 436 yuvDesc.fConfig = kAlpha_8_GrPixelConfig; | |
| 437 SkAutoTUnref<GrTexture> yuvTextures[3]; | |
| 438 for (int i = 0; i < 3; ++i) { | |
| 439 yuvDesc.fWidth = yuvInfo.fSize[i].fWidth; | |
| 440 yuvDesc.fHeight = yuvInfo.fSize[i].fHeight; | |
| 441 bool needsExactTexture = | |
| 442 (yuvDesc.fWidth != yuvInfo.fSize[0].fWidth) || | |
| 443 (yuvDesc.fHeight != yuvInfo.fSize[0].fHeight); | |
| 444 if (needsExactTexture) { | |
| 445 yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc,
true)); | |
| 446 } else { | |
| 447 yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuv
Desc)); | |
| 448 } | |
| 449 if (!yuvTextures[i] || | |
| 450 !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, | |
| 451 yuvDesc.fConfig, planes[i], yuvInfo.fRo
wBytes[i])) { | |
| 452 return nullptr; | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 GrSurfaceDesc rtDesc = desc; | |
| 457 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; | |
| 458 | |
| 459 GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRe
f, nullptr, 0); | |
| 460 if (!result) { | |
| 461 return nullptr; | 423 return nullptr; |
| 462 } | 424 } |
| 463 | 425 |
| 464 GrRenderTarget* renderTarget = result->asRenderTarget(); | 426 if (useCache) { |
| 465 SkASSERT(renderTarget); | 427 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); |
| 466 | 428 pixelRef->addGenIDChangeListener(listener); |
| 467 GrPaint paint; | 429 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture); |
| 468 SkAutoTUnref<GrFragmentProcessor> | |
| 469 yuvToRgbProcessor(GrYUVtoRGBEffect::Create(paint.getProcessorDataManager
(), yuvTextures[0], | |
| 470 yuvTextures[1], yuvTextures[2
], | |
| 471 yuvInfo.fSize, yuvInfo.fColor
Space)); | |
| 472 paint.addColorFragmentProcessor(yuvToRgbProcessor); | |
| 473 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth), | |
| 474 SkIntToScalar(yuvInfo.fSize[0].fHeight)); | |
| 475 | |
| 476 SkAutoTUnref<GrDrawContext> drawContext(ctx->drawContext()); | |
| 477 if (!drawContext) { | |
| 478 return nullptr; | |
| 479 } | 430 } |
| 480 | 431 return texture; |
| 481 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I()
, r); | |
| 482 | |
| 483 return result; | |
| 484 } | 432 } |
| 485 | 433 |
| 486 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, | 434 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
| 487 const SkBitmap& origBitmap, | 435 const SkBitmap& origBitmap, |
| 488 const GrUniqueKey& optionalK
ey) { | 436 const GrUniqueKey& optionalK
ey) { |
| 489 if (origBitmap.width() < ctx->caps()->minTextureSize() || | 437 if (origBitmap.width() < ctx->caps()->minTextureSize() || |
| 490 origBitmap.height() < ctx->caps()->minTextureSize()) { | 438 origBitmap.height() < ctx->caps()->minTextureSize()) { |
| 491 return nullptr; | 439 return nullptr; |
| 492 } | 440 } |
| 493 SkBitmap tmpBitmap; | 441 SkBitmap tmpBitmap; |
| 494 | 442 |
| 495 const SkBitmap* bitmap = &origBitmap; | 443 const SkBitmap* bitmap = &origBitmap; |
| 496 | 444 |
| 497 GrSurfaceDesc desc; | 445 GrSurfaceDesc desc; |
| 498 generate_bitmap_texture_desc(*bitmap, &desc); | 446 generate_bitmap_texture_desc(*bitmap, &desc); |
| 499 const GrCaps* caps = ctx->caps(); | 447 const GrCaps* caps = ctx->caps(); |
| 500 | 448 |
| 501 if (kIndex_8_SkColorType == bitmap->colorType()) { | 449 if (kIndex_8_SkColorType == bitmap->colorType()) { |
| 502 if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { | 450 if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { |
| 503 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig
, | 451 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig
, |
| 504 bitmap->width(), bitma
p->height()); | 452 bitmap->width(), bitma
p->height()); |
| 505 SkAutoMalloc storage(imageSize); | 453 SkAutoMalloc storage(imageSize); |
| 506 build_index8_data(storage.get(), origBitmap); | 454 build_index8_data(storage.get(), origBitmap); |
| 507 | 455 |
| 508 // our compressed data will be trimmed, so pass width() for its | 456 // our compressed data will be trimmed, so pass width() for its |
| 509 // "rowBytes", since they are the same now. | 457 // "rowBytes", since they are the same now. |
| 510 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pix
elRef(), | 458 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.p
ixelRef(), |
| 511 storage.get(), bitmap->width()); | 459 storage.get(), bitmap->width()); |
| 512 } else { | 460 } else { |
| 513 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); | 461 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); |
| 514 // now bitmap points to our temp, which has been promoted to 32bits | 462 // now bitmap points to our temp, which has been promoted to 32bits |
| 515 bitmap = &tmpBitmap; | 463 bitmap = &tmpBitmap; |
| 516 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); | 464 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); |
| 517 } | 465 } |
| 518 } | 466 } else if (!bitmap->readyToDraw()) { |
| 519 | 467 // If the bitmap had compressed data and was then uncompressed, it'll st
ill return |
| 520 // Is this an ETC1 encoded texture? | 468 // compressed data on 'refEncodedData' and upload it. Probably not good,
since if |
| 521 #ifndef SK_IGNORE_ETC1_SUPPORT | 469 // the bitmap has available pixels, then they might not be what the deco
mpressed |
| 522 // Make sure that the underlying device supports ETC1 textures before we go
ahead | 470 // data is. |
| 523 // and check the data. | |
| 524 else if (caps->isConfigTexturable(kETC1_GrPixelConfig) | |
| 525 // If the bitmap had compressed data and was then uncompressed, it'l
l still return | |
| 526 // compressed data on 'refEncodedData' and upload it. Probably not g
ood, since if | |
| 527 // the bitmap has available pixels, then they might not be what the
decompressed | |
| 528 // data is. | |
| 529 && !(bitmap->readyToDraw())) { | |
| 530 GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc); | 471 GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc); |
| 531 if (texture) { | 472 if (texture) { |
| 532 return texture; | 473 return texture; |
| 533 } | 474 } |
| 534 } | 475 } |
| 535 #endif // SK_IGNORE_ETC1_SUPPORT | |
| 536 | 476 |
| 537 GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc); | 477 GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc); |
| 538 if (texture) { | 478 if (texture) { |
| 539 return texture; | 479 return texture; |
| 540 } | 480 } |
| 541 | 481 |
| 542 SkAutoLockPixels alp(*bitmap); | 482 SkAutoLockPixels alp(*bitmap); |
| 543 if (!bitmap->readyToDraw()) { | 483 if (!bitmap->readyToDraw()) { |
| 544 return nullptr; | 484 return nullptr; |
| 545 } | 485 } |
| 546 | 486 |
| 547 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), | 487 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef(
), |
| 548 bitmap->getPixels(), bitmap->rowBytes()); | 488 bitmap->getPixels(), bitmap->rowBytes()); |
| 549 } | 489 } |
| 550 | 490 |
| 551 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) { | 491 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) { |
| 552 SkBitmap stretched; | 492 SkBitmap stretched; |
| 553 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight); | 493 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight); |
| 554 SkCanvas canvas(stretched); | 494 SkCanvas canvas(stretched); |
| 555 SkPaint paint; | 495 SkPaint paint; |
| 556 switch (stretch.fType) { | 496 switch (stretch.fType) { |
| 557 case Stretch::kNearest_Type: | 497 case Stretch::kNearest_Type: |
| 558 paint.setFilterQuality(kNone_SkFilterQuality); | 498 paint.setFilterQuality(kNone_SkFilterQuality); |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 SkErrorInternals::SetError( kInvalidPaint_SkError, | 860 SkErrorInternals::SetError( kInvalidPaint_SkError, |
| 921 "Sorry, I don't understand the filtering
" | 861 "Sorry, I don't understand the filtering
" |
| 922 "mode you asked for. Falling back to " | 862 "mode you asked for. Falling back to " |
| 923 "MIPMaps."); | 863 "MIPMaps."); |
| 924 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 864 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
| 925 break; | 865 break; |
| 926 | 866 |
| 927 } | 867 } |
| 928 return textureFilterMode; | 868 return textureFilterMode; |
| 929 } | 869 } |
| OLD | NEW |