diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2017-12-21 14:18:01 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-22 14:06:45 +0000 |
commit | 7461a4abe06ffdfbb62a479a71b14895a637bba9 (patch) | |
tree | 0ecba2733d86d3610f696586221ab2e29e0c54ae | |
parent | 8bc327bffb7ae7d10b93ee75c3d207caeb37f93b (diff) |
converted YUVEffect to SkSL
Bug: skia:
Change-Id: I1875e44417a0a583c4f35ee4d46856a34ba55245
Reviewed-on: https://skia-review.googlesource.com/88580
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
-rw-r--r-- | gm/yuvtorgbeffect.cpp | 18 | ||||
-rw-r--r-- | gn/gpu.gni | 4 | ||||
-rw-r--r-- | gn/sksl.gni | 1 | ||||
-rw-r--r-- | src/gpu/GrProcessor.h | 2 | ||||
-rw-r--r-- | src/gpu/GrYUVProvider.cpp | 10 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVEffect.cpp | 215 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVEffect.h | 29 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVtoRGBEffect.cpp | 173 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVtoRGBEffect.fp | 116 | ||||
-rw-r--r-- | src/gpu/effects/GrYUVtoRGBEffect.h | 84 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 6 |
11 files changed, 394 insertions, 264 deletions
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp index f957566d9f..f5a905c03f 100644 --- a/gm/yuvtorgbeffect.cpp +++ b/gm/yuvtorgbeffect.cpp @@ -17,7 +17,7 @@ #include "SkBitmap.h" #include "SkGr.h" #include "SkGradientShader.h" -#include "effects/GrYUVEffect.h" +#include "effects/GrYUVtoRGBEffect.h" #include "ops/GrDrawOp.h" #include "ops/GrRectOpFactory.h" @@ -119,12 +119,12 @@ protected: for (int i = 0; i < 6; ++i) { std::unique_ptr<GrFragmentProcessor> fp( - GrYUVEffect::MakeYUVToRGB(proxy[indices[i][0]], - proxy[indices[i][1]], - proxy[indices[i][2]], - sizes, - static_cast<SkYUVColorSpace>(space), - false)); + GrYUVtoRGBEffect::Make(proxy[indices[i][0]], + proxy[indices[i][1]], + proxy[indices[i][2]], + sizes, + static_cast<SkYUVColorSpace>(space), + false)); if (fp) { GrPaint grPaint; grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); @@ -247,8 +247,8 @@ protected: GrPaint grPaint; grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); - auto fp = GrYUVEffect::MakeYUVToRGB(proxy[0], proxy[1], proxy[2], sizes, - static_cast<SkYUVColorSpace>(space), true); + auto fp = GrYUVtoRGBEffect::Make(proxy[0], proxy[1], proxy[2], sizes, + static_cast<SkYUVColorSpace>(space), true); if (fp) { SkMatrix viewMatrix; viewMatrix.setTranslate(x, y); diff --git a/gn/gpu.gni b/gn/gpu.gni index fb512bf10b..fee613c951 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -384,8 +384,8 @@ skia_gpu_sources = [ "$_src/gpu/effects/GrUnpremulInputFragmentProcessor.h", "$_src/gpu/effects/GrXfermodeFragmentProcessor.cpp", "$_src/gpu/effects/GrXfermodeFragmentProcessor.h", - "$_src/gpu/effects/GrYUVEffect.cpp", - "$_src/gpu/effects/GrYUVEffect.h", + "$_src/gpu/effects/GrYUVtoRGBEffect.cpp", + "$_src/gpu/effects/GrYUVtoRGBEffect.h", # text "$_src/gpu/text/GrAtlasGlyphCache.cpp", diff --git a/gn/sksl.gni b/gn/sksl.gni index 1bb57718c0..6248e695e3 100644 --- a/gn/sksl.gni +++ b/gn/sksl.gni @@ -44,4 +44,5 @@ skia_gpu_processor_sources = [ "$_src/gpu/effects/GrOverdrawFragmentProcessor.fp", "$_src/gpu/effects/GrSimpleTextureEffect.fp", "$_src/gpu/effects/GrUnpremulInputFragmentProcessor.fp", + "$_src/gpu/effects/GrYUVtoRGBEffect.fp", ] diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 0736d036cd..aac22f32b7 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -135,6 +135,7 @@ public: kGrSweepGradient_ClassID, kGrTextureDomainEffect_ClassID, kGrUnpremulInputFragmentProcessor_ClassID, + kGrYUVtoRGBEffect_ClassID, kHighContrastFilterEffect_ClassID, kInstanceProcessor_ClassID, kLumaColorFilterEffect_ClassID, @@ -150,7 +151,6 @@ public: kSwizzleFragmentProcessor_ClassID, kTestFP_ClassID, kTextureGeometryProcessor_ClassID, - kYUVtoRGBEffect_ClassID }; virtual ~GrProcessor() = default; diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index 930a33e961..42319d2c06 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -18,7 +18,7 @@ #include "SkYUVPlanesCache.h" #include "effects/GrNonlinearColorSpaceXformEffect.h" #include "effects/GrSRGBEffect.h" -#include "effects/GrYUVEffect.h" +#include "effects/GrYUVtoRGBEffect.h" namespace { /** @@ -139,10 +139,10 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS GrPaint paint; auto yuvToRgbProcessor = - GrYUVEffect::MakeYUVToRGB(yuvTextureContexts[0]->asTextureProxyRef(), - yuvTextureContexts[1]->asTextureProxyRef(), - yuvTextureContexts[2]->asTextureProxyRef(), - yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false); + GrYUVtoRGBEffect::Make(yuvTextureContexts[0]->asTextureProxyRef(), + yuvTextureContexts[1]->asTextureProxyRef(), + yuvTextureContexts[2]->asTextureProxyRef(), + 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 deleted file mode 100644 index 6e0f766071..0000000000 --- a/src/gpu/effects/GrYUVEffect.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrYUVEffect.h" - -#include "GrCoordTransform.h" -#include "GrFragmentProcessor.h" -#include "GrProcessor.h" -#include "GrTextureProxy.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "glsl/GrGLSLProgramDataManager.h" -#include "glsl/GrGLSLUniformHandler.h" - -namespace { - -static const float kJPEGConversionMatrix[16] = { - 1.0f, 0.0f, 1.402f, -0.703749f, - 1.0f, -0.344136f, -0.714136f, 0.531211f, - 1.0f, 1.772f, 0.0f, -0.889475f, - 0.0f, 0.0f, 0.0f, 1.0 -}; - -static const float kRec601ConversionMatrix[16] = { - 1.164f, 0.0f, 1.596f, -0.87075f, - 1.164f, -0.391f, -0.813f, 0.52925f, - 1.164f, 2.018f, 0.0f, -1.08175f, - 0.0f, 0.0f, 0.0f, 1.0} -; - -static const float kRec709ConversionMatrix[16] = { - 1.164f, 0.0f, 1.793f, -0.96925f, - 1.164f, -0.213f, -0.533f, 0.30025f, - 1.164f, 2.112f, 0.0f, -1.12875f, - 0.0f, 0.0f, 0.0f, 1.0f} -; - -class YUVtoRGBEffect : public GrFragmentProcessor { -public: - static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy, - sk_sp<GrTextureProxy> uProxy, - sk_sp<GrTextureProxy> vProxy, - const SkISize sizes[3], - SkYUVColorSpace colorSpace, bool nv12) { - SkScalar w[3], h[3]; - w[0] = SkIntToScalar(sizes[0].fWidth); - h[0] = SkIntToScalar(sizes[0].fHeight); - w[1] = SkIntToScalar(sizes[1].fWidth); - h[1] = SkIntToScalar(sizes[1].fHeight); - w[2] = SkIntToScalar(sizes[2].fWidth); - h[2] = SkIntToScalar(sizes[2].fHeight); - const SkMatrix yuvMatrix[3] = { - SkMatrix::I(), - SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]), - SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]) - }; - GrSamplerState::Filter uvFilterMode = - ((sizes[1].fWidth != sizes[0].fWidth) || - (sizes[1].fHeight != sizes[0].fHeight) || - (sizes[2].fWidth != sizes[0].fWidth) || - (sizes[2].fHeight != sizes[0].fHeight)) ? - GrSamplerState::Filter::kBilerp : - GrSamplerState::Filter::kNearest; - return std::unique_ptr<GrFragmentProcessor>( - new YUVtoRGBEffect(std::move(yProxy), std::move(uProxy), std::move(vProxy), - yuvMatrix, uvFilterMode, colorSpace, nv12)); - } - - const char* name() const override { return "YUV to RGB"; } - - std::unique_ptr<GrFragmentProcessor> clone() const override { - return std::unique_ptr<GrFragmentProcessor>(new YUVtoRGBEffect(*this)); - } - - SkYUVColorSpace getColorSpace() const { return fColorSpace; } - - bool isNV12() const { - return fNV12; - } - - class GLSLProcessor : public GrGLSLFragmentProcessor { - public: - 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, kHalf4x4_GrSLType, - "ColorSpaceMatrix", &colorSpaceMatrix); - fragBuilder->codeAppendf("%s = half4(", args.fOutputColor); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], - args.fTransformedCoords[0].c_str(), - args.fTransformedCoords[0].getType()); - fragBuilder->codeAppend(".r,"); - fragBuilder->appendTextureLookup(args.fTexSamplers[1], - args.fTransformedCoords[1].c_str(), - args.fTransformedCoords[1].getType()); - if (effect.fNV12) { - fragBuilder->codeAppendf(".rg,"); - } else { - fragBuilder->codeAppend(".r,"); - fragBuilder->appendTextureLookup(args.fTexSamplers[2], - args.fTransformedCoords[2].c_str(), - args.fTransformedCoords[2].getType()); - fragBuilder->codeAppendf(".r,"); - } - fragBuilder->codeAppendf("1.0) * %s;", colorSpaceMatrix); - } - - protected: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& processor) override { - const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>(); - switch (yuvEffect.getColorSpace()) { - case kJPEG_SkYUVColorSpace: - pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix); - break; - case kRec601_SkYUVColorSpace: - pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix); - break; - case kRec709_SkYUVColorSpace: - pdman.setMatrix4f(fMatrixUni, kRec709ConversionMatrix); - break; - } - } - - private: - GrGLSLProgramDataManager::UniformHandle fMatrixUni; - - typedef GrGLSLFragmentProcessor INHERITED; - }; - -private: - YUVtoRGBEffect(sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy, - sk_sp<GrTextureProxy> vProxy, const SkMatrix yuvMatrix[3], - GrSamplerState::Filter uvFilterMode, SkYUVColorSpace colorSpace, bool nv12) - : INHERITED(kYUVtoRGBEffect_ClassID, kPreservesOpaqueInput_OptimizationFlag) - , fYTransform(yuvMatrix[0], yProxy.get()) - , fYSampler(std::move(yProxy)) - , fUTransform(yuvMatrix[1], uProxy.get()) - , fUSampler(std::move(uProxy), uvFilterMode) - , fVSampler(vProxy, uvFilterMode) - , fColorSpace(colorSpace) - , fNV12(nv12) { - this->addCoordTransform(&fYTransform); - this->addTextureSampler(&fYSampler); - this->addCoordTransform(&fUTransform); - this->addTextureSampler(&fUSampler); - if (!fNV12) { - fVTransform = GrCoordTransform(yuvMatrix[2], vProxy.get()); - this->addCoordTransform(&fVTransform); - this->addTextureSampler(&fVSampler); - } - } - - YUVtoRGBEffect(const YUVtoRGBEffect& that) - : INHERITED(kYUVtoRGBEffect_ClassID, kPreservesOpaqueInput_OptimizationFlag) - , fYTransform(that.fYTransform) - , fYSampler(that.fYSampler) - , fUTransform(that.fUTransform) - , fUSampler(that.fUSampler) - , fVTransform(that.fVTransform) - , fVSampler(that.fVSampler) - , fColorSpace(that.fColorSpace) - , fNV12(that.fNV12) { - this->addCoordTransform(&fYTransform); - this->addTextureSampler(&fYSampler); - this->addCoordTransform(&fUTransform); - this->addTextureSampler(&fUSampler); - if (!fNV12) { - this->addCoordTransform(&fVTransform); - this->addTextureSampler(&fVSampler); - } - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { - return new GLSLProcessor; - } - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - b->add32(fNV12); - } - - bool onIsEqual(const GrFragmentProcessor& sBase) const override { - const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>(); - return (fColorSpace == s.getColorSpace()) && (fNV12 == s.isNV12()); - } - - GrCoordTransform fYTransform; - TextureSampler fYSampler; - GrCoordTransform fUTransform; - TextureSampler fUSampler; - GrCoordTransform fVTransform; - TextureSampler fVSampler; - SkYUVColorSpace fColorSpace; - bool fNV12; - - typedef GrFragmentProcessor INHERITED; -}; - -} - -////////////////////////////////////////////////////////////////////////////// - -std::unique_ptr<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB( - sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy, sk_sp<GrTextureProxy> vProxy, - const SkISize sizes[3], SkYUVColorSpace colorSpace, bool nv12) { - SkASSERT(yProxy && uProxy && vProxy && sizes); - return YUVtoRGBEffect::Make(std::move(yProxy), std::move(uProxy), std::move(vProxy), - sizes, colorSpace, nv12); -} diff --git a/src/gpu/effects/GrYUVEffect.h b/src/gpu/effects/GrYUVEffect.h deleted file mode 100644 index e111d4e153..0000000000 --- a/src/gpu/effects/GrYUVEffect.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrYUVEffect_DEFINED -#define GrYUVEffect_DEFINED - -#include "SkImageInfo.h" - -class GrFragmentProcessor; -class GrTextureProxy; - -namespace GrYUVEffect { - -/** - * Creates an effect that performs color conversion from YUV to RGB. The input textures are - * assumed to be kA8_GrPixelConfig. - */ -std::unique_ptr<GrFragmentProcessor> MakeYUVToRGB(sk_sp<GrTextureProxy> yProxy, - sk_sp<GrTextureProxy> uProxy, - sk_sp<GrTextureProxy> vProxy, - const SkISize sizes[3], - SkYUVColorSpace colorSpace, bool nv12); -}; - -#endif diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp new file mode 100644 index 0000000000..b1cd36f72b --- /dev/null +++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp @@ -0,0 +1,173 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * This file was autogenerated from GrYUVtoRGBEffect.fp; do not modify. + */ +#include "GrYUVtoRGBEffect.h" +#if SK_SUPPORT_GPU + +static const float kJPEGConversionMatrix[16] = { + 1.0f, 0.0f, 1.402f, -0.703749f, 1.0f, -0.344136f, -0.714136f, 0.531211f, + 1.0f, 1.772f, 0.0f, -0.889475f, 0.0f, 0.0f, 0.0f, 1.0}; + +static const float kRec601ConversionMatrix[16] = { + 1.164f, 0.0f, 1.596f, -0.87075f, 1.164f, -0.391f, -0.813f, 0.52925f, + 1.164f, 2.018f, 0.0f, -1.08175f, 0.0f, 0.0f, 0.0f, 1.0}; + +static const float kRec709ConversionMatrix[16] = { + 1.164f, 0.0f, 1.793f, -0.96925f, 1.164f, -0.213f, -0.533f, 0.30025f, + 1.164f, 2.112f, 0.0f, -1.12875f, 0.0f, 0.0f, 0.0f, 1.0f}; + +std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(sk_sp<GrTextureProxy> yProxy, + sk_sp<GrTextureProxy> + uProxy, + sk_sp<GrTextureProxy> + vProxy, + const SkISize sizes[3], + SkYUVColorSpace colorSpace, + bool nv12) { + SkScalar w[3], h[3]; + w[0] = SkIntToScalar(sizes[0].fWidth); + h[0] = SkIntToScalar(sizes[0].fHeight); + w[1] = SkIntToScalar(sizes[1].fWidth); + h[1] = SkIntToScalar(sizes[1].fHeight); + w[2] = SkIntToScalar(sizes[2].fWidth); + h[2] = SkIntToScalar(sizes[2].fHeight); + SkMatrix yTransform = SkMatrix::I(); + SkMatrix uTransform = SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]); + SkMatrix vTransform = SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]); + GrSamplerState::Filter uvFilterMode = + ((sizes[1].fWidth != sizes[0].fWidth) || (sizes[1].fHeight != sizes[0].fHeight) || + (sizes[2].fWidth != sizes[0].fWidth) || (sizes[2].fHeight != sizes[0].fHeight)) + ? GrSamplerState::Filter::kBilerp + : GrSamplerState::Filter::kNearest; + SkMatrix44 mat; + switch (colorSpace) { + case kJPEG_SkYUVColorSpace: + mat.setColMajorf(kJPEGConversionMatrix); + break; + case kRec601_SkYUVColorSpace: + mat.setColMajorf(kRec601ConversionMatrix); + break; + case kRec709_SkYUVColorSpace: + mat.setColMajorf(kRec709ConversionMatrix); + break; + } + return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect( + std::move(yProxy), yTransform, std::move(uProxy), uTransform, std::move(vProxy), + vTransform, mat, nv12, GrSamplerState(GrSamplerState::WrapMode::kClamp, uvFilterMode))); +} +#include "glsl/GrGLSLFragmentProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" +#include "SkSLCPP.h" +#include "SkSLUtil.h" +class GrGLSLYUVtoRGBEffect : public GrGLSLFragmentProcessor { +public: + GrGLSLYUVtoRGBEffect() {} + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + const GrYUVtoRGBEffect& _outer = args.fFp.cast<GrYUVtoRGBEffect>(); + (void)_outer; + auto ySamplerTransform = _outer.ySamplerTransform(); + (void)ySamplerTransform; + auto uSamplerTransform = _outer.uSamplerTransform(); + (void)uSamplerTransform; + auto vSamplerTransform = _outer.vSamplerTransform(); + (void)vSamplerTransform; + auto colorSpaceMatrix = _outer.colorSpaceMatrix(); + (void)colorSpaceMatrix; + auto nv12 = _outer.nv12(); + (void)nv12; + fColorSpaceMatrixVar = + args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4x4_GrSLType, + kDefault_GrSLPrecision, "colorSpaceMatrix"); + SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); + SkString sk_TransformedCoords2D_1 = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]); + SkString sk_TransformedCoords2D_2 = fragBuilder->ensureCoords2D(args.fTransformedCoords[2]); + fragBuilder->codeAppendf( + "@if (%s) {\n %s = half4(texture(%s, %s).%s.x, texture(%s, %s).%s.xy, 1.0) * " + "%s;\n} else {\n %s = half4(texture(%s, %s).%s.x, texture(%s, %s).%s.x, " + "texture(%s, %s).%s.x, 1.0) * %s;\n}\n", + (_outer.nv12() ? "true" : "false"), args.fOutputColor, + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), + sk_TransformedCoords2D_0.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), + sk_TransformedCoords2D_1.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(), + args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar), args.fOutputColor, + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), + sk_TransformedCoords2D_0.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), + sk_TransformedCoords2D_1.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(), + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[2]).c_str(), + sk_TransformedCoords2D_2.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[2]).c_str(), + args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar)); + } + +private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& _proc) override { + const GrYUVtoRGBEffect& _outer = _proc.cast<GrYUVtoRGBEffect>(); + { + float colorSpaceMatrixValue[16]; + _outer.colorSpaceMatrix().asColMajorf(colorSpaceMatrixValue); + pdman.setMatrix4f(fColorSpaceMatrixVar, colorSpaceMatrixValue); + } + } + UniformHandle fColorSpaceMatrixVar; +}; +GrGLSLFragmentProcessor* GrYUVtoRGBEffect::onCreateGLSLInstance() const { + return new GrGLSLYUVtoRGBEffect(); +} +void GrYUVtoRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const { + b->add32((int32_t)fNv12); +} +bool GrYUVtoRGBEffect::onIsEqual(const GrFragmentProcessor& other) const { + const GrYUVtoRGBEffect& that = other.cast<GrYUVtoRGBEffect>(); + (void)that; + if (fYSampler != that.fYSampler) return false; + if (fYSamplerTransform != that.fYSamplerTransform) return false; + if (fUSampler != that.fUSampler) return false; + if (fUSamplerTransform != that.fUSamplerTransform) return false; + if (fVSampler != that.fVSampler) return false; + if (fVSamplerTransform != that.fVSamplerTransform) return false; + if (fColorSpaceMatrix != that.fColorSpaceMatrix) return false; + if (fNv12 != that.fNv12) return false; + return true; +} +GrYUVtoRGBEffect::GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src) + : INHERITED(kGrYUVtoRGBEffect_ClassID, src.optimizationFlags()) + , fYSampler(src.fYSampler) + , fYSamplerTransform(src.fYSamplerTransform) + , fUSampler(src.fUSampler) + , fUSamplerTransform(src.fUSamplerTransform) + , fVSampler(src.fVSampler) + , fVSamplerTransform(src.fVSamplerTransform) + , fColorSpaceMatrix(src.fColorSpaceMatrix) + , fNv12(src.fNv12) + , fYSamplerCoordTransform(src.fYSamplerCoordTransform) + , fUSamplerCoordTransform(src.fUSamplerCoordTransform) + , fVSamplerCoordTransform(src.fVSamplerCoordTransform) { + this->addTextureSampler(&fYSampler); + this->addTextureSampler(&fUSampler); + this->addTextureSampler(&fVSampler); + this->addCoordTransform(&fYSamplerCoordTransform); + this->addCoordTransform(&fUSamplerCoordTransform); + this->addCoordTransform(&fVSamplerCoordTransform); +} +std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::clone() const { + return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(*this)); +} +#endif diff --git a/src/gpu/effects/GrYUVtoRGBEffect.fp b/src/gpu/effects/GrYUVtoRGBEffect.fp new file mode 100644 index 0000000000..999d95502d --- /dev/null +++ b/src/gpu/effects/GrYUVtoRGBEffect.fp @@ -0,0 +1,116 @@ +in uniform sampler2D ySampler; +in half4x4 ySamplerTransform; +@coordTransform(ySampler) { + ySamplerTransform +} + +in uniform sampler2D uSampler; +in half4x4 uSamplerTransform; +@coordTransform(uSampler) { + uSamplerTransform +} +@samplerParams(uSampler) { + uvSamplerParams +} + +in uniform sampler2D vSampler; +in half4x4 vSamplerTransform; +@coordTransform(vSampler) { + vSamplerTransform +} +@samplerParams(vSampler) { + uvSamplerParams +} + +in uniform half4x4 colorSpaceMatrix; +layout(key) in bool nv12; + +@constructorParams { + GrSamplerState uvSamplerParams +} + +@class { + static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy, + sk_sp<GrTextureProxy> uProxy, + sk_sp<GrTextureProxy> vProxy, + const SkISize sizes[3], + SkYUVColorSpace colorSpace, bool nv12); +} + +@cpp { + static const float kJPEGConversionMatrix[16] = { + 1.0f, 0.0f, 1.402f, -0.703749f, + 1.0f, -0.344136f, -0.714136f, 0.531211f, + 1.0f, 1.772f, 0.0f, -0.889475f, + 0.0f, 0.0f, 0.0f, 1.0 + }; + + static const float kRec601ConversionMatrix[16] = { + 1.164f, 0.0f, 1.596f, -0.87075f, + 1.164f, -0.391f, -0.813f, 0.52925f, + 1.164f, 2.018f, 0.0f, -1.08175f, + 0.0f, 0.0f, 0.0f, 1.0} + ; + + static const float kRec709ConversionMatrix[16] = { + 1.164f, 0.0f, 1.793f, -0.96925f, + 1.164f, -0.213f, -0.533f, 0.30025f, + 1.164f, 2.112f, 0.0f, -1.12875f, + 0.0f, 0.0f, 0.0f, 1.0f} + ; + + std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(sk_sp<GrTextureProxy> yProxy, + sk_sp<GrTextureProxy> uProxy, + sk_sp<GrTextureProxy> vProxy, + const SkISize sizes[3], + SkYUVColorSpace colorSpace, + bool nv12) { + SkScalar w[3], h[3]; + w[0] = SkIntToScalar(sizes[0].fWidth); + h[0] = SkIntToScalar(sizes[0].fHeight); + w[1] = SkIntToScalar(sizes[1].fWidth); + h[1] = SkIntToScalar(sizes[1].fHeight); + w[2] = SkIntToScalar(sizes[2].fWidth); + h[2] = SkIntToScalar(sizes[2].fHeight); + SkMatrix yTransform = SkMatrix::I(); + SkMatrix uTransform = SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]); + SkMatrix vTransform = SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]); + GrSamplerState::Filter uvFilterMode = + ((sizes[1].fWidth != sizes[0].fWidth) || + (sizes[1].fHeight != sizes[0].fHeight) || + (sizes[2].fWidth != sizes[0].fWidth) || + (sizes[2].fHeight != sizes[0].fHeight)) ? + GrSamplerState::Filter::kBilerp : + GrSamplerState::Filter::kNearest; + SkMatrix44 mat; + switch (colorSpace) { + case kJPEG_SkYUVColorSpace: + mat.setColMajorf(kJPEGConversionMatrix); + break; + case kRec601_SkYUVColorSpace: + mat.setColMajorf(kRec601ConversionMatrix); + break; + case kRec709_SkYUVColorSpace: + mat.setColMajorf(kRec709ConversionMatrix); + break; + } + return std::unique_ptr<GrFragmentProcessor>( + new GrYUVtoRGBEffect(std::move(yProxy), yTransform, std::move(uProxy), uTransform, + std::move(vProxy), vTransform, mat, nv12, + GrSamplerState(GrSamplerState::WrapMode::kClamp, + uvFilterMode))); + } +} + +void main() { + @if (nv12) { + sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r, + texture(uSampler, sk_TransformedCoords2D[1]).rg, + 1.0) * colorSpaceMatrix; + } else { + sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r, + texture(uSampler, sk_TransformedCoords2D[1]).r, + texture(vSampler, sk_TransformedCoords2D[2]).r, + 1.0) * colorSpaceMatrix; + } +} diff --git a/src/gpu/effects/GrYUVtoRGBEffect.h b/src/gpu/effects/GrYUVtoRGBEffect.h new file mode 100644 index 0000000000..68223efa1e --- /dev/null +++ b/src/gpu/effects/GrYUVtoRGBEffect.h @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * This file was autogenerated from GrYUVtoRGBEffect.fp; do not modify. + */ +#ifndef GrYUVtoRGBEffect_DEFINED +#define GrYUVtoRGBEffect_DEFINED +#include "SkTypes.h" +#if SK_SUPPORT_GPU +#include "GrFragmentProcessor.h" +#include "GrCoordTransform.h" +class GrYUVtoRGBEffect : public GrFragmentProcessor { +public: + static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy, + sk_sp<GrTextureProxy> uProxy, + sk_sp<GrTextureProxy> vProxy, + const SkISize sizes[3], + SkYUVColorSpace colorSpace, bool nv12); + SkMatrix44 ySamplerTransform() const { return fYSamplerTransform; } + SkMatrix44 uSamplerTransform() const { return fUSamplerTransform; } + SkMatrix44 vSamplerTransform() const { return fVSamplerTransform; } + SkMatrix44 colorSpaceMatrix() const { return fColorSpaceMatrix; } + bool nv12() const { return fNv12; } + static std::unique_ptr<GrFragmentProcessor> Make( + sk_sp<GrTextureProxy> ySampler, SkMatrix44 ySamplerTransform, + sk_sp<GrTextureProxy> uSampler, SkMatrix44 uSamplerTransform, + sk_sp<GrTextureProxy> vSampler, SkMatrix44 vSamplerTransform, + SkMatrix44 colorSpaceMatrix, bool nv12, GrSamplerState uvSamplerParams) { + return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect( + ySampler, ySamplerTransform, uSampler, uSamplerTransform, vSampler, + vSamplerTransform, colorSpaceMatrix, nv12, uvSamplerParams)); + } + GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src); + std::unique_ptr<GrFragmentProcessor> clone() const override; + const char* name() const override { return "YUVtoRGBEffect"; } + +private: + GrYUVtoRGBEffect(sk_sp<GrTextureProxy> ySampler, SkMatrix44 ySamplerTransform, + sk_sp<GrTextureProxy> uSampler, SkMatrix44 uSamplerTransform, + sk_sp<GrTextureProxy> vSampler, SkMatrix44 vSamplerTransform, + SkMatrix44 colorSpaceMatrix, bool nv12, GrSamplerState uvSamplerParams) + : INHERITED(kGrYUVtoRGBEffect_ClassID, kNone_OptimizationFlags) + , fYSampler(std::move(ySampler)) + , fYSamplerTransform(ySamplerTransform) + , fUSampler(std::move(uSampler), uvSamplerParams) + , fUSamplerTransform(uSamplerTransform) + , fVSampler(std::move(vSampler), uvSamplerParams) + , fVSamplerTransform(vSamplerTransform) + , fColorSpaceMatrix(colorSpaceMatrix) + , fNv12(nv12) + , fYSamplerCoordTransform(ySamplerTransform, fYSampler.proxy()) + , fUSamplerCoordTransform(uSamplerTransform, fUSampler.proxy()) + , fVSamplerCoordTransform(vSamplerTransform, fVSampler.proxy()) { + this->addTextureSampler(&fYSampler); + this->addTextureSampler(&fUSampler); + this->addTextureSampler(&fVSampler); + this->addCoordTransform(&fYSamplerCoordTransform); + this->addCoordTransform(&fUSamplerCoordTransform); + this->addCoordTransform(&fVSamplerCoordTransform); + } + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; + bool onIsEqual(const GrFragmentProcessor&) const override; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST + TextureSampler fYSampler; + SkMatrix44 fYSamplerTransform; + TextureSampler fUSampler; + SkMatrix44 fUSamplerTransform; + TextureSampler fVSampler; + SkMatrix44 fVSamplerTransform; + SkMatrix44 fColorSpaceMatrix; + bool fNv12; + GrCoordTransform fYSamplerCoordTransform; + GrCoordTransform fUSamplerCoordTransform; + GrCoordTransform fVSamplerCoordTransform; + typedef GrFragmentProcessor INHERITED; +}; +#endif +#endif diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 9d2b9490de..54a7e98236 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -28,7 +28,7 @@ #include "GrTexturePriv.h" #include "GrTextureProxy.h" #include "effects/GrNonlinearColorSpaceXformEffect.h" -#include "effects/GrYUVEffect.h" +#include "effects/GrYUVtoRGBEffect.h" #include "SkCanvas.h" #include "SkBitmapCache.h" #include "SkGr.h" @@ -427,8 +427,8 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac GrPaint paint; paint.setPorterDuffXPFactory(SkBlendMode::kSrc); - paint.addColorFragmentProcessor(GrYUVEffect::MakeYUVToRGB(yProxy, uProxy, vProxy, - yuvSizes, colorSpace, nv12)); + paint.addColorFragmentProcessor(GrYUVtoRGBEffect::Make(yProxy, uProxy, vProxy, + yuvSizes, colorSpace, nv12)); const SkRect rect = SkRect::MakeIWH(width, height); |