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 "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" |
9 | |
10 | #include "include/gpu/GrTypes.h" |
11 | #include "src/gpu/glsl/GrGLSLProgramBuilder.h" |
12 | #include "src/gpu/glsl/GrGLSLVarying.h" |
13 | |
14 | void GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char* devPos, |
15 | const char* rtAdjustName, |
16 | GrSLType devPosType) { |
17 | if (this->getProgramBuilder()->snapVerticesToPixelCenters()) { |
18 | if (kFloat3_GrSLType == devPosType) { |
19 | const char* p = devPos; |
20 | out->appendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);" , p, p, p, p); |
21 | } else { |
22 | SkASSERT(kFloat2_GrSLType == devPosType); |
23 | out->appendf("{float2 _posTmp = %s;" , devPos); |
24 | } |
25 | out->appendf("_posTmp = floor(_posTmp) + half2(0.5, 0.5);" |
26 | "sk_Position = float4(_posTmp, 0, 1);}" ); |
27 | } else if (kFloat3_GrSLType == devPosType) { |
28 | out->appendf("sk_Position = float4(%s.x , %s.y, 0, %s.z);" , |
29 | devPos, devPos, devPos); |
30 | } else { |
31 | SkASSERT(kFloat2_GrSLType == devPosType); |
32 | out->appendf("sk_Position = float4(%s.x , %s.y, 0, 1);" , |
33 | devPos, devPos); |
34 | } |
35 | } |
36 | |
37 | void GrGLSLVertexBuilder::onFinalize() { |
38 | // We could have the GrGeometryProcessor do this, but its just easier to have it performed |
39 | // here. If we ever need to set variable pointsize, then we can reinvestigate. |
40 | if (this->getProgramBuilder()->hasPointSize()) { |
41 | this->codeAppend("sk_PointSize = 1.0;" ); |
42 | } |
43 | fProgramBuilder->varyingHandler()->getVertexDecls(&this->inputs(), &this->outputs()); |
44 | } |
45 | |
46 | static const char* input_type_name(GrGLSLGeometryBuilder::InputType in) { |
47 | using InputType = GrGLSLGeometryBuilder::InputType; |
48 | switch (in) { |
49 | case InputType::kPoints: return "points" ; |
50 | case InputType::kLines: return "lines" ; |
51 | case InputType::kTriangles: return "triangles" ; |
52 | } |
53 | SK_ABORT("invalid input type" ); |
54 | } |
55 | |
56 | static const char* output_type_name(GrGLSLGeometryBuilder::OutputType out) { |
57 | using OutputType = GrGLSLGeometryBuilder::OutputType; |
58 | switch (out) { |
59 | case OutputType::kPoints: return "points" ; |
60 | case OutputType::kLineStrip: return "line_strip" ; |
61 | case OutputType::kTriangleStrip: return "triangle_strip" ; |
62 | } |
63 | SK_ABORT("invalid output type" ); |
64 | } |
65 | |
66 | void GrGLSLGeometryBuilder::configure(InputType inputType, OutputType outputType, int maxVertices, |
67 | int numInvocations) { |
68 | SkASSERT(!this->isConfigured()); |
69 | fNumInvocations = numInvocations; |
70 | this->addLayoutQualifier(input_type_name(inputType), kIn_InterfaceQualifier); |
71 | this->addLayoutQualifier(SkStringPrintf("invocations = %i" , numInvocations).c_str(), |
72 | kIn_InterfaceQualifier); |
73 | this->addLayoutQualifier(output_type_name(outputType), kOut_InterfaceQualifier); |
74 | this->addLayoutQualifier(SkStringPrintf("max_vertices = %i" , maxVertices).c_str(), |
75 | kOut_InterfaceQualifier); |
76 | } |
77 | |
78 | void GrGLSLGeometryBuilder::emitVertex(SkString* out, const char* devPos, const char* rtAdjustName, |
79 | GrSLType devPosType) { |
80 | this->emitNormalizedSkPosition(out, devPos, rtAdjustName, devPosType); |
81 | out->append("EmitVertex();" ); |
82 | } |
83 | |
84 | void GrGLSLGeometryBuilder::endPrimitive() { |
85 | this->codeAppend("EndPrimitive();" ); |
86 | } |
87 | |
88 | void GrGLSLGeometryBuilder::onFinalize() { |
89 | SkASSERT(this->isConfigured()); |
90 | fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs()); |
91 | } |
92 | |