blob: c7b80390e924ce203f37f00cded5e897cb2fc5ea [file] [log] [blame]
Chris Dalton1a325d22017-07-14 15:17:41 -06001/*
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 "GrCCPRCoverageProcessor.h"
9
Chris Dalton6a3dbee2017-10-16 10:44:41 -060010#include "SkMakeUnique.h"
11#include "ccpr/GrCCPRCubicShader.h"
12#include "ccpr/GrCCPRQuadraticShader.h"
13#include "ccpr/GrCCPRTriangleShader.h"
Chris Dalton1a325d22017-07-14 15:17:41 -060014#include "glsl/GrGLSLFragmentShaderBuilder.h"
Chris Dalton1a325d22017-07-14 15:17:41 -060015
Chris Dalton6a3dbee2017-10-16 10:44:41 -060016void GrCCPRCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varyingHandler,
17 SkString* code, const char* position,
18 const char* coverage, const char* wind) {
19 WindHandling windHandling = this->onEmitVaryings(varyingHandler, code, position, coverage,
20 wind);
21 if (WindHandling::kNotHandled == windHandling) {
Chris Daltonfdde34e2017-10-16 14:15:26 -060022 varyingHandler->addFlatVarying("wind", &fWind);
Chris Dalton6a3dbee2017-10-16 10:44:41 -060023 code->appendf("%s = %s;", fWind.gsOut(), wind);
Chris Dalton1a325d22017-07-14 15:17:41 -060024 }
Eric Borend6365e52017-10-16 12:31:14 +000025}
26
Chris Dalton6a3dbee2017-10-16 10:44:41 -060027void GrCCPRCoverageProcessor::Shader::emitFragmentCode(const GrCCPRCoverageProcessor& proc,
28 GrGLSLPPFragmentBuilder* f,
29 const char* skOutputColor,
30 const char* skOutputCoverage) const {
31 f->codeAppendf("half coverage = 0;");
32 this->onEmitFragmentCode(f, "coverage");
33 if (fWind.fsIn()) {
34 f->codeAppendf("%s.a = coverage * %s;", skOutputColor, fWind.fsIn());
35 } else {
36 f->codeAppendf("%s.a = coverage;", skOutputColor);
Eric Borend6365e52017-10-16 12:31:14 +000037 }
Chris Dalton6a3dbee2017-10-16 10:44:41 -060038 f->codeAppendf("%s = half4(1);", skOutputCoverage);
Chris Dalton1a325d22017-07-14 15:17:41 -060039#ifdef SK_DEBUG
Chris Daltona640c492017-09-11 22:04:03 -070040 if (proc.debugVisualizationsEnabled()) {
Chris Dalton6a3dbee2017-10-16 10:44:41 -060041 f->codeAppendf("%s = half4(-%s.a, %s.a, 0, 1);",
42 skOutputColor, skOutputColor, skOutputColor);
Eric Borend6365e52017-10-16 12:31:14 +000043 }
44#endif
Eric Borend6365e52017-10-16 12:31:14 +000045}
46
Chris Dalton6a3dbee2017-10-16 10:44:41 -060047void GrCCPRCoverageProcessor::Shader::EmitEdgeDistanceEquation(GrGLSLShaderBuilder* s,
48 const char* leftPt,
49 const char* rightPt,
50 const char* outputDistanceEquation) {
Chris Dalton6a3dbee2017-10-16 10:44:41 -060051 s->codeAppendf("float2 n = float2(%s.y - %s.y, %s.x - %s.x);",
Eric Borend6365e52017-10-16 12:31:14 +000052 rightPt, leftPt, leftPt, rightPt);
Chris Daltoncc0ab7e2017-10-24 14:16:52 -060053 s->codeAppend ("float nwidth = (abs(n.x) + abs(n.y)) * (bloat * 2);");
54 // When nwidth=0, wind must also be 0 (and coverage * wind = 0). So it doesn't matter what we
55 // come up with here as long as it isn't NaN or Inf.
56 s->codeAppend ("n /= (0 != nwidth) ? nwidth : 1;");
57 s->codeAppendf("%s = float3(-n, dot(n, %s) - .5);", outputDistanceEquation, leftPt);
Eric Borend6365e52017-10-16 12:31:14 +000058}
59
Chris Dalton6a3dbee2017-10-16 10:44:41 -060060int GrCCPRCoverageProcessor::Shader::DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f,
61 const char* samplesName) {
Chris Dalton1a325d22017-07-14 15:17:41 -060062 // Standard DX11 sample locations.
63#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
Ethan Nicholas8aa45692017-09-20 11:24:15 -040064 f->defineConstant("float2[8]", samplesName, "float2[8]("
65 "float2(+1, -3)/16, float2(-1, +3)/16, float2(+5, +1)/16, float2(-3, -5)/16, "
66 "float2(-5, +5)/16, float2(-7, -1)/16, float2(+3, +7)/16, float2(+7, -7)/16."
Chris Dalton1a325d22017-07-14 15:17:41 -060067 ")");
68 return 8;
69#else
Ethan Nicholas8aa45692017-09-20 11:24:15 -040070 f->defineConstant("float2[16]", samplesName, "float2[16]("
71 "float2(+1, +1)/16, float2(-1, -3)/16, float2(-3, +2)/16, float2(+4, -1)/16, "
72 "float2(-5, -2)/16, float2(+2, +5)/16, float2(+5, +3)/16, float2(+3, -5)/16, "
73 "float2(-2, +6)/16, float2( 0, -7)/16, float2(-4, -6)/16, float2(-6, +4)/16, "
74 "float2(-8, 0)/16, float2(+7, -4)/16, float2(+6, +7)/16, float2(-7, -8)/16."
Chris Dalton1a325d22017-07-14 15:17:41 -060075 ")");
76 return 16;
77#endif
78}
79
Chris Dalton6a3dbee2017-10-16 10:44:41 -060080void GrCCPRCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
81 GrProcessorKeyBuilder* b) const {
82 b->add32((int)fRenderPass);
83}
84
85GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const {
86 std::unique_ptr<Shader> shader;
87 switch (fRenderPass) {
Chris Dalton6a3dbee2017-10-16 10:44:41 -060088 case RenderPass::kTriangleHulls:
89 shader = skstd::make_unique<GrCCPRTriangleHullShader>();
90 break;
91 case RenderPass::kTriangleEdges:
92 shader = skstd::make_unique<GrCCPRTriangleEdgeShader>();
93 break;
94 case RenderPass::kTriangleCorners:
95 shader = skstd::make_unique<GrCCPRTriangleCornerShader>();
96 break;
97 case RenderPass::kQuadraticHulls:
98 shader = skstd::make_unique<GrCCPRQuadraticHullShader>();
99 break;
100 case RenderPass::kQuadraticCorners:
101 shader = skstd::make_unique<GrCCPRQuadraticCornerShader>();
102 break;
Chris Daltonbe4ffab2017-12-08 10:59:58 -0700103 case RenderPass::kCubicHulls:
104 shader = skstd::make_unique<GrCCPRCubicHullShader>();
Chris Dalton6a3dbee2017-10-16 10:44:41 -0600105 break;
Chris Daltonbe4ffab2017-12-08 10:59:58 -0700106 case RenderPass::kCubicCorners:
107 shader = skstd::make_unique<GrCCPRCubicCornerShader>();
Chris Dalton6a3dbee2017-10-16 10:44:41 -0600108 break;
109 }
110 return CreateGSImpl(std::move(shader));
111}