OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2015 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 "SkArithmeticMode_gpu.h" | |
9 | |
10 #if SK_SUPPORT_GPU | |
11 #include "GrContext.h" | |
12 #include "GrFragmentProcessor.h" | |
13 #include "GrInvariantOutput.h" | |
14 #include "GrProcessor.h" | |
15 #include "GrTexture.h" | |
16 #include "gl/GrGLCaps.h" | |
17 #include "gl/GrGLProcessor.h" | |
18 #include "gl/GrGLProgramDataManager.h" | |
19 #include "gl/builders/GrGLProgramBuilder.h" | |
20 | |
21 static const bool gUseUnpremul = false; | |
22 | |
23 class GrGLArithmeticFP : public GrGLFragmentProcessor { | |
bsalomon
2015/01/14 15:25:31
Don't need the Gr prefix if this is just in a cpp
| |
24 public: | |
25 GrGLArithmeticFP(const GrProcessor&); | |
26 virtual ~GrGLArithmeticFP(); | |
27 | |
28 virtual void emitCode(GrGLFPBuilder*, | |
29 const GrFragmentProcessor&, | |
30 const char* outputColor, | |
31 const char* inputColor, | |
32 const TransformedCoordsArray&, | |
33 const TextureSamplerArray&) SK_OVERRIDE; | |
34 | |
35 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O VERRIDE; | |
36 | |
37 static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyB uilder* b); | |
38 | |
39 private: | |
40 GrGLProgramDataManager::UniformHandle fKUni; | |
41 bool fEnforcePMColor; | |
42 | |
43 typedef GrGLFragmentProcessor INHERITED; | |
44 }; | |
45 | |
46 /////////////////////////////////////////////////////////////////////////////// | |
47 | |
48 GrArithmeticFP::GrArithmeticFP(float k1, float k2, float k3, float k4, | |
49 bool enforcePMColor, GrTexture* background) | |
50 : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) { | |
51 this->initClassID<GrArithmeticFP>(); | |
52 if (background) { | |
53 fBackgroundTransform.reset(kLocal_GrCoordSet, background, | |
54 GrTextureParams::kNone_FilterMode); | |
55 this->addCoordTransform(&fBackgroundTransform); | |
56 fBackgroundAccess.reset(background); | |
57 this->addTextureAccess(&fBackgroundAccess); | |
58 } else { | |
59 this->setWillReadDstColor(); | |
60 } | |
61 } | |
62 | |
63 void GrArithmeticFP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuild er* b) const { | |
64 GrGLArithmeticFP::GenKey(*this, caps, b); | |
65 } | |
66 | |
67 GrGLFragmentProcessor* GrArithmeticFP::createGLInstance() const { | |
68 return SkNEW_ARGS(GrGLArithmeticFP, (*this)); | |
69 } | |
70 | |
71 bool GrArithmeticFP::onIsEqual(const GrFragmentProcessor& fpBase) const { | |
72 const GrArithmeticFP& fp = fpBase.cast<GrArithmeticFP>(); | |
73 return fK1 == fp.fK1 && | |
74 fK2 == fp.fK2 && | |
75 fK3 == fp.fK3 && | |
76 fK4 == fp.fK4 && | |
77 fEnforcePMColor == fp.fEnforcePMColor; | |
78 } | |
79 | |
80 void GrArithmeticFP::onComputeInvariantOutput(GrInvariantOutput* inout) const { | |
81 // TODO: optimize this | |
82 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); | |
83 } | |
84 | |
85 /////////////////////////////////////////////////////////////////////////////// | |
86 | |
87 GrGLArithmeticFP::GrGLArithmeticFP(const GrProcessor&) | |
88 : fEnforcePMColor(true) { | |
89 } | |
90 | |
91 GrGLArithmeticFP::~GrGLArithmeticFP() { | |
92 } | |
93 | |
94 void GrGLArithmeticFP::emitCode(GrGLFPBuilder* builder, | |
95 const GrFragmentProcessor& fp, | |
96 const char* outputColor, | |
97 const char* inputColor, | |
98 const TransformedCoordsArray& coords, | |
99 const TextureSamplerArray& samplers) { | |
100 | |
101 GrTexture* backgroundTex = fp.cast<GrArithmeticFP>().backgroundTexture(); | |
102 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | |
103 const char* dstColor; | |
104 if (backgroundTex) { | |
105 fsBuilder->codeAppend("\t\tvec4 bgColor = "); | |
106 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0] .getType()); | |
107 fsBuilder->codeAppendf(";\n"); | |
108 dstColor = "bgColor"; | |
109 } else { | |
110 dstColor = fsBuilder->dstColor(); | |
111 } | |
112 | |
113 SkASSERT(dstColor); | |
114 fKUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | |
115 kVec4f_GrSLType, kDefault_GrSLPrecision, | |
116 "k"); | |
117 const char* kUni = builder->getUniformCStr(fKUni); | |
118 | |
119 // We don't try to optimize for this case at all | |
120 if (NULL == inputColor) { | |
121 fsBuilder->codeAppendf("\t\tconst vec4 src = vec4(1);\n"); | |
122 } else { | |
123 fsBuilder->codeAppendf("\t\tvec4 src = %s;\n", inputColor); | |
124 if (gUseUnpremul) { | |
125 fsBuilder->codeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1. 0);\n"); | |
126 } | |
127 } | |
128 | |
129 fsBuilder->codeAppendf("\t\tvec4 dst = %s;\n", dstColor); | |
130 if (gUseUnpremul) { | |
131 fsBuilder->codeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\ n"); | |
132 } | |
133 | |
134 fsBuilder->codeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni); | |
135 fsBuilder->codeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu tColor); | |
136 if (gUseUnpremul) { | |
137 fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor ); | |
138 } else if (fEnforcePMColor) { | |
139 fsBuilder->codeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor); | |
140 } | |
141 } | |
142 | |
143 void GrGLArithmeticFP::setData(const GrGLProgramDataManager& pdman, | |
144 const GrProcessor& processor) { | |
145 const GrArithmeticFP& arith = processor.cast<GrArithmeticFP>(); | |
146 pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); | |
147 fEnforcePMColor = arith.enforcePMColor(); | |
148 } | |
149 | |
150 void GrGLArithmeticFP::GenKey(const GrProcessor& processor, | |
151 const GrGLCaps&, GrProcessorKeyBuilder* b) { | |
152 const GrArithmeticFP& arith = processor.cast<GrArithmeticFP>(); | |
153 uint32_t key = arith.enforcePMColor() ? 1 : 0; | |
154 if (arith.backgroundTexture()) { | |
155 key |= 2; | |
156 } | |
157 b->add32(key); | |
158 } | |
159 | |
160 GrFragmentProcessor* GrArithmeticFP::TestCreate(SkRandom* rand, | |
161 GrContext*, | |
162 const GrDrawTargetCaps&, | |
163 GrTexture*[]) { | |
164 float k1 = rand->nextF(); | |
165 float k2 = rand->nextF(); | |
166 float k3 = rand->nextF(); | |
167 float k4 = rand->nextF(); | |
168 bool enforcePMColor = rand->nextBool(); | |
169 | |
170 return SkNEW_ARGS(GrArithmeticFP, (k1, k2, k3, k4, enforcePMColor, NULL)); | |
171 } | |
172 | |
173 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticFP); | |
174 | |
175 #endif | |
OLD | NEW |