Index: src/gpu/effects/GrYUVtoRGBEffect.cpp |
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp |
index 1a46c969ef3469f4e25c4e12682030f4d0cf5f77..0023b1b30079293646c33cb49739154ffa457d05 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<YUVtoRGBEffect>(); |
+ 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<YUVtoRGBEffect>(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); |
} |