Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73022fd2 authored by Nader Jawad's avatar Nader Jawad Committed by Automerger Merge Worker
Browse files

Merge "Introduce more RenderEffect APIs" am: ef3da571

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12974134

Change-Id: I99962c7c1688b12d5cc2d485ac6e7e4cd3ab8b47
parents 7661b8bf ef3da571
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -15610,6 +15610,19 @@ package android.graphics {
    method public final boolean next(android.graphics.Rect);
  }
  public final class RenderEffect {
    method @NonNull public static android.graphics.RenderEffect createBitmapEffect(@NonNull android.graphics.Bitmap);
    method @NonNull public static android.graphics.RenderEffect createBitmapEffect(@NonNull android.graphics.Bitmap, @Nullable android.graphics.Rect, @NonNull android.graphics.Rect);
    method @NonNull public static android.graphics.RenderEffect createBlendModeEffect(@NonNull android.graphics.RenderEffect, @NonNull android.graphics.RenderEffect, @NonNull android.graphics.BlendMode);
    method @NonNull public static android.graphics.RenderEffect createBlurEffect(float, float, @NonNull android.graphics.RenderEffect, @NonNull android.graphics.Shader.TileMode);
    method @NonNull public static android.graphics.RenderEffect createBlurEffect(float, float, @NonNull android.graphics.Shader.TileMode);
    method @NonNull public static android.graphics.RenderEffect createChainEffect(@NonNull android.graphics.RenderEffect, @NonNull android.graphics.RenderEffect);
    method @NonNull public static android.graphics.RenderEffect createColorFilterEffect(@NonNull android.graphics.ColorFilter, @NonNull android.graphics.RenderEffect);
    method @NonNull public static android.graphics.RenderEffect createColorFilterEffect(@NonNull android.graphics.ColorFilter);
    method @NonNull public static android.graphics.RenderEffect createOffsetEffect(float, float);
    method @NonNull public static android.graphics.RenderEffect createOffsetEffect(float, float, @NonNull android.graphics.RenderEffect);
  }
  public final class RenderNode {
    ctor public RenderNode(@Nullable String);
    method @NonNull public android.graphics.RecordingCanvas beginRecording(int, int);
@@ -15669,6 +15682,7 @@ package android.graphics {
    method public boolean setPosition(@NonNull android.graphics.Rect);
    method public boolean setProjectBackwards(boolean);
    method public boolean setProjectionReceiver(boolean);
    method public void setRenderEffect(@Nullable android.graphics.RenderEffect);
    method public boolean setRotationX(float);
    method public boolean setRotationY(float);
    method public boolean setRotationZ(float);
+14 −0
Original line number Diff line number Diff line
@@ -15592,6 +15592,19 @@ package android.graphics {
    method public final boolean next(android.graphics.Rect);
  }
  public final class RenderEffect {
    method @NonNull public static android.graphics.RenderEffect createBitmapEffect(@NonNull android.graphics.Bitmap);
    method @NonNull public static android.graphics.RenderEffect createBitmapEffect(@NonNull android.graphics.Bitmap, @Nullable android.graphics.Rect, @NonNull android.graphics.Rect);
    method @NonNull public static android.graphics.RenderEffect createBlendModeEffect(@NonNull android.graphics.RenderEffect, @NonNull android.graphics.RenderEffect, @NonNull android.graphics.BlendMode);
    method @NonNull public static android.graphics.RenderEffect createBlurEffect(float, float, @NonNull android.graphics.RenderEffect, @NonNull android.graphics.Shader.TileMode);
    method @NonNull public static android.graphics.RenderEffect createBlurEffect(float, float, @NonNull android.graphics.Shader.TileMode);
    method @NonNull public static android.graphics.RenderEffect createChainEffect(@NonNull android.graphics.RenderEffect, @NonNull android.graphics.RenderEffect);
    method @NonNull public static android.graphics.RenderEffect createColorFilterEffect(@NonNull android.graphics.ColorFilter, @NonNull android.graphics.RenderEffect);
    method @NonNull public static android.graphics.RenderEffect createColorFilterEffect(@NonNull android.graphics.ColorFilter);
    method @NonNull public static android.graphics.RenderEffect createOffsetEffect(float, float);
    method @NonNull public static android.graphics.RenderEffect createOffsetEffect(float, float, @NonNull android.graphics.RenderEffect);
  }
  public final class RenderNode {
    ctor public RenderNode(@Nullable String);
    method @NonNull public android.graphics.RecordingCanvas beginRecording(int, int);
@@ -15651,6 +15664,7 @@ package android.graphics {
    method public boolean setPosition(@NonNull android.graphics.Rect);
    method public boolean setProjectBackwards(boolean);
    method public boolean setProjectionReceiver(boolean);
    method public void setRenderEffect(@Nullable android.graphics.RenderEffect);
    method public boolean setRotationX(float);
    method public boolean setRotationY(float);
    method public boolean setRotationZ(float);
+158 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.graphics;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Shader.TileMode;

import libcore.util.NativeAllocationRegistry;
@@ -24,8 +25,6 @@ import libcore.util.NativeAllocationRegistry;
/**
 * Intermediate rendering step used to render drawing commands with a corresponding
 * visual effect
 *
 * @hide
 */
public final class RenderEffect {

@@ -99,7 +98,7 @@ public final class RenderEffect {
    /**
     * Create a {@link RenderEffect} that blurs the contents of the
     * {@link android.graphics.RenderNode} that this RenderEffect is installed on with the
     * specified radius along hte x and y axis.
     * specified radius along the x and y axis.
     * @param radiusX Radius of blur along the X axis
     * @param radiusY Radius of blur along the Y axis
     * @param edgeTreatment Policy for how to blur content near edges of the blur kernel
@@ -120,6 +119,156 @@ public final class RenderEffect {
            );
    }

    /**
     * Create a {@link RenderEffect} that renders the contents of the input {@link Bitmap}.
     * This is useful to create an input for other {@link RenderEffect} types such as
     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, TileMode)} or
     * {@link RenderEffect#createColorFilterEffect(ColorFilter, RenderEffect)}
     *
     * @param bitmap The source bitmap to be rendered by the created {@link RenderEffect}
     */
    @NonNull
    public static RenderEffect createBitmapEffect(@NonNull Bitmap bitmap) {
        float right = bitmap.getWidth();
        float bottom = bitmap.getHeight();
        return new RenderEffect(
                nativeCreateBitmapEffect(
                        bitmap.getNativeInstance(),
                        0f,
                        0f,
                        right,
                        bottom,
                        0f,
                        0f,
                        right,
                        bottom
                )
        );
    }

    /**
     * Create a {@link RenderEffect} that renders the contents of the input {@link Bitmap}.
     * This is useful to create an input for other {@link RenderEffect} types such as
     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, TileMode)} or
     * {@link RenderEffect#createColorFilterEffect(ColorFilter, RenderEffect)}
     *
     * @param bitmap The source bitmap to be rendered by the created {@link RenderEffect}
     * @param src Optional subset of the bitmap to be part of the rendered output. If null
     *            is provided, the entire bitmap bounds are used.
     * @param dst Bounds of the destination which the bitmap is translated and scaled to be
     *            drawn into
     */
    @NonNull
    public static RenderEffect createBitmapEffect(
            @NonNull Bitmap bitmap,
            @Nullable Rect src,
            @NonNull Rect dst
    ) {
        long bitmapHandle = bitmap.getNativeInstance();
        int left = src == null ? 0 : src.left;
        int top = src == null ? 0 : src.top;
        int right = src == null ? bitmap.getWidth() : src.right;
        int bottom = src == null ? bitmap.getHeight() : src.bottom;
        return new RenderEffect(
                nativeCreateBitmapEffect(
                        bitmapHandle,
                        left,
                        top,
                        right,
                        bottom,
                        dst.left,
                        dst.top,
                        dst.right,
                        dst.bottom
                )
        );
    }

    /**
     * Create a filter that applies the color filter to the provided RenderEffect
     *
     * @param colorFilter ColorFilter applied to the content in the input RenderEffect
     * @param renderEffect Source to be transformed by the specified {@link ColorFilter}
     */
    @NonNull
    public static RenderEffect createColorFilterEffect(
            @NonNull ColorFilter colorFilter,
            @NonNull RenderEffect renderEffect
    ) {
        return new RenderEffect(
                nativeCreateColorFilterEffect(
                    colorFilter.getNativeInstance(),
                    renderEffect.getNativeInstance()
                )
            );
    }

    /**
     * Create a filter that applies the color filter to the contents of the
     * {@link android.graphics.RenderNode} that this RenderEffect is installed on
     * @param colorFilter ColorFilter applied to the content in the input RenderEffect
     */
    @NonNull
    public static RenderEffect createColorFilterEffect(@NonNull ColorFilter colorFilter) {
        return new RenderEffect(
                nativeCreateColorFilterEffect(
                        colorFilter.getNativeInstance(),
                        0
                )
        );
    }

    /**
     * {@link RenderEffect} that is a composition of 2 other {@link RenderEffect} instances
     * combined by the specified {@link BlendMode}
     *
     * @param dst The Dst pixels used in blending, if null the source bitmap is used.
     * @param src The Src pixels used in blending, if null the source bitmap is use
     * @param blendMode The {@link BlendMode} to be used to combine colors from the two
     *                  {@link RenderEffect}s
     */
    @NonNull
    public static RenderEffect createBlendModeEffect(
            @NonNull RenderEffect dst,
            @NonNull RenderEffect src,
            @NonNull BlendMode blendMode
    ) {
        return new RenderEffect(
                nativeCreateBlendModeEffect(
                        dst.getNativeInstance(),
                        src.getNativeInstance(),
                        blendMode.getXfermode().porterDuffMode
                )
        );
    }

    /**
     * Create a filter that composes 'inner' with 'outer', such that the results of 'inner' are
     * treated as the source bitmap passed to 'outer', i.e.
     *
     * result = outer(inner(source)).
     *
     * Consumers should favor explicit chaining of {@link RenderEffect} instances at creation time
     * rather than using chain effect. Chain effects are useful for situations where the input or
     * output are provided from elsewhere and the input or output {@link RenderEffect} need to be
     * changed.
     *
     * @param outer {@link RenderEffect} that consumes the output of {@param inner} as its input
     * @param inner {@link RenderEffect} that is consumed as input by {@param outer}
     */
    @NonNull
    public static RenderEffect createChainEffect(
            @NonNull RenderEffect outer,
            @NonNull RenderEffect inner
    ) {
        return new RenderEffect(
                nativeCreateChainEffect(
                    outer.getNativeInstance(),
                    inner.getNativeInstance()
                )
            );
    }

    private final long mNativeRenderEffect;

    /* only constructed from static factory methods */
@@ -141,5 +290,11 @@ public final class RenderEffect {
            float offsetX, float offsetY, long nativeInput);
    private static native long nativeCreateBlurEffect(
            float radiusX, float radiusY, long nativeInput, int edgeTreatment);
    private static native long nativeCreateBitmapEffect(
            long bitmapHandle, float srcLeft, float srcTop, float srcRight, float srcBottom,
            float dstLeft, float dstTop, float dstRight, float dstBottom);
    private static native long nativeCreateColorFilterEffect(long colorFilter, long nativeInput);
    private static native long nativeCreateBlendModeEffect(long dst, long src, int blendmode);
    private static native long nativeCreateChainEffect(long outer, long inner);
    private static native long nativeGetFinalizer();
}
+0 −2
Original line number Diff line number Diff line
@@ -858,8 +858,6 @@ public final class RenderNode {
     * be blurred when this RenderNode is drawn into the destination.
     * @param renderEffect to be applied to the RenderNode. Passing null clears all previously
     *          configured RenderEffects
     *
     * @hide
     */
    public void setRenderEffect(@Nullable RenderEffect renderEffect) {
        nSetRenderEffect(mNativeRenderNode,
+72 −1
Original line number Diff line number Diff line
@@ -48,6 +48,73 @@ static jlong createBlurEffect(JNIEnv* env , jobject, jfloat radiusX,
    return reinterpret_cast<jlong>(blurFilter.release());
}

static jlong createBitmapEffect(
    JNIEnv* env,
    jobject,
    jlong bitmapHandle,
    jfloat srcLeft,
    jfloat srcTop,
    jfloat srcRight,
    jfloat srcBottom,
    jfloat dstLeft,
    jfloat dstTop,
    jfloat dstRight,
    jfloat dstBottom
) {
    sk_sp<SkImage> image = android::bitmap::toBitmap(bitmapHandle).makeImage();
    SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
    SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
    sk_sp<SkImageFilter> bitmapFilter =
        SkImageFilters::Image(image, srcRect, dstRect, kLow_SkFilterQuality);
    return reinterpret_cast<jlong>(bitmapFilter.release());
}

static jlong createColorFilterEffect(
    JNIEnv* env,
    jobject,
    jlong colorFilterHandle,
    jlong inputFilterHandle
) {
    auto* colorFilter = reinterpret_cast<const SkColorFilter*>(colorFilterHandle);
    auto* inputFilter = reinterpret_cast<const SkImageFilter*>(inputFilterHandle);
    sk_sp<SkImageFilter> colorFilterImageFilter = SkImageFilters::ColorFilter(
            sk_ref_sp(colorFilter), sk_ref_sp(inputFilter), nullptr);
   return reinterpret_cast<jlong>(colorFilterImageFilter.release());
}

static jlong createBlendModeEffect(
    JNIEnv* env,
    jobject,
    jlong backgroundImageFilterHandle,
    jlong foregroundImageFilterHandle,
    jint blendmodeHandle
) {
    auto* backgroundFilter = reinterpret_cast<const SkImageFilter*>(backgroundImageFilterHandle);
    auto* foregroundFilter = reinterpret_cast<const SkImageFilter*>(foregroundImageFilterHandle);
    SkBlendMode blendMode = static_cast<SkBlendMode>(blendmodeHandle);
    sk_sp<SkImageFilter> xfermodeFilter = SkImageFilters::Blend(
            blendMode,
            sk_ref_sp(backgroundFilter),
            sk_ref_sp(foregroundFilter)
    );
    return reinterpret_cast<jlong>(xfermodeFilter.release());
}

static jlong createChainEffect(
    JNIEnv* env,
    jobject,
    jlong outerFilterHandle,
    jlong innerFilterHandle
) {
    auto* outerImageFilter = reinterpret_cast<const SkImageFilter*>(outerFilterHandle);
    auto* innerImageFilter = reinterpret_cast<const SkImageFilter*>(innerFilterHandle);
    sk_sp<SkImageFilter> composeFilter = SkImageFilters::Compose(
        sk_ref_sp(outerImageFilter),
        sk_ref_sp(innerImageFilter)
    );
    return reinterpret_cast<jlong>(composeFilter.release());
}

static void RenderEffect_safeUnref(SkImageFilter* filter) {
    SkSafeUnref(filter);
}
@@ -59,7 +126,11 @@ static jlong getRenderEffectFinalizer(JNIEnv*, jobject) {
static const JNINativeMethod gRenderEffectMethods[] = {
    {"nativeGetFinalizer", "()J", (void*)getRenderEffectFinalizer},
    {"nativeCreateOffsetEffect", "(FFJ)J", (void*)createOffsetEffect},
    {"nativeCreateBlurEffect", "(FFJI)J", (void*)createBlurEffect}
    {"nativeCreateBlurEffect", "(FFJI)J", (void*)createBlurEffect},
    {"nativeCreateBitmapEffect", "(JFFFFFFFF)J", (void*)createBitmapEffect},
    {"nativeCreateColorFilterEffect", "(JJ)J", (void*)createColorFilterEffect},
    {"nativeCreateBlendModeEffect", "(JJI)J", (void*)createBlendModeEffect},
    {"nativeCreateChainEffect", "(JJ)J", (void*)createChainEffect}
};

int register_android_graphics_RenderEffect(JNIEnv* env) {