Added support for BitmapShader anisotropic filtering
Relnote: "Created new BitmapShader constructor that enables support for anisotropic filtering." Bug: 267687306 Test: Added tests to BitmapShaderTest Change-Id: Ie6e5551f3ae6140dc3afb2d65967b5a6bc08523c
This commit is contained in:
@@ -14908,7 +14908,9 @@ 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 int getMaxAnisotropy();
|
||||
method public void setFilterMode(int);
|
||||
method public void setMaxAnisotropy(@IntRange(from=1) 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
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.graphics;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -102,6 +103,8 @@ public class BitmapShader extends Shader {
|
||||
|
||||
private boolean mRequestDirectSampling;
|
||||
|
||||
private int mMaxAniso = 0;
|
||||
|
||||
/**
|
||||
* Call this to create a new shader that will draw with a bitmap.
|
||||
*
|
||||
@@ -135,15 +138,47 @@ public class BitmapShader extends Shader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filter mode to be used when sampling from this shader
|
||||
* Set the filter mode to be used when sampling from this shader. If this is configured
|
||||
* then the anisotropic filtering value specified in any previous call to
|
||||
* {@link #setMaxAnisotropy(int)} is ignored.
|
||||
*/
|
||||
public void setFilterMode(@FilterMode int mode) {
|
||||
if (mode != mFilterMode) {
|
||||
mFilterMode = mode;
|
||||
mMaxAniso = 0;
|
||||
discardNativeInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables and configures the max anisotropy sampling value. If this value is configured,
|
||||
* {@link #setFilterMode(int)} is ignored.
|
||||
*
|
||||
* Anisotropic filtering can enhance visual quality by removing aliasing effects of images
|
||||
* that are at oblique viewing angles. This value is typically consumed as a power of 2 and
|
||||
* anisotropic values of the next power of 2 typically provide twice the quality improvement
|
||||
* as the previous value. For example, a sampling value of 4 would provide twice the improvement
|
||||
* of a sampling value of 2. It is important to note that higher sampling values reach
|
||||
* diminishing returns as the improvements between 8 and 16 can be slight.
|
||||
*
|
||||
* @param maxAnisotropy The Anisotropy value to use for filtering. Must be greater than 0.
|
||||
*/
|
||||
public void setMaxAnisotropy(@IntRange(from = 1) int maxAnisotropy) {
|
||||
if (mMaxAniso != maxAnisotropy && maxAnisotropy > 0) {
|
||||
mMaxAniso = maxAnisotropy;
|
||||
mFilterMode = FILTER_MODE_DEFAULT;
|
||||
discardNativeInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current max anisotropic filtering value configured by
|
||||
* {@link #setFilterMode(int)}. If {@link #setFilterMode(int)} is invoked this returns zero.
|
||||
*/
|
||||
public int getMaxAnisotropy() {
|
||||
return mMaxAniso;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/* package */ synchronized long getNativeInstanceWithDirectSampling() {
|
||||
mRequestDirectSampling = true;
|
||||
@@ -162,8 +197,13 @@ public class BitmapShader extends Shader {
|
||||
mIsDirectSampled = mRequestDirectSampling;
|
||||
mRequestDirectSampling = false;
|
||||
|
||||
return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY,
|
||||
enableLinearFilter, mIsDirectSampled);
|
||||
if (mMaxAniso > 0) {
|
||||
return nativeCreateWithMaxAniso(nativeMatrix, mBitmap.getNativeInstance(), mTileX,
|
||||
mTileY, mMaxAniso, mIsDirectSampled);
|
||||
} else {
|
||||
return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY,
|
||||
enableLinearFilter, mIsDirectSampled);
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -175,5 +215,8 @@ public class BitmapShader extends Shader {
|
||||
|
||||
private static native long nativeCreate(long nativeMatrix, long bitmapHandle,
|
||||
int shaderTileModeX, int shaderTileModeY, boolean filter, boolean isDirectSampled);
|
||||
|
||||
private static native long nativeCreateWithMaxAniso(long nativeMatrix, long bitmapHandle,
|
||||
int shaderTileModeX, int shaderTileModeY, int maxAniso, boolean isDirectSampled);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,11 +71,9 @@ static jlong Shader_getNativeFinalizer(JNIEnv*, jobject) {
|
||||
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
|
||||
jint tileModeX, jint tileModeY, bool filter,
|
||||
bool isDirectSampled) {
|
||||
static jlong createBitmapShaderHelper(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
|
||||
jint tileModeX, jint tileModeY, bool isDirectSampled,
|
||||
const SkSamplingOptions& sampling) {
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
sk_sp<SkImage> image;
|
||||
if (bitmapHandle) {
|
||||
@@ -88,8 +86,7 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j
|
||||
SkBitmap bitmap;
|
||||
image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
|
||||
}
|
||||
SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
|
||||
SkMipmapMode::kNone);
|
||||
|
||||
sk_sp<SkShader> shader;
|
||||
if (isDirectSampled) {
|
||||
shader = image->makeRawShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
|
||||
@@ -107,6 +104,26 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
|
||||
jint tileModeX, jint tileModeY, bool filter,
|
||||
bool isDirectSampled) {
|
||||
SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
|
||||
SkMipmapMode::kNone);
|
||||
return createBitmapShaderHelper(env, o, matrixPtr, bitmapHandle, tileModeX, tileModeY,
|
||||
isDirectSampled, sampling);
|
||||
}
|
||||
|
||||
static jlong BitmapShader_constructorWithMaxAniso(JNIEnv* env, jobject o, jlong matrixPtr,
|
||||
jlong bitmapHandle, jint tileModeX,
|
||||
jint tileModeY, jint maxAniso,
|
||||
bool isDirectSampled) {
|
||||
auto sampling = SkSamplingOptions::Aniso(static_cast<int>(maxAniso));
|
||||
return createBitmapShaderHelper(env, o, matrixPtr, bitmapHandle, tileModeX, tileModeY,
|
||||
isDirectSampled, sampling);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static std::vector<SkColor4f> convertColorLongs(JNIEnv* env, jlongArray colorArray) {
|
||||
const size_t count = env->GetArrayLength(colorArray);
|
||||
const jlong* colorValues = env->GetLongArrayElements(colorArray, nullptr);
|
||||
@@ -408,6 +425,8 @@ static const JNINativeMethod gShaderMethods[] = {
|
||||
|
||||
static const JNINativeMethod gBitmapShaderMethods[] = {
|
||||
{"nativeCreate", "(JJIIZZ)J", (void*)BitmapShader_constructor},
|
||||
{"nativeCreateWithMaxAniso", "(JJIIIZ)J", (void*)BitmapShader_constructorWithMaxAniso},
|
||||
|
||||
};
|
||||
|
||||
static const JNINativeMethod gLinearGradientMethods[] = {
|
||||
|
||||
Reference in New Issue
Block a user