• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gl/builders/GrGLProgramBuilder.h"
9 #include "GrYUVtoRGBEffect.h"
10 
11 #include "GrCoordTransform.h"
12 #include "GrProcessor.h"
13 #include "gl/GrGLProcessor.h"
14 #include "GrTBackendProcessorFactory.h"
15 
16 namespace {
17 
18 class YUVtoRGBEffect : public GrFragmentProcessor {
19 public:
Create(GrTexture * yTexture,GrTexture * uTexture,GrTexture * vTexture,SkYUVColorSpace colorSpace)20     static GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture,
21                                        GrTexture* vTexture, SkYUVColorSpace colorSpace) {
22         return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace));
23     }
24 
Name()25     static const char* Name() { return "YUV to RGB"; }
26 
getFactory() const27     virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
28         return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::getInstance();
29     }
30 
getConstantColorComponents(GrColor * color,uint32_t * validFlags) const31     virtual void getConstantColorComponents(GrColor* color,
32                                             uint32_t* validFlags) const SK_OVERRIDE {
33         // YUV is opaque
34         *color = 0xFF;
35         *validFlags = kA_GrColorComponentFlag;
36     }
37 
getColorSpace() const38     SkYUVColorSpace getColorSpace() const {
39         return fColorSpace;
40     }
41 
42     class GLProcessor : public GrGLFragmentProcessor {
43     public:
44         static const GrGLfloat kJPEGConversionMatrix[16];
45         static const GrGLfloat kRec601ConversionMatrix[16];
46 
47         // this class always generates the same code.
GenKey(const GrProcessor &,const GrGLCaps &,GrProcessorKeyBuilder *)48         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
49 
GLProcessor(const GrBackendProcessorFactory & factory,const GrProcessor &)50         GLProcessor(const GrBackendProcessorFactory& factory,
51                     const GrProcessor&)
52         : INHERITED(factory) {
53         }
54 
emitCode(GrGLProgramBuilder * builder,const GrFragmentProcessor &,const GrProcessorKey &,const char * outputColor,const char * inputColor,const TransformedCoordsArray & coords,const TextureSamplerArray & samplers)55         virtual void emitCode(GrGLProgramBuilder* builder,
56                               const GrFragmentProcessor&,
57                               const GrProcessorKey&,
58                               const char* outputColor,
59                               const char* inputColor,
60                               const TransformedCoordsArray& coords,
61                               const TextureSamplerArray& samplers) SK_OVERRIDE {
62             GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
63 
64             const char* yuvMatrix   = NULL;
65             fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
66                                              kMat44f_GrSLType, "YUVMatrix",
67                                              &yuvMatrix);
68             fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
69             fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
70             fsBuilder->codeAppend(".r,\n\t\t");
71             fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType());
72             fsBuilder->codeAppend(".r,\n\t\t");
73             fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType());
74             fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
75         }
76 
setData(const GrGLProgramDataManager & pdman,const GrProcessor & processor)77         virtual void setData(const GrGLProgramDataManager& pdman,
78                              const GrProcessor& processor) SK_OVERRIDE {
79             const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>();
80             switch (yuvEffect.getColorSpace()) {
81                 case kJPEG_SkYUVColorSpace:
82                     pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix);
83                     break;
84                 case kRec601_SkYUVColorSpace:
85                     pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
86                     break;
87             }
88         }
89 
90     private:
91         GrGLProgramDataManager::UniformHandle fMatrixUni;
92 
93         typedef GrGLFragmentProcessor INHERITED;
94     };
95 
96 private:
YUVtoRGBEffect(GrTexture * yTexture,GrTexture * uTexture,GrTexture * vTexture,SkYUVColorSpace colorSpace)97     YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
98                    SkYUVColorSpace colorSpace)
99      : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
100                        yTexture)
101     , fYAccess(yTexture)
102     , fUAccess(uTexture)
103     , fVAccess(vTexture)
104     , fColorSpace(colorSpace) {
105         this->addCoordTransform(&fCoordTransform);
106         this->addTextureAccess(&fYAccess);
107         this->addTextureAccess(&fUAccess);
108         this->addTextureAccess(&fVAccess);
109         this->setWillNotUseInputColor();
110     }
111 
onIsEqual(const GrProcessor & sBase) const112     virtual bool onIsEqual(const GrProcessor& sBase) const {
113         const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
114         return fYAccess.getTexture() == s.fYAccess.getTexture() &&
115                fUAccess.getTexture() == s.fUAccess.getTexture() &&
116                fVAccess.getTexture() == s.fVAccess.getTexture() &&
117                fColorSpace == s.getColorSpace();
118     }
119 
120     GrCoordTransform fCoordTransform;
121     GrTextureAccess fYAccess;
122     GrTextureAccess fUAccess;
123     GrTextureAccess fVAccess;
124     SkYUVColorSpace fColorSpace;
125 
126     typedef GrFragmentProcessor INHERITED;
127 };
128 
129 const GrGLfloat YUVtoRGBEffect::GLProcessor::kJPEGConversionMatrix[16] = {
130     1.0f,  0.0f,      1.402f,  -0.701f,
131     1.0f, -0.34414f, -0.71414f, 0.529f,
132     1.0f,  1.772f,    0.0f,    -0.886f,
133     0.0f,  0.0f,      0.0f,     1.0};
134 const GrGLfloat YUVtoRGBEffect::GLProcessor::kRec601ConversionMatrix[16] = {
135     1.164f,  0.0f,    1.596f, -0.87075f,
136     1.164f, -0.391f, -0.813f,  0.52925f,
137     1.164f,  2.018f,  0.0f,   -1.08175f,
138     0.0f,    0.0f,    0.0f,    1.0};
139 }
140 
141 //////////////////////////////////////////////////////////////////////////////
142 
143 GrFragmentProcessor*
Create(GrTexture * yTexture,GrTexture * uTexture,GrTexture * vTexture,SkYUVColorSpace colorSpace)144 GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
145                          SkYUVColorSpace colorSpace) {
146     return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);
147 }
148