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

Commit 783e5aeb authored by Derek Sollenberger's avatar Derek Sollenberger
Browse files

Refactor RuntimeShader to support easier assignment of uniforms.

uniforms are no longer set as single block of bytes where the caller
has to know the offset, but instead by the string identfier in the
shader.  This CL only supports floats, but future expansions of this
will provide helpers for ints, colors, and byte[].

Also by storing the shaders and uniforms in the RuntimeShaderBuilder
we can more easily copy them.  This enables Canvas.drawRipple to not
just copy the compiled SkSL effect, but also all the uniforms and
other input shaders set on the RuntimeShader.

Bug: 177051137
Test: HwAccelerationTest
Change-Id: I4733f42ba662546be6bebc37f0b89832778e66ce
parent 68c395f4
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -220,7 +220,7 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
            CanvasProperty<Float> progress, RuntimeShader shader) {
            CanvasProperty<Float> progress, RuntimeShader shader) {
        nDrawRipple(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
        nDrawRipple(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
                radius.getNativeContainer(), paint.getNativeContainer(),
                radius.getNativeContainer(), paint.getNativeContainer(),
                progress.getNativeContainer(), shader.getNativeShaderFactory());
                progress.getNativeContainer(), shader.getNativeShaderBuilder());
    }
    }


    /**
    /**
+53 −50
Original line number Original line Diff line number Diff line
@@ -17,7 +17,6 @@
package android.graphics;
package android.graphics;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;


import libcore.util.NativeAllocationRegistry;
import libcore.util.NativeAllocationRegistry;


@@ -33,14 +32,12 @@ public class RuntimeShader extends Shader {
                RuntimeShader.class.getClassLoader(), nativeGetFinalizer());
                RuntimeShader.class.getClassLoader(), nativeGetFinalizer());
    }
    }


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


    /**
    /**
     * Current native shader factory instance.
     * Current native shader builder instance.
     */
     */
    private long mNativeInstanceRuntimeShaderFactory;
    private long mNativeInstanceRuntimeShaderBuilder;


    /**
    /**
     * Creates a new RuntimeShader.
     * Creates a new RuntimeShader.
@@ -50,80 +47,86 @@ public class RuntimeShader extends Shader {
     *                 on number of uniforms declared by sksl.
     *                 on number of uniforms declared by sksl.
     * @param isOpaque True if all pixels have alpha 1.0f.
     * @param isOpaque True if all pixels have alpha 1.0f.
     */
     */
    public RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms, boolean isOpaque) {
    public RuntimeShader(@NonNull String sksl, boolean isOpaque) {
        this(sksl, uniforms, null, isOpaque, ColorSpace.get(ColorSpace.Named.SRGB));
        super(ColorSpace.get(ColorSpace.Named.SRGB));
        mIsOpaque = isOpaque;
        mNativeInstanceRuntimeShaderBuilder = nativeCreateBuilder(sksl);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(
                this, mNativeInstanceRuntimeShaderBuilder);
    }
    }


    /**
    /**
     * Creates a new RuntimeShader.
     * Sets the uniform value corresponding to this shader.  If the shader does not have a uniform
     * with that name or if the uniform is declared with a type other than float then an
     * IllegalArgumentException is thrown.
     *
     *
     * @param sksl The text of SKSL program to run on the GPU.
     * @param uniformName name matching the uniform declared in the SKSL shader
     * @param uniforms Array of parameters passed by the SKSL shader. Array size depends
     * @param value
     *                 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,
    public void setUniform(@NonNull String uniformName, float value) {
                          @Nullable Shader[] shaderInputs, boolean isOpaque) {
        setUniform(uniformName, new float[] {value});
        this(sksl, uniforms, shaderInputs, isOpaque, ColorSpace.get(ColorSpace.Named.SRGB));
    }
    }


    private RuntimeShader(@NonNull String sksl, @Nullable byte[] uniforms,
    /**
                          @Nullable Shader[] shaderInputs, boolean isOpaque,
     * Sets the uniform value corresponding to this shader.  If the shader does not have a uniform
                          ColorSpace colorSpace) {
     * with that name or if the uniform is declared with a type other than float2/vec2 then an
        super(colorSpace);
     * IllegalArgumentException is thrown.
        mUniforms = uniforms;
     *
        mInputShaders = shaderInputs;
     * @param uniformName name matching the uniform declared in the SKSL shader
        mIsOpaque = isOpaque;
     * @param value1
        mNativeInstanceRuntimeShaderFactory = nativeCreateShaderFactory(sksl);
     * @param value2
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this,
     */
                mNativeInstanceRuntimeShaderFactory);
    public void setUniform(@NonNull String uniformName, float value1, float value2) {
        setUniform(uniformName, new float[] {value1, value2});
    }
    }


    /**
    /**
     * Sets new value for shader parameters.
     * Sets the uniform value corresponding to this shader.  If the shader does not have a uniform
     * with that name or if the uniform is declared with a type other than a vecN/floatN where N is
     * the size of the values array then an IllegalArgumentException is thrown.
     *
     *
     * @param uniforms Array of parameters passed by the SKSL shader. Array size depends
     * @param uniformName name matching the uniform declared in the SKSL shader
     *                 on number of uniforms declared by mSksl.
     * @param values
     */
     */
    public void updateUniforms(@Nullable byte[] uniforms) {
    public void setUniform(@NonNull String uniformName, float[] values) {
        mUniforms = uniforms;
        nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, values);
        discardNativeInstance();
        discardNativeInstance();
    }
    }


    /**
    /**
     * Sets new values for the shaders that serve as inputs to this shader.
     * Sets the uniform shader that is declares as input to this shader.  If the shader does not
     * have a uniform shader with that name then an IllegalArgumentException is thrown.
     *
     *
     * @param shaderInputs Array of Shaders passed into the SKSL shader. Array size depends
     * @param shaderName name matching the uniform declared in the SKSL shader
     *                     on number of input shaders declared by sksl.
     * @param shader shader passed into the SKSL shader for sampling
     */
     */
    public void updateInputShaders(@Nullable Shader[] shaderInputs) {
    public void setInputShader(@NonNull String shaderName, @NonNull Shader shader) {
        mInputShaders = shaderInputs;
        nativeUpdateShader(
                    mNativeInstanceRuntimeShaderBuilder, shaderName, shader.getNativeInstance());
        discardNativeInstance();
        discardNativeInstance();
    }
    }


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


        return nativeCreate(mNativeInstanceRuntimeShaderFactory, nativeMatrix, mUniforms,
    public long getNativeShaderBuilder() {
                nativeShaders, colorSpace().getNativeInstance(), mIsOpaque);
        return mNativeInstanceRuntimeShaderBuilder;
    }
    }


    public long getNativeShaderFactory() {
    public boolean isOpaque() {
        return mNativeInstanceRuntimeShaderFactory;
        return mIsOpaque;
    }
    }


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

    private static native long nativeCreateShaderFactory(String sksl);

    private static native long nativeGetFinalizer();
    private static native long nativeGetFinalizer();
    private static native long nativeCreateBuilder(String sksl);
    private static native long nativeCreateShader(
            long shaderBuilder, long matrix, boolean isOpaque);
    private static native void nativeUpdateUniforms(
            long shaderBuilder, String uniformName, float[] uniforms);
    private static native void nativeUpdateShader(
            long shaderBuilder, String shaderName, long shader);
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -819,10 +819,10 @@ void SkiaCanvas::drawRipple(uirenderer::CanvasPropertyPrimitive* x,
                            uirenderer::CanvasPropertyPrimitive* radius,
                            uirenderer::CanvasPropertyPrimitive* radius,
                            uirenderer::CanvasPropertyPaint* paint,
                            uirenderer::CanvasPropertyPaint* paint,
                            uirenderer::CanvasPropertyPrimitive* progress,
                            uirenderer::CanvasPropertyPrimitive* progress,
                            sk_sp<SkRuntimeEffect> runtimeEffect) {
                            const SkRuntimeShaderBuilder& effectBuilder) {
    sk_sp<uirenderer::skiapipeline::AnimatedRipple> drawable(
    sk_sp<uirenderer::skiapipeline::AnimatedRipple> drawable(
            new uirenderer::skiapipeline::AnimatedRipple(x, y, radius, paint, progress,
            new uirenderer::skiapipeline::AnimatedRipple(x, y, radius, paint, progress,
                                                         runtimeEffect));
                                                         effectBuilder));
    mCanvas->drawDrawable(drawable.get());
    mCanvas->drawDrawable(drawable.get());
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -152,7 +152,7 @@ public:
                            uirenderer::CanvasPropertyPrimitive* radius,
                            uirenderer::CanvasPropertyPrimitive* radius,
                            uirenderer::CanvasPropertyPaint* paint,
                            uirenderer::CanvasPropertyPaint* paint,
                            uirenderer::CanvasPropertyPrimitive* progress,
                            uirenderer::CanvasPropertyPrimitive* progress,
                            sk_sp<SkRuntimeEffect> runtimeEffect) override;
                            const SkRuntimeShaderBuilder& effectBuilder) override;


    virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
    virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
    virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
    virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
+1 −1
Original line number Original line Diff line number Diff line
@@ -161,7 +161,7 @@ struct CanvasOp<CanvasOpType::DrawRippleProperty> {
        }
        }


        SkRuntimeShaderBuilder::BuilderUniform radiusU =
        SkRuntimeShaderBuilder::BuilderUniform radiusU =
                runtimeEffectBuilder.uniform("in_maxRadius");
                runtimeEffectBuilder.uniform("in_radius");
        if (radiusU.fVar != nullptr) {
        if (radiusU.fVar != nullptr) {
            radiusU = radius->value;
            radiusU = radius->value;
        }
        }
Loading