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; |