| 52 | } |
| 53 | |
| 54 | void GrGLMatrixConvolutionEffect::emitCode(GrGLProgramBuilder* builder, |
| 55 | const GrFragmentProcessor& fp, |
| 56 | const GrProcessorKey& key, |
| 57 | const char* outputColor, |
| 58 | const char* inputColor, |
| 59 | const TransformedCoordsArray& coords, |
| 60 | const TextureSamplerArray& samplers) { |
| 61 | sk_ignore_unused_variable(inputColor); |
| 62 | const GrTextureDomain& domain = fp.cast<GrMatrixConvolutionEffect>().domain(); |
| 63 | |
| 64 | fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 65 | kVec4f_GrSLType, "Bounds"); |
| 66 | fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 67 | kVec2f_GrSLType, "ImageIncrement"); |
| 68 | fKernelUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, |
| 69 | kFloat_GrSLType, |
| 70 | "Kernel", |
| 71 | fKernelSize.width() * fKernelSize.height()); |
| 72 | fKernelOffsetUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 73 | kVec2f_GrSLType, "KernelOffset"); |
| 74 | fGainUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 75 | kFloat_GrSLType, "Gain"); |
| 76 | fBiasUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 77 | kFloat_GrSLType, "Bias"); |
| 78 | |
| 79 | const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni); |
| 80 | const char* imgInc = builder->getUniformCStr(fImageIncrementUni); |
| 81 | const char* kernel = builder->getUniformCStr(fKernelUni); |
| 82 | const char* gain = builder->getUniformCStr(fGainUni); |
| 83 | const char* bias = builder->getUniformCStr(fBiasUni); |
| 84 | int kWidth = fKernelSize.width(); |
| 85 | int kHeight = fKernelSize.height(); |
| 86 | |
| 87 | GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
| 88 | SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); |
| 89 | fsBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);"); |
| 90 | fsBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, |
| 91 | imgInc); |
| 92 | fsBuilder->codeAppend("vec4 c;"); |
| 93 | |
| 94 | for (int y = 0; y < kHeight; y++) { |
| 95 | for (int x = 0; x < kWidth; x++) { |
| 96 | GrGLShaderBuilder::ShaderBlock block(fsBuilder); |
| 97 | fsBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, kWidth, x); |
| 98 | SkString coord; |
| 99 | coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc); |
| 100 | fDomain.sampleTexture(fsBuilder, domain, "c", coord, samplers[0]); |
| 101 | if (!fConvolveAlpha) { |
| 102 | fsBuilder->codeAppend("c.rgb /= c.a;"); |
| 103 | } |
| 104 | fsBuilder->codeAppend("sum += c * k;"); |
| 105 | } |
| 106 | } |
| 107 | if (fConvolveAlpha) { |
| 108 | fsBuilder->codeAppendf("%s = sum * %s + %s;", outputColor, gain, bias); |
| 109 | fsBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);", |
| 110 | outputColor, outputColor, outputColor); |
| 111 | } else { |
nothing calls this directly
no test coverage detected