Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Unified Diff: src/core/SkNormalBevelSource.cpp

Issue 2151653002: Added math for SkNormalBevelSource to create bevels on GPU side (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-bevel-impl-0
Patch Set: Fixed some oversized lines Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkNormalBevelSource.cpp
diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp
index a63e434c3fb1fe7f01162735d8ac7ebbd11dc330..beb3d9b8b795414240b4cd8bf5f1c6fdadc9bc51 100644
--- a/src/core/SkNormalBevelSource.cpp
+++ b/src/core/SkNormalBevelSource.cpp
@@ -19,6 +19,14 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "SkGr.h"
+/** \class NormalBevelFP
+ *
+ * Fragment processor for the SkNormalBevelSource.
+ *
robertphillips 2016/08/03 16:33:15 What do you think about renaming these bevelWidth,
dvonbeck 2016/08/03 21:04:20 Done. Should I do this in the user-facing API too?
+ * @param type type of the bevel
+ * @param width width of the bevel in device space
+ * @param height height of the bevel in device space
+ */
class NormalBevelFP : public GrFragmentProcessor {
public:
NormalBevelFP(SkNormalSource::BevelType type, SkScalar width, SkScalar height)
@@ -39,6 +47,7 @@ public:
void onEmitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const NormalBevelFP& fp = args.fFp.cast<NormalBevelFP>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
const char* widthUniName = nullptr;
@@ -49,7 +58,14 @@ public:
fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
kDefault_GrSLPrecision, "Height", &heightUniName);
robertphillips 2016/08/03 16:33:14 Do you think the shader compilers are going to be
dvonbeck 2016/08/03 16:39:24 I assume so but I don't know. Do you think I shoul
dvonbeck 2016/08/03 21:04:19 No longer necessary.
- fragBuilder->codeAppendf("%s = vec4(0.0, 0.0, 1.0, 0.0);", args.fOutputColor);
+ fragBuilder->codeAppend( "vec3 normal;");
+ fragBuilder->codeAppendf("if (length(%s) >= %s) {",
+ fragBuilder->distanceVectorName(), widthUniName);
+ fragBuilder->codeAppend( " normal = vec3(0.0, 0.0, 1.0);");
+ fragBuilder->codeAppend( "} else {");
+ this->emitMath(fragBuilder, fp.fType, widthUniName, heightUniName);
+ fragBuilder->codeAppend( "}");
+ fragBuilder->codeAppendf("%s = vec4(normal, 0.0);", args.fOutputColor);
}
static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
@@ -73,6 +89,44 @@ public:
}
}
+ void emitMath(GrGLSLFPFragmentBuilder* fb, SkNormalSource::BevelType type,
+ const char* width, const char* height) {
+ const char* distanceVector = fb->distanceVectorName();
+
+ // Setting t to the distance from the end of the bevel as opposed to the beginning if
+ // the bevel is rounded out.
+ if ( type == SkNormalSource::BevelType::kRoundedIn ) {
+ fb->codeAppendf(" float t = %s - length(%s);", width, distanceVector);
+ } else if (type == SkNormalSource::BevelType::kRoundedOut) {
+ fb->codeAppendf(" float t = length(%s);", distanceVector);
+ }
+
+ switch (type) {
+ case SkNormalSource::BevelType::kLinear:
+ fb->codeAppendf(" normal = normalize(%s*vec3(%s, 0.0) "
+ "+ vec3(0.0, 0.0, %s));",
+ height, distanceVector, width);
+ break;
robertphillips 2016/08/03 16:33:15 Add a "// fall through" comment
dvonbeck 2016/08/03 21:04:20 Done.
+ case SkNormalSource::BevelType::kRoundedOut:
+ case SkNormalSource::BevelType::kRoundedIn:
+ // calculating the slope of the normal with respect to the distance vector by
+ // setting it equal to the negative reciprocal of the derivative of the bezier
robertphillips 2016/08/03 16:33:15 cure -> curve One would hope the shader compilers
dvonbeck 2016/08/03 16:39:24 Do you think they will, or should I make it explic
dvonbeck 2016/08/03 21:04:20 Done.
+ // cure
+ fb->codeAppendf("float slope = %s * sqrt(t) / (%s * (sqrt(%s) - sqrt(t)));",
+ width, height, width);
+ // calculating a value so that when appended to the distance vector and
+ // normalized, it would result in a normal with the correct slope
+ fb->codeAppend("float z_prenorm = slope * t;");
+ // Multiplying with the height's sign to orient the vector inwards for bevels of
+ // negative height
robertphillips 2016/08/03 16:33:15 Is sign() verboten?
dvonbeck 2016/08/03 21:04:20 No longer necessary.
+ fb->codeAppendf("normal = normalize(vec3(%s, z_prenorm)) * normalize(%s);",
+ distanceVector, height);
+ break;
+ default:
+ SkDEBUGFAIL("Invalid bevel type passed to emitMath");
+ }
+ }
+
private:
SkScalar fPrevWidth;
GrGLSLProgramDataManager::UniformHandle fWidthUni;
@@ -107,9 +161,12 @@ private:
};
sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor(
- const SkShader::AsFPArgs&) const {
+ const SkShader::AsFPArgs& args) const {
+
+ SkScalar maxScale = args.fViewMatrix->getMaxScale();
- return sk_make_sp<NormalBevelFP>(fType, fWidth, fHeight);
+ // Providing device-space width and height
+ return sk_make_sp<NormalBevelFP>(fType, maxScale * fWidth, maxScale * fHeight);
}
#endif // SK_SUPPORT_GPU
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698