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

Side by Side Diff: src/gpu/effects/GrDashingEffect.cpp

Issue 274673004: Add Dashing gpu effect for simple dashed lines (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Updates Created 6 years, 7 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "GrDashingEffect.h"
9
10 #include "gl/GrGLEffect.h"
11 #include "gl/GrGLSL.h"
12 #include "GrTBackendEffectFactory.h"
13
14 #include "SkPath.h"
15
16 //////////////////////////////////////////////////////////////////////////////
17
18 class GrGLDashingEffect : public GrGLEffect {
19 public:
20 GrGLDashingEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
21
22 virtual void emitCode(GrGLShaderBuilder* builder,
23 const GrDrawEffect& drawEffect,
24 EffectKey key,
25 const char* outputColor,
26 const char* inputColor,
27 const TransformedCoordsArray&,
28 const TextureSamplerArray&) SK_OVERRIDE;
29
30 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
31
32 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
33
34 private:
35 GrGLUniformManager::UniformHandle fRectUniform;
36 GrGLUniformManager::UniformHandle fIntervalUniform;
37 SkRect fPrevRect;
38 SkScalar fPrevIntervalLength;
39 typedef GrGLEffect INHERITED;
40 };
41
42 GrGLDashingEffect::GrGLDashingEffect(const GrBackendEffectFactory& factory,
43 const GrDrawEffect& drawEffect)
44 : INHERITED (factory) {
45 fPrevRect.fLeft = SK_ScalarNaN;
46 fPrevIntervalLength = SK_ScalarMax;
47
48 }
49
50 void GrGLDashingEffect::emitCode(GrGLShaderBuilder* builder,
51 const GrDrawEffect& drawEffect,
52 EffectKey key,
53 const char* outputColor,
54 const char* inputColor,
55 const TransformedCoordsArray& coords,
56 const TextureSamplerArray& samplers) {
57 const GrDashingEffect& de = drawEffect.castEffect<GrDashingEffect>();
58 const char *rectName;
59 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5),
60 // respectively.
61 fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
62 kVec4f_GrSLType,
63 "rect",
64 &rectName);
65 const char *intervalName;
66 // The interval uniform's refers to the total length of the interval (on + o ff)
67 fIntervalUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili ty,
68 kFloat_GrSLType,
69 "interval",
70 &intervalName);
71 // transforms all points so that we can compare them to our test rect
72 builder->fsCodeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n ",
73 coords[0].c_str(), coords[0].c_str(), intervalName, i ntervalName);
74 builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", coords[0].c_str());
75 if (GrEffectEdgeTypeIsAA(de.getEdgeType())) {
76 // The amount of coverage removed in x and y by the edges is computed as a pair of negative
77 // numbers, xSub and ySub.
78 builder->fsCodeAppend("\t\tfloat xSub, ySub;\n");
79 builder->fsCodeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n" , rectName);
80 builder->fsCodeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n ", rectName);
81 builder->fsCodeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n" , rectName);
82 builder->fsCodeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n ", rectName);
83 // Now compute coverage in x and y and multiply them to get the fraction of the pixel
84 // covered.
85 builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
86 } else {
87 // Assuming the bounding geometry is tight so no need to check y values
88 builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
89 builder->fsCodeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName);
90 builder->fsCodeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName);
91 }
92 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
93 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
94 }
95
96 void GrGLDashingEffect::setData(const GrGLUniformManager& uman, const GrDrawEffe ct& drawEffect) {
97 const GrDashingEffect& de = drawEffect.castEffect<GrDashingEffect>();
98 const SkRect& rect = de.getRect();
99 SkScalar intervalLength = de.getIntervalLength();
100 if (rect != fPrevRect || intervalLength != fPrevIntervalLength) {
101 uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
102 rect.fRight - 0.5f, rect.fBottom - 0.5f);
103 uman.set1f(fIntervalUniform, intervalLength);
104 fPrevRect = rect;
105 fPrevIntervalLength = intervalLength;
106 }
107 }
108
109 GrGLEffect::EffectKey GrGLDashingEffect::GenKey(const GrDrawEffect& drawEffect,
110 const GrGLCaps&) {
111 const GrDashingEffect& de = drawEffect.castEffect<GrDashingEffect>();
112 return de.getEdgeType();
113 }
114
115 //////////////////////////////////////////////////////////////////////////////
116
117 GrEffectRef* GrDashingEffect::Create(GrEffectEdgeType edgeType, const DashInfo& info,
118 const SkMatrix& matrix, SkScalar strokeWidt h) {
119 if (info.fCount != 2) {
120 return NULL;
121 }
122
123 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrDashingEffect,
124 (edgeType, info, matrix, s trokeWidth))));
125 }
126
127 GrDashingEffect::~GrDashingEffect() {}
128
129 void GrDashingEffect::getConstantColorComponents(GrColor* color, uint32_t* valid Flags) const {
130 *validFlags = 0;
131 }
132
133 const GrBackendEffectFactory& GrDashingEffect::getFactory() const {
134 return GrTBackendEffectFactory<GrDashingEffect>::getInstance();
135 }
136
137 GrDashingEffect::GrDashingEffect(GrEffectEdgeType edgeType, const DashInfo& info ,
138 const SkMatrix& matrix, SkScalar strokeWidth)
139 : fEdgeType(edgeType)
140 , fCoordTransform(kLocal_GrCoordSet, matrix) {
141 SkScalar onLen = info.fIntervals[0];
142 SkScalar offLen = info.fIntervals[1];
143 SkScalar halfOffLen = SkScalarHalf(offLen);
144 SkScalar halfStroke = SkScalarHalf(strokeWidth);
145 fIntervalLength = onLen + offLen;
146 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke);
147
148 addCoordTransform(&fCoordTransform);
149 }
150
151 bool GrDashingEffect::onIsEqual(const GrEffect& other) const {
152 const GrDashingEffect& de = CastEffect<GrDashingEffect>(other);
153 return (fEdgeType == de.fEdgeType &&
154 fCoordTransform == de.fCoordTransform &&
155 fRect == de.fRect &&
156 fIntervalLength == de.fIntervalLength);
157 }
158
159 GR_DEFINE_EFFECT_TEST(GrDashingEffect);
160
161 GrEffectRef* GrDashingEffect::TestCreate(SkRandom* random,
162 GrContext*,
163 const GrDrawTargetCaps& caps,
164 GrTexture*[]) {
165 GrEffectRef* effect;
166 SkMatrix m;
167 m.reset();
168 GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(random->nextULessT han(
169 kGrEffectEdgeTypeCnt));
170 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f);
171 DashInfo info;
172 info.fCount = 2;
173 SkAutoTArray<SkScalar> intervals(info.fCount);
174 info.fIntervals = intervals.get();
175 info.fIntervals[0] = random->nextRangeScalar(0, 10.f);
176 info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
177 info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fInterval s[1]);
178
179 effect = GrDashingEffect::Create(edgeType, info, m, strokeWidth);
180 return effect;
181 }
182
OLDNEW
« src/gpu/effects/GrDashingEffect.h ('K') | « src/gpu/effects/GrDashingEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698