2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "gl/builders/GrGLProgramBuilder.h"
9 #include "GrYUVtoRGBEffect.h"
11 #include "GrCoordTransform.h"
12 #include "GrProcessor.h"
13 #include "gl/GrGLProcessor.h"
14 #include "GrTBackendProcessorFactory.h"
18 class YUVtoRGBEffect : public GrFragmentProcessor {
20 static GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture,
21 GrTexture* vTexture, SkYUVColorSpace colorSpace) {
22 return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace));
25 static const char* Name() { return "YUV to RGB"; }
27 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
28 return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::getInstance();
31 SkYUVColorSpace getColorSpace() const {
35 class GLProcessor : public GrGLFragmentProcessor {
37 static const GrGLfloat kJPEGConversionMatrix[16];
38 static const GrGLfloat kRec601ConversionMatrix[16];
40 // this class always generates the same code.
41 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
43 GLProcessor(const GrBackendProcessorFactory& factory,
45 : INHERITED(factory) {
48 virtual void emitCode(GrGLFPBuilder* builder,
49 const GrFragmentProcessor&,
50 const GrProcessorKey&,
51 const char* outputColor,
52 const char* inputColor,
53 const TransformedCoordsArray& coords,
54 const TextureSamplerArray& samplers) SK_OVERRIDE {
55 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
57 const char* yuvMatrix = NULL;
58 fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
59 kMat44f_GrSLType, "YUVMatrix",
61 fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
62 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
63 fsBuilder->codeAppend(".r,\n\t\t");
64 fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType());
65 fsBuilder->codeAppend(".r,\n\t\t");
66 fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType());
67 fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
70 virtual void setData(const GrGLProgramDataManager& pdman,
71 const GrProcessor& processor) SK_OVERRIDE {
72 const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>();
73 switch (yuvEffect.getColorSpace()) {
74 case kJPEG_SkYUVColorSpace:
75 pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix);
77 case kRec601_SkYUVColorSpace:
78 pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
84 GrGLProgramDataManager::UniformHandle fMatrixUni;
86 typedef GrGLFragmentProcessor INHERITED;
90 YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
91 SkYUVColorSpace colorSpace)
92 : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
97 , fColorSpace(colorSpace) {
98 this->addCoordTransform(&fCoordTransform);
99 this->addTextureAccess(&fYAccess);
100 this->addTextureAccess(&fUAccess);
101 this->addTextureAccess(&fVAccess);
104 virtual bool onIsEqual(const GrFragmentProcessor& sBase) const {
105 const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
106 return fColorSpace == s.getColorSpace();
109 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
111 inout->setToOther(kA_GrColorComponentFlag, 0xFF << GrColor_SHIFT_A,
112 InvariantOutput::kWillNot_ReadInput);
115 GrCoordTransform fCoordTransform;
116 GrTextureAccess fYAccess;
117 GrTextureAccess fUAccess;
118 GrTextureAccess fVAccess;
119 SkYUVColorSpace fColorSpace;
121 typedef GrFragmentProcessor INHERITED;
124 const GrGLfloat YUVtoRGBEffect::GLProcessor::kJPEGConversionMatrix[16] = {
125 1.0f, 0.0f, 1.402f, -0.701f,
126 1.0f, -0.34414f, -0.71414f, 0.529f,
127 1.0f, 1.772f, 0.0f, -0.886f,
128 0.0f, 0.0f, 0.0f, 1.0};
129 const GrGLfloat YUVtoRGBEffect::GLProcessor::kRec601ConversionMatrix[16] = {
130 1.164f, 0.0f, 1.596f, -0.87075f,
131 1.164f, -0.391f, -0.813f, 0.52925f,
132 1.164f, 2.018f, 0.0f, -1.08175f,
133 0.0f, 0.0f, 0.0f, 1.0};
136 //////////////////////////////////////////////////////////////////////////////
139 GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
140 SkYUVColorSpace colorSpace) {
141 return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);