Merge "Add filtering and directSampling features for BitmapShader"
This commit is contained in:
committed by
Android (Google) Code Review
commit
1a58f4a793
@@ -15242,6 +15242,11 @@ package android.graphics {
|
||||
|
||||
public class BitmapShader extends android.graphics.Shader {
|
||||
ctor public BitmapShader(@NonNull android.graphics.Bitmap, @NonNull android.graphics.Shader.TileMode, @NonNull android.graphics.Shader.TileMode);
|
||||
method public int getFilterMode();
|
||||
method public void setFilterMode(int);
|
||||
field public static final int FILTER_MODE_DEFAULT = 0; // 0x0
|
||||
field public static final int FILTER_MODE_LINEAR = 2; // 0x2
|
||||
field public static final int FILTER_MODE_NEAREST = 1; // 0x1
|
||||
}
|
||||
|
||||
public enum BlendMode {
|
||||
@@ -16648,6 +16653,7 @@ package android.graphics {
|
||||
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 setInputBuffer(@NonNull String, @NonNull android.graphics.BitmapShader);
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
@@ -48,6 +93,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.
|
||||
*
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -64,7 +64,8 @@ static jlong Shader_getNativeFinalizer(JNIEnv*, jobject) {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
|
||||
jint tileModeX, jint tileModeY, bool filter) {
|
||||
jint tileModeX, jint tileModeY, bool filter,
|
||||
bool isDirectSampled) {
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
sk_sp<SkImage> image;
|
||||
if (bitmapHandle) {
|
||||
@@ -79,8 +80,12 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j
|
||||
}
|
||||
SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
|
||||
SkMipmapMode::kNone);
|
||||
sk_sp<SkShader> shader = image->makeShader(
|
||||
(SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
|
||||
sk_sp<SkShader> shader;
|
||||
if (isDirectSampled) {
|
||||
shader = image->makeRawShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
|
||||
} else {
|
||||
shader = image->makeShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
|
||||
}
|
||||
ThrowIAE_IfNull(env, shader.get());
|
||||
|
||||
if (matrix) {
|
||||
@@ -393,7 +398,7 @@ static const JNINativeMethod gShaderMethods[] = {
|
||||
};
|
||||
|
||||
static const JNINativeMethod gBitmapShaderMethods[] = {
|
||||
{ "nativeCreate", "(JJIIZ)J", (void*)BitmapShader_constructor },
|
||||
{"nativeCreate", "(JJIIZZ)J", (void*)BitmapShader_constructor},
|
||||
};
|
||||
|
||||
static const JNINativeMethod gLinearGradientMethods[] = {
|
||||
|
||||
Reference in New Issue
Block a user