OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "InstanceProcessor.h" | 8 #include "InstanceProcessor.h" |
9 | 9 |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
11 #include "GrRenderTargetPriv.h" | 11 #include "GrRenderTargetPriv.h" |
12 #include "GrResourceCache.h" | 12 #include "GrResourceCache.h" |
13 #include "GrResourceProvider.h" | 13 #include "GrResourceProvider.h" |
14 #include "glsl/GrGLSLGeometryProcessor.h" | 14 #include "glsl/GrGLSLGeometryProcessor.h" |
15 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 15 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
16 #include "glsl/GrGLSLProgramBuilder.h" | 16 #include "glsl/GrGLSLProgramBuilder.h" |
17 #include "glsl/GrGLSLVarying.h" | 17 #include "glsl/GrGLSLVarying.h" |
18 | 18 |
19 namespace gr_instanced { | 19 namespace gr_instanced { |
20 | 20 |
21 bool InstanceProcessor::IsSupported(const GrGLSLCaps& glslCaps, const GrCaps& ca
ps, | 21 GrCaps::InstancedSupport InstanceProcessor::CheckSupport(const GrGLSLCaps& glslC
aps, |
22 AntialiasMode* lastSupportedAAMode) { | 22 const GrCaps& caps) { |
23 if (!glslCaps.canUseAnyFunctionInShader() || | 23 if (!glslCaps.canUseAnyFunctionInShader() || |
24 !glslCaps.flatInterpolationSupport() || | 24 !glslCaps.flatInterpolationSupport() || |
25 !glslCaps.integerSupport() || | 25 !glslCaps.integerSupport() || |
26 0 == glslCaps.maxVertexSamplers() || | 26 0 == glslCaps.maxVertexSamplers() || |
27 !caps.shaderCaps()->texelBufferSupport() || | 27 !caps.shaderCaps()->texelBufferSupport() || |
28 caps.maxVertexAttributes() < kNumAttribs) { | 28 caps.maxVertexAttributes() < kNumAttribs) { |
29 return false; | 29 return GrCaps::InstancedSupport::kNone; |
30 } | 30 } |
31 if (caps.sampleLocationsSupport() && | 31 if (!caps.sampleLocationsSupport() || |
32 glslCaps.sampleVariablesSupport() && | 32 !glslCaps.sampleVariablesSupport() || |
33 glslCaps.shaderDerivativeSupport()) { | 33 !glslCaps.shaderDerivativeSupport()) { |
34 if (0 != caps.maxRasterSamples() && | 34 return GrCaps::InstancedSupport::kBasic; |
35 glslCaps.sampleMaskOverrideCoverageSupport()) { | |
36 *lastSupportedAAMode = AntialiasMode::kMixedSamples; | |
37 } else { | |
38 *lastSupportedAAMode = AntialiasMode::kMSAA; | |
39 } | |
40 } else { | |
41 *lastSupportedAAMode = AntialiasMode::kCoverage; | |
42 } | 35 } |
43 return true; | 36 if (0 == caps.maxRasterSamples() || |
| 37 !glslCaps.sampleMaskOverrideCoverageSupport()) { |
| 38 return GrCaps::InstancedSupport::kMultisampled; |
| 39 } |
| 40 return GrCaps::InstancedSupport::kMixedSampled; |
44 } | 41 } |
45 | 42 |
46 InstanceProcessor::InstanceProcessor(BatchInfo batchInfo, GrBuffer* paramsBuffer
) | 43 InstanceProcessor::InstanceProcessor(BatchInfo batchInfo, GrBuffer* paramsBuffer
) |
47 : fBatchInfo(batchInfo) { | 44 : fBatchInfo(batchInfo) { |
48 this->initClassID<InstanceProcessor>(); | 45 this->initClassID<InstanceProcessor>(); |
49 | 46 |
50 this->addVertexAttrib(Attribute("shapeCoords", kVec2f_GrVertexAttribType, kH
igh_GrSLPrecision)); | 47 this->addVertexAttrib(Attribute("shapeCoords", kVec2f_GrVertexAttribType, kH
igh_GrSLPrecision)); |
51 this->addVertexAttrib(Attribute("vertexAttrs", kInt_GrVertexAttribType)); | 48 this->addVertexAttrib(Attribute("vertexAttrs", kInt_GrVertexAttribType)); |
52 this->addVertexAttrib(Attribute("instanceInfo", kUint_GrVertexAttribType)); | 49 this->addVertexAttrib(Attribute("instanceInfo", kUint_GrVertexAttribType)); |
53 this->addVertexAttrib(Attribute("shapeMatrixX", kVec3f_GrVertexAttribType, | 50 this->addVertexAttrib(Attribute("shapeMatrixX", kVec3f_GrVertexAttribType, |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSL
Precision); | 757 varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSL
Precision); |
761 } | 758 } |
762 v->codeAppend("float rectCoverage = 0.0;"); | 759 v->codeAppend("float rectCoverage = 0.0;"); |
763 } | 760 } |
764 if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) { | 761 if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) { |
765 varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_Gr
SLPrecision); | 762 varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_Gr
SLPrecision); |
766 if (!fShapeIsCircle) { | 763 if (!fShapeIsCircle) { |
767 varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium
_GrSLPrecision); | 764 varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium
_GrSLPrecision); |
768 varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_G
rSLPrecision); | 765 varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_G
rSLPrecision); |
769 } else { | 766 } else { |
770 varyingHandler->addVarying("circleCoords", &fEllipseCoords, kMedium_
GrSLPrecision); | 767 varyingHandler->addVarying("circleCoords", &fEllipseCoords, kHigh_Gr
SLPrecision); |
771 varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kMe
dium_GrSLPrecision); | 768 varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kHi
gh_GrSLPrecision); |
772 } | 769 } |
773 } | 770 } |
774 } | 771 } |
775 | 772 |
776 void GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) { | 773 void GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) { |
777 // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs
. | 774 // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs
. |
778 v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;", | 775 v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;", |
779 fInputs.attr(Attrib::kVertexAttrs)); | 776 fInputs.attr(Attrib::kVertexAttrs)); |
780 // Here we use the absolute value, because when the rect is thinner than a p
ixel, this makes it | 777 // Here we use the absolute value, because when the rect is thinner than a p
ixel, this makes it |
781 // mark the spot where pixel center is within half a pixel of the *opposite*
edge. This, | 778 // mark the spot where pixel center is within half a pixel of the *opposite*
edge. This, |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn()); | 1006 f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn()); |
1010 } else { | 1007 } else { |
1011 f->codeAppendf("%s = 1.0;", outCoverage); | 1008 f->codeAppendf("%s = 1.0;", outCoverage); |
1012 } | 1009 } |
1013 } | 1010 } |
1014 | 1011 |
1015 void GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder*
f, | 1012 void GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder*
f, |
1016 const char* outCoverage)
{ | 1013 const char* outCoverage)
{ |
1017 // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimiz
ation on rrects. | 1014 // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimiz
ation on rrects. |
1018 SkASSERT(!(kRRect_ShapesMask & fBatchInfo.fShapeTypes)); | 1015 SkASSERT(!(kRRect_ShapesMask & fBatchInfo.fShapeTypes)); |
1019 f->appendPrecisionModifier(kLow_GrSLPrecision); | 1016 f->appendPrecisionModifier(kMedium_GrSLPrecision); |
1020 f->codeAppendf("float distanceToEdge = %s - length(%s);", | 1017 f->codeAppendf("float distanceToEdge = %s - length(%s);", |
1021 fBloatedRadius.fsIn(), fEllipseCoords.fsIn()); | 1018 fBloatedRadius.fsIn(), fEllipseCoords.fsIn()); |
1022 f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage); | 1019 f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage); |
1023 } | 1020 } |
1024 | 1021 |
1025 void GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f, | 1022 void GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f, |
1026 const char* ellipseCoords, | 1023 const char* ellipseCoords, |
1027 const char* ellipseName, | 1024 const char* ellipseName, |
1028 bool ellipseCoordsNeedClamp
, | 1025 bool ellipseCoordsNeedClamp
, |
1029 bool ellipseCoordsMayBeNega
tive, | 1026 bool ellipseCoordsMayBeNega
tive, |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 if (!this->isMixedSampled()) { | 1397 if (!this->isMixedSampled()) { |
1401 SkASSERT(!fArcTest.fsIn()); | 1398 SkASSERT(!fArcTest.fsIn()); |
1402 if (fTriangleIsArc.fsIn()) { | 1399 if (fTriangleIsArc.fsIn()) { |
1403 f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn()); | 1400 f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn()); |
1404 this->emitArc(f, arcCoords, false, clampArcCoords, opts); | 1401 this->emitArc(f, arcCoords, false, clampArcCoords, opts); |
1405 | 1402 |
1406 f->codeAppend ("}"); | 1403 f->codeAppend ("}"); |
1407 } | 1404 } |
1408 } else { | 1405 } else { |
1409 const char* arcTest = fArcTest.fsIn(); | 1406 const char* arcTest = fArcTest.fsIn(); |
1410 SkASSERT(arcTest); | 1407 if (arcTest && fBatchInfo.fHasPerspective) { |
1411 if (fBatchInfo.fHasPerspective) { | 1408 // The non-perspective version accounts for fwidth() in the vertex s
hader. |
1412 // The non-perspective version accounts for fwith() in the vertex sh
ader. | |
1413 // We make sure to take the derivative here, before a neighbor pixel
may early accept. | 1409 // We make sure to take the derivative here, before a neighbor pixel
may early accept. |
1414 f->enableFeature(GrGLSLPPFragmentBuilder::kStandardDerivatives_GLSLF
eature); | 1410 f->enableFeature(GrGLSLPPFragmentBuilder::kStandardDerivatives_GLSLF
eature); |
1415 f->appendPrecisionModifier(kHigh_GrSLPrecision); | 1411 f->appendPrecisionModifier(kHigh_GrSLPrecision); |
1416 f->codeAppendf("vec2 arcTest = %s - 0.5 * fwidth(%s);", | 1412 f->codeAppendf("vec2 arcTest = %s - 0.5 * fwidth(%s);", |
1417 fArcTest.fsIn(), fArcTest.fsIn()); | 1413 fArcTest.fsIn(), fArcTest.fsIn()); |
1418 arcTest = "arcTest"; | 1414 arcTest = "arcTest"; |
1419 } | 1415 } |
1420 const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "S
AMPLE_MASK_ALL"; | 1416 const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "S
AMPLE_MASK_ALL"; |
1421 f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept); | 1417 f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept); |
1422 f->overrideSampleCoverage(earlyAccept); | 1418 f->overrideSampleCoverage(earlyAccept); |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2117 | 2113 |
2118 case kCorneredRect_FirstIndex: return "basic_round_rect"; | 2114 case kCorneredRect_FirstIndex: return "basic_round_rect"; |
2119 case kCorneredFramedRect_FirstIndex: return "coverage_round_rect"; | 2115 case kCorneredFramedRect_FirstIndex: return "coverage_round_rect"; |
2120 case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect"; | 2116 case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect"; |
2121 | 2117 |
2122 default: return "unknown"; | 2118 default: return "unknown"; |
2123 } | 2119 } |
2124 } | 2120 } |
2125 | 2121 |
2126 } | 2122 } |
OLD | NEW |