@@ -45,7 +45,8 @@ class CircularRRectEffect : public GrFragmentProcessor {
4545
4646 // The flags are used to indicate which corners are circluar (unflagged corners are assumed to
4747 // be square).
48- static std::unique_ptr<GrFragmentProcessor> Make (GrClipEdgeType,
48+ static std::unique_ptr<GrFragmentProcessor> Make (std::unique_ptr<GrFragmentProcessor> inputFP,
49+ GrClipEdgeType,
4950 uint32_t circularCornerFlags, const SkRRect&);
5051
5152 ~CircularRRectEffect () override {}
@@ -60,45 +61,65 @@ class CircularRRectEffect : public GrFragmentProcessor {
6061
6162 GrClipEdgeType getEdgeType () const { return fEdgeType ; }
6263
64+ int getInputFPIndex () const { return fInputFPIndex ; }
65+
6366private:
64- CircularRRectEffect (GrClipEdgeType, uint32_t circularCornerFlags, const SkRRect&);
67+ CircularRRectEffect (std::unique_ptr<GrFragmentProcessor> inputFP,
68+ GrClipEdgeType, uint32_t circularCornerFlags, const SkRRect&);
6569
6670 GrGLSLFragmentProcessor* onCreateGLSLInstance () const override ;
6771
6872 void onGetGLSLProcessorKey (const GrShaderCaps&, GrProcessorKeyBuilder*) const override ;
6973
7074 bool onIsEqual (const GrFragmentProcessor& other) const override ;
7175
72- SkRRect fRRect ;
76+ SkRRect fRRect ;
7377 GrClipEdgeType fEdgeType ;
74- uint32_t fCircularCornerFlags ;
78+ uint32_t fCircularCornerFlags ;
79+ int fInputFPIndex ;
7580
7681 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
7782
7883 typedef GrFragmentProcessor INHERITED;
7984};
8085
81- std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::Make (GrClipEdgeType edgeType,
82- uint32_t circularCornerFlags ,
83- const SkRRect& rrect) {
86+ std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::Make (
87+ std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType ,
88+ uint32_t circularCornerFlags, const SkRRect& rrect) {
8489 if (GrClipEdgeType::kFillAA != edgeType && GrClipEdgeType::kInverseFillAA != edgeType) {
8590 return nullptr ;
8691 }
8792 return std::unique_ptr<GrFragmentProcessor>(
88- new CircularRRectEffect (edgeType, circularCornerFlags, rrect));
93+ new CircularRRectEffect (std::move (inputFP), edgeType, circularCornerFlags, rrect));
8994}
9095
91- CircularRRectEffect::CircularRRectEffect (GrClipEdgeType edgeType, uint32_t circularCornerFlags,
96+ CircularRRectEffect::CircularRRectEffect (std::unique_ptr<GrFragmentProcessor> inputFP,
97+ GrClipEdgeType edgeType, uint32_t circularCornerFlags,
9298 const SkRRect& rrect)
93- : INHERITED(kCircularRRectEffect_ClassID , kCompatibleWithCoverageAsAlpha_OptimizationFlag )
99+ : INHERITED(
100+ kCircularRRectEffect_ClassID ,
101+ (inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
102+ kCompatibleWithCoverageAsAlpha_OptimizationFlag)
94103 , fRRect(rrect)
95104 , fEdgeType(edgeType)
96105 , fCircularCornerFlags(circularCornerFlags) {
106+ fInputFPIndex = inputFP
107+ ? this ->registerChildProcessor (std::move (inputFP))
108+ : -1 ;
97109}
98110
99111std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::clone () const {
100- return std::unique_ptr<GrFragmentProcessor>(
101- new CircularRRectEffect (fEdgeType , fCircularCornerFlags , fRRect ));
112+ std::unique_ptr<GrFragmentProcessor> inputFPClone;
113+ if (fInputFPIndex >= 0 ) {
114+ const GrFragmentProcessor& inputFP = this ->childProcessor (fInputFPIndex );
115+ inputFPClone = inputFP.clone ();
116+ if (inputFP.isSampledWithExplicitCoords ()) {
117+ inputFPClone->setSampledWithExplicitCoords ();
118+ }
119+ }
120+
121+ return std::unique_ptr<GrFragmentProcessor>(new CircularRRectEffect (
122+ std::move (inputFPClone), fEdgeType , fCircularCornerFlags , fRRect ));
102123}
103124
104125bool CircularRRectEffect::onIsEqual (const GrFragmentProcessor& other) const {
@@ -191,85 +212,85 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
191212 // alphas together.
192213 switch (crre.getCircularCornerFlags ()) {
193214 case CircularRRectEffect::kAll_CornerFlags :
194- fragBuilder->codeAppendf (" float2 dxy0 = %s.xy - sk_FragCoord.xy;" , rectName);
195- fragBuilder->codeAppendf (" float2 dxy1 = sk_FragCoord.xy - %s.zw ;" , rectName);
215+ fragBuilder->codeAppendf (" float2 dxy0 = %s.LT - sk_FragCoord.xy;" , rectName);
216+ fragBuilder->codeAppendf (" float2 dxy1 = sk_FragCoord.xy - %s.RB ;" , rectName);
196217 fragBuilder->codeAppend (" float2 dxy = max(max(dxy0, dxy1), 0.0);" );
197218 fragBuilder->codeAppendf (" half alpha = half(%s);" , clampedCircleDistance.c_str ());
198219 break ;
199220 case CircularRRectEffect::kTopLeft_CornerFlag :
200- fragBuilder->codeAppendf (" float2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);" ,
221+ fragBuilder->codeAppendf (" float2 dxy = max(%s.LT - sk_FragCoord.xy, 0.0);" ,
201222 rectName);
202- fragBuilder->codeAppendf (" half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));" ,
223+ fragBuilder->codeAppendf (" half rightAlpha = half(saturate(%s.R - sk_FragCoord.x));" ,
203224 rectName);
204- fragBuilder->codeAppendf (" half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));" ,
225+ fragBuilder->codeAppendf (" half bottomAlpha = half(saturate(%s.B - sk_FragCoord.y));" ,
205226 rectName);
206227 fragBuilder->codeAppendf (" half alpha = bottomAlpha * rightAlpha * half(%s);" ,
207228 clampedCircleDistance.c_str ());
208229 break ;
209230 case CircularRRectEffect::kTopRight_CornerFlag :
210- fragBuilder->codeAppendf (" float2 dxy = max(float2(sk_FragCoord.x - %s.z , "
211- " %s.y - sk_FragCoord.y), 0.0);" ,
231+ fragBuilder->codeAppendf (" float2 dxy = max(float2(sk_FragCoord.x - %s.R , "
232+ " %s.T - sk_FragCoord.y), 0.0);" ,
212233 rectName, rectName);
213- fragBuilder->codeAppendf (" half leftAlpha = half(saturate(sk_FragCoord.x - %s.x ));" ,
234+ fragBuilder->codeAppendf (" half leftAlpha = half(saturate(sk_FragCoord.x - %s.L ));" ,
214235 rectName);
215- fragBuilder->codeAppendf (" half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));" ,
236+ fragBuilder->codeAppendf (" half bottomAlpha = half(saturate(%s.B - sk_FragCoord.y));" ,
216237 rectName);
217238 fragBuilder->codeAppendf (" half alpha = bottomAlpha * leftAlpha * half(%s);" ,
218239 clampedCircleDistance.c_str ());
219240 break ;
220241 case CircularRRectEffect::kBottomRight_CornerFlag :
221- fragBuilder->codeAppendf (" float2 dxy = max(sk_FragCoord.xy - %s.zw , 0.0);" ,
242+ fragBuilder->codeAppendf (" float2 dxy = max(sk_FragCoord.xy - %s.RB , 0.0);" ,
222243 rectName);
223- fragBuilder->codeAppendf (" half leftAlpha = half(saturate(sk_FragCoord.x - %s.x ));" ,
244+ fragBuilder->codeAppendf (" half leftAlpha = half(saturate(sk_FragCoord.x - %s.L ));" ,
224245 rectName);
225- fragBuilder->codeAppendf (" half topAlpha = half(saturate(sk_FragCoord.y - %s.y ));" ,
246+ fragBuilder->codeAppendf (" half topAlpha = half(saturate(sk_FragCoord.y - %s.T ));" ,
226247 rectName);
227248 fragBuilder->codeAppendf (" half alpha = topAlpha * leftAlpha * half(%s);" ,
228249 clampedCircleDistance.c_str ());
229250 break ;
230251 case CircularRRectEffect::kBottomLeft_CornerFlag :
231- fragBuilder->codeAppendf (" float2 dxy = max(float2(%s.x - sk_FragCoord.x, "
232- " sk_FragCoord.y - %s.w ), 0.0);" ,
252+ fragBuilder->codeAppendf (" float2 dxy = max(float2(%s.L - sk_FragCoord.x, "
253+ " sk_FragCoord.y - %s.B ), 0.0);" ,
233254 rectName, rectName);
234- fragBuilder->codeAppendf (" half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));" ,
255+ fragBuilder->codeAppendf (" half rightAlpha = half(saturate(%s.R - sk_FragCoord.x));" ,
235256 rectName);
236- fragBuilder->codeAppendf (" half topAlpha = half(saturate(sk_FragCoord.y - %s.y ));" ,
257+ fragBuilder->codeAppendf (" half topAlpha = half(saturate(sk_FragCoord.y - %s.T ));" ,
237258 rectName);
238259 fragBuilder->codeAppendf (" half alpha = topAlpha * rightAlpha * half(%s);" ,
239260 clampedCircleDistance.c_str ());
240261 break ;
241262 case CircularRRectEffect::kLeft_CornerFlags :
242- fragBuilder->codeAppendf (" float2 dxy0 = %s.xy - sk_FragCoord.xy;" , rectName);
243- fragBuilder->codeAppendf (" float dy1 = sk_FragCoord.y - %s.w ;" , rectName);
263+ fragBuilder->codeAppendf (" float2 dxy0 = %s.LT - sk_FragCoord.xy;" , rectName);
264+ fragBuilder->codeAppendf (" float dy1 = sk_FragCoord.y - %s.B ;" , rectName);
244265 fragBuilder->codeAppend (" float2 dxy = max(float2(dxy0.x, max(dxy0.y, dy1)), 0.0);" );
245- fragBuilder->codeAppendf (" half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));" ,
266+ fragBuilder->codeAppendf (" half rightAlpha = half(saturate(%s.R - sk_FragCoord.x));" ,
246267 rectName);
247268 fragBuilder->codeAppendf (" half alpha = rightAlpha * half(%s);" ,
248269 clampedCircleDistance.c_str ());
249270 break ;
250271 case CircularRRectEffect::kTop_CornerFlags :
251- fragBuilder->codeAppendf (" float2 dxy0 = %s.xy - sk_FragCoord.xy;" , rectName);
252- fragBuilder->codeAppendf (" float dx1 = sk_FragCoord.x - %s.z ;" , rectName);
272+ fragBuilder->codeAppendf (" float2 dxy0 = %s.LT - sk_FragCoord.xy;" , rectName);
273+ fragBuilder->codeAppendf (" float dx1 = sk_FragCoord.x - %s.R ;" , rectName);
253274 fragBuilder->codeAppend (" float2 dxy = max(float2(max(dxy0.x, dx1), dxy0.y), 0.0);" );
254- fragBuilder->codeAppendf (" half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));" ,
275+ fragBuilder->codeAppendf (" half bottomAlpha = half(saturate(%s.B - sk_FragCoord.y));" ,
255276 rectName);
256277 fragBuilder->codeAppendf (" half alpha = bottomAlpha * half(%s);" ,
257278 clampedCircleDistance.c_str ());
258279 break ;
259280 case CircularRRectEffect::kRight_CornerFlags :
260- fragBuilder->codeAppendf (" float dy0 = %s.y - sk_FragCoord.y;" , rectName);
261- fragBuilder->codeAppendf (" float2 dxy1 = sk_FragCoord.xy - %s.zw ;" , rectName);
281+ fragBuilder->codeAppendf (" float dy0 = %s.T - sk_FragCoord.y;" , rectName);
282+ fragBuilder->codeAppendf (" float2 dxy1 = sk_FragCoord.xy - %s.RB ;" , rectName);
262283 fragBuilder->codeAppend (" float2 dxy = max(float2(dxy1.x, max(dy0, dxy1.y)), 0.0);" );
263- fragBuilder->codeAppendf (" half leftAlpha = half(saturate(sk_FragCoord.x - %s.x ));" ,
284+ fragBuilder->codeAppendf (" half leftAlpha = half(saturate(sk_FragCoord.x - %s.L ));" ,
264285 rectName);
265286 fragBuilder->codeAppendf (" half alpha = leftAlpha * half(%s);" ,
266287 clampedCircleDistance.c_str ());
267288 break ;
268289 case CircularRRectEffect::kBottom_CornerFlags :
269- fragBuilder->codeAppendf (" float dx0 = %s.x - sk_FragCoord.x;" , rectName);
270- fragBuilder->codeAppendf (" float2 dxy1 = sk_FragCoord.xy - %s.zw ;" , rectName);
290+ fragBuilder->codeAppendf (" float dx0 = %s.L - sk_FragCoord.x;" , rectName);
291+ fragBuilder->codeAppendf (" float2 dxy1 = sk_FragCoord.xy - %s.RB ;" , rectName);
271292 fragBuilder->codeAppend (" float2 dxy = max(float2(max(dx0, dxy1.x), dxy1.y), 0.0);" );
272- fragBuilder->codeAppendf (" half topAlpha = half(saturate(sk_FragCoord.y - %s.y ));" ,
293+ fragBuilder->codeAppendf (" half topAlpha = half(saturate(sk_FragCoord.y - %s.T ));" ,
273294 rectName);
274295 fragBuilder->codeAppendf (" half alpha = topAlpha * half(%s);" ,
275296 clampedCircleDistance.c_str ());
@@ -280,7 +301,11 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
280301 fragBuilder->codeAppend (" alpha = 1.0 - alpha;" );
281302 }
282303
283- fragBuilder->codeAppendf (" %s = %s * alpha;" , args.fOutputColor , args.fInputColor );
304+ SkString inputSample = (crre.getInputFPIndex () >= 0 )
305+ ? this ->invokeChild (crre.getInputFPIndex (), args.fInputColor , args)
306+ : SkString (args.fInputColor );
307+
308+ fragBuilder->codeAppendf (" %s = %s * alpha;" , args.fOutputColor , inputSample.c_str ());
284309}
285310
286311void GLCircularRRectEffect::GenKey (const GrProcessor& processor, const GrShaderCaps&,
@@ -690,8 +715,8 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
690715 return GrConvexPolyEffect::Make (edgeType, rrect.getBounds ());
691716 }
692717 if (SkRRectPriv::GetSimpleRadii (rrect).fX == SkRRectPriv::GetSimpleRadii (rrect).fY ) {
693- return CircularRRectEffect::Make (edgeType, CircularRRectEffect:: kAll_CornerFlags ,
694- rrect);
718+ return CircularRRectEffect::Make (/* inputFP= */ nullptr , edgeType ,
719+ CircularRRectEffect:: kAll_CornerFlags , rrect);
695720 } else {
696721 return EllipticalRRectEffect::Make (edgeType, rrect);
697722 }
@@ -749,7 +774,7 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
749774 if (squashedRadii) {
750775 rr.writable ()->setRectRadii (rrect.getBounds (), radii);
751776 }
752- return CircularRRectEffect::Make (edgeType, cornerFlags, *rr);
777+ return CircularRRectEffect::Make (/* inputFP= */ nullptr , edgeType, cornerFlags, *rr);
753778 }
754779 case CircularRRectEffect::kNone_CornerFlags :
755780 return GrConvexPolyEffect::Make (edgeType, rrect.getBounds ());
0 commit comments