1616#include " src/gpu/effects/GrXfermodeFragmentProcessor.h"
1717#include " src/image/SkImage_Base.h"
1818
19- static GrSurfaceProxyView blur (GrContext* ctx,
20- GrSurfaceProxyView src,
21- SkIRect dstB,
22- SkIRect srcB,
23- float sigmaX,
24- float sigmaY,
25- SkTileMode mode) {
26- auto resultRTC =
27- SkGpuBlurUtils::GaussianBlur (ctx, src, GrColorType::kRGBA_8888 , kPremul_SkAlphaType ,
28- nullptr , dstB, srcB, sigmaX, sigmaY, mode);
29- if (!resultRTC) {
30- return {};
31- }
32- return resultRTC->readSurfaceView ();
33- };
34-
35- static void run (GrContext* ctx, GrRenderTargetContext* rtc, bool subsetSrc, bool ref) {
36- auto srcII = SkImageInfo::Make (60 , 60 , kRGBA_8888_SkColorType , kPremul_SkAlphaType );
19+ DEF_SIMPLE_GPU_GM (gpu_blur_utils, ctx, rtc, canvas, 985 , 740 ) {
20+ auto srcII = SkImageInfo::Make (80 , 80 , kRGBA_8888_SkColorType , kPremul_SkAlphaType );
3721 auto surf = SkSurface::MakeRenderTarget (ctx, SkBudgeted::kYes , srcII);
3822 GrSurfaceProxyView src;
3923 if (surf) {
@@ -73,117 +57,57 @@ static void run(GrContext* ctx, GrRenderTargetContext* rtc, bool subsetSrc, bool
7357 if (!src) {
7458 return ;
7559 }
60+ auto blur = [&](SkIRect dstB, SkIRect srcB, SkTileMode mode) -> GrSurfaceProxyView {
61+ const SkScalar sigmaX = src.width () /10 .f ;
62+ const SkScalar sigmaY = src.height ()/10 .f ;
63+ auto resultRTC =
64+ SkGpuBlurUtils::GaussianBlur (ctx, src, GrColorType::kRGBA_8888 , kPremul_SkAlphaType ,
65+ nullptr , dstB, srcB, sigmaX, sigmaY, mode);
66+ if (!resultRTC) {
67+ return {};
68+ }
69+ return resultRTC->readSurfaceView ();
70+ };
7671
77- SkIRect srcRect = SkIRect::MakeSize (src.dimensions ());
78- if (subsetSrc) {
79- srcRect = SkIRect::MakeXYWH (2 .f *srcRect.width () /8 .f ,
80- 1 .f *srcRect.height ()/8 .f ,
81- 5 .f *srcRect.width () /8 .f ,
82- 6 .f *srcRect.height ()/8 .f );
83- }
84- int srcW = srcRect.width ();
85- int srcH = srcRect.height ();
86- // Each set of rects is drawn in one test area so they probably should not abut or overlap
87- // to visualize the blurs separately.
88- const std::vector<SkIRect> dstRectSets[] = {
89- {
90- srcRect.makeOutset (srcW/5 , srcH/5 )
91- },
92-
93- {
94- SkIRect::MakeXYWH (srcRect.x (), srcRect.y () + 3 *srcH/4 , srcW, srcH),
95- SkIRect::MakeXYWH (srcRect.x (), srcRect.y () - 3 *srcH/4 , srcW, srcH)
96- },
97-
98- {
99- srcRect.makeOffset ( 0 , srcH),
100- srcRect.makeOffset ( srcW, 0 ),
101- srcRect.makeOffset ( 0 , -srcH),
102- srcRect.makeOffset (-srcW, 0 ),
103- },
72+ SkVector trans = {};
73+ rtc->clear (SK_PMColor4fWHITE);
74+ const SkIRect dstRects[] = {
75+ SkIRect::MakeSize (src.dimensions ()).makeOutset (src.width ()/5 , src.height ()/5 ),
76+ SkIRect::MakeXYWH (0 , 3 *src.height ()/4 , src.width (), src.height ()),
77+ SkIRect::MakeXYWH (0 , src.height (), src.width (), src.height ())
78+ };
10479
105- {
106- SkIRect::MakeXYWH (-6 .f *srcW/8 .f , -7 .f *srcH/8 .f , 4 .f *srcW/8 .f , 20 .f *srcH/8 .f )
107- .makeOffset (srcRect.topLeft ()),
108- SkIRect::MakeXYWH (-1 .f *srcW/8 .f , -7 .f *srcH/8 .f , 16 .f *srcW/8 .f , 2 .f *srcH/8 .f )
109- .makeOffset (srcRect.topLeft ()),
110- SkIRect::MakeXYWH (10 .f *srcW/8 .f , -3 .f *srcH/8 .f , 4 .f *srcW/8 .f , 16 .f *srcH/8 .f )
111- .makeOffset (srcRect.topLeft ()),
112- SkIRect::MakeXYWH (-7 .f *srcW/8 .f , 14 .f *srcH/8 .f , 18 .f *srcW/8 .f , 1 .f *srcH/8 .f )
113- .makeOffset (srcRect.topLeft ()),
114- },
80+ const SkIRect srcRects[] = {
81+ SkIRect::MakeSize (src.dimensions ()),
11582 };
11683
11784 const auto & caps = *ctx->priv ().caps ();
118-
119- static constexpr SkScalar kPad = 10 ;
120- SkVector trans = {kPad , kPad };
121-
122- rtc->clear (SK_PMColor4fWHITE);
123-
124- SkIRect testArea = srcRect;
125- testArea.outset (testArea.width (), testArea.height ());
126- for (const auto & dstRectSet : dstRectSets) {
127- for (int t = 0 ; t < kSkTileModeCount ; ++t) {
128- auto mode = static_cast <SkTileMode>(t);
129- GrSamplerState sampler (SkTileModeToWrapMode (mode), GrSamplerState::Filter::kNearest );
130- SkMatrix m = SkMatrix::MakeTrans (trans.x () - testArea.x (), trans.y () - testArea.y ());
131- // Draw the src subset in the tile mode faded as a reference before drawing the blur
132- // on top.
133- {
134- auto fp = GrTextureEffect::MakeSubset (src, kPremul_SkAlphaType , SkMatrix::I (),
135- sampler, SkRect::Make (srcRect), caps);
136- GrPaint paint;
137- paint.addColorFragmentProcessor (std::move (fp));
138- static constexpr float kAlpha = 0 .2f ;
139- paint.setColor4f ({kAlpha , kAlpha , kAlpha , kAlpha });
140- rtc->drawRect (GrNoClip (), std::move (paint), GrAA::kNo , m, SkRect::Make (testArea));
141- }
142- // If we're in ref mode we will create a temp image that has the original image
143- // tiled into it and then do a clamp blur with adjusted params that should produce
144- // the same result as the original params.
145- std::unique_ptr<GrRenderTargetContext> refSrc;
146- SkIRect refRect;
147- if (ref) {
148- // Blow up testArea into a much larger rect so that our clamp blur will not
149- // reach anywhere near the edge of our temp surface.
150- refRect = testArea.makeOutset (testArea.width (), testArea.height ());
151- refSrc = GrRenderTargetContext::Make (ctx, GrColorType::kRGBA_8888 , nullptr ,
152- SkBackingFit::kApprox , refRect.size ());
153- refSrc->clear (SK_PMColor4fWHITE);
154- // Setup an effect to put the original src rect at the correct logical place
155- // in the temp where the temp's origin is at the top left of refRect.
156- SkMatrix tm = SkMatrix::MakeTrans (refRect.left (), refRect.top ());
157- auto fp = GrTextureEffect::MakeSubset (src, kPremul_SkAlphaType , tm, sampler,
158- SkRect::Make (srcRect), caps);
159- GrPaint paint;
160- paint.addColorFragmentProcessor (std::move (fp));
161- refSrc->drawRect (GrNoClip (), std::move (paint), GrAA::kNo , SkMatrix::I (),
162- SkRect::Make (refRect.size ()));
163- }
164- // Do a blur for each dstRect in the set over our testArea-sized background.
165- for (const auto & dstRect : dstRectSet) {
166- // Setup the normal blur args.
167- const SkScalar sigmaX = src.width () / 10 .f ;
168- const SkScalar sigmaY = src.height () / 10 .f ;
169- auto blurSrc = src;
170- auto blurMode = mode;
171- auto blurDstRect = dstRect;
172- auto blurSrcRect = srcRect;
173- if (ref) {
174- // Move the dst rect to be relative to our temp surface.
175- blurDstRect = dstRect.makeOffset (-refRect.topLeft ());
176- // Our new src is the entire temp containing the tiled original.
177- blurSrcRect = SkIRect::MakeSize (refRect.size ());
178- // This shouldn't really matter because we should have made a large enough
179- // temp that the edges don't come into play. But this puts us on a simpler
180- // path through SkGpuBlurUtils.
181- blurMode = SkTileMode::kClamp ;
182- blurSrc = refSrc->readSurfaceView ();
85+ static constexpr SkScalar kPad = 5 ;
86+
87+ for (const auto & srcRect : srcRects) {
88+ SkIRect testArea = SkIRect::MakeSize (srcRect.size ());
89+ testArea.outset (testArea.width (), testArea.height ());
90+ for (const auto & dstRect : dstRects) {
91+ for (int t = 0 ; t < kSkTileModeCount ; ++t) {
92+ auto mode = static_cast <SkTileMode>(t);
93+ GrSamplerState sampler (SkTileModeToWrapMode (mode),
94+ GrSamplerState::Filter::kNearest );
95+ SkMatrix m = SkMatrix::MakeTrans (trans.x () - testArea.x (),
96+ trans.y () - testArea.y ());
97+ // Draw the src subset in the tile mode faded as a reference before drawing the blur
98+ // on top
99+ {
100+ auto fp = GrTextureEffect::MakeSubset (src, kPremul_SkAlphaType , SkMatrix::I (),
101+ sampler, SkRect::Make (srcRect), caps);
102+ GrPaint paint;
103+ paint.addColorFragmentProcessor (std::move (fp));
104+ static constexpr float kAlpha = 0 .2f ;
105+ paint.setColor4f ({kAlpha , kAlpha , kAlpha , kAlpha });
106+ rtc->drawRect (GrNoClip (), std::move (paint), GrAA::kNo , m,
107+ SkRect::Make (testArea));
183108 }
184109 // Blur using the rect and draw on top.
185- if (auto blurView = blur (ctx, blurSrc, blurDstRect, blurSrcRect, sigmaX, sigmaY,
186- blurMode)) {
110+ if (auto blurView = blur (dstRect, srcRect, mode)) {
187111 auto fp = GrTextureEffect::Make (blurView, kPremul_SkAlphaType , SkMatrix::I (),
188112 sampler, caps);
189113 GrPaint paint;
@@ -196,6 +120,18 @@ static void run(GrContext* ctx, GrRenderTargetContext* rtc, bool subsetSrc, bool
196120 rtc->fillRectToRect (GrNoClip (), std::move (paint), GrAA::kNo , m,
197121 SkRect::Make (dstRect), SkRect::Make (blurView.dimensions ()));
198122 }
123+ // Show the rect that's being blurred.
124+ {
125+ GrPaint paint;
126+ static constexpr float kAlpha = 0 .3f ;
127+ paint.setColor4f ({0 , 0 , 0 , kAlpha });
128+ SkPaint stroke;
129+ stroke.setStyle (SkPaint::kStroke_Style );
130+ stroke.setStrokeWidth (1 .f );
131+ GrStyle style (stroke);
132+ auto srcR = SkRect::Make (srcRect).makeOutset (0 .5f , 0 .5f );
133+ rtc->drawRect (GrNoClip (), std::move (paint), GrAA::kNo , m, srcR, &style);
134+ }
199135 // Show the outline of the dst rect. Mostly for kDecal but also allows visual
200136 // confirmation that the resulting blur is the right size and in the right place.
201137 {
@@ -209,34 +145,10 @@ static void run(GrContext* ctx, GrRenderTargetContext* rtc, bool subsetSrc, bool
209145 auto dstR = SkRect::Make (dstRect).makeOutset (0 .5f , 0 .5f );
210146 rtc->drawRect (GrNoClip (), std::move (paint), GrAA::kNo , m, dstR, &style);
211147 }
148+ trans.fX += testArea.width () + kPad ;
212149 }
213- // Show the rect that's being blurred.
214- {
215- GrPaint paint;
216- static constexpr float kAlpha = 0 .3f ;
217- paint.setColor4f ({0 , 0 , 0 , kAlpha });
218- SkPaint stroke;
219- stroke.setStyle (SkPaint::kStroke_Style );
220- stroke.setStrokeWidth (1 .f );
221- GrStyle style (stroke);
222- auto srcR = SkRect::Make (srcRect).makeOutset (0 .5f , 0 .5f );
223- rtc->drawRect (GrNoClip (), std::move (paint), GrAA::kNo , m, srcR, &style);
224- }
225- trans.fX += testArea.width () + kPad ;
150+ trans.fX = 0 ;
151+ trans.fY += testArea.height () + kPad ;
226152 }
227- trans.fX = kPad ;
228- trans.fY += testArea.height () + kPad ;
229153 }
230154}
231-
232- DEF_SIMPLE_GPU_GM (gpu_blur_utils, ctx, rtc, canvas, 765 , 765 ) { run (ctx, rtc, false , false ); }
233-
234- DEF_SIMPLE_GPU_GM (gpu_blur_utils_ref, ctx, rtc, canvas, 765 , 765 ) { run (ctx, rtc, false , true ); }
235-
236- DEF_SIMPLE_GPU_GM (gpu_blur_utils_subset_rect, ctx, rtc, canvas, 765 , 765 ) {
237- run (ctx, rtc, true , false );
238- }
239-
240- DEF_SIMPLE_GPU_GM (gpu_blur_utils_subset_ref, ctx, rtc, canvas, 765 , 765 ) {
241- run (ctx, rtc, true , true );
242- }
0 commit comments