1 /* 2 * Copyright 2017 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 "GrCCCoverageProcessor.h" 9 10 #include "SkMakeUnique.h" 11 #include "ccpr/GrCCCubicShader.h" 12 #include "ccpr/GrCCQuadraticShader.h" 13 #include "ccpr/GrCCTriangleShader.h" 14 #include "glsl/GrGLSLVertexGeoBuilder.h" 15 #include "glsl/GrGLSLFragmentShaderBuilder.h" 16 #include "glsl/GrGLSLVertexGeoBuilder.h" 17 18 void GrCCCoverageProcessor::Shader::emitFragmentCode(const GrCCCoverageProcessor& proc, 19 GrGLSLFPFragmentBuilder* f, 20 const char* skOutputColor, 21 const char* skOutputCoverage) const { 22 f->codeAppendf("half coverage = 0;"); 23 this->onEmitFragmentCode(f, "coverage"); 24 f->codeAppendf("%s.a = coverage;", skOutputColor); 25 f->codeAppendf("%s = half4(1);", skOutputCoverage); 26 #ifdef SK_DEBUG 27 if (proc.debugVisualizationsEnabled()) { 28 f->codeAppendf("%s = half4(-%s.a, %s.a, 0, 1);", 29 skOutputColor, skOutputColor, skOutputColor); 30 } 31 #endif 32 } 33 34 void GrCCCoverageProcessor::Shader::EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder* s, 35 const char* leftPt, 36 const char* rightPt, 37 const char* outputDistanceEquation) { 38 s->codeAppendf("float2 n = float2(%s.y - %s.y, %s.x - %s.x);", 39 rightPt, leftPt, leftPt, rightPt); 40 s->codeAppend ("float nwidth = (abs(n.x) + abs(n.y)) * (bloat * 2);"); 41 // When nwidth=0, wind must also be 0 (and coverage * wind = 0). So it doesn't matter what we 42 // come up with here as long as it isn't NaN or Inf. 43 s->codeAppend ("n /= (0 != nwidth) ? nwidth : 1;"); 44 s->codeAppendf("%s = float3(-n, dot(n, %s) - .5);", outputDistanceEquation, leftPt); 45 } 46 47 int GrCCCoverageProcessor::Shader::DefineSoftSampleLocations(GrGLSLFPFragmentBuilder* f, 48 const char* samplesName) { 49 // Standard DX11 sample locations. 50 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) 51 f->defineConstant("float2[8]", samplesName, "float2[8](" 52 "float2(+1, -3)/16, float2(-1, +3)/16, float2(+5, +1)/16, float2(-3, -5)/16, " 53 "float2(-5, +5)/16, float2(-7, -1)/16, float2(+3, +7)/16, float2(+7, -7)/16." 54 ")"); 55 return 8; 56 #else 57 f->defineConstant("float2[16]", samplesName, "float2[16](" 58 "float2(+1, +1)/16, float2(-1, -3)/16, float2(-3, +2)/16, float2(+4, -1)/16, " 59 "float2(-5, -2)/16, float2(+2, +5)/16, float2(+5, +3)/16, float2(+3, -5)/16, " 60 "float2(-2, +6)/16, float2( 0, -7)/16, float2(-4, -6)/16, float2(-6, +4)/16, " 61 "float2(-8, 0)/16, float2(+7, -4)/16, float2(+6, +7)/16, float2(-7, -8)/16." 62 ")"); 63 return 16; 64 #endif 65 } 66 67 void GrCCCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&, 68 GrProcessorKeyBuilder* b) const { 69 int key = (int)fRenderPass << 2; 70 if (WindMethod::kInstanceData == fWindMethod) { 71 key |= 2; 72 } 73 if (Impl::kVertexShader == fImpl) { 74 key |= 1; 75 } 76 #ifdef SK_DEBUG 77 uint32_t bloatBits; 78 memcpy(&bloatBits, &fDebugBloat, 4); 79 b->add32(bloatBits); 80 #endif 81 b->add32(key); 82 } 83 84 GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const { 85 std::unique_ptr<Shader> shader; 86 switch (fRenderPass) { 87 case RenderPass::kTriangleHulls: 88 case RenderPass::kTriangleEdges: 89 shader = skstd::make_unique<GrCCTriangleShader>(); 90 break; 91 case RenderPass::kTriangleCorners: 92 shader = skstd::make_unique<GrCCTriangleCornerShader>(); 93 break; 94 case RenderPass::kQuadraticHulls: 95 shader = skstd::make_unique<GrCCQuadraticHullShader>(); 96 break; 97 case RenderPass::kQuadraticCorners: 98 shader = skstd::make_unique<GrCCQuadraticCornerShader>(); 99 break; 100 case RenderPass::kCubicHulls: 101 shader = skstd::make_unique<GrCCCubicHullShader>(); 102 break; 103 case RenderPass::kCubicCorners: 104 shader = skstd::make_unique<GrCCCubicCornerShader>(); 105 break; 106 } 107 return Impl::kGeometryShader == fImpl ? this->createGSImpl(std::move(shader)) 108 : this->createVSImpl(std::move(shader)); 109 } 110