From abaef86f2b37d8a939506a2076da07f6db456951 Mon Sep 17 00:00:00 2001 From: rileya Date: Fri, 12 Sep 2014 17:45:58 -0700 Subject: Add support for the Rec601 YUV color space to GrYUVtoRGBEffect. R=bsalomon@google.com, senorblanco@chromium.org, sugoi@chromium.org, reed@google.com Author: rileya@chromium.org Review URL: https://codereview.chromium.org/516463005 --- src/gpu/effects/GrYUVtoRGBEffect.cpp | 70 +++++++++++++++++++++++++++--------- src/gpu/effects/GrYUVtoRGBEffect.h | 5 ++- 2 files changed, 58 insertions(+), 17 deletions(-) (limited to 'src/gpu/effects') diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp index 1a46c969ef..0023b1b300 100644 --- a/src/gpu/effects/GrYUVtoRGBEffect.cpp +++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp @@ -17,8 +17,9 @@ namespace { class YUVtoRGBEffect : public GrEffect { public: - static GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) { - return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture)); + static GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, + SkYUVColorSpace colorSpace) { + return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace)); } static const char* Name() { return "YUV to RGB"; } @@ -34,8 +35,15 @@ public: *validFlags = kA_GrColorComponentFlag; } + SkYUVColorSpace getColorSpace() const { + return fColorSpace; + } + class GLEffect : public GrGLEffect { public: + static const GrGLfloat kJPEGConversionMatrix[16]; + static const GrGLfloat kRec601ConversionMatrix[16]; + // this class always generates the same code. static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {} @@ -45,19 +53,18 @@ public: } virtual void emitCode(GrGLProgramBuilder* builder, - const GrDrawEffect&, + const GrDrawEffect& drawEffect, const GrEffectKey&, const char* outputColor, const char* inputColor, const TransformedCoordsArray& coords, const TextureSamplerArray& samplers) SK_OVERRIDE { GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); - const char* yuvMatrix = "yuvMatrix"; - fsBuilder->codeAppendf("\tconst mat4 %s = mat4(1.0, 0.0, 1.402, -0.701,\n\t\t\t" - "1.0, -0.344, -0.714, 0.529,\n\t\t\t" - "1.0, 1.772, 0.0, -0.886,\n\t\t\t" - "0.0, 0.0, 0.0, 1.0);\n", - yuvMatrix); + + const char* yuvMatrix = NULL; + fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, + kMat44f_GrSLType, "YUVMatrix", + &yuvMatrix); fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor); fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type()); fsBuilder->codeAppend(".r,\n\t\t"); @@ -67,16 +74,34 @@ public: fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix); } + virtual void setData(const GrGLProgramDataManager& pdman, + const GrDrawEffect& drawEffect) SK_OVERRIDE { + const YUVtoRGBEffect& yuvEffect = drawEffect.castEffect(); + switch (yuvEffect.getColorSpace()) { + case kJPEG_SkYUVColorSpace: + pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix); + break; + case kRec601_SkYUVColorSpace: + pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix); + break; + } + } + + private: + GrGLProgramDataManager::UniformHandle fMatrixUni; + typedef GrGLEffect INHERITED; }; private: - YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) - : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture), - yTexture) + YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, + SkYUVColorSpace colorSpace) + : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture), + yTexture) , fYAccess(yTexture) , fUAccess(uTexture) - , fVAccess(vTexture) { + , fVAccess(vTexture) + , fColorSpace(colorSpace) { this->addCoordTransform(&fCoordTransform); this->addTextureAccess(&fYAccess); this->addTextureAccess(&fUAccess); @@ -88,21 +113,34 @@ private: const YUVtoRGBEffect& s = CastEffect(sBase); return fYAccess.getTexture() == s.fYAccess.getTexture() && fUAccess.getTexture() == s.fUAccess.getTexture() && - fVAccess.getTexture() == s.fVAccess.getTexture(); + fVAccess.getTexture() == s.fVAccess.getTexture() && + fColorSpace == s.getColorSpace(); } GrCoordTransform fCoordTransform; GrTextureAccess fYAccess; GrTextureAccess fUAccess; GrTextureAccess fVAccess; + SkYUVColorSpace fColorSpace; typedef GrEffect INHERITED; }; +const GrGLfloat YUVtoRGBEffect::GLEffect::kJPEGConversionMatrix[16] = { + 1.0f, 0.0f, 1.402f, -0.701f, + 1.0f, -0.34414f, -0.71414f, 0.529f, + 1.0f, 1.772f, 0.0f, -0.886f, + 0.0f, 0.0f, 0.0f, 1.0}; +const GrGLfloat YUVtoRGBEffect::GLEffect::kRec601ConversionMatrix[16] = { + 1.164f, 0.0f, 1.596f, -1.08175f, + 1.164f, -0.391f, -0.813f, 0.529f, + 1.164f, 2.018f, 0.0f, -1.08175f, + 0.0f, 0.0f, 0.0f, 1.0}; } ////////////////////////////////////////////////////////////////////////////// -GrEffect* GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) { - return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture); +GrEffect* GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, + SkYUVColorSpace colorSpace) { + return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace); } diff --git a/src/gpu/effects/GrYUVtoRGBEffect.h b/src/gpu/effects/GrYUVtoRGBEffect.h index 150acd5a90..52ccd23bbb 100644 --- a/src/gpu/effects/GrYUVtoRGBEffect.h +++ b/src/gpu/effects/GrYUVtoRGBEffect.h @@ -8,6 +8,8 @@ #ifndef GrYUVtoRGBEffect_DEFINED #define GrYUVtoRGBEffect_DEFINED +#include "SkImageInfo.h" + class GrEffect; class GrTexture; @@ -15,7 +17,8 @@ namespace GrYUVtoRGBEffect { /** * Creates an effect that performs color conversion from YUV to RGB */ - GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture); + GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture, + SkYUVColorSpace colorSpace); }; #endif -- cgit v1.2.3