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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkNormalBevelSource.h" 8 #include "SkNormalBevelSource.h"
9 9
10 #include "SkNormalSource.h" 10 #include "SkNormalSource.h"
11 #include "SkNormalSourcePriv.h" 11 #include "SkNormalSourcePriv.h"
12 #include "SkPoint3.h" 12 #include "SkPoint3.h"
13 #include "SkReadBuffer.h" 13 #include "SkReadBuffer.h"
14 #include "SkWriteBuffer.h" 14 #include "SkWriteBuffer.h"
15 15
16 #if SK_SUPPORT_GPU 16 #if SK_SUPPORT_GPU
17 #include "GrInvariantOutput.h" 17 #include "GrInvariantOutput.h"
18 #include "glsl/GrGLSLFragmentProcessor.h" 18 #include "glsl/GrGLSLFragmentProcessor.h"
19 #include "glsl/GrGLSLFragmentShaderBuilder.h" 19 #include "glsl/GrGLSLFragmentShaderBuilder.h"
20 #include "SkGr.h" 20 #include "SkGr.h"
21 21
22 /** \class NormalBevelFP
23 *
24 * Fragment processor for the SkNormalBevelSource.
25 *
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?
26 * @param type type of the bevel
27 * @param width width of the bevel in device space
28 * @param height height of the bevel in device space
29 */
22 class NormalBevelFP : public GrFragmentProcessor { 30 class NormalBevelFP : public GrFragmentProcessor {
23 public: 31 public:
24 NormalBevelFP(SkNormalSource::BevelType type, SkScalar width, SkScalar heigh t) 32 NormalBevelFP(SkNormalSource::BevelType type, SkScalar width, SkScalar heigh t)
25 : fType(type) 33 : fType(type)
26 , fWidth(width) 34 , fWidth(width)
27 , fHeight(height) { 35 , fHeight(height) {
28 this->initClassID<NormalBevelFP>(); 36 this->initClassID<NormalBevelFP>();
29 37
30 fUsesDistanceVectorField = true; 38 fUsesDistanceVectorField = true;
31 } 39 }
32 40
33 class GLSLNormalBevelFP : public GLSLNormalFP { 41 class GLSLNormalBevelFP : public GLSLNormalFP {
34 public: 42 public:
35 GLSLNormalBevelFP() { 43 GLSLNormalBevelFP() {
36 fPrevWidth = SkFloatToScalar(0.0f); 44 fPrevWidth = SkFloatToScalar(0.0f);
37 fPrevHeight = SkFloatToScalar(0.0f); 45 fPrevHeight = SkFloatToScalar(0.0f);
38 } 46 }
39 47
40 void onEmitCode(EmitArgs& args) override { 48 void onEmitCode(EmitArgs& args) override {
41 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 49 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
50 const NormalBevelFP& fp = args.fFp.cast<NormalBevelFP>();
42 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 51 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
43 52
44 const char* widthUniName = nullptr; 53 const char* widthUniName = nullptr;
45 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloa t_GrSLType, 54 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloa t_GrSLType,
46 kDefault_GrSLPrecision, "Width", &widthUniName); 55 kDefault_GrSLPrecision, "Width", &widthUniName);
47 56
48 const char* heightUniName = nullptr; 57 const char* heightUniName = nullptr;
49 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFlo at_GrSLType, 58 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFlo at_GrSLType,
50 kDefault_GrSLPrecision, "Height", &heightUniName); 59 kDefault_GrSLPrecision, "Height", &heightUniName);
51 60
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.
52 fragBuilder->codeAppendf("%s = vec4(0.0, 0.0, 1.0, 0.0);", args.fOut putColor); 61 fragBuilder->codeAppend( "vec3 normal;");
62 fragBuilder->codeAppendf("if (length(%s) >= %s) {",
63 fragBuilder->distanceVectorName(), widthUni Name);
64 fragBuilder->codeAppend( " normal = vec3(0.0, 0.0, 1.0);");
65 fragBuilder->codeAppend( "} else {");
66 this->emitMath(fragBuilder, fp.fType, widthUniName, heightUniName);
67 fragBuilder->codeAppend( "}");
68 fragBuilder->codeAppendf("%s = vec4(normal, 0.0);", args.fOutputColo r);
53 } 69 }
54 70
55 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 71 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
56 GrProcessorKeyBuilder* b) { 72 GrProcessorKeyBuilder* b) {
57 const NormalBevelFP& fp = proc.cast<NormalBevelFP>(); 73 const NormalBevelFP& fp = proc.cast<NormalBevelFP>();
58 b->add32(static_cast<int>(fp.fType)); 74 b->add32(static_cast<int>(fp.fType));
59 } 75 }
60 76
61 protected: 77 protected:
62 void setNormalData(const GrGLSLProgramDataManager& pdman, 78 void setNormalData(const GrGLSLProgramDataManager& pdman,
63 const GrProcessor& proc) override { 79 const GrProcessor& proc) override {
64 const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>(); 80 const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>();
65 81
66 if (fPrevWidth != normalBevelFP.fWidth) { 82 if (fPrevWidth != normalBevelFP.fWidth) {
67 pdman.set1f(fWidthUni, normalBevelFP.fWidth); 83 pdman.set1f(fWidthUni, normalBevelFP.fWidth);
68 fPrevWidth = normalBevelFP.fWidth; 84 fPrevWidth = normalBevelFP.fWidth;
69 } 85 }
70 if (fPrevHeight != normalBevelFP.fHeight) { 86 if (fPrevHeight != normalBevelFP.fHeight) {
71 pdman.set1f(fHeightUni, normalBevelFP.fHeight); 87 pdman.set1f(fHeightUni, normalBevelFP.fHeight);
72 fPrevHeight = normalBevelFP.fHeight; 88 fPrevHeight = normalBevelFP.fHeight;
73 } 89 }
74 } 90 }
75 91
92 void emitMath(GrGLSLFPFragmentBuilder* fb, SkNormalSource::BevelType typ e,
93 const char* width, const char* height) {
94 const char* distanceVector = fb->distanceVectorName();
95
96 // Setting t to the distance from the end of the bevel as opposed to the beginning if
97 // the bevel is rounded out.
98 if ( type == SkNormalSource::BevelType::kRoundedIn ) {
99 fb->codeAppendf(" float t = %s - length(%s);", width, distanc eVector);
100 } else if (type == SkNormalSource::BevelType::kRoundedOut) {
101 fb->codeAppendf(" float t = length(%s);", distanceVector);
102 }
103
104 switch (type) {
105 case SkNormalSource::BevelType::kLinear:
106 fb->codeAppendf(" normal = normalize(%s*vec3(%s, 0.0) "
107 "+ vec3(0.0, 0.0, %s) );",
108 height, distanceVector, width);
109 break;
robertphillips 2016/08/03 16:33:15 Add a "// fall through" comment
dvonbeck 2016/08/03 21:04:20 Done.
110 case SkNormalSource::BevelType::kRoundedOut:
111 case SkNormalSource::BevelType::kRoundedIn:
112 // calculating the slope of the normal with respect to the d istance vector by
113 // setting it equal to the negative reciprocal of the deriva tive 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.
114 // cure
115 fb->codeAppendf("float slope = %s * sqrt(t) / (%s * (sqrt(%s ) - sqrt(t)));",
116 width, height, width);
117 // calculating a value so that when appended to the distance vector and
118 // normalized, it would result in a normal with the correct slope
119 fb->codeAppend("float z_prenorm = slope * t;");
120 // Multiplying with the height's sign to orient the vector i nwards for bevels of
121 // negative height
robertphillips 2016/08/03 16:33:15 Is sign() verboten?
dvonbeck 2016/08/03 21:04:20 No longer necessary.
122 fb->codeAppendf("normal = normalize(vec3(%s, z_prenorm)) * n ormalize(%s);",
123 distanceVector, height);
124 break;
125 default:
126 SkDEBUGFAIL("Invalid bevel type passed to emitMath");
127 }
128 }
129
76 private: 130 private:
77 SkScalar fPrevWidth; 131 SkScalar fPrevWidth;
78 GrGLSLProgramDataManager::UniformHandle fWidthUni; 132 GrGLSLProgramDataManager::UniformHandle fWidthUni;
79 133
80 SkScalar fPrevHeight; 134 SkScalar fPrevHeight;
81 GrGLSLProgramDataManager::UniformHandle fHeightUni; 135 GrGLSLProgramDataManager::UniformHandle fHeightUni;
82 }; 136 };
83 137
84 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 138 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
85 GLSLNormalBevelFP::GenKey(*this, caps, b); 139 GLSLNormalBevelFP::GenKey(*this, caps, b);
(...skipping 14 matching lines...) Expand all
100 fWidth == normalBevelFP.fWidth && 154 fWidth == normalBevelFP.fWidth &&
101 fHeight == normalBevelFP.fHeight; 155 fHeight == normalBevelFP.fHeight;
102 } 156 }
103 157
104 SkNormalSource::BevelType fType; 158 SkNormalSource::BevelType fType;
105 SkScalar fWidth; 159 SkScalar fWidth;
106 SkScalar fHeight; 160 SkScalar fHeight;
107 }; 161 };
108 162
109 sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor( 163 sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor(
110 const SkShader::AsFPArgs&) const { 164 const SkShader::AsFPArgs& args) const {
111 165
112 return sk_make_sp<NormalBevelFP>(fType, fWidth, fHeight); 166 SkScalar maxScale = args.fViewMatrix->getMaxScale();
167
168 // Providing device-space width and height
169 return sk_make_sp<NormalBevelFP>(fType, maxScale * fWidth, maxScale * fHeigh t);
113 } 170 }
114 171
115 #endif // SK_SUPPORT_GPU 172 #endif // SK_SUPPORT_GPU
116 173
117 //////////////////////////////////////////////////////////////////////////// 174 ////////////////////////////////////////////////////////////////////////////
118 175
119 SkNormalBevelSourceImpl::Provider::Provider() {} 176 SkNormalBevelSourceImpl::Provider::Provider() {}
120 177
121 SkNormalBevelSourceImpl::Provider::~Provider() {} 178 SkNormalBevelSourceImpl::Provider::~Provider() {}
122 179
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 sk_sp<SkNormalSource> SkNormalSource::MakeBevel(BevelType type, SkScalar width, SkScalar height) { 217 sk_sp<SkNormalSource> SkNormalSource::MakeBevel(BevelType type, SkScalar width, SkScalar height) {
161 /* TODO make sure this checks are tolerant enough to account for loss of con version when GPUs 218 /* TODO make sure this checks are tolerant enough to account for loss of con version when GPUs
162 use 16-bit float types. We don't want to assume stuff is non-zero on the GPU and be wrong.*/ 219 use 16-bit float types. We don't want to assume stuff is non-zero on the GPU and be wrong.*/
163 SkASSERT(width > 0.0f && !SkScalarNearlyZero(width)); 220 SkASSERT(width > 0.0f && !SkScalarNearlyZero(width));
164 if (SkScalarNearlyZero(height)) { 221 if (SkScalarNearlyZero(height)) {
165 return SkNormalSource::MakeFlat(); 222 return SkNormalSource::MakeFlat();
166 } 223 }
167 224
168 return sk_make_sp<SkNormalBevelSourceImpl>(type, width, height); 225 return sk_make_sp<SkNormalBevelSourceImpl>(type, width, height);
169 } 226 }
OLDNEW
« 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