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

Commit 1a58f4a7 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Add filtering and directSampling features for BitmapShader"

parents 0eea23e3 4d3df820
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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);
+94 −4
Original line number Diff line number Diff line
@@ -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) {
        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);
}
+25 −3
Original line number Diff line number Diff line
@@ -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) {
+9 −4
Original line number Diff line number Diff line
@@ -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[] = {