WEBGL_video_texture : sharing texture prototype in skia
Bug: 776222 Change-Id: I84c81bdaa6dc0b5548f116a28c6319e601effb32 Reviewed-on: https://skia-review.googlesource.com/146695 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Kenneth Russell <kbr@google.com>
This commit is contained in:
parent
29a49bd220
commit
d2fcfb5813
@ -31,7 +31,7 @@ protected:
|
||||
}
|
||||
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(50, 175);
|
||||
return SkISize::Make(50, 300);
|
||||
}
|
||||
|
||||
void onOnceBeforeDraw() override {
|
||||
@ -114,6 +114,23 @@ protected:
|
||||
context->resetContext();
|
||||
}
|
||||
|
||||
void createExternalBackendTexture(GrContext* context, int width, int height,
|
||||
GrBackendTexture externalBackendTexture[1]) {
|
||||
if (context->abandoned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrGpu* gpu = context->contextPriv().getGpu();
|
||||
if (!gpu) {
|
||||
return;
|
||||
}
|
||||
|
||||
externalBackendTexture[0] = gpu->createTestingOnlyBackendTexture(
|
||||
nullptr, width, height, kRGBA_8888_GrPixelConfig, true, GrMipMapped::kNo);
|
||||
|
||||
context->resetContext();
|
||||
}
|
||||
|
||||
void deleteYUVTextures(GrContext* context, GrBackendTexture yuvTextures[3]) {
|
||||
if (context->abandoned()) {
|
||||
return;
|
||||
@ -135,6 +152,19 @@ protected:
|
||||
context->resetContext();
|
||||
}
|
||||
|
||||
void deleteAllTextures(GrContext* context, GrBackendTexture yuvTextures[3],
|
||||
GrBackendTexture externalBackendTexture) {
|
||||
this->deleteYUVTextures(context, yuvTextures);
|
||||
|
||||
GrGpu* gpu = context->contextPriv().getGpu();
|
||||
gpu->testingOnly_flushGpuAndSync();
|
||||
if (externalBackendTexture.isValid()) {
|
||||
gpu->deleteTestingOnlyBackendTexture(externalBackendTexture);
|
||||
}
|
||||
|
||||
context->resetContext();
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
GrContext* context = canvas->getGrContext();
|
||||
if (!context) {
|
||||
@ -162,6 +192,30 @@ protected:
|
||||
|
||||
canvas->drawImage(images[i].get(), x, y);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> image;
|
||||
for (int space = kJPEG_SkYUVColorSpace, i = images.count();
|
||||
space <= kLastEnum_SkYUVColorSpace; ++space, ++i) {
|
||||
GrBackendTexture yuvTextures[3];
|
||||
GrBackendTexture externalBackendTexture[1];
|
||||
this->createYUVTextures(context, yuvTextures);
|
||||
this->createExternalBackendTexture(context,
|
||||
yuvTextures[0].width(),
|
||||
yuvTextures[0].height(),
|
||||
externalBackendTexture);
|
||||
image = SkImage::MakeFromYUVTexturesCopyWithExternalBackend(
|
||||
context,
|
||||
static_cast<SkYUVColorSpace>(space),
|
||||
yuvTextures,
|
||||
kTopLeft_GrSurfaceOrigin,
|
||||
externalBackendTexture[0]);
|
||||
|
||||
SkScalar y = (i + 1) * kPad + i * fYUVBmps[0].height();
|
||||
SkScalar x = kPad;
|
||||
|
||||
canvas->drawImage(image.get(), x, y);
|
||||
this->deleteAllTextures(context, yuvTextures, externalBackendTexture[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -342,6 +342,25 @@ public:
|
||||
GrSurfaceOrigin surfaceOrigin,
|
||||
sk_sp<SkColorSpace> colorSpace = nullptr);
|
||||
|
||||
/** Creates SkImage from copy of yuvTextures, an array of textures on GPU.
|
||||
yuvTextures contain pixels for YUV planes of SkImage. Returned SkImage has the dimensions
|
||||
yuvTextures[0] and stores pixels in backendTexture. yuvColorSpace describes how YUV colors
|
||||
convert to RGB colors.
|
||||
|
||||
@param context GPU context
|
||||
@param yuvColorSpace one of: kJPEG_SkYUVColorSpace, kRec601_SkYUVColorSpace,
|
||||
kRec709_SkYUVColorSpace
|
||||
@param yuvTextures array of YUV textures on GPU
|
||||
@param surfaceOrigin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
|
||||
@param backendTexture the resource that stores the final pixels
|
||||
@param colorSpace range of colors; may be nullptr
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromYUVTexturesCopyWithExternalBackend(
|
||||
GrContext* context, SkYUVColorSpace yuvColorSpace,
|
||||
const GrBackendTexture yuvTextures[3], GrSurfaceOrigin surfaceOrigin,
|
||||
const GrBackendTexture backendTexture, sk_sp<SkColorSpace> colorSpace = nullptr);
|
||||
|
||||
/** Creates SkImage from copy of nv12Textures, an array of textures on GPU.
|
||||
nv12Textures[0] contains pixels for YUV component y plane.
|
||||
nv12Textures[1] contains pixels for YUV component u plane,
|
||||
@ -363,6 +382,30 @@ public:
|
||||
GrSurfaceOrigin surfaceOrigin,
|
||||
sk_sp<SkColorSpace> colorSpace = nullptr);
|
||||
|
||||
/** Creates SkImage from copy of nv12Textures, an array of textures on GPU.
|
||||
nv12Textures[0] contains pixels for YUV_Component_Y plane.
|
||||
nv12Textures[1] contains pixels for YUV_Component_U plane,
|
||||
followed by pixels for YUV_Component_V plane.
|
||||
Returned SkImage has the dimensions nv12Textures[2] and stores pixels in backendTexture.
|
||||
yuvColorSpace describes how YUV colors convert to RGB colors.
|
||||
|
||||
@param context GPU context
|
||||
@param yuvColorSpace one of: kJPEG_SkYUVColorSpace, kRec601_SkYUVColorSpace,
|
||||
kRec709_SkYUVColorSpace
|
||||
@param nv12Textures array of YUV textures on GPU
|
||||
@param surfaceOrigin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
|
||||
@param backendTexture the resource that stores the final pixels
|
||||
@param colorSpace range of colors; may be nullptr
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromNV12TexturesCopyWithExternalBackend(
|
||||
GrContext* context,
|
||||
SkYUVColorSpace yuvColorSpace,
|
||||
const GrBackendTexture nv12Textures[2],
|
||||
GrSurfaceOrigin surfaceOrigin,
|
||||
const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> colorSpace = nullptr);
|
||||
|
||||
enum class BitDepth {
|
||||
kU8, //!< uses 8-bit unsigned int per color component
|
||||
kF16, //!< uses 16-bit float per color component
|
||||
|
@ -377,6 +377,13 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopyWithExternalBackend(
|
||||
GrContext* context, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvTextures[3],
|
||||
GrSurfaceOrigin surfaceOrigin, const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace space,
|
||||
const GrBackendTexture[2],
|
||||
GrSurfaceOrigin origin,
|
||||
@ -389,6 +396,15 @@ sk_sp<SkImage> SkImage::makeTextureImage(GrContext*, SkColorSpace* dstColorSpace
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> MakeFromNV12TexturesCopyWithExternalBackend(GrContext* context,
|
||||
SkYUVColorSpace yuvColorSpace,
|
||||
const GrBackendTexture nv12Textures[2],
|
||||
GrSurfaceOrigin surfaceOrigin,
|
||||
const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -339,13 +339,12 @@ sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx,
|
||||
kAdopt_GrWrapOwnership, nullptr, nullptr);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage_Gpu::MakeFromYUVATexturesCopyImpl(GrContext* ctx,
|
||||
SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture yuvaTextures[],
|
||||
SkYUVAIndex yuvaIndices[4],
|
||||
SkISize size,
|
||||
GrSurfaceOrigin origin,
|
||||
sk_sp<SkColorSpace> imageColorSpace) {
|
||||
sk_sp<SkImage> SkImage_Gpu::ConvertYUVATexturesToRGB(
|
||||
GrContext* ctx, SkYUVColorSpace colorSpace, const GrBackendTexture yuvaTextures[],
|
||||
SkYUVAIndex yuvaIndices[4], SkISize size, GrSurfaceOrigin origin, SkBudgeted isBudgeted,
|
||||
GrRenderTargetContext* renderTargetContext) {
|
||||
SkASSERT(renderTargetContext);
|
||||
|
||||
GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
|
||||
|
||||
// Right now this still only deals with YUV and NV12 formats. Assuming that YUV has different
|
||||
@ -411,15 +410,6 @@ sk_sp<SkImage> SkImage_Gpu::MakeFromYUVATexturesCopyImpl(GrContext* ctx,
|
||||
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(
|
||||
ctx->contextPriv().makeDeferredRenderTargetContext(
|
||||
SkBackingFit::kExact, width, height, kRGBA_8888_GrPixelConfig,
|
||||
std::move(imageColorSpace), 1, GrMipMapped::kNo, origin));
|
||||
if (!renderTargetContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrPaint paint;
|
||||
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
|
||||
// TODO: Modify the fragment processor to sample from different channel instead of taking nv12
|
||||
@ -442,7 +432,62 @@ sk_sp<SkImage> SkImage_Gpu::MakeFromYUVATexturesCopyImpl(GrContext* ctx,
|
||||
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(ctx), kNeedNewImageUniqueID, kOpaque_SkAlphaType,
|
||||
renderTargetContext->asTextureProxyRef(),
|
||||
renderTargetContext->colorSpaceInfo().refColorSpace(),
|
||||
SkBudgeted::kYes);
|
||||
isBudgeted);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage_Gpu::MakeFromYUVATexturesCopyImpl(GrContext* ctx,
|
||||
SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture yuvaTextures[],
|
||||
SkYUVAIndex yuvaIndices[4],
|
||||
SkISize size,
|
||||
GrSurfaceOrigin origin,
|
||||
sk_sp<SkColorSpace> imageColorSpace) {
|
||||
const int width = size.width();
|
||||
const int height = size.height();
|
||||
|
||||
// Needs to create a render target in order to draw to it for the yuv->rgb conversion.
|
||||
sk_sp<GrRenderTargetContext> renderTargetContext(
|
||||
ctx->contextPriv().makeDeferredRenderTargetContext(
|
||||
SkBackingFit::kExact, width, height, kRGBA_8888_GrPixelConfig,
|
||||
std::move(imageColorSpace), 1, GrMipMapped::kNo, origin));
|
||||
if (!renderTargetContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SkImage_Gpu::ConvertYUVATexturesToRGB(ctx, colorSpace, yuvaTextures, yuvaIndices, size,
|
||||
origin, SkBudgeted::kYes,
|
||||
renderTargetContext.get());
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage_Gpu::MakeFromYUVATexturesCopyWithExternalBackendImpl(
|
||||
GrContext* ctx,
|
||||
SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture yuvaTextures[],
|
||||
SkYUVAIndex yuvaIndices[4],
|
||||
SkISize size,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> imageColorSpace) {
|
||||
GrBackendTexture backendTextureCopy = backendTexture;
|
||||
|
||||
if (!validate_backend_texture(ctx, backendTextureCopy, &backendTextureCopy.fConfig, kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType, nullptr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Needs to create a render target with external texture
|
||||
// in order to draw to it for the yuv->rgb conversion.
|
||||
sk_sp<GrRenderTargetContext> renderTargetContext(
|
||||
ctx->contextPriv().makeBackendTextureRenderTargetContext(backendTextureCopy, origin, 1,
|
||||
std::move(imageColorSpace)));
|
||||
|
||||
if (!renderTargetContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SkImage_Gpu::ConvertYUVATexturesToRGB(ctx, colorSpace, yuvaTextures, yuvaIndices, size,
|
||||
origin, SkBudgeted::kNo,
|
||||
renderTargetContext.get());
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace,
|
||||
@ -460,6 +505,21 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace
|
||||
size, origin, std::move(imageColorSpace));
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopyWithExternalBackend(
|
||||
GrContext* ctx, SkYUVColorSpace colorSpace, const GrBackendTexture yuvTextures[3],
|
||||
GrSurfaceOrigin origin, const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> imageColorSpace) {
|
||||
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::MakeFromYUVATexturesCopyWithExternalBackendImpl(
|
||||
ctx, colorSpace, yuvTextures, yuvaIndices, size, origin, backendTexture,
|
||||
std::move(imageColorSpace));
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture nv12Textures[2],
|
||||
GrSurfaceOrigin origin,
|
||||
@ -475,6 +535,24 @@ sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace
|
||||
size, origin, std::move(imageColorSpace));
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopyWithExternalBackend(
|
||||
GrContext* ctx,
|
||||
SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture nv12Textures[2],
|
||||
GrSurfaceOrigin origin,
|
||||
const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> imageColorSpace) {
|
||||
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::MakeFromYUVATexturesCopyWithExternalBackendImpl(
|
||||
ctx, colorSpace, nv12Textures, yuvaIndices, size, origin, backendTexture,
|
||||
std::move(imageColorSpace));
|
||||
}
|
||||
|
||||
static sk_sp<SkImage> create_image_from_producer(GrContext* context, GrTextureProducer* producer,
|
||||
SkAlphaType at, uint32_t id,
|
||||
SkColorSpace* dstColorSpace,
|
||||
|
@ -131,6 +131,18 @@ public:
|
||||
GrSurfaceOrigin origin,
|
||||
sk_sp<SkColorSpace> imageColorSpace);
|
||||
|
||||
/** Implementation of MakeFromYUVTexturesCopyWithExternalBackend and
|
||||
MakeFromNV12TexturesCopyWithExternalBackend */
|
||||
static sk_sp<SkImage> MakeFromYUVATexturesCopyWithExternalBackendImpl(
|
||||
GrContext* ctx,
|
||||
SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture yuvaTextures[],
|
||||
SkYUVAIndex yuvaIndices[4],
|
||||
SkISize size,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrBackendTexture backendTexture,
|
||||
sk_sp<SkColorSpace> imageColorSpace);
|
||||
|
||||
bool onIsValid(GrContext*) const override;
|
||||
|
||||
void resetContext(sk_sp<GrContext> newContext) {
|
||||
@ -139,6 +151,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static sk_sp<SkImage> ConvertYUVATexturesToRGB(
|
||||
GrContext* ctx, SkYUVColorSpace colorSpace, const GrBackendTexture yuvaTextures[],
|
||||
SkYUVAIndex yuvaIndices[4], SkISize size, GrSurfaceOrigin origin,
|
||||
SkBudgeted isBudgeted, GrRenderTargetContext* renderTargetContext);
|
||||
|
||||
sk_sp<GrContext> fContext;
|
||||
sk_sp<GrTextureProxy> fProxy;
|
||||
const SkAlphaType fAlphaType;
|
||||
|
Loading…
Reference in New Issue
Block a user