Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / effects / GrYUVtoRGBEffect.cpp
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:
20     static GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture,
21                                        GrTexture* vTexture, SkYUVColorSpace colorSpace) {
22         return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace));
23     }
24
25     static const char* Name() { return "YUV to RGB"; }
26
27     virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
28         return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::getInstance();
29     }
30
31     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
38     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.
48         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
49
50         GLProcessor(const GrBackendProcessorFactory& factory,
51                     const GrProcessor&)
52         : INHERITED(factory) {
53         }
54
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
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:
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
112     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*
144 GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
145                          SkYUVColorSpace colorSpace) {
146     return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);
147 }