Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12a5d4d1 authored by Nader Jawad's avatar Nader Jawad Committed by Android (Google) Code Review
Browse files

Merge "Added support for BitmapShader anisotropic filtering"

parents 0dc49b41 2a49934e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -14912,7 +14912,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
+46 −3
Original line number Diff line number Diff line
@@ -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,9 +197,14 @@ public class BitmapShader extends Shader {
        mIsDirectSampled = mRequestDirectSampling;
        mRequestDirectSampling = false;

        if (mMaxAniso > 0) {
            return nativeCreateWithMaxAniso(nativeMatrix, mBitmap.getNativeInstance(), mTileX,
                    mTileY, mMaxAniso, mIsDirectSampled);
        } else {
            return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY,
                    enableLinearFilter, mIsDirectSampled);
        }
    }

    /** @hide */
    @Override
@@ -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);
}
+26 −7
Original line number Diff line number Diff line
@@ -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[] = {