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 GLArithmeticFP : public GrGLFragmentProcessor { |
| 24 public: |
| 25 GLArithmeticFP(const GrProcessor&); |
| 26 virtual ~GLArithmeticFP(); |
| 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 GLArithmeticFP::GenKey(*this, caps, b); |
| 65 } |
| 66 |
| 67 GrGLFragmentProcessor* GrArithmeticFP::createGLInstance() const { |
| 68 return SkNEW_ARGS(GLArithmeticFP, (*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 GLArithmeticFP::GLArithmeticFP(const GrProcessor&) |
| 88 : fEnforcePMColor(true) { |
| 89 } |
| 90 |
| 91 GLArithmeticFP::~GLArithmeticFP() { |
| 92 } |
| 93 |
| 94 void GLArithmeticFP::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 GLArithmeticFP::setData(const GrGLProgramDataManager& pdman, const GrProces
sor& processor) { |
| 144 const GrArithmeticFP& arith = processor.cast<GrArithmeticFP>(); |
| 145 pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); |
| 146 fEnforcePMColor = arith.enforcePMColor(); |
| 147 } |
| 148 |
| 149 void GLArithmeticFP::GenKey(const GrProcessor& processor, const GrGLCaps&, |
| 150 GrProcessorKeyBuilder* b) { |
| 151 const GrArithmeticFP& arith = processor.cast<GrArithmeticFP>(); |
| 152 uint32_t key = arith.enforcePMColor() ? 1 : 0; |
| 153 if (arith.backgroundTexture()) { |
| 154 key |= 2; |
| 155 } |
| 156 b->add32(key); |
| 157 } |
| 158 |
| 159 GrFragmentProcessor* GrArithmeticFP::TestCreate(SkRandom* rand, |
| 160 GrContext*, |
| 161 const GrDrawTargetCaps&, |
| 162 GrTexture*[]) { |
| 163 float k1 = rand->nextF(); |
| 164 float k2 = rand->nextF(); |
| 165 float k3 = rand->nextF(); |
| 166 float k4 = rand->nextF(); |
| 167 bool enforcePMColor = rand->nextBool(); |
| 168 |
| 169 return SkNEW_ARGS(GrArithmeticFP, (k1, k2, k3, k4, enforcePMColor, NULL)); |
| 170 } |
| 171 |
| 172 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticFP); |
| 173 |
| 174 #endif |
OLD | NEW |