From 6c2296137ee296823f0cc5809994953182dcb609 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Mon, 21 Sep 2020 20:49:25 -0700 Subject: [PATCH] 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 --- api/current.txt | 2 ++ .../java/android/graphics/BlurShader.java | 28 +++++++++++++++++-- graphics/java/android/graphics/Shader.java | 6 +++- libs/hwui/jni/Shader.cpp | 5 ++-- libs/hwui/shader/BlurShader.cpp | 5 ++-- libs/hwui/shader/BlurShader.h | 6 +++- non-updatable-api/current.txt | 2 ++ 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/api/current.txt b/api/current.txt index 4590325cb771b..0e9b34abfb909 100644 --- a/api/current.txt +++ b/api/current.txt @@ -14292,6 +14292,7 @@ package android.graphics { public final class BlurShader extends android.graphics.Shader { ctor public BlurShader(float, float, @Nullable android.graphics.Shader); + ctor public BlurShader(float, float, @Nullable android.graphics.Shader, @NonNull android.graphics.Shader.TileMode); } public class Camera { @@ -15630,6 +15631,7 @@ package android.graphics { public enum Shader.TileMode { enum_constant public static final android.graphics.Shader.TileMode CLAMP; + enum_constant public static final android.graphics.Shader.TileMode DECAL; enum_constant public static final android.graphics.Shader.TileMode MIRROR; enum_constant public static final android.graphics.Shader.TileMode REPEAT; } diff --git a/graphics/java/android/graphics/BlurShader.java b/graphics/java/android/graphics/BlurShader.java index 779a890510604..3bc8119833362 100644 --- a/graphics/java/android/graphics/BlurShader.java +++ b/graphics/java/android/graphics/BlurShader.java @@ -16,6 +16,7 @@ package android.graphics; +import android.annotation.NonNull; import android.annotation.Nullable; /** @@ -28,9 +29,26 @@ public final class BlurShader extends Shader { private final float mRadiusX; private final float mRadiusY; private final Shader mInputShader; + private final TileMode mEdgeTreatment; private long mNativeInputShader = 0; + /** + * Create a {@link BlurShader} that blurs the contents of the optional input shader + * with the specified radius along the x and y axis. If no input shader is provided + * then all drawing commands issued with a {@link android.graphics.Paint} that this + * shader is installed in will be blurred. + * + * This uses a default {@link TileMode#DECAL} for edge treatment + * + * @param radiusX Radius of blur along the X axis + * @param radiusY Radius of blur along the Y axis + * @param inputShader Input shader that provides the content to be blurred + */ + public BlurShader(float radiusX, float radiusY, @Nullable Shader inputShader) { + this(radiusX, radiusY, inputShader, TileMode.DECAL); + } + /** * Create a {@link BlurShader} that blurs the contents of the optional input shader * with the specified radius along the x and y axis. If no input shader is provided @@ -39,18 +57,22 @@ public final class BlurShader extends Shader { * @param radiusX Radius of blur along the X axis * @param radiusY Radius of blur along the Y axis * @param inputShader Input shader that provides the content to be blurred + * @param edgeTreatment Policy for how to blur content near edges of the blur shader */ - public BlurShader(float radiusX, float radiusY, @Nullable Shader inputShader) { + public BlurShader(float radiusX, float radiusY, @Nullable Shader inputShader, + @NonNull TileMode edgeTreatment) { mRadiusX = radiusX; mRadiusY = radiusY; mInputShader = inputShader; + mEdgeTreatment = edgeTreatment; } /** @hide **/ @Override protected long createNativeInstance(long nativeMatrix) { mNativeInputShader = mInputShader != null ? mInputShader.getNativeInstance() : 0; - return nativeCreate(nativeMatrix, mRadiusX, mRadiusY, mNativeInputShader); + return nativeCreate(nativeMatrix, mRadiusX, mRadiusY, mNativeInputShader, + mEdgeTreatment.nativeInt); } /** @hide **/ @@ -61,5 +83,5 @@ public final class BlurShader extends Shader { } private static native long nativeCreate(long nativeMatrix, float radiusX, float radiusY, - long inputShader); + long inputShader, int edgeTreatment); } diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index 8154ebf1e5081..d71ff1138b252 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -95,7 +95,11 @@ public class Shader { * repeat the shader's image horizontally and vertically, alternating * mirror images so that adjacent images always seam */ - MIRROR (2); + MIRROR(2), + /** + * Only draw within the original domain, return transparent-black everywhere else + */ + DECAL(3); TileMode(int nativeInt) { this.nativeInt = nativeInt; diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp index 7cb77233846fc..0a194f9dd666e 100644 --- a/libs/hwui/jni/Shader.cpp +++ b/libs/hwui/jni/Shader.cpp @@ -224,7 +224,7 @@ static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr, /////////////////////////////////////////////////////////////////////////////////////////////// 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(matrixPtr); auto* inputShader = reinterpret_cast(shaderHandle); @@ -232,6 +232,7 @@ static jlong BlurShader_create(JNIEnv* env , jobject o, jlong matrixPtr, jfloat sigmaX, sigmaY, inputShader, + static_cast(edgeTreatment), matrix ); return reinterpret_cast(blurShader); @@ -291,7 +292,7 @@ static const JNINativeMethod gBitmapShaderMethods[] = { }; 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 fa10be100bca5..2abd8714204bb 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 9eb22bd11f4ac..60a15898893e4 100644 --- a/libs/hwui/shader/BlurShader.h +++ b/libs/hwui/shader/BlurShader.h @@ -30,8 +30,12 @@ public: * * 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 makeSkImageFilter() override; diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 80300611c7f2e..b9869e7faaee0 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -14292,6 +14292,7 @@ package android.graphics { public final class BlurShader extends android.graphics.Shader { ctor public BlurShader(float, float, @Nullable android.graphics.Shader); + ctor public BlurShader(float, float, @Nullable android.graphics.Shader, @NonNull android.graphics.Shader.TileMode); } public class Camera { @@ -15612,6 +15613,7 @@ package android.graphics { public enum Shader.TileMode { enum_constant public static final android.graphics.Shader.TileMode CLAMP; + enum_constant public static final android.graphics.Shader.TileMode DECAL; enum_constant public static final android.graphics.Shader.TileMode MIRROR; enum_constant public static final android.graphics.Shader.TileMode REPEAT; }