SkImage* SkImage::NewFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorSpace, const GrBackendObject yuvTextureHandles[3], const SkISize yuvSizes[3], GrSurfaceOrigin origin) { const SkSurface::Budgeted budgeted = SkSurface::kYes_Budgeted; if (yuvSizes[0].fWidth <= 0 || yuvSizes[0].fHeight <= 0 || yuvSizes[1].fWidth <= 0 || yuvSizes[1].fHeight <= 0 || yuvSizes[2].fWidth <= 0 || yuvSizes[2].fHeight <= 0) { return nullptr; } static const GrPixelConfig kConfig = kAlpha_8_GrPixelConfig; GrBackendTextureDesc yDesc; yDesc.fConfig = kConfig; yDesc.fOrigin = origin; yDesc.fSampleCnt = 0; yDesc.fTextureHandle = yuvTextureHandles[0]; yDesc.fWidth = yuvSizes[0].fWidth; yDesc.fHeight = yuvSizes[0].fHeight; GrBackendTextureDesc uDesc; uDesc.fConfig = kConfig; uDesc.fOrigin = origin; uDesc.fSampleCnt = 0; uDesc.fTextureHandle = yuvTextureHandles[1]; uDesc.fWidth = yuvSizes[1].fWidth; uDesc.fHeight = yuvSizes[1].fHeight; GrBackendTextureDesc vDesc; vDesc.fConfig = kConfig; vDesc.fOrigin = origin; vDesc.fSampleCnt = 0; vDesc.fTextureHandle = yuvTextureHandles[2]; vDesc.fWidth = yuvSizes[2].fWidth; vDesc.fHeight = yuvSizes[2].fHeight; SkAutoTUnref<GrTexture> yTex(ctx->textureProvider()->wrapBackendTexture( yDesc, kBorrow_GrWrapOwnership)); SkAutoTUnref<GrTexture> uTex(ctx->textureProvider()->wrapBackendTexture( uDesc, kBorrow_GrWrapOwnership)); SkAutoTUnref<GrTexture> vTex(ctx->textureProvider()->wrapBackendTexture( vDesc, kBorrow_GrWrapOwnership)); if (!yTex || !uTex || !vTex) { return nullptr; } GrSurfaceDesc dstDesc; // Needs to be a render target in order to draw to it for the yuv->rgb conversion. dstDesc.fFlags = kRenderTarget_GrSurfaceFlag; dstDesc.fOrigin = origin; dstDesc.fWidth = yuvSizes[0].fWidth; dstDesc.fHeight = yuvSizes[0].fHeight; dstDesc.fConfig = kRGBA_8888_GrPixelConfig; dstDesc.fSampleCnt = 0; SkAutoTUnref<GrTexture> dst(ctx->textureProvider()->createTexture(dstDesc, true)); if (!dst) { return nullptr; } GrPaint paint; paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); paint.addColorFragmentProcessor(GrYUVtoRGBEffect::Create(paint.getProcessorDataManager(), yTex, uTex, vTex, yuvSizes, colorSpace))->unref(); const SkRect rect = SkRect::MakeWH(SkIntToScalar(dstDesc.fWidth), SkIntToScalar(dstDesc.fHeight)); SkAutoTUnref<GrDrawContext> drawContext(ctx->drawContext()); if (!drawContext) { return nullptr; } drawContext->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), rect); ctx->flushSurfaceWrites(dst); return new SkImage_Gpu(dstDesc.fWidth, dstDesc.fHeight, kNeedNewImageUniqueID, kOpaque_SkAlphaType, dst, budgeted); }
static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpace colorSpace, bool nv12, const GrBackendObject yuvTextureHandles[], const SkISize yuvSizes[], GrSurfaceOrigin origin, sk_sp<SkColorSpace> imageColorSpace) { const SkBudgeted budgeted = SkBudgeted::kYes; if (yuvSizes[0].fWidth <= 0 || yuvSizes[0].fHeight <= 0 || yuvSizes[1].fWidth <= 0 || yuvSizes[1].fHeight <= 0) { return nullptr; } if (!nv12 && (yuvSizes[2].fWidth <= 0 || yuvSizes[2].fHeight <= 0)) { return nullptr; } const GrPixelConfig kConfig = nv12 ? kRGBA_8888_GrPixelConfig : kAlpha_8_GrPixelConfig; GrBackendTextureDesc yDesc; yDesc.fConfig = kConfig; yDesc.fOrigin = origin; yDesc.fSampleCnt = 0; yDesc.fTextureHandle = yuvTextureHandles[0]; yDesc.fWidth = yuvSizes[0].fWidth; yDesc.fHeight = yuvSizes[0].fHeight; GrBackendTextureDesc uDesc; uDesc.fConfig = kConfig; uDesc.fOrigin = origin; uDesc.fSampleCnt = 0; uDesc.fTextureHandle = yuvTextureHandles[1]; uDesc.fWidth = yuvSizes[1].fWidth; uDesc.fHeight = yuvSizes[1].fHeight; sk_sp<GrTexture> yTex( ctx->textureProvider()->wrapBackendTexture(yDesc, kBorrow_GrWrapOwnership)); sk_sp<GrTexture> uTex( ctx->textureProvider()->wrapBackendTexture(uDesc, kBorrow_GrWrapOwnership)); sk_sp<GrTexture> vTex; if (nv12) { vTex = uTex; } else { GrBackendTextureDesc vDesc; vDesc.fConfig = kConfig; vDesc.fOrigin = origin; vDesc.fSampleCnt = 0; vDesc.fTextureHandle = yuvTextureHandles[2]; vDesc.fWidth = yuvSizes[2].fWidth; vDesc.fHeight = yuvSizes[2].fHeight; vTex = sk_sp<GrTexture>( ctx->textureProvider()->wrapBackendTexture(vDesc, kBorrow_GrWrapOwnership)); } if (!yTex || !uTex || !vTex) { return nullptr; } const int width = yuvSizes[0].fWidth; const int height = yuvSizes[0].fHeight; // Needs to be a render target in order to draw to it for the yuv->rgb conversion. sk_sp<GrRenderTargetContext> renderTargetContext(ctx->makeRenderTargetContext( SkBackingFit::kExact, width, height, kRGBA_8888_GrPixelConfig, std::move(imageColorSpace), 0, origin)); if (!renderTargetContext) { return nullptr; } GrPaint paint; paint.setPorterDuffXPFactory(SkBlendMode::kSrc); paint.addColorFragmentProcessor( GrYUVEffect::MakeYUVToRGB(yTex.get(), uTex.get(), vTex.get(), yuvSizes, colorSpace, nv12)); const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect); ctx->flushSurfaceWrites(renderTargetContext->accessRenderTarget()); return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID, kOpaque_SkAlphaType, renderTargetContext->asTexture(), sk_ref_sp(renderTargetContext->getColorSpace()), budgeted); }
sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorSpace, const GrBackendObject yuvTextureHandles[3], const SkISize yuvSizes[3], GrSurfaceOrigin origin) { const SkBudgeted budgeted = SkBudgeted::kYes; if (yuvSizes[0].fWidth <= 0 || yuvSizes[0].fHeight <= 0 || yuvSizes[1].fWidth <= 0 || yuvSizes[1].fHeight <= 0 || yuvSizes[2].fWidth <= 0 || yuvSizes[2].fHeight <= 0) { return nullptr; } static const GrPixelConfig kConfig = kAlpha_8_GrPixelConfig; GrBackendTextureDesc yDesc; yDesc.fConfig = kConfig; yDesc.fOrigin = origin; yDesc.fSampleCnt = 0; yDesc.fTextureHandle = yuvTextureHandles[0]; yDesc.fWidth = yuvSizes[0].fWidth; yDesc.fHeight = yuvSizes[0].fHeight; GrBackendTextureDesc uDesc; uDesc.fConfig = kConfig; uDesc.fOrigin = origin; uDesc.fSampleCnt = 0; uDesc.fTextureHandle = yuvTextureHandles[1]; uDesc.fWidth = yuvSizes[1].fWidth; uDesc.fHeight = yuvSizes[1].fHeight; GrBackendTextureDesc vDesc; vDesc.fConfig = kConfig; vDesc.fOrigin = origin; vDesc.fSampleCnt = 0; vDesc.fTextureHandle = yuvTextureHandles[2]; vDesc.fWidth = yuvSizes[2].fWidth; vDesc.fHeight = yuvSizes[2].fHeight; SkAutoTUnref<GrTexture> yTex(ctx->textureProvider()->wrapBackendTexture( yDesc, kBorrow_GrWrapOwnership)); SkAutoTUnref<GrTexture> uTex(ctx->textureProvider()->wrapBackendTexture( uDesc, kBorrow_GrWrapOwnership)); SkAutoTUnref<GrTexture> vTex(ctx->textureProvider()->wrapBackendTexture( vDesc, kBorrow_GrWrapOwnership)); if (!yTex || !uTex || !vTex) { return nullptr; } const int width = yuvSizes[0].fWidth; const int height = yuvSizes[0].fHeight; // Needs to be a render target in order to draw to it for the yuv->rgb conversion. sk_sp<GrDrawContext> drawContext(ctx->newDrawContext(GrContext::kTight_BackingFit, width, height, kRGBA_8888_GrPixelConfig, 0, origin)); if (!drawContext) { return nullptr; } GrPaint paint; paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); paint.addColorFragmentProcessor(GrYUVEffect::CreateYUVToRGB(yTex, uTex, vTex, yuvSizes, colorSpace))->unref(); const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect); ctx->flushSurfaceWrites(drawContext->accessRenderTarget()); return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID, kOpaque_SkAlphaType, drawContext->asTexture().get(), budgeted); }