blob: 01ff6d65831c54ff143bee28e71755614e8e3128 [file] [log] [blame]
sugoi24dcac22014-07-07 15:09:48 -07001/*
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 "GrYUVtoRGBEffect.h"
9
10#include "GrCoordTransform.h"
11#include "GrEffect.h"
12#include "gl/GrGLEffect.h"
13#include "GrTBackendEffectFactory.h"
14
15namespace {
16
17class YUVtoRGBEffect : public GrEffect {
18public:
bsalomon97b9ab72014-07-08 06:52:35 -070019 static GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) {
bsalomon55fad7a2014-07-08 07:34:20 -070020 return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture));
sugoi24dcac22014-07-07 15:09:48 -070021 }
22
23 static const char* Name() { return "YUV to RGB"; }
24
25 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
26 return GrTBackendEffectFactory<YUVtoRGBEffect>::getInstance();
27 }
28
29 virtual void getConstantColorComponents(GrColor* color,
30 uint32_t* validFlags) const SK_OVERRIDE {
31 // YUV is opaque
32 *color = 0xFF;
33 *validFlags = kA_GrColorComponentFlag;
34 }
35
36 class GLEffect : public GrGLEffect {
37 public:
38 // this class always generates the same code.
39 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
40
41 GLEffect(const GrBackendEffectFactory& factory,
42 const GrDrawEffect&)
43 : INHERITED(factory) {
44 }
45
46 virtual void emitCode(GrGLShaderBuilder* builder,
47 const GrDrawEffect&,
48 EffectKey,
49 const char* outputColor,
50 const char* inputColor,
51 const TransformedCoordsArray& coords,
52 const TextureSamplerArray& samplers) SK_OVERRIDE {
53 const char* yuvMatrix = "yuvMatrix";
54 builder->fsCodeAppendf("\tconst mat4 %s = mat4(1.0, 0.0, 1.402, -0.701,\n\t\t\t"
55 "1.0, -0.344, -0.714, 0.529,\n\t\t\t"
56 "1.0, 1.772, 0.0, -0.886,\n\t\t\t"
57 "0.0, 0.0, 0.0, 1.0);\n",
58 yuvMatrix);
59 builder->fsCodeAppendf("\t%s = vec4(\n\t\t", outputColor);
60 builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
61 builder->fsCodeAppend(".r,\n\t\t");
62 builder->fsAppendTextureLookup(samplers[1], coords[0].c_str(), coords[0].type());
63 builder->fsCodeAppend(".r,\n\t\t");
64 builder->fsAppendTextureLookup(samplers[2], coords[0].c_str(), coords[0].type());
65 builder->fsCodeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
66 }
67
68 typedef GrGLEffect INHERITED;
69 };
70
71private:
72 YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture)
73 : fCoordTransform(kLocal_GrCoordSet, MakeDivByTextureWHMatrix(yTexture), yTexture)
74 , fYAccess(yTexture)
75 , fUAccess(uTexture)
76 , fVAccess(vTexture) {
77 this->addCoordTransform(&fCoordTransform);
78 this->addTextureAccess(&fYAccess);
79 this->addTextureAccess(&fUAccess);
80 this->addTextureAccess(&fVAccess);
81 this->setWillNotUseInputColor();
82 }
83
84 virtual bool onIsEqual(const GrEffect& sBase) const {
85 const YUVtoRGBEffect& s = CastEffect<YUVtoRGBEffect>(sBase);
86 return fYAccess.getTexture() == s.fYAccess.getTexture() &&
87 fUAccess.getTexture() == s.fUAccess.getTexture() &&
88 fVAccess.getTexture() == s.fVAccess.getTexture();
89 }
90
91 GrCoordTransform fCoordTransform;
92 GrTextureAccess fYAccess;
93 GrTextureAccess fUAccess;
94 GrTextureAccess fVAccess;
95
96 typedef GrEffect INHERITED;
97};
98
99}
100
101//////////////////////////////////////////////////////////////////////////////
102
bsalomon83d081a2014-07-08 09:56:10 -0700103GrEffect* GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) {
sugoi24dcac22014-07-07 15:09:48 -0700104 return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture);
105}