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 |