Chromium Code Reviews| 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 |