Merge "Clip blur to bounds of layer"
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 902348b..1f25fbf 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -512,7 +512,8 @@
// displays might have different scaling when compared to the physical screen.
canvas->clipRect(getSkRect(display.physicalDisplay));
- canvas->translate(display.physicalDisplay.left, display.physicalDisplay.top);
+ SkMatrix screenTransform;
+ screenTransform.setTranslate(display.physicalDisplay.left, display.physicalDisplay.top);
const auto clipWidth = display.clip.width();
const auto clipHeight = display.clip.height();
@@ -526,25 +527,28 @@
static_cast<SkScalar>(rotatedClipWidth);
const auto scaleY = static_cast<SkScalar>(display.physicalDisplay.height()) /
static_cast<SkScalar>(rotatedClipHeight);
- canvas->scale(scaleX, scaleY);
+ screenTransform.preScale(scaleX, scaleY);
// Canvas rotation is done by centering the clip window at the origin, rotating, translating
// back so that the top left corner of the clip is at (0, 0).
- canvas->translate(rotatedClipWidth / 2, rotatedClipHeight / 2);
- canvas->rotate(toDegrees(display.orientation));
- canvas->translate(-clipWidth / 2, -clipHeight / 2);
- canvas->translate(-display.clip.left, -display.clip.top);
+ screenTransform.preTranslate(rotatedClipWidth / 2, rotatedClipHeight / 2);
+ screenTransform.preRotate(toDegrees(display.orientation));
+ screenTransform.preTranslate(-clipWidth / 2, -clipHeight / 2);
+ screenTransform.preTranslate(-display.clip.left, -display.clip.top);
for (const auto& layer : layers) {
+ const SkMatrix drawTransform = getDrawTransform(layer, screenTransform);
+
SkPaint paint;
const auto& bounds = layer->geometry.boundaries;
const auto dest = getSkRect(bounds);
std::unordered_map<uint32_t, sk_sp<SkSurface>> cachedBlurs;
if (mBlurFilter) {
+ const auto layerRect = drawTransform.mapRect(dest);
if (layer->backgroundBlurRadius > 0) {
ATRACE_NAME("BackgroundBlur");
auto blurredSurface =
- mBlurFilter->draw(canvas, surface, layer->backgroundBlurRadius);
+ mBlurFilter->draw(canvas, surface, layer->backgroundBlurRadius, layerRect);
cachedBlurs[layer->backgroundBlurRadius] = blurredSurface;
}
if (layer->blurRegions.size() > 0) {
@@ -553,7 +557,8 @@
continue;
}
ATRACE_NAME("BlurRegion");
- auto blurredSurface = mBlurFilter->generate(canvas, surface, region.blurRadius);
+ auto blurredSurface =
+ mBlurFilter->generate(canvas, surface, region.blurRadius, layerRect);
cachedBlurs[region.blurRadius] = blurredSurface;
}
}
@@ -658,9 +663,8 @@
paint.setColorFilter(SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform)));
- // Layers have a local transform matrix that should be applied to them.
canvas->save();
- canvas->concat(getSkM44(layer->geometry.positionTransform));
+ canvas->concat(drawTransform);
for (const auto effectRegion : layer->blurRegions) {
drawBlurRegion(canvas, effectRegion, dest, cachedBlurs[effectRegion.blurRadius]);
@@ -737,6 +741,13 @@
matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);
}
+inline SkMatrix SkiaGLRenderEngine::getDrawTransform(const LayerSettings* layer,
+ const SkMatrix& screenTransform) {
+ // Layers have a local transform matrix that should be applied to them.
+ const auto layerTransform = getSkM44(layer->geometry.positionTransform).asM33();
+ return SkMatrix::Concat(screenTransform, layerTransform);
+}
+
inline SkPoint3 SkiaGLRenderEngine::getSkPoint3(const vec3& vector) {
return SkPoint3::Make(vector.x, vector.y, vector.z);
}
@@ -872,4 +883,4 @@
} // namespace skia
} // namespace renderengine
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 0143445..c65e431 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -69,6 +69,7 @@
inline SkRRect getRoundedRect(const LayerSettings* layer);
inline SkColor getSkColor(const vec4& color);
inline SkM44 getSkM44(const mat4& matrix);
+ inline SkMatrix getDrawTransform(const LayerSettings* layer, const SkMatrix& screenTransform);
inline SkPoint3 getSkPoint3(const vec3& vector);
base::unique_fd flush();
@@ -107,4 +108,4 @@
} // namespace renderengine
} // namespace android
-#endif /* SF_GLESRENDERENGINE_H_ */
\ No newline at end of file
+#endif /* SF_GLESRENDERENGINE_H_ */
diff --git a/libs/renderengine/skia/filters/BlurFilter.cpp b/libs/renderengine/skia/filters/BlurFilter.cpp
index f6a316f..dfb306f 100644
--- a/libs/renderengine/skia/filters/BlurFilter.cpp
+++ b/libs/renderengine/skia/filters/BlurFilter.cpp
@@ -56,7 +56,7 @@
}
sk_sp<SkSurface> BlurFilter::generate(SkCanvas* canvas, const sk_sp<SkSurface> input,
- const uint32_t blurRadius) const {
+ const uint32_t blurRadius, SkRect rect) const {
ATRACE_CALL();
// Kawase is an approximation of Gaussian, but it behaves differently from it.
@@ -68,6 +68,9 @@
SkImageInfo scaledInfo = SkImageInfo::MakeN32Premul((float)input->width() * kInputScale,
(float)input->height() * kInputScale);
+
+ SkRect scaledRect = {rect.fLeft * kInputScale, rect.fTop * kInputScale,
+ rect.fRight * kInputScale, rect.fBottom * kInputScale};
auto drawSurface = canvas->makeSurface(scaledInfo);
const float stepX = radiusByPasses;
@@ -88,7 +91,9 @@
SkPaint paint;
paint.setShader(blurBuilder.makeShader(nullptr, false));
paint.setFilterQuality(kLow_SkFilterQuality);
- drawSurface->getCanvas()->drawIRect(scaledInfo.bounds(), paint);
+
+ drawSurface->getCanvas()->drawRect(scaledRect, paint);
+
blurBuilder.child("input") = nullptr;
}
@@ -110,7 +115,8 @@
SkPaint paint;
paint.setShader(blurBuilder.makeShader(nullptr, false));
paint.setFilterQuality(kLow_SkFilterQuality);
- drawSurface->getCanvas()->drawIRect(scaledInfo.bounds(), paint);
+
+ drawSurface->getCanvas()->drawRect(scaledRect, paint);
// Swap buffers for next iteration
const auto tmp = drawSurface;
@@ -125,16 +131,18 @@
}
sk_sp<SkSurface> BlurFilter::draw(SkCanvas* canvas, const sk_sp<SkSurface> input,
- const uint32_t blurRadius) const {
+ const uint32_t blurRadius, SkRect rect) const {
ATRACE_CALL();
- auto surface = generate(canvas, input, blurRadius);
+ sk_sp<SkSurface> surface = generate(canvas, input, blurRadius, rect);
+ const auto image = surface->makeImageSnapshot();
SkPaint paint;
- const auto image = surface->makeImageSnapshot();
paint.setShader(image->makeShader(SkMatrix::MakeScale(kInverseInputScale)));
paint.setFilterQuality(kLow_SkFilterQuality);
paint.setAlpha(std::min(1.0f, (float)blurRadius / kMaxCrossFadeRadius) * 255);
- canvas->drawIRect(SkIRect::MakeWH(input->width(), input->height()), paint);
+
+ canvas->drawRect(rect, paint);
+
return surface;
}
@@ -146,4 +154,4 @@
} // namespace skia
} // namespace renderengine
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/libs/renderengine/skia/filters/BlurFilter.h b/libs/renderengine/skia/filters/BlurFilter.h
index 6f973d7..c0a92f6 100644
--- a/libs/renderengine/skia/filters/BlurFilter.h
+++ b/libs/renderengine/skia/filters/BlurFilter.h
@@ -48,11 +48,11 @@
virtual ~BlurFilter(){};
// Execute blur, saving it to a texture
- sk_sp<SkSurface> generate(SkCanvas* canvas, const sk_sp<SkSurface> input,
- const uint32_t radius) const;
+ sk_sp<SkSurface> generate(SkCanvas* canvas, const sk_sp<SkSurface> input, const uint32_t radius,
+ SkRect rect) const;
// Same as generate but also drawing to the screen
- sk_sp<SkSurface> draw(SkCanvas* canvas, const sk_sp<SkSurface> input,
- const uint32_t radius) const;
+ sk_sp<SkSurface> draw(SkCanvas* canvas, const sk_sp<SkSurface> input, const uint32_t radius,
+ SkRect rect) const;
// Returns a matrix that should be applied to the blur shader
SkMatrix getShaderMatrix(const SkMatrix& transformMatrix) const;