Skip to content

Commit ea74a6c

Browse files
author
Shan Huang
committed
Split blur into low sample and high sample shaders.
Bug: 353826438 Test: atest BlurTests Flag: com.android.graphics.surfaceflinger.flags.window_blur_kawase2 Change-Id: I5d1a4b34dc6419bd355251153042c0e8d76f8bde
1 parent 0189163 commit ea74a6c

2 files changed

Lines changed: 54 additions & 19 deletions

File tree

libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,36 @@ namespace renderengine {
3939
namespace skia {
4040

4141
KawaseBlurDualFilter::KawaseBlurDualFilter() : BlurFilter() {
42-
// A shader to sample each vertex of a unit regular heptagon
43-
// plus the original fragment coordinate.
44-
SkString blurString(R"(
42+
// A shader to sample each vertex of a square, plus the original fragment coordinate,
43+
// using a total of 5 samples.
44+
SkString lowSampleBlurString(R"(
4545
uniform shader child;
4646
uniform float in_blurOffset;
4747
uniform float in_crossFade;
48+
uniform float in_weightedCrossFade;
49+
50+
const float2 STEP_0 = float2( 0.707106781, 0.707106781);
51+
const float2 STEP_1 = float2( 0.707106781, -0.707106781);
52+
const float2 STEP_2 = float2(-0.707106781, -0.707106781);
53+
const float2 STEP_3 = float2(-0.707106781, 0.707106781);
54+
55+
half4 main(float2 xy) {
56+
half3 c = child.eval(xy).rgb;
57+
58+
c += child.eval(xy + STEP_0 * in_blurOffset).rgb;
59+
c += child.eval(xy + STEP_1 * in_blurOffset).rgb;
60+
c += child.eval(xy + STEP_2 * in_blurOffset).rgb;
61+
c += child.eval(xy + STEP_3 * in_blurOffset).rgb;
62+
63+
return half4(c * in_weightedCrossFade, in_crossFade);
64+
}
65+
)");
66+
67+
// A shader to sample each vertex of a unit regular heptagon, plus the original fragment
68+
// coordinate, using a total of 8 samples.
69+
SkString highSampleBlurString(R"(
70+
uniform shader child;
71+
uniform float in_blurOffset;
4872
4973
const float2 STEP_0 = float2( 1.0, 0.0);
5074
const float2 STEP_1 = float2( 0.623489802, 0.781831482);
@@ -65,39 +89,46 @@ KawaseBlurDualFilter::KawaseBlurDualFilter() : BlurFilter() {
6589
c += child.eval(xy + STEP_5 * in_blurOffset).rgb;
6690
c += child.eval(xy + STEP_6 * in_blurOffset).rgb;
6791
68-
return half4(c * 0.125 * in_crossFade, in_crossFade);
92+
return half4(c * 0.125, 1.0);
6993
}
7094
)");
7195

72-
auto [blurEffect, error] = SkRuntimeEffect::MakeForShader(blurString);
73-
LOG_ALWAYS_FATAL_IF(!blurEffect, "RuntimeShader error: %s", error.c_str());
74-
mBlurEffect = std::move(blurEffect);
96+
auto [lowSampleBlurEffect, error] = SkRuntimeEffect::MakeForShader(lowSampleBlurString);
97+
auto [highSampleBlurEffect, error2] = SkRuntimeEffect::MakeForShader(highSampleBlurString);
98+
LOG_ALWAYS_FATAL_IF(!lowSampleBlurEffect, "RuntimeShader error: %s", error.c_str());
99+
LOG_ALWAYS_FATAL_IF(!highSampleBlurEffect, "RuntimeShader error: %s", error2.c_str());
100+
mLowSampleBlurEffect = std::move(lowSampleBlurEffect);
101+
mHighSampleBlurEffect = std::move(highSampleBlurEffect);
75102
}
76103

77104
void KawaseBlurDualFilter::blurInto(const sk_sp<SkSurface>& drawSurface,
78105
const sk_sp<SkImage>& readImage, const float radius,
79-
const float alpha) const {
106+
const float alpha,
107+
const sk_sp<SkRuntimeEffect>& blurEffect) const {
80108
const float scale = static_cast<float>(drawSurface->width()) / readImage->width();
81109
SkMatrix blurMatrix = SkMatrix::Scale(scale, scale);
82110
blurInto(drawSurface,
83111
readImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
84112
SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone),
85113
blurMatrix),
86-
readImage->width() / static_cast<float>(drawSurface->width()), radius, alpha);
114+
radius, alpha, blurEffect);
87115
}
88116

89117
void KawaseBlurDualFilter::blurInto(const sk_sp<SkSurface>& drawSurface, sk_sp<SkShader> input,
90-
const float inverseScale, const float radius,
91-
const float alpha) const {
118+
const float radius, const float alpha,
119+
const sk_sp<SkRuntimeEffect>& blurEffect) const {
92120
SkPaint paint;
93121
if (radius == 0) {
94122
paint.setShader(std::move(input));
95123
paint.setAlphaf(alpha);
96124
} else {
97-
SkRuntimeShaderBuilder blurBuilder(mBlurEffect);
125+
SkRuntimeShaderBuilder blurBuilder(blurEffect);
98126
blurBuilder.child("child") = std::move(input);
127+
if (blurEffect == mLowSampleBlurEffect) {
128+
blurBuilder.uniform("in_crossFade") = alpha;
129+
blurBuilder.uniform("in_weightedCrossFade") = alpha * 0.2f;
130+
}
99131
blurBuilder.uniform("in_blurOffset") = radius;
100-
blurBuilder.uniform("in_crossFade") = alpha;
101132
paint.setShader(blurBuilder.makeShader(nullptr));
102133
}
103134
paint.setBlendMode(alpha == 1.0f ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
@@ -163,16 +194,19 @@ sk_sp<SkImage> KawaseBlurDualFilter::generate(SkiaGpuContext* context, const uin
163194
input->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
164195
SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone),
165196
blurMatrix);
166-
blurInto(surfaces[0], std::move(sourceShader), kInputScale, kWeights[0] * step, 1.0f);
197+
blurInto(surfaces[0], std::move(sourceShader), kWeights[0] * step, 1.0f,
198+
mLowSampleBlurEffect);
167199
}
168200
// Next the remaining downscale blur passes.
169201
for (int i = 0; i < filterPasses; i++) {
170-
blurInto(surfaces[i + 1], surfaces[i]->makeTemporaryImage(), kWeights[1 + i] * step, 1.0f);
202+
// Blur with the higher sample effect into the smaller buffers, for better visual quality.
203+
blurInto(surfaces[i + 1], surfaces[i]->makeTemporaryImage(), kWeights[1 + i] * step, 1.0f,
204+
i == 0 ? mLowSampleBlurEffect : mHighSampleBlurEffect);
171205
}
172206
// Finally blur+upscale back to our original size.
173207
for (int i = filterPasses - 1; i >= 0; i--) {
174208
blurInto(surfaces[i], surfaces[i + 1]->makeTemporaryImage(), kWeights[4 - i] * step,
175-
std::min(1.0f, filterDepth - i));
209+
std::min(1.0f, filterDepth - i), mLowSampleBlurEffect);
176210
}
177211
return surfaces[0]->makeTemporaryImage();
178212
}

libs/renderengine/skia/filters/KawaseBlurDualFilter.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ class KawaseBlurDualFilter : public BlurFilter {
4141
const sk_sp<SkImage> blurInput, const SkRect& blurRect) const override;
4242

4343
private:
44-
sk_sp<SkRuntimeEffect> mBlurEffect;
44+
sk_sp<SkRuntimeEffect> mLowSampleBlurEffect;
45+
sk_sp<SkRuntimeEffect> mHighSampleBlurEffect;
4546

4647
void blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkImage>& readImage,
47-
const float radius, const float alpha) const;
48+
const float radius, const float alpha, const sk_sp<SkRuntimeEffect>&) const;
4849

4950
void blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkShader> input,
50-
const float inverseScale, const float radius, const float alpha) const;
51+
const float radius, const float alpha, const sk_sp<SkRuntimeEffect>&) const;
5152
};
5253

5354
} // namespace skia

0 commit comments

Comments
 (0)