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