aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-02-02 11:06:30 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-02 18:43:29 +0000
commit7b046312edd9219ba8e66c255f5347c000b69ee1 (patch)
tree1119465d75682b9d5952e30695033d1105a24c93
parent7a9263906c677c0fa5636521e3cc58ba60837720 (diff)
ccpr: Don't use flat interpolation when it is slow
Bug: skia: Change-Id: I1bc087187541183fdbaa5f2b93e8b8d287ac8ef8 Reviewed-on: https://skia-review.googlesource.com/102100 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--src/gpu/ccpr/GrCCCubicShader.cpp6
-rw-r--r--src/gpu/ccpr/GrCCPathProcessor.cpp6
-rw-r--r--src/gpu/ccpr/GrCCQuadraticShader.cpp6
-rw-r--r--src/gpu/ccpr/GrCCTriangleShader.cpp8
-rw-r--r--src/gpu/effects/GrAtlasedShaderHelpers.h10
-rw-r--r--src/gpu/glsl/GrGLSLVarying.cpp44
-rw-r--r--src/gpu/glsl/GrGLSLVarying.h30
-rw-r--r--src/gpu/ops/GrTextureOp.cpp22
8 files changed, 66 insertions, 66 deletions
diff --git a/src/gpu/ccpr/GrCCCubicShader.cpp b/src/gpu/ccpr/GrCCCubicShader.cpp
index fbaf7d9da8..3bf8479536 100644
--- a/src/gpu/ccpr/GrCCCubicShader.cpp
+++ b/src/gpu/ccpr/GrCCCubicShader.cpp
@@ -133,14 +133,16 @@ void GrCCCubicCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const cha
void GrCCCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+
fdKLMDdx.reset(kFloat4_GrSLType, scope);
- varyingHandler->addFlatVarying("dklmddx", &fdKLMDdx);
+ varyingHandler->addVarying("dklmddx", &fdKLMDdx, Interpolation::kCanBeFlat);
code->appendf("%s = float4(%s[0].x, %s[1].x, %s[2].x, %s.x);",
OutName(fdKLMDdx), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
fdKLMDdy.reset(kFloat4_GrSLType, scope);
- varyingHandler->addFlatVarying("dklmddy", &fdKLMDdy);
+ varyingHandler->addVarying("dklmddy", &fdKLMDdy, Interpolation::kCanBeFlat);
code->appendf("%s = float4(%s[0].y, %s[1].y, %s[2].y, %s.y);",
OutName(fdKLMDdy), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index f93a0bd631..986b5870d7 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -146,6 +146,8 @@ GrGLSLPrimitiveProcessor* GrCCPathProcessor::createGLSLInstance(const GrShaderCa
void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
using InstanceAttribs = GrCCPathProcessor::InstanceAttribs;
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+
const GrCCPathProcessor& proc = args.fGP.cast<GrCCPathProcessor>();
GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
@@ -160,8 +162,8 @@ void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVarying texcoord(kFloat2_GrSLType);
GrGLSLVarying color(kHalf4_GrSLType);
varyingHandler->addVarying("texcoord", &texcoord);
- varyingHandler->addFlatPassThroughAttribute(&proc.getInstanceAttrib(InstanceAttribs::kColor),
- args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(&proc.getInstanceAttrib(InstanceAttribs::kColor),
+ args.fOutputColor, Interpolation::kCanBeFlat);
// The vertex shader bloats and intersects the devBounds and devBounds45 rectangles, in order to
// find an octagon that circumscribes the (bloated) path.
diff --git a/src/gpu/ccpr/GrCCQuadraticShader.cpp b/src/gpu/ccpr/GrCCQuadraticShader.cpp
index 002fcfd340..1122eafc98 100644
--- a/src/gpu/ccpr/GrCCQuadraticShader.cpp
+++ b/src/gpu/ccpr/GrCCQuadraticShader.cpp
@@ -101,14 +101,16 @@ void GrCCQuadraticCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const
void GrCCQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+
fdXYDdx.reset(kFloat3_GrSLType, scope);
- varyingHandler->addFlatVarying("dXYDdx", &fdXYDdx);
+ varyingHandler->addVarying("dXYDdx", &fdXYDdx, Interpolation::kCanBeFlat);
code->appendf("%s = float3(%s[0].x, %s[0].y, %s.x);",
OutName(fdXYDdx), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
fEdgeDistanceEquation.c_str());
fdXYDdy.reset(kFloat3_GrSLType, scope);
- varyingHandler->addFlatVarying("dXYDdy", &fdXYDdy);
+ varyingHandler->addVarying("dXYDdy", &fdXYDdy, Interpolation::kCanBeFlat);
code->appendf("%s = float3(%s[1].x, %s[1].y, %s.y);",
OutName(fdXYDdy), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
fEdgeDistanceEquation.c_str());
diff --git a/src/gpu/ccpr/GrCCTriangleShader.cpp b/src/gpu/ccpr/GrCCTriangleShader.cpp
index 6e9b13ef69..6ed875822e 100644
--- a/src/gpu/ccpr/GrCCTriangleShader.cpp
+++ b/src/gpu/ccpr/GrCCTriangleShader.cpp
@@ -18,7 +18,8 @@ void GrCCTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
const char* wind) {
fCoverageTimesWind.reset(kHalf_GrSLType, scope);
if (!inputCoverage) {
- varyingHandler->addFlatVarying("wind", &fCoverageTimesWind);
+ varyingHandler->addVarying("wind", &fCoverageTimesWind,
+ GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
code->appendf("%s = %s;", OutName(fCoverageTimesWind), wind);
} else {
varyingHandler->addVarying("coverage_times_wind", &fCoverageTimesWind);
@@ -89,13 +90,14 @@ void GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandl
GrGLSLVarying::Scope scope, SkString* code,
const char* position, const char* inputCoverage,
const char* wind) {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
SkASSERT(!inputCoverage);
fCornerLocationInAABoxes.reset(kFloat2x2_GrSLType, scope);
varyingHandler->addVarying("corner_location_in_aa_boxes", &fCornerLocationInAABoxes);
fBisectInAABoxes.reset(kFloat2x2_GrSLType, scope);
- varyingHandler->addFlatVarying("bisect_in_aa_boxes", &fBisectInAABoxes);
+ varyingHandler->addVarying("bisect_in_aa_boxes", &fBisectInAABoxes, Interpolation::kCanBeFlat);
code->appendf("for (int i = 0; i < 2; ++i) {");
code->appendf( "%s[i] = %s * %s[i] + %s[i];",
@@ -105,7 +107,7 @@ void GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandl
code->appendf("}");
fWindTimesHalf.reset(kHalf_GrSLType, scope);
- varyingHandler->addFlatVarying("wind_times_half", &fWindTimesHalf);
+ varyingHandler->addVarying("wind_times_half", &fWindTimesHalf, Interpolation::kCanBeFlat);
code->appendf("%s = %s * .5;", OutName(fWindTimesHalf), wind);
}
diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h
index 8c09291d6a..a7d445ac86 100644
--- a/src/gpu/effects/GrAtlasedShaderHelpers.h
+++ b/src/gpu/effects/GrAtlasedShaderHelpers.h
@@ -20,6 +20,8 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args,
GrGLSLVarying *uv,
GrGLSLVarying *texIdx,
GrGLSLVarying *st) {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+
// This extracts the texture index and texel coordinates from the same variable
// Packing structure: texel coordinates are multiplied by 2 (or shifted left 1)
// texture index is stored as lower bits of both x and y
@@ -40,11 +42,9 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args,
args.fVaryingHandler->addVarying("TextureCoords", uv);
args.fVertBuilder->codeAppendf("%s = unormTexCoords * %s;", uv->vsOut(), atlasSizeInvName);
- if (args.fShaderCaps->integerSupport()) {
- args.fVaryingHandler->addFlatVarying("TexIndex", texIdx);
- } else {
- args.fVaryingHandler->addVarying("TexIndex", texIdx);
- }
+ args.fVaryingHandler->addVarying("TexIndex", texIdx, args.fShaderCaps->integerSupport()
+ ? Interpolation::kMustBeFlat
+ : Interpolation::kCanBeFlat);
args.fVertBuilder->codeAppendf("%s = texIdx;", texIdx->vsOut());
if (st) {
diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp
index 5a57613b3a..c5cef3492a 100644
--- a/src/gpu/glsl/GrGLSLVarying.cpp
+++ b/src/gpu/glsl/GrGLSLVarying.cpp
@@ -10,36 +10,44 @@
#include "glsl/GrGLSLProgramBuilder.h"
void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input,
- const char* output) {
- GrSLType type = GrVertexAttribTypeToSLType(input->fType);
- GrGLSLVarying v(type);
- this->addVarying(input->fName, &v);
- this->writePassThroughAttribute(input, output, v);
-}
-
-void GrGLSLVaryingHandler::addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute* input,
- const char* output) {
+ const char* output,
+ Interpolation interpolation) {
+ SkASSERT(!fProgramBuilder->primitiveProcessor().willUseGeoShader());
GrSLType type = GrVertexAttribTypeToSLType(input->fType);
GrGLSLVarying v(type);
- this->addFlatVarying(input->fName, &v);
- this->writePassThroughAttribute(input, output, v);
-}
-
-void GrGLSLVaryingHandler::writePassThroughAttribute(const GrGeometryProcessor::Attribute* input,
- const char* output, const GrGLSLVarying& v) {
- SkASSERT(!fProgramBuilder->primitiveProcessor().willUseGeoShader());
+ this->addVarying(input->fName, &v, interpolation);
fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName);
fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn());
}
-void GrGLSLVaryingHandler::internalAddVarying(const char* name, GrGLSLVarying* varying, bool flat) {
+static bool use_flat_interpolation(GrGLSLVaryingHandler::Interpolation interpolation,
+ const GrShaderCaps& shaderCaps) {
+ switch (interpolation) {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+ case Interpolation::kInterpolated:
+ return false;
+ case Interpolation::kCanBeFlat:
+ SkASSERT(!shaderCaps.preferFlatInterpolation() ||
+ shaderCaps.flatInterpolationSupport());
+ return shaderCaps.preferFlatInterpolation();
+ case Interpolation::kMustBeFlat:
+ SkASSERT(shaderCaps.flatInterpolationSupport());
+ return true;
+ }
+ SK_ABORT("Invalid interpolation");
+ return false;
+}
+
+void GrGLSLVaryingHandler::addVarying(const char* name, GrGLSLVarying* varying,
+ Interpolation interpolation) {
+ SkASSERT(GrSLTypeIsFloatType(varying->type()) || Interpolation::kMustBeFlat == interpolation);
bool willUseGeoShader = fProgramBuilder->primitiveProcessor().willUseGeoShader();
VaryingInfo& v = fVaryings.push_back();
SkASSERT(varying);
SkASSERT(kVoid_GrSLType != varying->fType);
v.fType = varying->fType;
- v.fIsFlat = flat;
+ v.fIsFlat = use_flat_interpolation(interpolation, *fProgramBuilder->shaderCaps());
fProgramBuilder->nameVariable(&v.fVsOut, 'v', name);
v.fVisibility = kNone_GrShaderFlags;
if (varying->isInVertexShader()) {
diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h
index dac9bb771f..57704ad075 100644
--- a/src/gpu/glsl/GrGLSLVarying.h
+++ b/src/gpu/glsl/GrGLSLVarying.h
@@ -79,6 +79,12 @@ public:
*/
void setNoPerspective();
+ enum class Interpolation {
+ kInterpolated,
+ kCanBeFlat, // Use "flat" if it will be faster.
+ kMustBeFlat // Use "flat" even if it is known to be slow.
+ };
+
/*
* addVarying allows fine grained control for setting up varyings between stages. Calling this
* function will make sure all necessary decls are setup for the client. The client however is
@@ -87,20 +93,8 @@ public:
* addPassThroughAttribute.
* TODO convert most uses of addVarying to addPassThroughAttribute
*/
- void addVarying(const char* name, GrGLSLVarying* varying) {
- SkASSERT(GrSLTypeIsFloatType(varying->type())); // Integers must use addFlatVarying.
- this->internalAddVarying(name, varying, false /*flat*/);
- }
-
- /*
- * addFlatVarying sets up a varying whose value is constant across every fragment. The graphics
- * pipeline will pull its value from the final vertex of the draw primitive (provoking vertex).
- * Flat interpolation is not always supported and the user must check the caps before using.
- * TODO: Some platforms can change the provoking vertex. Should we be resetting this knob?
- */
- void addFlatVarying(const char* name, GrGLSLVarying* varying) {
- this->internalAddVarying(name, varying, true /*flat*/);
- }
+ void addVarying(const char* name, GrGLSLVarying* varying,
+ Interpolation = Interpolation::kInterpolated);
/*
* The GP can use these calls to pass an attribute through all shaders directly to 'output' in
@@ -110,8 +104,8 @@ public:
* that will be set as the output varying for all emitted vertices.
* TODO it might be nicer behavior to have a flag to declare output inside these calls
*/
- void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output);
- void addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output);
+ void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output,
+ Interpolation = Interpolation::kInterpolated);
void emitAttributes(const GrGeometryProcessor& gp);
@@ -148,10 +142,6 @@ protected:
GrGLSLProgramBuilder* fProgramBuilder;
private:
- void internalAddVarying(const char* name, GrGLSLVarying*, bool flat);
- void writePassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output,
- const GrGLSLVarying&);
-
void addAttribute(const GrShaderVar& var);
virtual void onFinalize() = 0;
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 46d2630270..565a65883d 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -116,6 +116,7 @@ public:
private:
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
const auto& textureGP = args.fGP.cast<TextureGeometryProcessor>();
fColorSpaceXformHelper.emitCode(
args.fUniformHandler, textureGP.fColorSpaceXform.get());
@@ -127,26 +128,19 @@ public:
args.fUniformHandler,
textureGP.fTextureCoords.asShaderVar(),
args.fFPCoordTransformHandler);
- if (args.fShaderCaps->preferFlatInterpolation()) {
- args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fColors,
- args.fOutputColor);
- } else {
- args.fVaryingHandler->addPassThroughAttribute(&textureGP.fColors,
- args.fOutputColor);
- }
+ args.fVaryingHandler->addPassThroughAttribute(&textureGP.fColors,
+ args.fOutputColor,
+ Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppend("float2 texCoord;");
args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureCoords,
"texCoord");
if (textureGP.numTextureSamplers() > 1) {
+ // If this changes to float, reconsider Interpolation::kMustBeFlat.
+ SkASSERT(kInt_GrVertexAttribType == textureGP.fTextureIdx.fType);
SkASSERT(args.fShaderCaps->integerSupport());
args.fFragBuilder->codeAppend("int texIdx;");
- if (args.fShaderCaps->flatInterpolationSupport()) {
- args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fTextureIdx,
- "texIdx");
- } else {
- args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureIdx,
- "texIdx");
- }
+ args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureIdx, "texIdx",
+ Interpolation::kMustBeFlat);
args.fFragBuilder->codeAppend("switch (texIdx) {");
for (int i = 0; i < textureGP.numTextureSamplers(); ++i) {
args.fFragBuilder->codeAppendf("case %d: %s = ", i, args.fOutputColor);