diff options
author | Weiliang Chen <weiliangc@chromium.org> | 2018-05-22 18:44:02 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-23 18:50:53 +0000 |
commit | bed9d5ec3e1c83d17325069c739853a856564a83 (patch) | |
tree | 13228152dbc650ddfa80fe4add68280cfb639890 /src/image | |
parent | 4fa5824fa2ae896670517d01c58ed4aef4a97941 (diff) |
Add usage of SkYUVAIndex as pre-step to transfer to new YUVA API
The plan foward is to have a new API on SkImage to make from YUVA
textures which a combination of array of textures and array of
SkYUVAIndex struct indicating which texture and channel to read for
each plane. This is a pre-step to let the old API use these ideas.
Bug: skia: 7903
Change-Id: I6a696db31a574247eb2abff60f2186a74b640142
Reviewed-on: https://skia-review.googlesource.com/128601
Commit-Queue: Weiliang Chen <weiliangc@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/image')
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 104 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.h | 11 |
2 files changed, 83 insertions, 32 deletions
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 40e055e520..d3500e4f4e 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -368,39 +368,70 @@ sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx, kAdopt_GrWrapOwnership, nullptr, nullptr); } -sk_sp<SkImage> SkImage_Gpu::MakeFromYUVTexturesCopyImpl( - GrContext* ctx, SkYUVColorSpace colorSpace, bool nv12, - const GrBackendTexture yuvBackendTexturesOrig[], GrSurfaceOrigin origin, - sk_sp<SkColorSpace> imageColorSpace) { +sk_sp<SkImage> SkImage_Gpu::MakeFromYUVATexturesCopyImpl(GrContext* ctx, + SkYUVColorSpace colorSpace, + const GrBackendTexture yuvaTextures[], + SkYUVAIndex yuvaIndices[4], + SkISize size, + GrSurfaceOrigin origin, + sk_sp<SkColorSpace> imageColorSpace) { GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider(); - GrBackendTexture yuvBackendTextures[]{ - yuvBackendTexturesOrig[0], - yuvBackendTexturesOrig[1], - yuvBackendTexturesOrig[2], - }; + // Right now this still only deals with YUV and NV12 formats. Assuming that YUV has different + // textures for U and V planes, while NV12 uses same texture for U and V planes. + bool nv12 = (yuvaIndices[1].fIndex == yuvaIndices[2].fIndex); auto ct = nv12 ? kRGBA_8888_SkColorType : kAlpha_8_SkColorType; - for (int i = 0; i < (nv12 ? 2 : 3); ++i) { - if (!validate_backend_texture(ctx, yuvBackendTextures[i], &yuvBackendTextures[i].fConfig, - ct, kPremul_SkAlphaType, nullptr)) { + + for (int i = 0; i < 4; ++i) { + // Validate that the yuvaIndices refer to valid backend textures. + SkYUVAIndex& yuvaIndex = yuvaIndices[i]; + if (i == 3 && yuvaIndex.fIndex == -1) { + // Meaning the A plane isn't passed in. + continue; + } + if (yuvaIndex.fIndex == -1 || yuvaIndex.fIndex > 3) { + // Y plane, U plane, and V plane must refer to image sources being passed in. There are + // at most 4 images sources being passed in, could not have a index more than 3. + return nullptr; + } + auto texture = yuvaTextures[yuvaIndex.fIndex]; + // TODO: Instead of using assumption about whether it is NV12 format to guess colorType, + // actually use channel information here. + if (!validate_backend_texture(ctx, texture, &texture.fConfig, ct, kPremul_SkAlphaType, + nullptr)) { return nullptr; } + + // TODO: Check that for each plane, the channel actually exist in the image source we are + // reading from. } - sk_sp<GrTextureProxy> yProxy = proxyProvider->wrapBackendTexture(yuvBackendTextures[0], origin); - sk_sp<GrTextureProxy> uProxy = proxyProvider->wrapBackendTexture(yuvBackendTextures[1], origin); - sk_sp<GrTextureProxy> vProxy; - if (nv12) { - vProxy = uProxy; - } else { - vProxy = proxyProvider->wrapBackendTexture(yuvBackendTextures[2], origin); + sk_sp<GrTextureProxy> tempTextureProxies[4]; + for (int i = 0; i < 4; ++i) { + // Fill in tempTextureProxies to avoid duplicate texture proxies. + int textureIndex = yuvaIndices[i].fIndex; + + // Safely ignore since this means we are missing the A plane. + if (textureIndex == -1) { + SkASSERT(3 == i); + continue; + } + + if (!tempTextureProxies[textureIndex]) { + tempTextureProxies[textureIndex] = + proxyProvider->wrapBackendTexture(yuvaTextures[textureIndex], origin); + } } + sk_sp<GrTextureProxy> yProxy = tempTextureProxies[yuvaIndices[0].fIndex]; + sk_sp<GrTextureProxy> uProxy = tempTextureProxies[yuvaIndices[1].fIndex]; + sk_sp<GrTextureProxy> vProxy = tempTextureProxies[yuvaIndices[2].fIndex]; + if (!yProxy || !uProxy || !vProxy) { return nullptr; } - const int width = yuvBackendTextures[0].width(); - const int height = yuvBackendTextures[0].height(); + const int width = size.width(); + const int height = size.height(); // Needs to be a render target in order to draw to it for the yuv->rgb conversion. sk_sp<GrRenderTargetContext> renderTargetContext( @@ -413,9 +444,12 @@ sk_sp<SkImage> SkImage_Gpu::MakeFromYUVTexturesCopyImpl( GrPaint paint; paint.setPorterDuffXPFactory(SkBlendMode::kSrc); - SkISize sizes[] = {{yuvBackendTextures[0].width(), yuvBackendTextures[0].height()}, - {yuvBackendTextures[1].width(), yuvBackendTextures[1].height()}, - {yuvBackendTextures[2].width(), yuvBackendTextures[2].height()}}; + // TODO: Move the sizes into GrYUVtoRGBEffect since this can just be done there. + SkISize sizes[] = {{yProxy->width(), yProxy->height()}, + {uProxy->width(), uProxy->height()}, + {vProxy->width(), vProxy->height()}}; + // TODO: Modify the fragment processor to sample from different channel instead of taking nv12 + // bool. paint.addColorFragmentProcessor( GrYUVtoRGBEffect::Make(yProxy, uProxy, vProxy, sizes, colorSpace, nv12)); @@ -439,16 +473,30 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace const GrBackendTexture yuvTextures[3], GrSurfaceOrigin origin, sk_sp<SkColorSpace> imageColorSpace) { - return SkImage_Gpu::MakeFromYUVTexturesCopyImpl(ctx, colorSpace, false, yuvTextures, - origin, std::move(imageColorSpace)); + // TODO: SkImageSourceChannel input is being ingored right now. Setup correctly in the future. + SkYUVAIndex yuvaIndices[4] = { + SkYUVAIndex{0, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}, + SkYUVAIndex{1, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}, + SkYUVAIndex{2, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}, + SkYUVAIndex{-1, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}}; + SkISize size{yuvTextures[0].width(), yuvTextures[0].height()}; + return SkImage_Gpu::MakeFromYUVATexturesCopyImpl(ctx, colorSpace, yuvTextures, yuvaIndices, + size, origin, std::move(imageColorSpace)); } sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace, const GrBackendTexture nv12Textures[2], GrSurfaceOrigin origin, sk_sp<SkColorSpace> imageColorSpace) { - return SkImage_Gpu::MakeFromYUVTexturesCopyImpl(ctx, colorSpace, true, nv12Textures, - origin, std::move(imageColorSpace)); + // TODO: SkImageSourceChannel input is being ingored right now. Setup correctly in the future. + SkYUVAIndex yuvaIndices[4] = { + SkYUVAIndex{0, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}, + SkYUVAIndex{1, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}, + SkYUVAIndex{1, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}, + SkYUVAIndex{-1, SkImageSourceChannel::kLastEnum_SkImageSourceChannel}}; + SkISize size{nv12Textures[0].width(), nv12Textures[0].height()}; + return SkImage_Gpu::MakeFromYUVATexturesCopyImpl(ctx, colorSpace, nv12Textures, yuvaIndices, + size, origin, std::move(imageColorSpace)); } static sk_sp<SkImage> create_image_from_maker(GrContext* context, GrTextureMaker* maker, diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h index cb9a7c7a9f..b0c2785ece 100644 --- a/src/image/SkImage_Gpu.h +++ b/src/image/SkImage_Gpu.h @@ -125,10 +125,13 @@ public: TextureContext textureContext); /** Implementation of MakeFromYUVTexturesCopy and MakeFromNV12TexturesCopy */ - static sk_sp<SkImage> MakeFromYUVTexturesCopyImpl( - GrContext* ctx, SkYUVColorSpace colorSpace, bool nv12, - const GrBackendTexture yuvBackendTextures[], GrSurfaceOrigin origin, - sk_sp<SkColorSpace> imageColorSpace); + static sk_sp<SkImage> MakeFromYUVATexturesCopyImpl(GrContext* ctx, + SkYUVColorSpace colorSpace, + const GrBackendTexture yuvaTextures[], + SkYUVAIndex yuvaIndices[4], + SkISize size, + GrSurfaceOrigin origin, + sk_sp<SkColorSpace> imageColorSpace); bool onIsValid(GrContext*) const override; |