Update To 11.40.268.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     SkYUVColorSpace getColorSpace() const {
32         return fColorSpace;
33     }
34
35     class GLProcessor : public GrGLFragmentProcessor {
36     public:
37         static const GrGLfloat kJPEGConversionMatrix[16];
38         static const GrGLfloat kRec601ConversionMatrix[16];
39
40         // this class always generates the same code.
41         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
42
43         GLProcessor(const GrBackendProcessorFactory& factory,
44                     const GrProcessor&)
45         : INHERITED(factory) {
46         }
47
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();
56
57             const char* yuvMatrix   = NULL;
58             fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
59                                              kMat44f_GrSLType, "YUVMatrix",
60                                              &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);
68         }
69
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);
76                     break;
77                 case kRec601_SkYUVColorSpace:
78                     pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
79                     break;
80             }
81         }
82
83     private:
84         GrGLProgramDataManager::UniformHandle fMatrixUni;
85
86         typedef GrGLFragmentProcessor INHERITED;
87     };
88
89 private:
90     YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
91                    SkYUVColorSpace colorSpace)
92      : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
93                        yTexture)
94     , fYAccess(yTexture)
95     , fUAccess(uTexture)
96     , fVAccess(vTexture)
97     , fColorSpace(colorSpace) {
98         this->addCoordTransform(&fCoordTransform);
99         this->addTextureAccess(&fYAccess);
100         this->addTextureAccess(&fUAccess);
101         this->addTextureAccess(&fVAccess);
102     }
103
104     virtual bool onIsEqual(const GrFragmentProcessor& sBase) const {
105         const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
106         return fColorSpace == s.getColorSpace();
107     }
108
109     virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
110         // YUV is opaque
111         inout->setToOther(kA_GrColorComponentFlag, 0xFF << GrColor_SHIFT_A,
112                           InvariantOutput::kWillNot_ReadInput);
113     }
114
115     GrCoordTransform fCoordTransform;
116     GrTextureAccess fYAccess;
117     GrTextureAccess fUAccess;
118     GrTextureAccess fVAccess;
119     SkYUVColorSpace fColorSpace;
120
121     typedef GrFragmentProcessor INHERITED;
122 };
123
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};
134 }
135
136 //////////////////////////////////////////////////////////////////////////////
137
138 GrFragmentProcessor*
139 GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
140                          SkYUVColorSpace colorSpace) {
141     return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);
142 }