Added support for edge treatment parameters for BlurShader

Added configurable parameters for edge treatment for
BlurShader to determine how edge pixels are to be
computed as part of the blur kernel. This provides
the option to sample the edge pixels of the source
for larger windows as well as using transparent
(default behavior)

Fixes: 167714368
Test: Added CTS tests to verify results of edge treatment parameters
Change-Id: I3880ff4aa2e2a4eba831a0aa6d2ec77b07e84813
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index 7cb7723..0a194f9 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -224,7 +224,7 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 static jlong BlurShader_create(JNIEnv* env , jobject o, jlong matrixPtr, jfloat sigmaX,
-        jfloat sigmaY, jlong shaderHandle) {
+        jfloat sigmaY, jlong shaderHandle, jint edgeTreatment) {
     auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     auto* inputShader = reinterpret_cast<Shader*>(shaderHandle);
 
@@ -232,6 +232,7 @@
                 sigmaX,
                 sigmaY,
                 inputShader,
+                static_cast<SkTileMode>(edgeTreatment),
                 matrix
             );
     return reinterpret_cast<jlong>(blurShader);
@@ -291,7 +292,7 @@
 };
 
 static const JNINativeMethod gBlurShaderMethods[] = {
-    { "nativeCreate",      "(JFFJ)J", (void*)BlurShader_create }
+    { "nativeCreate",      "(JFFJI)J", (void*)BlurShader_create }
 };
 
 static const JNINativeMethod gLinearGradientMethods[] = {
diff --git a/libs/hwui/shader/BlurShader.cpp b/libs/hwui/shader/BlurShader.cpp
index fa10be1..2abd871 100644
--- a/libs/hwui/shader/BlurShader.cpp
+++ b/libs/hwui/shader/BlurShader.cpp
@@ -20,13 +20,14 @@
 #include "utils/Blur.h"
 
 namespace android::uirenderer {
-BlurShader::BlurShader(float radiusX, float radiusY, Shader* inputShader, const SkMatrix* matrix)
+BlurShader::BlurShader(float radiusX, float radiusY, Shader* inputShader, SkTileMode edgeTreatment,
+        const SkMatrix* matrix)
     : Shader(matrix)
     , skImageFilter(
             SkImageFilters::Blur(
                     Blur::convertRadiusToSigma(radiusX),
                     Blur::convertRadiusToSigma(radiusY),
-                    SkTileMode::kClamp,
+                    edgeTreatment,
                     inputShader ? inputShader->asSkImageFilter() : nullptr,
                     nullptr)
             ) { }
diff --git a/libs/hwui/shader/BlurShader.h b/libs/hwui/shader/BlurShader.h
index 9eb22bd..60a1589 100644
--- a/libs/hwui/shader/BlurShader.h
+++ b/libs/hwui/shader/BlurShader.h
@@ -30,8 +30,12 @@
      *
      * This will blur the contents of the provided input shader if it is non-null, otherwise
      * the source bitmap will be blurred instead.
+     *
+     * The edge treatment parameter determines how content near the edges of the source is to
+     * participate in the blur
      */
-    BlurShader(float radiusX, float radiusY, Shader* inputShader, const SkMatrix* matrix);
+    BlurShader(float radiusX, float radiusY, Shader* inputShader, SkTileMode edgeTreatment,
+            const SkMatrix* matrix);
     ~BlurShader() override;
 protected:
     sk_sp<SkImageFilter> makeSkImageFilter() override;