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

Commit 123247e2 authored by Nader Jawad's avatar Nader Jawad Committed by Android (Google) Code Review
Browse files

Merge "Add RenderEffect support for Shaders as inputs" into sc-dev

parents 81d98299 011aac83
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15795,6 +15795,7 @@ package android.graphics {
    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);
    method @NonNull public static android.graphics.RenderEffect createShaderEffect(@NonNull android.graphics.Shader);
  }
  public final class RenderNode {
+18 −5
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ public final class RenderEffect {
    }

    /**
     * Create a filter that applies the color filter to the provided RenderEffect
     * Create a {@link RenderEffect} 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}
@@ -209,7 +209,7 @@ public final class RenderEffect {
    }

    /**
     * Create a filter that applies the color filter to the contents of the
     * Create a {@link RenderEffect} 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
     */
@@ -224,7 +224,7 @@ public final class RenderEffect {
    }

    /**
     * {@link RenderEffect} that is a composition of 2 other {@link RenderEffect} instances
     * Create a {@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
@@ -248,8 +248,8 @@ public final class RenderEffect {
    }

    /**
     * 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.
     * Create a {@link RenderEffect} that composes 'inner' with 'outer', such that the results of
     * 'inner' are treated as the source bitmap passed to 'outer', i.e.
     *
     * <pre>
     * {@code
@@ -278,6 +278,18 @@ public final class RenderEffect {
            );
    }

    /**
     * Create a {@link RenderEffect} that renders the contents of the input {@link Shader}.
     * This is useful to create an input for other {@link RenderEffect} types such as
     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, TileMode)}
     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, TileMode)} or
     * {@link RenderEffect#createColorFilterEffect(ColorFilter, RenderEffect)}.
     */
    @NonNull
    public static RenderEffect createShaderEffect(@NonNull Shader shader) {
        return new RenderEffect(nativeCreateShaderEffect(shader.getNativeInstance()));
    }

    private final long mNativeRenderEffect;

    /* only constructed from static factory methods */
@@ -305,5 +317,6 @@ public final class RenderEffect {
    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 nativeCreateShaderEffect(long shader);
    private static native long nativeGetFinalizer();
}
+14 −1
Original line number Diff line number Diff line
@@ -115,6 +115,18 @@ static jlong createChainEffect(
    return reinterpret_cast<jlong>(composeFilter.release());
}

static jlong createShaderEffect(
    JNIEnv* env,
    jobject,
    jlong shaderHandle
) {
    auto* shader = reinterpret_cast<const SkShader*>(shaderHandle);
    sk_sp<SkImageFilter> shaderFilter = SkImageFilters::Shader(
          sk_ref_sp(shader), nullptr
    );
    return reinterpret_cast<jlong>(shaderFilter.release());
}

static void RenderEffect_safeUnref(SkImageFilter* filter) {
    SkSafeUnref(filter);
}
@@ -130,7 +142,8 @@ static const JNINativeMethod gRenderEffectMethods[] = {
    {"nativeCreateBitmapEffect", "(JFFFFFFFF)J", (void*)createBitmapEffect},
    {"nativeCreateColorFilterEffect", "(JJ)J", (void*)createColorFilterEffect},
    {"nativeCreateBlendModeEffect", "(JJI)J", (void*)createBlendModeEffect},
    {"nativeCreateChainEffect", "(JJ)J", (void*)createChainEffect}
    {"nativeCreateChainEffect", "(JJ)J", (void*)createChainEffect},
    {"nativeCreateShaderEffect", "(J)J", (void*)createShaderEffect}
};

int register_android_graphics_RenderEffect(JNIEnv* env) {
+9 −0
Original line number Diff line number Diff line
@@ -753,6 +753,15 @@
            </intent-filter>
        </activity>

        <activity android:name="RenderEffectShaderActivity"
                  android:label="RenderEffect/Shader"
                  android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="com.android.test.hwui.TEST"/>
            </intent-filter>
        </activity>

        <activity android:name="TextActivity"
             android:label="Text/Simple Text"
             android:theme="@android:style/Theme.NoTitleBar"
+107 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.test.hwui;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RenderEffect;
import android.graphics.RenderNode;
import android.graphics.Shader;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;

@SuppressWarnings({"UnusedDeclaration"})
public class RenderEffectShaderActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout layout = new LinearLayout(this);
        layout.setClipChildren(false);
        layout.setGravity(Gravity.CENTER);
        layout.setOrientation(LinearLayout.VERTICAL);


        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(500, 500);
        params.bottomMargin = 100;

        layout.addView(new ShaderRenderEffectView(this), params);

        setContentView(layout);
    }

    public static class ShaderRenderEffectView extends View {

        private final Paint mPaint;
        private final RenderNode mRenderNode;

        public ShaderRenderEffectView(Context c) {
            super(c);

            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mRenderNode = new RenderNode("blurNode");

        }

        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            if (changed) {
                LinearGradient gradient = new LinearGradient(
                        0f, 0f,
                        0f, bottom - top,
                        new int[]{Color.CYAN, Color.MAGENTA},
                        null,
                        Shader.TileMode.CLAMP
                );
                mRenderNode.setRenderEffect(
                        RenderEffect.createShaderEffect(gradient)
                );

                int width = right - left;
                int height = bottom - top;
                mRenderNode.setPosition(0, 0, width, height);
                Canvas canvas = mRenderNode.beginRecording(width, height);
                mPaint.setColor(Color.BLUE);

                canvas.drawRect(
                        0,
                        0,
                        width,
                        height,
                        mPaint
                );

                mPaint.setColor(Color.RED);
                canvas.drawCircle((right - left) / 2f, (bottom - top) / 2f, 50f, mPaint);

                mRenderNode.endRecording();
            }
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawRenderNode(mRenderNode);
        }
    }
}