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;