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>
This commit is contained in:
parent
4fa5824fa2
commit
bed9d5ec3e
@ -1037,6 +1037,22 @@ with studio range of 16 to 235 range for components.
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#Struct SkYUVAIndex
|
||||
|
||||
Describes which image source and which channel to read for each YUVA planes.
|
||||
|
||||
#Member int fIndex
|
||||
Describes which image source to be reading from. The Alpha plane is optional and could be set to -1.
|
||||
##
|
||||
|
||||
#Member SkImageSourceChannel fChannel
|
||||
Describes which of the RGBA channel to read from.
|
||||
##
|
||||
|
||||
#Struct SkYUVAIndex ##
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#Struct SkImageInfo
|
||||
|
||||
Describes pixel dimensions and encoding. Bitmap, Image, PixMap, and Surface
|
||||
|
@ -219,6 +219,42 @@ enum SkYUVColorSpace {
|
||||
kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace,
|
||||
};
|
||||
|
||||
/** \enum SkImageInfo::SkImageSourceChannel
|
||||
Describes different channels we could read from image source.
|
||||
*/
|
||||
enum SkImageSourceChannel {
|
||||
/** Describes the red channel; */
|
||||
kR_SkImageSourceChannel,
|
||||
|
||||
/** Describes the green channel; */
|
||||
kG_SkImageSourceChannel,
|
||||
|
||||
/** Describes the blue channel; */
|
||||
kB_SkImageSourceChannel,
|
||||
|
||||
/** Describes the alpha channel; */
|
||||
kA_SkImageSourceChannel,
|
||||
|
||||
/** Describes the alpha channel; */
|
||||
kLastEnum_SkImageSourceChannel = kA_SkImageSourceChannel,
|
||||
};
|
||||
|
||||
/** \struct SkYUVAIndex
|
||||
Describes from which image source and which channel to read each individual YUVA plane.
|
||||
|
||||
SkYUVAIndex contains a index for which image source to read from and a enum for which channel
|
||||
to read from.
|
||||
*/
|
||||
struct SK_API SkYUVAIndex {
|
||||
/** The index is a number between -1..3 which definies which image source to read from, where -1
|
||||
* means the image source doesn't exist. The assumption is we will always have image sources for
|
||||
* each of YUV planes, but optionally have image source for A plane. */
|
||||
int fIndex;
|
||||
/** The channel describes from which channel to read the info from. Currently we only deal with
|
||||
* YUV and NV12 and channel info is ignored. */
|
||||
SkImageSourceChannel fChannel;
|
||||
};
|
||||
|
||||
/** \struct SkImageInfo
|
||||
Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
|
||||
can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
// TODO: Check that for each plane, the channel actually exist in the image source we are
|
||||
// reading from.
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user