Loading graphics/java/android/graphics/RuntimeShader.java +39 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ public class RuntimeShader extends Shader { } private byte[] mUniforms; private Shader[] mInputShaders; private boolean mIsOpaque; /** Loading @@ -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, Loading @@ -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); Loading libs/hwui/jni/Shader.cpp +15 −3 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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 }, }; Loading tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java +9 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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]; Loading @@ -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); Loading Loading
graphics/java/android/graphics/RuntimeShader.java +39 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ public class RuntimeShader extends Shader { } private byte[] mUniforms; private Shader[] mInputShaders; private boolean mIsOpaque; /** Loading @@ -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, Loading @@ -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); Loading
libs/hwui/jni/Shader.cpp +15 −3 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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 }, }; Loading
tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java +9 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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]; Loading @@ -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); Loading