diff options
Diffstat (limited to 'graphics/java')
| -rw-r--r-- | graphics/java/android/graphics/BitmapShader.java | 98 | ||||
| -rw-r--r-- | graphics/java/android/graphics/RuntimeShader.java | 28 |
2 files changed, 119 insertions, 7 deletions
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java index e6ff187bd99d..43cb5ee8b5c0 100644 --- a/graphics/java/android/graphics/BitmapShader.java +++ b/graphics/java/android/graphics/BitmapShader.java @@ -16,8 +16,12 @@ package android.graphics; +import android.annotation.IntDef; import android.annotation.NonNull; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Shader used to draw a bitmap as a texture. The bitmap can be repeated or * mirrored by setting the tiling mode. @@ -31,6 +35,47 @@ public class BitmapShader extends Shader { private int mTileX; private int mTileY; + /** @hide */ + @IntDef(prefix = {"FILTER_MODE"}, value = { + FILTER_MODE_DEFAULT, + FILTER_MODE_NEAREST, + FILTER_MODE_LINEAR + }) + @Retention(RetentionPolicy.SOURCE) + public @interface FilterMode {} + + /** + * This FilterMode value will respect the value of the Paint#isFilterBitmap flag while the + * shader is attached to the Paint. + * + * <p>The exception to this rule is when a Shader is attached as input to a RuntimeShader. In + * that case this mode will default to FILTER_MODE_NEAREST.</p> + * + * @see #setFilterMode(int) + */ + public static final int FILTER_MODE_DEFAULT = 0; + /** + * This FilterMode value will cause the shader to sample from the nearest pixel to the requested + * sample point. + * + * <p>This value will override the effect of Paint#isFilterBitmap.</p> + * + * @see #setFilterMode(int) + */ + public static final int FILTER_MODE_NEAREST = 1; + /** + * This FilterMode value will cause the shader to interpolate the output of the shader from a + * 2x2 grid of pixels nearest to the sample point (i.e. bilinear interpolation). + * + * <p>This value will override the effect of Paint#isFilterBitmap.</p> + * + * @see #setFilterMode(int) + */ + public static final int FILTER_MODE_LINEAR = 2; + + @FilterMode + private int mFilterMode; + /* * This is cache of the last value from the Paint of bitmap-filtering. * In the future, BitmapShaders will carry their own (expanded) data for this @@ -49,6 +94,15 @@ public class BitmapShader extends Shader { private boolean mFilterFromPaint; /** + * Stores whether or not the contents of this shader's bitmap will be sampled + * without modification or if the bitmap's properties, like colorspace and + * premultiplied alpha, will be respected when sampling from the bitmap's buffer. + */ + private boolean mIsDirectSampled; + + private boolean mRequestDirectSampling; + + /** * Call this to create a new shader that will draw with a bitmap. * * @param bitmap The bitmap to use inside the shader @@ -66,24 +120,60 @@ public class BitmapShader extends Shader { mBitmap = bitmap; mTileX = tileX; mTileY = tileY; + mFilterMode = FILTER_MODE_DEFAULT; mFilterFromPaint = false; + mIsDirectSampled = false; + mRequestDirectSampling = false; + } + + /** + * Returns the filter mode used when sampling from this shader + */ + @FilterMode + public int getFilterMode() { + return mFilterMode; + } + + /** + * Set the filter mode to be used when sampling from this shader + */ + public void setFilterMode(@FilterMode int mode) { + if (mode != mFilterMode) { + mFilterMode = mode; + discardNativeInstance(); + } + } + + /** @hide */ + /* package */ synchronized long getNativeInstanceWithDirectSampling() { + mRequestDirectSampling = true; + return getNativeInstance(); } /** @hide */ @Override protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) { - mFilterFromPaint = filterFromPaint; + boolean enableLinearFilter = mFilterMode == FILTER_MODE_LINEAR; + if (mFilterMode == FILTER_MODE_DEFAULT) { + mFilterFromPaint = filterFromPaint; + enableLinearFilter = mFilterFromPaint; + } + + mIsDirectSampled = mRequestDirectSampling; + mRequestDirectSampling = false; + return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY, - mFilterFromPaint); + enableLinearFilter, mIsDirectSampled); } /** @hide */ @Override protected boolean shouldDiscardNativeInstance(boolean filterFromPaint) { - return mFilterFromPaint != filterFromPaint; + return mIsDirectSampled != mRequestDirectSampling + || (mFilterMode == FILTER_MODE_DEFAULT && mFilterFromPaint != filterFromPaint); } private static native long nativeCreate(long nativeMatrix, long bitmapHandle, - int shaderTileModeX, int shaderTileModeY, boolean filter); + int shaderTileModeX, int shaderTileModeY, boolean filter, boolean isDirectSampled); } diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java index ef57f4a76007..57046f5de61d 100644 --- a/graphics/java/android/graphics/RuntimeShader.java +++ b/graphics/java/android/graphics/RuntimeShader.java @@ -279,11 +279,11 @@ public class RuntimeShader extends Shader { } /** - * Sets the uniform shader that is declares as input to this shader. If the shader does not + * Assigns the uniform shader to the provided shader parameter. If the shader program does not * have a uniform shader with that name then an IllegalArgumentException is thrown. * - * @param shaderName name matching the uniform declared in the SKSL shader - * @param shader shader passed into the SKSL shader for sampling + * @param shaderName name matching the uniform declared in the AGSL shader program + * @param shader shader passed into the AGSL shader program for sampling */ public void setInputShader(@NonNull String shaderName, @NonNull Shader shader) { if (shaderName == null) { @@ -297,6 +297,28 @@ public class RuntimeShader extends Shader { discardNativeInstance(); } + /** + * Assigns the uniform shader to the provided shader parameter. If the shader program does not + * have a uniform shader with that name then an IllegalArgumentException is thrown. + * + * Unlike setInputShader this method returns samples directly from the bitmap's buffer. This + * means that there will be no transformation of the sampled pixels, such as colorspace + * conversion or alpha premultiplication. + */ + public void setInputBuffer(@NonNull String shaderName, @NonNull BitmapShader 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.getNativeInstanceWithDirectSampling()); + discardNativeInstance(); + } + + /** @hide */ @Override protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) { |