Chromium Code Reviews| Index: src/gpu/SkGr.cpp |
| diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
| index c4e2c1f93fd87b128a27206a3f0256f40fcc4456..5a14c81c8c1440183410bdbf28d56ccc0495d4cb 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,83 @@ static GrTexture *load_etc1_texture(GrContext* ctx, |
| } |
| #endif // SK_IGNORE_ETC1_SUPPORT |
|
robertphillips
2014/07/10 12:47:20
You could reduce the indent level of this by rever
sugoi1
2014/07/10 16:10:53
Done.
|
| +static GrTexture *load_yuv_texture(GrContext* ctx, |
| + const GrTextureParams* params, |
|
robertphillips
2014/07/10 12:47:20
const GrTextureDesc& desc ?
sugoi1
2014/07/10 16:10:53
Done.
|
| + const SkBitmap &bm, GrTextureDesc desc) { |
|
bsalomon
2014/07/09 20:19:18
style nit: Can you move the & to the left of the s
sugoi1
2014/07/10 16:10:53
Done.
|
| + GrTexture* result = NULL; |
| + |
| + SkPixelRef* pixelRef = bm.pixelRef(); |
| + SkISize yuvSizes[3]; |
|
robertphillips
2014/07/10 12:47:20
NULL != pixelRef ?
sugoi1
2014/07/10 16:10:53
Done.
|
| + if (pixelRef && pixelRef->getYUV8Planes(yuvSizes, NULL)) { |
|
robertphillips
2014/07/10 12:47:20
Allcate -> Allocate ?
sugoi1
2014/07/10 16:10:53
Done.
|
| + // Allcate the memory for YUV |
| + size_t ySize = yuvSizes[0].fWidth * yuvSizes[0].fHeight; |
| + size_t uSize = yuvSizes[1].fWidth * yuvSizes[1].fHeight; |
| + // size_t vSize = yuvSizes[2].fWidth * yuvSizes[2].fHeight; |
| + size_t yuvSize = 4 * ySize; // FIXME: ySize + uSize + vSize; |
| + SkAutoMalloc storage(yuvSize); |
| + uint8_t* planes = (uint8_t*)storage.get(); |
| + // Get the YUV planes |
| + if ((NULL != planes) && pixelRef->getYUV8Planes(yuvSizes, planes)) { |
| + // Put the planes into SkBitmap objects |
|
bsalomon
2014/07/09 20:19:18
Do we really need the intermediate step of going i
sugoi1
2014/07/10 16:10:52
Done.
|
| + SkBitmap yBitmap, uBitmap, vBitmap; |
| + SkImageInfo yInfo = SkImageInfo::MakeA8(yuvSizes[0].fWidth, yuvSizes[0].fHeight); |
| + SkImageInfo uInfo = SkImageInfo::MakeA8(yuvSizes[1].fWidth, yuvSizes[1].fHeight); |
| + SkImageInfo vInfo = SkImageInfo::MakeA8(yuvSizes[2].fWidth, yuvSizes[2].fHeight); |
| + if (yBitmap.installPixels(yInfo, planes, yInfo.minRowBytes()) && |
| + uBitmap.installPixels(uInfo, planes + ySize, uInfo.minRowBytes()) && |
| + vBitmap.installPixels(vInfo, planes + ySize + uSize, vInfo.minRowBytes())) { |
| + // Upload bitmaps as textures (don't cache these) |
| + yBitmap.setIsVolatile(true); |
| + uBitmap.setIsVolatile(true); |
| + vBitmap.setIsVolatile(true); |
| + GrTexture* yTexture = GrLockAndRefCachedBitmapTexture(ctx, yBitmap, params); |
| + GrTexture* uTexture = GrLockAndRefCachedBitmapTexture(ctx, uBitmap, params); |
| + GrTexture* vTexture = GrLockAndRefCachedBitmapTexture(ctx, vBitmap, params); |
| + if (yTexture && uTexture && vTexture) { |
| + 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(yTexture, uTexture, vTexture)); |
| + 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); |
| + ctx->drawRect(paint, r); |
| + } else { |
| + SkSafeSetNull(result); |
| + } |
| + } |
| + if (NULL != yTexture) { |
| + GrUnlockAndUnrefCachedBitmapTexture(yTexture); |
| + } |
| + if (NULL != uTexture) { |
| + GrUnlockAndUnrefCachedBitmapTexture(uTexture); |
| + } |
| + if (NULL != vTexture) { |
| + GrUnlockAndUnrefCachedBitmapTexture(vTexture); |
| + } |
| + } |
| + } |
| + } |
| + |
| + return result; |
| +} |
| + |
| static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, |
| bool cache, |
| const GrTextureParams* params, |
| @@ -264,6 +342,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; |