diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrYUVProvider.cpp | 8 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVEffect.cpp | 63 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVEffect.h | 2 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 71 |
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)); |