Loading core/api/current.txt +20 −0 Original line number Diff line number Diff line Loading @@ -16589,6 +16589,26 @@ package android.graphics { method public boolean setUseCompositingLayer(boolean, @Nullable android.graphics.Paint); } public class RuntimeShader extends android.graphics.Shader { ctor public RuntimeShader(@NonNull String); ctor public RuntimeShader(@NonNull String, boolean); method public boolean isForceOpaque(); method public void setColorUniform(@NonNull String, @ColorInt int); method public void setColorUniform(@NonNull String, @ColorLong long); method public void setColorUniform(@NonNull String, @NonNull android.graphics.Color); method public void setFloatUniform(@NonNull String, float); method public void setFloatUniform(@NonNull String, float, float); method public void setFloatUniform(@NonNull String, float, float, float); method public void setFloatUniform(@NonNull String, float, float, float, float); method public void setFloatUniform(@NonNull String, @NonNull float[]); method public void setInputShader(@NonNull String, @NonNull android.graphics.Shader); method public void setIntUniform(@NonNull String, int); method public void setIntUniform(@NonNull String, int, int); method public void setIntUniform(@NonNull String, int, int, int); method public void setIntUniform(@NonNull String, int, int, int, int); method public void setIntUniform(@NonNull String, @NonNull int[]); } public class Shader { ctor @Deprecated public Shader(); method public boolean getLocalMatrix(@NonNull android.graphics.Matrix); graphics/java/android/graphics/RuntimeShader.java +259 −33 Original line number Diff line number Diff line Loading @@ -16,13 +16,15 @@ package android.graphics; import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import libcore.util.NativeAllocationRegistry; /** * Shader that calculates pixel output with a program (fragment shader) running on a GPU. * @hide * Shader that calculates per-pixel color via a user defined Android Graphics Shading Language * (AGSL) function. */ public class RuntimeShader extends Shader { Loading @@ -32,7 +34,7 @@ public class RuntimeShader extends Shader { RuntimeShader.class.getClassLoader(), nativeGetFinalizer()); } private boolean mIsOpaque; private boolean mForceOpaque; /** * Current native shader builder instance. Loading @@ -42,57 +44,270 @@ public class RuntimeShader extends Shader { /** * 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 isOpaque True if all pixels have alpha 1.0f. * @param shader The text of AGSL shader program to run. */ public RuntimeShader(@NonNull String shader) { this(shader, false); } /** * Creates a new RuntimeShader. * * @param shader The text of AGSL shader program to run. * @param forceOpaque If true then all pixels produced by the AGSL shader program will have an * alpha of 1.0f. */ public RuntimeShader(@NonNull String sksl, boolean isOpaque) { public RuntimeShader(@NonNull String shader, boolean forceOpaque) { // colorspace is required, but the RuntimeShader always produces colors in the destination // buffer's colorspace regardless of the value specified here. super(ColorSpace.get(ColorSpace.Named.SRGB)); mIsOpaque = isOpaque; mNativeInstanceRuntimeShaderBuilder = nativeCreateBuilder(sksl); if (shader == null) { throw new NullPointerException("RuntimeShader requires a non-null AGSL string"); } mForceOpaque = forceOpaque; mNativeInstanceRuntimeShaderBuilder = nativeCreateBuilder(shader); NoImagePreloadHolder.sRegistry.registerNativeAllocation( this, mNativeInstanceRuntimeShaderBuilder); } public boolean isForceOpaque() { return mForceOpaque; } /** * Sets the uniform color 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 vec3 or vec4 and * corresponding layout(color) annotation then an IllegalArgumentException is thrown. * * @param uniformName name matching the color uniform declared in the AGSL shader program * @param color the provided sRGB color will be transformed into the shader program's output * colorspace and will be available as a vec4 uniform in the program. */ public void setColorUniform(@NonNull String uniformName, @ColorInt int color) { setUniform(uniformName, Color.valueOf(color).getComponents(), true); } /** * Sets the uniform color 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 vec3 or vec4 and * corresponding layout(color) annotation then an IllegalArgumentException is thrown. * * @param uniformName name matching the color uniform declared in the AGSL shader program * @param color the provided sRGB color will be transformed into the shader program's output * colorspace and will be available as a vec4 uniform in the program. */ public void setColorUniform(@NonNull String uniformName, @ColorLong long color) { Color exSRGB = Color.valueOf(color).convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)); setUniform(uniformName, exSRGB.getComponents(), true); } /** * Sets the uniform color 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 vec3 or vec4 and * corresponding layout(color) annotation then an IllegalArgumentException is thrown. * * @param uniformName name matching the color uniform declared in the AGSL shader program * @param color the provided sRGB color will be transformed into the shader program's output * colorspace and will be available as a vec4 uniform in the program. */ public void setColorUniform(@NonNull String uniformName, @NonNull Color color) { if (color == null) { throw new NullPointerException("The color parameter must not be null"); } Color exSRGB = color.convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)); setUniform(uniformName, exSRGB.getComponents(), true); } /** * 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 * with that name or if the uniform is declared with a type other than a float or float[1] * then an IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setFloatUniform(@NonNull String uniformName, float value) { setFloatUniform(uniformName, value, 0.0f, 0.0f, 0.0f, 1); } /** * 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 vec2 or float[2] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the SKSL shader * @param value * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setUniform(@NonNull String uniformName, float value) { setUniform(uniformName, new float[] {value}); public void setFloatUniform(@NonNull String uniformName, float value1, float value2) { setFloatUniform(uniformName, value1, value2, 0.0f, 0.0f, 2); } /** * 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 float2/vec2 then an * with that name or if the uniform is declared with a type other than vec3 or float[3] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the SKSL shader * @param value1 * @param value2 * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setUniform(@NonNull String uniformName, float value1, float value2) { setUniform(uniformName, new float[] {value1, value2}); public void setFloatUniform(@NonNull String uniformName, float value1, float value2, float value3) { setFloatUniform(uniformName, value1, value2, value3, 0.0f, 3); } /** * 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. * with that name or if the uniform is declared with a type other than vec4 or float[4] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the SKSL shader * @param values * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setFloatUniform(@NonNull String uniformName, float value1, float value2, float value3, float value4) { setFloatUniform(uniformName, value1, value2, value3, value4, 4); } /** * 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 float (for N=1), vecN, * or float[N] where N is the length of the values param then an IllegalArgumentException is * thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setFloatUniform(@NonNull String uniformName, @NonNull float[] values) { setUniform(uniformName, values, false); } /** * Old method signature used by some callers within the platform code * @hide * @deprecated use setFloatUniform instead */ @Deprecated public void setUniform(@NonNull String uniformName, float[] values) { setFloatUniform(uniformName, values); } /** * Old method signature used by some callers within the platform code * @hide * @deprecated use setFloatUniform instead */ @Deprecated public void setUniform(@NonNull String uniformName, float value) { setFloatUniform(uniformName, value); } /** * Old method signature used by some callers within the platform code * @hide * @deprecated use setFloatUniform instead */ @Deprecated public void setUniform(@NonNull String uniformName, float value1, float value2) { setFloatUniform(uniformName, value1, value2); } private void setFloatUniform(@NonNull String uniformName, float value1, float value2, float value3, float value4, int count) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, value1, value2, value3, value4, count); discardNativeInstance(); } private void setUniform(@NonNull String uniformName, @NonNull float[] values, boolean isColor) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } if (values == null) { throw new NullPointerException("The uniform values parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, values, isColor); discardNativeInstance(); } /** * 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 an int or int[1] * then an IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value) { setIntUniform(uniformName, value, 0, 0, 0, 1); } /** * 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 ivec2 or int[2] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value1, int value2) { setIntUniform(uniformName, value1, value2, 0, 0, 2); } /** * 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 ivec3 or int[3] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3) { setIntUniform(uniformName, value1, value2, value3, 0, 3); } /** * 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 ivec4 or int[4] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3, int value4) { setIntUniform(uniformName, value1, value2, value3, value4, 4); } /** * 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 an int (for N=1), ivecN, * or int[N] where N is the length of the values param then an IllegalArgumentException is * thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, @NonNull int[] values) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } if (values == null) { throw new NullPointerException("The uniform values parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, values); discardNativeInstance(); } private void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3, int value4, int count) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, value1, value2, value3, value4, count); discardNativeInstance(); } /** * 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. Loading @@ -101,6 +316,12 @@ public class RuntimeShader extends Shader { * @param shader shader passed into the SKSL shader for sampling */ public void setInputShader(@NonNull String shaderName, @NonNull Shader shader) { if (shaderName == null) { throw new NullPointerException("The shaderName parameter must not be null"); } if (shader == null) { throw new NullPointerException("The shader parameter must not be null"); } nativeUpdateShader( mNativeInstanceRuntimeShaderBuilder, shaderName, shader.getNativeInstance()); discardNativeInstance(); Loading @@ -109,23 +330,28 @@ public class RuntimeShader extends Shader { /** @hide */ @Override protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) { return nativeCreateShader(mNativeInstanceRuntimeShaderBuilder, nativeMatrix, mIsOpaque); return nativeCreateShader(mNativeInstanceRuntimeShaderBuilder, nativeMatrix, mForceOpaque); } public long getNativeShaderBuilder() { /** @hide */ protected long getNativeShaderBuilder() { return mNativeInstanceRuntimeShaderBuilder; } public boolean isOpaque() { return mIsOpaque; } private static native long nativeGetFinalizer(); private static native long nativeCreateBuilder(String sksl); private static native long nativeCreateBuilder(String agsl); private static native long nativeCreateShader( long shaderBuilder, long matrix, boolean isOpaque); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, float[] uniforms); long shaderBuilder, String uniformName, float[] uniforms, boolean isColor); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, float value1, float value2, float value3, float value4, int count); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, int[] uniforms); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, int value1, int value2, int value3, int value4, int count); private static native void nativeUpdateShader( long shaderBuilder, String shaderName, long shader); } Loading libs/hwui/jni/Shader.cpp +92 −7 Original line number Diff line number Diff line Loading @@ -273,21 +273,99 @@ static inline int ThrowIAEFmt(JNIEnv* env, const char* fmt, ...) { return ret; } static void RuntimeShader_updateUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jfloatArray jvalues) { static bool isIntUniformType(const SkRuntimeEffect::Uniform::Type& type) { switch (type) { case SkRuntimeEffect::Uniform::Type::kFloat: case SkRuntimeEffect::Uniform::Type::kFloat2: case SkRuntimeEffect::Uniform::Type::kFloat3: case SkRuntimeEffect::Uniform::Type::kFloat4: case SkRuntimeEffect::Uniform::Type::kFloat2x2: case SkRuntimeEffect::Uniform::Type::kFloat3x3: case SkRuntimeEffect::Uniform::Type::kFloat4x4: return false; case SkRuntimeEffect::Uniform::Type::kInt: case SkRuntimeEffect::Uniform::Type::kInt2: case SkRuntimeEffect::Uniform::Type::kInt3: case SkRuntimeEffect::Uniform::Type::kInt4: return true; } } static void UpdateFloatUniforms(JNIEnv* env, SkRuntimeShaderBuilder* builder, const char* uniformName, const float values[], int count, bool isColor) { SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(uniformName); if (uniform.fVar == nullptr) { ThrowIAEFmt(env, "unable to find uniform named %s", uniformName); } else if (isColor != ((uniform.fVar->flags & SkRuntimeEffect::Uniform::kColor_Flag) != 0)) { if (isColor) { jniThrowExceptionFmt( env, "java/lang/IllegalArgumentException", "attempting to set a color uniform using the non-color specific APIs: %s %x", uniformName, uniform.fVar->flags); } else { ThrowIAEFmt(env, "attempting to set a non-color uniform using the setColorUniform APIs: %s", uniformName); } } else if (isIntUniformType(uniform.fVar->type)) { ThrowIAEFmt(env, "attempting to set a int uniform using the setUniform APIs: %s", uniformName); } else if (!uniform.set<float>(values, count)) { ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]", uniform.fVar->sizeInBytes(), sizeof(float) * count); } } static void RuntimeShader_updateFloatUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jfloat value1, jfloat value2, jfloat value3, jfloat value4, jint count) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); const float values[4] = {value1, value2, value3, value4}; UpdateFloatUniforms(env, builder, name.c_str(), values, count, false); } static void RuntimeShader_updateFloatArrayUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jfloatArray jvalues, jboolean isColor) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); AutoJavaFloatArray autoValues(env, jvalues, 0, kRO_JNIAccess); UpdateFloatUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length(), isColor); } SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(name.c_str()); static void UpdateIntUniforms(JNIEnv* env, SkRuntimeShaderBuilder* builder, const char* uniformName, const int values[], int count) { SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(uniformName); if (uniform.fVar == nullptr) { ThrowIAEFmt(env, "unable to find uniform named %s", name.c_str()); } else if (!uniform.set<float>(autoValues.ptr(), autoValues.length())) { ThrowIAEFmt(env, "unable to find uniform named %s", uniformName); } else if (!isIntUniformType(uniform.fVar->type)) { ThrowIAEFmt(env, "attempting to set a non-int uniform using the setIntUniform APIs: %s", uniformName); } else if (!uniform.set<int>(values, count)) { ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]", uniform.fVar->sizeInBytes(), sizeof(float) * autoValues.length()); uniform.fVar->sizeInBytes(), sizeof(float) * count); } } static void RuntimeShader_updateIntUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jint value1, jint value2, jint value3, jint value4, jint count) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); const int values[4] = {value1, value2, value3, value4}; UpdateIntUniforms(env, builder, name.c_str(), values, count); } static void RuntimeShader_updateIntArrayUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jintArray jvalues) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); AutoJavaIntArray autoValues(env, jvalues, 0); UpdateIntUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length()); } static void RuntimeShader_updateShader(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jlong shaderHandle) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); Loading Loading @@ -338,7 +416,14 @@ static const JNINativeMethod gRuntimeShaderMethods[] = { {"nativeGetFinalizer", "()J", (void*)RuntimeShader_getNativeFinalizer}, {"nativeCreateShader", "(JJZ)J", (void*)RuntimeShader_create}, {"nativeCreateBuilder", "(Ljava/lang/String;)J", (void*)RuntimeShader_createShaderBuilder}, {"nativeUpdateUniforms", "(JLjava/lang/String;[F)V", (void*)RuntimeShader_updateUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V", (void*)RuntimeShader_updateFloatArrayUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;FFFFI)V", (void*)RuntimeShader_updateFloatUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;[I)V", (void*)RuntimeShader_updateIntArrayUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V", (void*)RuntimeShader_updateIntUniforms}, {"nativeUpdateShader", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateShader}, }; Loading Loading
core/api/current.txt +20 −0 Original line number Diff line number Diff line Loading @@ -16589,6 +16589,26 @@ package android.graphics { method public boolean setUseCompositingLayer(boolean, @Nullable android.graphics.Paint); } public class RuntimeShader extends android.graphics.Shader { ctor public RuntimeShader(@NonNull String); ctor public RuntimeShader(@NonNull String, boolean); method public boolean isForceOpaque(); method public void setColorUniform(@NonNull String, @ColorInt int); method public void setColorUniform(@NonNull String, @ColorLong long); method public void setColorUniform(@NonNull String, @NonNull android.graphics.Color); method public void setFloatUniform(@NonNull String, float); method public void setFloatUniform(@NonNull String, float, float); method public void setFloatUniform(@NonNull String, float, float, float); method public void setFloatUniform(@NonNull String, float, float, float, float); method public void setFloatUniform(@NonNull String, @NonNull float[]); method public void setInputShader(@NonNull String, @NonNull android.graphics.Shader); method public void setIntUniform(@NonNull String, int); method public void setIntUniform(@NonNull String, int, int); method public void setIntUniform(@NonNull String, int, int, int); method public void setIntUniform(@NonNull String, int, int, int, int); method public void setIntUniform(@NonNull String, @NonNull int[]); } public class Shader { ctor @Deprecated public Shader(); method public boolean getLocalMatrix(@NonNull android.graphics.Matrix);
graphics/java/android/graphics/RuntimeShader.java +259 −33 Original line number Diff line number Diff line Loading @@ -16,13 +16,15 @@ package android.graphics; import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import libcore.util.NativeAllocationRegistry; /** * Shader that calculates pixel output with a program (fragment shader) running on a GPU. * @hide * Shader that calculates per-pixel color via a user defined Android Graphics Shading Language * (AGSL) function. */ public class RuntimeShader extends Shader { Loading @@ -32,7 +34,7 @@ public class RuntimeShader extends Shader { RuntimeShader.class.getClassLoader(), nativeGetFinalizer()); } private boolean mIsOpaque; private boolean mForceOpaque; /** * Current native shader builder instance. Loading @@ -42,57 +44,270 @@ public class RuntimeShader extends Shader { /** * 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 isOpaque True if all pixels have alpha 1.0f. * @param shader The text of AGSL shader program to run. */ public RuntimeShader(@NonNull String shader) { this(shader, false); } /** * Creates a new RuntimeShader. * * @param shader The text of AGSL shader program to run. * @param forceOpaque If true then all pixels produced by the AGSL shader program will have an * alpha of 1.0f. */ public RuntimeShader(@NonNull String sksl, boolean isOpaque) { public RuntimeShader(@NonNull String shader, boolean forceOpaque) { // colorspace is required, but the RuntimeShader always produces colors in the destination // buffer's colorspace regardless of the value specified here. super(ColorSpace.get(ColorSpace.Named.SRGB)); mIsOpaque = isOpaque; mNativeInstanceRuntimeShaderBuilder = nativeCreateBuilder(sksl); if (shader == null) { throw new NullPointerException("RuntimeShader requires a non-null AGSL string"); } mForceOpaque = forceOpaque; mNativeInstanceRuntimeShaderBuilder = nativeCreateBuilder(shader); NoImagePreloadHolder.sRegistry.registerNativeAllocation( this, mNativeInstanceRuntimeShaderBuilder); } public boolean isForceOpaque() { return mForceOpaque; } /** * Sets the uniform color 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 vec3 or vec4 and * corresponding layout(color) annotation then an IllegalArgumentException is thrown. * * @param uniformName name matching the color uniform declared in the AGSL shader program * @param color the provided sRGB color will be transformed into the shader program's output * colorspace and will be available as a vec4 uniform in the program. */ public void setColorUniform(@NonNull String uniformName, @ColorInt int color) { setUniform(uniformName, Color.valueOf(color).getComponents(), true); } /** * Sets the uniform color 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 vec3 or vec4 and * corresponding layout(color) annotation then an IllegalArgumentException is thrown. * * @param uniformName name matching the color uniform declared in the AGSL shader program * @param color the provided sRGB color will be transformed into the shader program's output * colorspace and will be available as a vec4 uniform in the program. */ public void setColorUniform(@NonNull String uniformName, @ColorLong long color) { Color exSRGB = Color.valueOf(color).convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)); setUniform(uniformName, exSRGB.getComponents(), true); } /** * Sets the uniform color 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 vec3 or vec4 and * corresponding layout(color) annotation then an IllegalArgumentException is thrown. * * @param uniformName name matching the color uniform declared in the AGSL shader program * @param color the provided sRGB color will be transformed into the shader program's output * colorspace and will be available as a vec4 uniform in the program. */ public void setColorUniform(@NonNull String uniformName, @NonNull Color color) { if (color == null) { throw new NullPointerException("The color parameter must not be null"); } Color exSRGB = color.convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)); setUniform(uniformName, exSRGB.getComponents(), true); } /** * 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 * with that name or if the uniform is declared with a type other than a float or float[1] * then an IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setFloatUniform(@NonNull String uniformName, float value) { setFloatUniform(uniformName, value, 0.0f, 0.0f, 0.0f, 1); } /** * 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 vec2 or float[2] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the SKSL shader * @param value * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setUniform(@NonNull String uniformName, float value) { setUniform(uniformName, new float[] {value}); public void setFloatUniform(@NonNull String uniformName, float value1, float value2) { setFloatUniform(uniformName, value1, value2, 0.0f, 0.0f, 2); } /** * 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 float2/vec2 then an * with that name or if the uniform is declared with a type other than vec3 or float[3] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the SKSL shader * @param value1 * @param value2 * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setUniform(@NonNull String uniformName, float value1, float value2) { setUniform(uniformName, new float[] {value1, value2}); public void setFloatUniform(@NonNull String uniformName, float value1, float value2, float value3) { setFloatUniform(uniformName, value1, value2, value3, 0.0f, 3); } /** * 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. * with that name or if the uniform is declared with a type other than vec4 or float[4] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the SKSL shader * @param values * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setFloatUniform(@NonNull String uniformName, float value1, float value2, float value3, float value4) { setFloatUniform(uniformName, value1, value2, value3, value4, 4); } /** * 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 float (for N=1), vecN, * or float[N] where N is the length of the values param then an IllegalArgumentException is * thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setFloatUniform(@NonNull String uniformName, @NonNull float[] values) { setUniform(uniformName, values, false); } /** * Old method signature used by some callers within the platform code * @hide * @deprecated use setFloatUniform instead */ @Deprecated public void setUniform(@NonNull String uniformName, float[] values) { setFloatUniform(uniformName, values); } /** * Old method signature used by some callers within the platform code * @hide * @deprecated use setFloatUniform instead */ @Deprecated public void setUniform(@NonNull String uniformName, float value) { setFloatUniform(uniformName, value); } /** * Old method signature used by some callers within the platform code * @hide * @deprecated use setFloatUniform instead */ @Deprecated public void setUniform(@NonNull String uniformName, float value1, float value2) { setFloatUniform(uniformName, value1, value2); } private void setFloatUniform(@NonNull String uniformName, float value1, float value2, float value3, float value4, int count) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, value1, value2, value3, value4, count); discardNativeInstance(); } private void setUniform(@NonNull String uniformName, @NonNull float[] values, boolean isColor) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } if (values == null) { throw new NullPointerException("The uniform values parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, values, isColor); discardNativeInstance(); } /** * 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 an int or int[1] * then an IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value) { setIntUniform(uniformName, value, 0, 0, 0, 1); } /** * 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 ivec2 or int[2] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value1, int value2) { setIntUniform(uniformName, value1, value2, 0, 0, 2); } /** * 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 ivec3 or int[3] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3) { setIntUniform(uniformName, value1, value2, value3, 0, 3); } /** * 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 ivec4 or int[4] then an * IllegalArgumentException is thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3, int value4) { setIntUniform(uniformName, value1, value2, value3, value4, 4); } /** * 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 an int (for N=1), ivecN, * or int[N] where N is the length of the values param then an IllegalArgumentException is * thrown. * * @param uniformName name matching the uniform declared in the AGSL shader program */ public void setIntUniform(@NonNull String uniformName, @NonNull int[] values) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } if (values == null) { throw new NullPointerException("The uniform values parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, values); discardNativeInstance(); } private void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3, int value4, int count) { if (uniformName == null) { throw new NullPointerException("The uniformName parameter must not be null"); } nativeUpdateUniforms(mNativeInstanceRuntimeShaderBuilder, uniformName, value1, value2, value3, value4, count); discardNativeInstance(); } /** * 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. Loading @@ -101,6 +316,12 @@ public class RuntimeShader extends Shader { * @param shader shader passed into the SKSL shader for sampling */ public void setInputShader(@NonNull String shaderName, @NonNull Shader shader) { if (shaderName == null) { throw new NullPointerException("The shaderName parameter must not be null"); } if (shader == null) { throw new NullPointerException("The shader parameter must not be null"); } nativeUpdateShader( mNativeInstanceRuntimeShaderBuilder, shaderName, shader.getNativeInstance()); discardNativeInstance(); Loading @@ -109,23 +330,28 @@ public class RuntimeShader extends Shader { /** @hide */ @Override protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) { return nativeCreateShader(mNativeInstanceRuntimeShaderBuilder, nativeMatrix, mIsOpaque); return nativeCreateShader(mNativeInstanceRuntimeShaderBuilder, nativeMatrix, mForceOpaque); } public long getNativeShaderBuilder() { /** @hide */ protected long getNativeShaderBuilder() { return mNativeInstanceRuntimeShaderBuilder; } public boolean isOpaque() { return mIsOpaque; } private static native long nativeGetFinalizer(); private static native long nativeCreateBuilder(String sksl); private static native long nativeCreateBuilder(String agsl); private static native long nativeCreateShader( long shaderBuilder, long matrix, boolean isOpaque); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, float[] uniforms); long shaderBuilder, String uniformName, float[] uniforms, boolean isColor); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, float value1, float value2, float value3, float value4, int count); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, int[] uniforms); private static native void nativeUpdateUniforms( long shaderBuilder, String uniformName, int value1, int value2, int value3, int value4, int count); private static native void nativeUpdateShader( long shaderBuilder, String shaderName, long shader); } Loading
libs/hwui/jni/Shader.cpp +92 −7 Original line number Diff line number Diff line Loading @@ -273,21 +273,99 @@ static inline int ThrowIAEFmt(JNIEnv* env, const char* fmt, ...) { return ret; } static void RuntimeShader_updateUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jfloatArray jvalues) { static bool isIntUniformType(const SkRuntimeEffect::Uniform::Type& type) { switch (type) { case SkRuntimeEffect::Uniform::Type::kFloat: case SkRuntimeEffect::Uniform::Type::kFloat2: case SkRuntimeEffect::Uniform::Type::kFloat3: case SkRuntimeEffect::Uniform::Type::kFloat4: case SkRuntimeEffect::Uniform::Type::kFloat2x2: case SkRuntimeEffect::Uniform::Type::kFloat3x3: case SkRuntimeEffect::Uniform::Type::kFloat4x4: return false; case SkRuntimeEffect::Uniform::Type::kInt: case SkRuntimeEffect::Uniform::Type::kInt2: case SkRuntimeEffect::Uniform::Type::kInt3: case SkRuntimeEffect::Uniform::Type::kInt4: return true; } } static void UpdateFloatUniforms(JNIEnv* env, SkRuntimeShaderBuilder* builder, const char* uniformName, const float values[], int count, bool isColor) { SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(uniformName); if (uniform.fVar == nullptr) { ThrowIAEFmt(env, "unable to find uniform named %s", uniformName); } else if (isColor != ((uniform.fVar->flags & SkRuntimeEffect::Uniform::kColor_Flag) != 0)) { if (isColor) { jniThrowExceptionFmt( env, "java/lang/IllegalArgumentException", "attempting to set a color uniform using the non-color specific APIs: %s %x", uniformName, uniform.fVar->flags); } else { ThrowIAEFmt(env, "attempting to set a non-color uniform using the setColorUniform APIs: %s", uniformName); } } else if (isIntUniformType(uniform.fVar->type)) { ThrowIAEFmt(env, "attempting to set a int uniform using the setUniform APIs: %s", uniformName); } else if (!uniform.set<float>(values, count)) { ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]", uniform.fVar->sizeInBytes(), sizeof(float) * count); } } static void RuntimeShader_updateFloatUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jfloat value1, jfloat value2, jfloat value3, jfloat value4, jint count) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); const float values[4] = {value1, value2, value3, value4}; UpdateFloatUniforms(env, builder, name.c_str(), values, count, false); } static void RuntimeShader_updateFloatArrayUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jfloatArray jvalues, jboolean isColor) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); AutoJavaFloatArray autoValues(env, jvalues, 0, kRO_JNIAccess); UpdateFloatUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length(), isColor); } SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(name.c_str()); static void UpdateIntUniforms(JNIEnv* env, SkRuntimeShaderBuilder* builder, const char* uniformName, const int values[], int count) { SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(uniformName); if (uniform.fVar == nullptr) { ThrowIAEFmt(env, "unable to find uniform named %s", name.c_str()); } else if (!uniform.set<float>(autoValues.ptr(), autoValues.length())) { ThrowIAEFmt(env, "unable to find uniform named %s", uniformName); } else if (!isIntUniformType(uniform.fVar->type)) { ThrowIAEFmt(env, "attempting to set a non-int uniform using the setIntUniform APIs: %s", uniformName); } else if (!uniform.set<int>(values, count)) { ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]", uniform.fVar->sizeInBytes(), sizeof(float) * autoValues.length()); uniform.fVar->sizeInBytes(), sizeof(float) * count); } } static void RuntimeShader_updateIntUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jint value1, jint value2, jint value3, jint value4, jint count) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); const int values[4] = {value1, value2, value3, value4}; UpdateIntUniforms(env, builder, name.c_str(), values, count); } static void RuntimeShader_updateIntArrayUniforms(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jintArray jvalues) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); ScopedUtfChars name(env, jUniformName); AutoJavaIntArray autoValues(env, jvalues, 0); UpdateIntUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length()); } static void RuntimeShader_updateShader(JNIEnv* env, jobject, jlong shaderBuilder, jstring jUniformName, jlong shaderHandle) { SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder); Loading Loading @@ -338,7 +416,14 @@ static const JNINativeMethod gRuntimeShaderMethods[] = { {"nativeGetFinalizer", "()J", (void*)RuntimeShader_getNativeFinalizer}, {"nativeCreateShader", "(JJZ)J", (void*)RuntimeShader_create}, {"nativeCreateBuilder", "(Ljava/lang/String;)J", (void*)RuntimeShader_createShaderBuilder}, {"nativeUpdateUniforms", "(JLjava/lang/String;[F)V", (void*)RuntimeShader_updateUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V", (void*)RuntimeShader_updateFloatArrayUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;FFFFI)V", (void*)RuntimeShader_updateFloatUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;[I)V", (void*)RuntimeShader_updateIntArrayUniforms}, {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V", (void*)RuntimeShader_updateIntUniforms}, {"nativeUpdateShader", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateShader}, }; Loading