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

Commit b06bedb8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add basic support for input shaders to RuntimeShader."

parents 72c765cd 80e3a1a9
Loading
Loading
Loading
Loading
+39 −5
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ public class RuntimeShader extends Shader {
    }

    private byte[] mUniforms;
    private Shader[] mInputShaders;
    private boolean mIsOpaque;

    /**
@@ -50,13 +51,30 @@ public class RuntimeShader extends Shader {
     * @param isOpaque True if all pixels have alpha 1.0f.
     */
    public RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms, boolean isOpaque) {
        this(sksl, uniforms, isOpaque, ColorSpace.get(ColorSpace.Named.SRGB));
        this(sksl, uniforms, null, isOpaque, ColorSpace.get(ColorSpace.Named.SRGB));
    }

    private RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms, boolean isOpaque,
    /**
     * Creates a new RuntimeShader.
     *
     * @param sksl The text of SKSL program to run on the GPU.
     * @param uniforms Array of parameters passed by the SKSL shader. Array size depends
     *                 on number of uniforms declared by sksl.
     * @param shaderInputs Array of shaders passed to the SKSL shader. Array size depends
     *                     on the number of input shaders declared in the sksl
     * @param isOpaque True if all pixels have alpha 1.0f.
     */
    public  RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms,
                          @Nullable Shader[] shaderInputs, boolean isOpaque) {
        this(sksl, uniforms, shaderInputs, isOpaque, ColorSpace.get(ColorSpace.Named.SRGB));
    }

    private RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms,
                          @Nullable Shader[] shaderInputs, boolean isOpaque,
                          ColorSpace colorSpace) {
        super(colorSpace);
        mUniforms = uniforms;
        mInputShaders = shaderInputs;
        mIsOpaque = isOpaque;
        mNativeInstanceRuntimeShaderFactory = nativeCreateShaderFactory(sksl);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this,
@@ -74,15 +92,31 @@ public class RuntimeShader extends Shader {
        discardNativeInstance();
    }

    /**
     * Sets new values for the shaders that serve as inputs to this shader.
     *
     * @param shaderInputs Array of Shaders passed into the SKSL shader. Array size depends
     *                     on number of input shaders declared by sksl.
     */
    public void updateInputShaders(@Nullable Shader[] shaderInputs) {
        mInputShaders = shaderInputs;
        discardNativeInstance();
    }

    /** @hide */
    @Override
    protected long createNativeInstance(long nativeMatrix) {
        long[] nativeShaders = mInputShaders.length > 0 ? new long[mInputShaders.length] : null;
        for (int i = 0; i < mInputShaders.length; i++) {
            nativeShaders[i] = mInputShaders[i].getNativeInstance();
        }

        return nativeCreate(mNativeInstanceRuntimeShaderFactory, nativeMatrix, mUniforms,
                colorSpace().getNativeInstance(), mIsOpaque);
                nativeShaders, colorSpace().getNativeInstance(), mIsOpaque);
    }

    private static native long nativeCreate(long shaderFactory, long matrix, byte[] inputs,
            long colorSpaceHandle, boolean isOpaque);
            long[] shaderInputs, long colorSpaceHandle, boolean isOpaque);

    private static native long nativeCreateShaderFactory(String sksl);

+15 −3
Original line number Diff line number Diff line
@@ -211,14 +211,26 @@ static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
///////////////////////////////////////////////////////////////////////////////////////////////

static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderFactory, jlong matrixPtr,
        jbyteArray inputs, jlong colorSpaceHandle, jboolean isOpaque) {
        jbyteArray inputs, jlongArray inputShaders, jlong colorSpaceHandle, jboolean isOpaque) {
    SkRuntimeEffect* effect = reinterpret_cast<SkRuntimeEffect*>(shaderFactory);
    AutoJavaByteArray arInputs(env, inputs);

    std::vector<sk_sp<SkShader>> shaderVector;
    if (inputShaders) {
        jsize shaderCount = env->GetArrayLength(inputShaders);
        shaderVector.resize(shaderCount);
        jlong* arrayPtr = env->GetLongArrayElements(inputShaders, NULL);
        for (int i = 0; i < shaderCount; i++) {
            shaderVector[i] = sk_ref_sp(reinterpret_cast<SkShader*>(arrayPtr[i]));
        }
        env->ReleaseLongArrayElements(inputShaders, arrayPtr, 0);
    }

    sk_sp<SkData> fData;
    fData = SkData::MakeWithCopy(arInputs.ptr(), arInputs.length());
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    sk_sp<SkShader> shader = effect->makeShader(fData, nullptr, 0, matrix, isOpaque == JNI_TRUE);
    sk_sp<SkShader> shader = effect->makeShader(fData, shaderVector.data(), shaderVector.size(),
                                                matrix, isOpaque == JNI_TRUE);
    ThrowIAE_IfNull(env, shader);

    return reinterpret_cast<jlong>(shader.release());
@@ -280,7 +292,7 @@ static const JNINativeMethod gComposeShaderMethods[] = {

static const JNINativeMethod gRuntimeShaderMethods[] = {
    { "nativeGetFinalizer",   "()J",    (void*)RuntimeShader_getNativeFinalizer },
    { "nativeCreate",     "(JJ[BJZ)J",  (void*)RuntimeShader_create     },
    { "nativeCreate",     "(JJ[B[JJZ)J",  (void*)RuntimeShader_create     },
    { "nativeCreateShaderFactory",     "(Ljava/lang/String;)J",
      (void*)RuntimeShader_createShaderFactory     },
};
+9 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
@@ -30,6 +31,7 @@ import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RuntimeShader;
import android.graphics.Shader;
import android.os.Bundle;
import android.view.View;

@@ -59,9 +61,10 @@ public class ColorFiltersMutateActivity extends Activity {
        private int mPorterDuffColor = 0;

        static final String sSkSL =
                "uniform float param1;\n"
                + "void main(float2 xy, inout half4 color) {\n"
                + "color = half4(color.r, half(param1), color.b, 1.0);\n"
                "in shader bitmapShader;\n"
                + "uniform float param1;\n"
                + "half4 main(float2 xy) {\n"
                + "  return half4(sample(bitmapShader, xy).rgb, param1);\n"
                + "}\n";

        private byte[] mUniforms = new byte[4];
@@ -84,7 +87,9 @@ public class ColorFiltersMutateActivity extends Activity {
            mBlendPaint.setColorFilter(new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_OVER));

            mShaderPaint = new Paint();
            mShaderPaint.setShader(new RuntimeShader(sSkSL, mUniforms, true));
            Shader[] inputShaders = { new BitmapShader(mBitmap1, Shader.TileMode.CLAMP,
                                                       Shader.TileMode.CLAMP) };
            mShaderPaint.setShader(new RuntimeShader(sSkSL, mUniforms, inputShaders, true));
            setShaderParam1(0.0f);

            ObjectAnimator sat = ObjectAnimator.ofFloat(this, "saturation", 1.0f);