Chromium Code Reviews| Index: src/gpu/SkGr.cpp |
| diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
| index c4e2c1f93fd87b128a27206a3f0256f40fcc4456..63d1bb30e16666ee10aca5db3a1bf6899c46c1a2 100644 |
| --- a/src/gpu/SkGr.cpp |
| +++ b/src/gpu/SkGr.cpp |
| @@ -15,6 +15,7 @@ |
| #include "GrGpu.h" |
| #include "effects/GrDitherEffect.h" |
| #include "GrDrawTargetCaps.h" |
| +#include "effects/GrYUVtoRGBEffect.h" |
| #ifndef SK_IGNORE_ETC1_SUPPORT |
| # include "ktx.h" |
| @@ -193,6 +194,79 @@ static GrTexture *load_etc1_texture(GrContext* ctx, |
| } |
| #endif // SK_IGNORE_ETC1_SUPPORT |
| +static GrTexture *load_yuv_texture(GrContext* ctx, const GrTextureParams* params, |
| + const SkBitmap& bm, const GrTextureDesc& desc) { |
| + GrTexture* result = NULL; |
| + |
| + SkPixelRef* pixelRef = bm.pixelRef(); |
| + SkISize yuvSizes[3]; |
| + void* planes[3] = { NULL, NULL, NULL }; |
| + int rowBytes[3] = { 0, 0, 0 }; |
| + if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes)) { |
| + return NULL; |
| + } |
| + |
| + // Allocate the memory for YUV |
| + size_t totalSize = 0; |
| + size_t sizes[3]; |
| + for (int i = 0; i < 3; ++i) { |
| + rowBytes[i] = yuvSizes[i].fWidth; |
| + totalSize += sizes[i] = rowBytes[i] * yuvSizes[i].fHeight; |
| + } |
| + SkAutoMalloc storage(totalSize); |
| + planes[0] = storage.get(); |
| + planes[1] = (uint8_t*)planes[0] + sizes[0]; |
| + planes[2] = (uint8_t*)planes[1] + sizes[1]; |
| + |
| + // Get the YUV planes |
| + if ((NULL == planes[0]) || !pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes)) { |
|
reed1
2014/07/10 17:15:15
I don't think SkAutoMalloc can ever fail, can it?
sugoi1
2014/07/10 17:54:24
I don't know. What happens if we're out of memory?
|
| + return NULL; |
| + } |
| + |
| + GrTextureDesc yuvDesc; |
| + yuvDesc.fConfig = kAlpha_8_GrPixelConfig; |
| + SkAutoTUnref<GrTexture> yuvTextures[3]; |
| + for (int i = 0; i < 3; ++i) { |
| + yuvDesc.fWidth = yuvSizes[i].fWidth; |
| + yuvDesc.fHeight = yuvSizes[i].fHeight; |
| + GrTexture* tex = ctx->createUncachedTexture(yuvDesc, planes[i], rowBytes[i]); |
|
bsalomon
2014/07/10 18:29:39
We should probably use scratch textures here. We'd
sugoi1
2014/07/10 19:59:06
Done.
|
| + if (NULL == tex) { |
| + return NULL; |
| + } |
| + yuvTextures[i].reset(tex); |
| + } |
| + |
| + GrTextureDesc rtDesc = desc; |
| + rtDesc.fFlags = rtDesc.fFlags | |
| + kRenderTarget_GrTextureFlagBit | |
| + kNoStencil_GrTextureFlagBit; |
| + |
| + // This texture is likely to be used again so leave it in the cache |
| + GrCacheID cacheID; |
| + generate_bitmap_cache_id(bm, &cacheID); |
| + |
| + GrResourceKey key; |
| + result = ctx->createTexture(params, rtDesc, cacheID, NULL, 0, &key); |
| + GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; |
| + if (NULL != renderTarget) { |
| + add_genID_listener(key, bm.pixelRef()); |
| + SkAutoTUnref<GrEffect> yuvToRgbEffect(GrYUVtoRGBEffect::Create( |
| + yuvTextures[0].get(), yuvTextures[1].get(), yuvTextures[2].get())); |
| + GrPaint paint; |
| + paint.addColorEffect(yuvToRgbEffect); |
| + SkRect r = SkRect::MakeWH(yuvSizes[0].fWidth, yuvSizes[0].fHeight); |
| + GrContext::AutoRenderTarget autoRT(ctx, renderTarget); |
| + GrContext::AutoMatrix am; |
| + am.setIdentity(ctx); |
| + GrContext::AutoClip ac(ctx, r); |
|
bsalomon
2014/07/10 18:29:39
Maybe ac(ctx, GrContext::AutoClip::kWideOpen_Initi
sugoi1
2014/07/10 19:59:06
Will that work if I'm rendering a JPEG while rende
sugoi1
2014/07/11 18:46:15
Done. Seems to work properly in all cases I've tes
|
| + ctx->drawRect(paint, r); |
| + } else { |
| + SkSafeSetNull(result); |
| + } |
| + |
| + return result; |
| +} |
| + |
| static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, |
| bool cache, |
| const GrTextureParams* params, |
| @@ -264,6 +338,12 @@ static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, |
| } |
| #endif // SK_IGNORE_ETC1_SUPPORT |
| + else { |
| + GrTexture *texture = load_yuv_texture(ctx, params, *bitmap, desc); |
| + if (NULL != texture) { |
| + return texture; |
| + } |
| + } |
| SkAutoLockPixels alp(*bitmap); |
| if (!bitmap->readyToDraw()) { |
| return NULL; |