aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrYUVProvider.cpp8
-rw-r--r--src/gpu/effects/GrYUVEffect.cpp63
-rw-r--r--src/gpu/effects/GrYUVEffect.h2
-rw-r--r--src/image/SkImage_Gpu.cpp71
4 files changed, 88 insertions, 56 deletions
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index b30ff1fa3c..c35f57a68f 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -121,11 +121,9 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
}
GrPaint paint;
- sk_sp<GrFragmentProcessor> yuvToRgbProcessor(GrYUVEffect::MakeYUVToRGB(yuvTextures[0],
- yuvTextures[1],
- yuvTextures[2],
- yuvInfo.fSizeInfo.fSizes,
- yuvInfo.fColorSpace));
+ sk_sp<GrFragmentProcessor> yuvToRgbProcessor(
+ GrYUVEffect::MakeYUVToRGB(yuvTextures[0], yuvTextures[1], yuvTextures[2],
+ yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false));
paint.addColorFragmentProcessor(std::move(yuvToRgbProcessor));
// If we're decoding an sRGB image, the result of our linear math on the YUV planes is already
diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp
index 94dca84df6..7f959306f4 100644
--- a/src/gpu/effects/GrYUVEffect.cpp
+++ b/src/gpu/effects/GrYUVEffect.cpp
@@ -64,7 +64,7 @@ class YUVtoRGBEffect : public GrFragmentProcessor {
public:
static sk_sp<GrFragmentProcessor> Make(GrTexture* yTexture, GrTexture* uTexture,
GrTexture* vTexture, const SkISize sizes[3],
- SkYUVColorSpace colorSpace) {
+ SkYUVColorSpace colorSpace, bool nv12) {
SkScalar w[3], h[3];
w[0] = SkIntToScalar(sizes[0].fWidth) / SkIntToScalar(yTexture->width());
h[0] = SkIntToScalar(sizes[0].fHeight) / SkIntToScalar(yTexture->height());
@@ -85,21 +85,23 @@ public:
(sizes[2].fHeight != sizes[0].fHeight)) ?
GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode;
- return sk_sp<GrFragmentProcessor>(
- new YUVtoRGBEffect(yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace));
+ return sk_sp<GrFragmentProcessor>(new YUVtoRGBEffect(
+ yTexture, uTexture, vTexture, yuvMatrix, uvFilterMode, colorSpace, nv12));
}
const char* name() const override { return "YUV to RGB"; }
SkYUVColorSpace getColorSpace() const { return fColorSpace; }
+ bool isNV12() const {
+ return fNV12;
+ }
+
class GLSLProcessor : public GrGLSLFragmentProcessor {
public:
- // this class always generates the same code.
- static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {}
-
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const YUVtoRGBEffect& effect = args.fFp.cast<YUVtoRGBEffect>();
const char* colorSpaceMatrix = nullptr;
fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
@@ -111,10 +113,15 @@ public:
fragBuilder->codeAppend(".r,");
fragBuilder->appendTextureLookup(args.fTexSamplers[1], args.fCoords[1].c_str(),
args.fCoords[1].getType());
- fragBuilder->codeAppend(".r,");
- fragBuilder->appendTextureLookup(args.fTexSamplers[2], args.fCoords[2].c_str(),
- args.fCoords[2].getType());
- fragBuilder->codeAppendf(".r, 1.0) * %s;", colorSpaceMatrix);
+ if (effect.fNV12) {
+ fragBuilder->codeAppendf(".rg,");
+ } else {
+ fragBuilder->codeAppend(".r,");
+ fragBuilder->appendTextureLookup(args.fTexSamplers[2], args.fCoords[2].c_str(),
+ args.fCoords[2].getType());
+ fragBuilder->codeAppendf(".g,");
+ }
+ fragBuilder->codeAppendf("1.0) * %s;", colorSpaceMatrix);
}
protected:
@@ -143,21 +150,24 @@ public:
private:
YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
const SkMatrix yuvMatrix[3], GrTextureParams::FilterMode uvFilterMode,
- SkYUVColorSpace colorSpace)
- : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode)
- , fYAccess(yTexture)
- , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode)
- , fUAccess(uTexture, uvFilterMode)
- , fVTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, uvFilterMode)
- , fVAccess(vTexture, uvFilterMode)
- , fColorSpace(colorSpace) {
+ SkYUVColorSpace colorSpace, bool nv12)
+ : fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode)
+ , fYAccess(yTexture)
+ , fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, uvFilterMode)
+ , fUAccess(uTexture, uvFilterMode)
+ , fVAccess(vTexture, uvFilterMode)
+ , fColorSpace(colorSpace)
+ , fNV12(nv12) {
this->initClassID<YUVtoRGBEffect>();
this->addCoordTransform(&fYTransform);
this->addTextureAccess(&fYAccess);
this->addCoordTransform(&fUTransform);
this->addTextureAccess(&fUAccess);
- this->addCoordTransform(&fVTransform);
- this->addTextureAccess(&fVAccess);
+ if (!fNV12) {
+ fVTransform = GrCoordTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, uvFilterMode);
+ this->addCoordTransform(&fVTransform);
+ this->addTextureAccess(&fVAccess);
+ }
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
@@ -165,12 +175,12 @@ private:
}
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
- GLSLProcessor::GenKey(*this, caps, b);
+ b->add32(fNV12);
}
bool onIsEqual(const GrFragmentProcessor& sBase) const override {
const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
- return fColorSpace == s.getColorSpace();
+ return (fColorSpace == s.getColorSpace()) && (fNV12 == s.isNV12());
}
void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
@@ -186,6 +196,7 @@ private:
GrCoordTransform fVTransform;
GrTextureAccess fVAccess;
SkYUVColorSpace fColorSpace;
+ bool fNV12;
typedef GrFragmentProcessor INHERITED;
};
@@ -350,11 +361,11 @@ private:
//////////////////////////////////////////////////////////////////////////////
-sk_sp<GrFragmentProcessor>
-GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
- const SkISize sizes[3], SkYUVColorSpace colorSpace) {
+sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture,
+ GrTexture* vTexture, const SkISize sizes[3],
+ SkYUVColorSpace colorSpace, bool nv12) {
SkASSERT(yTexture && uTexture && vTexture && sizes);
- return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace);
+ return YUVtoRGBEffect::Make(yTexture, uTexture, vTexture, sizes, colorSpace, nv12);
}
sk_sp<GrFragmentProcessor>
diff --git a/src/gpu/effects/GrYUVEffect.h b/src/gpu/effects/GrYUVEffect.h
index 6d3b158ae9..902a181fd4 100644
--- a/src/gpu/effects/GrYUVEffect.h
+++ b/src/gpu/effects/GrYUVEffect.h
@@ -20,7 +20,7 @@ namespace GrYUVEffect {
*/
sk_sp<GrFragmentProcessor> MakeYUVToRGB(GrTexture* yTexture, GrTexture* uTexture,
GrTexture* vTexture, const SkISize sizes[3],
- SkYUVColorSpace colorSpace);
+ SkYUVColorSpace colorSpace, bool nv12);
/**
* Creates a processor that performs color conversion from the passed in processor's RGB
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index cc92d4efa5..9ad33ea2ba 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -205,18 +205,23 @@ sk_sp<SkImage> SkImage::MakeFromTextureCopy(GrContext* ctx, const GrBackendTextu
SkBudgeted::kYes);
}
-sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorSpace,
- const GrBackendObject yuvTextureHandles[3],
- const SkISize yuvSizes[3],
- GrSurfaceOrigin origin) {
+static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpace colorSpace,
+ bool nv12,
+ const GrBackendObject yuvTextureHandles[],
+ const SkISize yuvSizes[],
+ 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) {
+ 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;
}
- static const GrPixelConfig kConfig = kAlpha_8_GrPixelConfig;
+
+ const GrPixelConfig kConfig = nv12 ? kRGBA_8888_GrPixelConfig : kAlpha_8_GrPixelConfig;
+
GrBackendTextureDesc yDesc;
yDesc.fConfig = kConfig;
yDesc.fOrigin = origin;
@@ -233,20 +238,25 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace
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));
+ 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;
}
@@ -266,8 +276,8 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace
GrPaint paint;
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
- paint.addColorFragmentProcessor(GrYUVEffect::MakeYUVToRGB(yTex, uTex, vTex, yuvSizes,
- colorSpace));
+ paint.addColorFragmentProcessor(
+ GrYUVEffect::MakeYUVToRGB(yTex.get(), uTex.get(), vTex.get(), yuvSizes, colorSpace, nv12));
const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
@@ -278,6 +288,19 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace
drawContext->asTexture().get(), budgeted);
}
+sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace,
+ const GrBackendObject yuvTextureHandles[3],
+ const SkISize yuvSizes[3], GrSurfaceOrigin origin) {
+ return make_from_yuv_textures_copy(ctx, colorSpace, false, yuvTextureHandles, yuvSizes, origin);
+}
+
+sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace,
+ const GrBackendObject yuvTextureHandles[2],
+ const SkISize yuvSizes[2],
+ GrSurfaceOrigin origin) {
+ return make_from_yuv_textures_copy(ctx, colorSpace, true, yuvTextureHandles, yuvSizes, origin);
+}
+
static sk_sp<SkImage> create_image_from_maker(GrTextureMaker* maker, SkAlphaType at, uint32_t id) {
SkAutoTUnref<GrTexture> texture(maker->refTextureForParams(GrTextureParams::ClampNoFilter(),
SkSourceGammaTreatment::kRespect));