| 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 |