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; }