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

Commit b581e670 authored by Chris Craik's avatar Chris Craik
Browse files

Support for shader mutation

Bug: 36025103

Test: cts-tradefed run singleCommand cts-dev --module CtsGraphicsTestCases
Test: cts-tradefed run singleCommand cts-dev --module CtsUiRenderingTestCases
Test: manually inspected for leaks via SK_TRACK_SHADER_LIFETIME and forcing a GC after ComposeShaderTest

Change-Id: Ib5d33a80d2f9f468705806b05832e753508143cc
parent 9f2888d9
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -12321,6 +12321,7 @@ package android.graphics {
  public class BitmapShader extends android.graphics.Shader {
    ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
  }
  public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -12704,6 +12705,8 @@ package android.graphics {
  public class ComposeShader extends android.graphics.Shader {
    ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
    ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
  }
  public class CornerPathEffect extends android.graphics.PathEffect {
@@ -12779,6 +12782,8 @@ package android.graphics {
  public class LinearGradient extends android.graphics.Shader {
    ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
    ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
  }
  public class MaskFilter {
@@ -13297,6 +13302,8 @@ package android.graphics {
  public class RadialGradient extends android.graphics.Shader {
    ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
    ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
  }
  public final class Rect implements android.os.Parcelable {
@@ -13436,7 +13443,7 @@ package android.graphics {
  }
  public class Shader {
    ctor public Shader();
    ctor public deprecated Shader();
    method public boolean getLocalMatrix(android.graphics.Matrix);
    method public void setLocalMatrix(android.graphics.Matrix);
  }
@@ -13481,6 +13488,8 @@ package android.graphics {
  public class SweepGradient extends android.graphics.Shader {
    ctor public SweepGradient(float, float, int[], float[]);
    ctor public SweepGradient(float, float, int, int);
    method public void set(float, float, int[], float[]);
    method public void set(float, float, int, int);
  }
  public class Typeface {
+10 −1
Original line number Diff line number Diff line
@@ -13038,6 +13038,7 @@ package android.graphics {
  public class BitmapShader extends android.graphics.Shader {
    ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
  }
  public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -13421,6 +13422,8 @@ package android.graphics {
  public class ComposeShader extends android.graphics.Shader {
    ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
    ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
  }
  public class CornerPathEffect extends android.graphics.PathEffect {
@@ -13496,6 +13499,8 @@ package android.graphics {
  public class LinearGradient extends android.graphics.Shader {
    ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
    ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
  }
  public class MaskFilter {
@@ -14014,6 +14019,8 @@ package android.graphics {
  public class RadialGradient extends android.graphics.Shader {
    ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
    ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
  }
  public final class Rect implements android.os.Parcelable {
@@ -14153,7 +14160,7 @@ package android.graphics {
  }
  public class Shader {
    ctor public Shader();
    ctor public deprecated Shader();
    method public boolean getLocalMatrix(android.graphics.Matrix);
    method public void setLocalMatrix(android.graphics.Matrix);
  }
@@ -14198,6 +14205,8 @@ package android.graphics {
  public class SweepGradient extends android.graphics.Shader {
    ctor public SweepGradient(float, float, int[], float[]);
    ctor public SweepGradient(float, float, int, int);
    method public void set(float, float, int[], float[]);
    method public void set(float, float, int, int);
  }
  public class Typeface {
+10 −1
Original line number Diff line number Diff line
@@ -12359,6 +12359,7 @@ package android.graphics {
  public class BitmapShader extends android.graphics.Shader {
    ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
  }
  public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -12742,6 +12743,8 @@ package android.graphics {
  public class ComposeShader extends android.graphics.Shader {
    ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
    ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
  }
  public class CornerPathEffect extends android.graphics.PathEffect {
@@ -12817,6 +12820,8 @@ package android.graphics {
  public class LinearGradient extends android.graphics.Shader {
    ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
    ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
  }
  public class MaskFilter {
@@ -13335,6 +13340,8 @@ package android.graphics {
  public class RadialGradient extends android.graphics.Shader {
    ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
    ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
  }
  public final class Rect implements android.os.Parcelable {
@@ -13474,7 +13481,7 @@ package android.graphics {
  }
  public class Shader {
    ctor public Shader();
    ctor public deprecated Shader();
    method public boolean getLocalMatrix(android.graphics.Matrix);
    method public void setLocalMatrix(android.graphics.Matrix);
  }
@@ -13519,6 +13526,8 @@ package android.graphics {
  public class SweepGradient extends android.graphics.Shader {
    ctor public SweepGradient(float, float, int[], float[]);
    ctor public SweepGradient(float, float, int, int);
    method public void set(float, float, int[], float[]);
    method public void set(float, float, int, int);
  }
  public class Typeface {
+55 −80
Original line number Diff line number Diff line
@@ -42,53 +42,16 @@ static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvAr

///////////////////////////////////////////////////////////////////////////////////////////////

static void Shader_destructor(JNIEnv* env, jobject o, jlong shaderHandle, jlong shaderWithLMHandle)
{
static void Shader_safeUnref(JNIEnv* env, jobject o, jlong shaderHandle) {
    SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
    SkSafeUnref(shader);
}

static jlong Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, jlong matrixHandle)
{
    // ensure we have a valid matrix to use
    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
    if (NULL == matrix) {
        matrix = &SkMatrix::I();
    }

    // The current shader will no longer need a direct reference owned by Shader.java
    // as all the data needed is contained within the newly created LocalMatrixShader.
    SkASSERT(shaderHandle);
    sk_sp<SkShader> currentShader(reinterpret_cast<SkShader*>(shaderHandle));

    // Attempt to peel off an existing proxy shader and get the proxy's matrix. If
    // the proxy existed and it's matrix equals the desired matrix then just return
    // the proxy, otherwise replace it with a new proxy containing the desired matrix.
    //
    // refAsALocalMatrixShader(): if the shader contains a proxy then it unwraps the proxy
    //                            returning both the underlying shader and the proxy's matrix.
    // newWithLocalMatrix(): will return a proxy shader that wraps the provided shader and
    //                       concats the provided local matrix with the shader's matrix.
    //
    // WARNING: This proxy replacement only behaves like a setter because the Java
    //          API enforces that all local matrices are set using this call and
    //          not passed to the constructor of the Shader.
    SkMatrix proxyMatrix;
    sk_sp<SkShader> baseShader = currentShader->makeAsALocalMatrixShader(&proxyMatrix);
    if (baseShader.get()) {
        if (proxyMatrix == *matrix) {
            return reinterpret_cast<jlong>(currentShader.release());
        }
        return reinterpret_cast<jlong>(baseShader->makeWithLocalMatrix(*matrix).release());
    }
    return reinterpret_cast<jlong>(currentShader->makeWithLocalMatrix(*matrix).release());
}

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap,
                                      jint tileModeX, jint tileModeY)
{
static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
        jint tileModeX, jint tileModeY) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkBitmap bitmap;
    if (jbitmap) {
        // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
@@ -97,8 +60,8 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap,
    }

    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
    sk_sp<SkShader> shader = image->makeShader((SkShader::TileMode)tileModeX,
                                               (SkShader::TileMode)tileModeY);
    sk_sp<SkShader> shader = image->makeShader(
            (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY, matrix);

    ThrowIAE_IfNull(env, shader.get());
    return reinterpret_cast<jlong>(shader.release());
@@ -106,10 +69,10 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap,

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong LinearGradient_create1(JNIEnv* env, jobject o,
static jlong LinearGradient_create1(JNIEnv* env, jobject o, jlong matrixPtr,
        jfloat x0, jfloat y0, jfloat x1, jfloat y1,
                                    jintArray colorArray, jfloatArray posArray, jint tileMode)
{
        jintArray colorArray, jfloatArray posArray, jint tileMode) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkPoint pts[2];
    pts[0].set(x0, y0);
    pts[1].set(x1, y1);
@@ -126,17 +89,17 @@ static jlong LinearGradient_create1(JNIEnv* env, jobject o,

    SkShader* shader = SkGradientShader::MakeLinear(pts,
            reinterpret_cast<const SkColor*>(colorValues), pos, count,
            static_cast<SkShader::TileMode>(tileMode)).release();
            static_cast<SkShader::TileMode>(tileMode), /* flags */ 0, matrix).release();

    env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
    ThrowIAE_IfNull(env, shader);
    return reinterpret_cast<jlong>(shader);
}

static jlong LinearGradient_create2(JNIEnv* env, jobject o,
                                    jfloat x0, jfloat y0, jfloat x1, jfloat y1,
                                    jint color0, jint color1, jint tileMode)
{
static jlong LinearGradient_create2(JNIEnv* env, jobject o, jlong matrixPtr,
        jfloat x0, jfloat y0, jfloat x1, jfloat y1, jint color0, jint color1, jint tileMode) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);

    SkPoint pts[2];
    pts[0].set(x0, y0);
    pts[1].set(x1, y1);
@@ -145,7 +108,8 @@ static jlong LinearGradient_create2(JNIEnv* env, jobject o,
    colors[0] = color0;
    colors[1] = color1;

    SkShader* s = SkGradientShader::MakeLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode).release();
    SkShader* s = SkGradientShader::MakeLinear(pts, colors, NULL, 2,
            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();

    ThrowIAE_IfNull(env, s);
    return reinterpret_cast<jlong>(s);
@@ -153,8 +117,9 @@ static jlong LinearGradient_create2(JNIEnv* env, jobject o,

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong RadialGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat radius,
        jintArray colorArray, jfloatArray posArray, jint tileMode) {
static jlong RadialGradient_create1(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
        jfloat radius, jintArray colorArray, jfloatArray posArray, jint tileMode) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkPoint center;
    center.set(x, y);

@@ -170,7 +135,7 @@ static jlong RadialGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y, jf

    SkShader* shader = SkGradientShader::MakeRadial(center, radius,
            reinterpret_cast<const SkColor*>(colorValues), pos, count,
            static_cast<SkShader::TileMode>(tileMode)).release();
            static_cast<SkShader::TileMode>(tileMode), /* flags */ 0, matrix).release();
    env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
                                 JNI_ABORT);

@@ -178,8 +143,9 @@ static jlong RadialGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y, jf
    return reinterpret_cast<jlong>(shader);
}

static jlong RadialGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat radius,
static jlong RadialGradient_create2(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y, jfloat radius,
        jint color0, jint color1, jint tileMode) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkPoint center;
    center.set(x, y);

@@ -188,15 +154,16 @@ static jlong RadialGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y, jf
    colors[1] = color1;

    SkShader* s = SkGradientShader::MakeRadial(center, radius, colors, NULL, 2,
            (SkShader::TileMode)tileMode).release();
            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
    ThrowIAE_IfNull(env, s);
    return reinterpret_cast<jlong>(s);
}

///////////////////////////////////////////////////////////////////////////////

static jlong SweepGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y,
static jlong SweepGradient_create1(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
        jintArray jcolors, jfloatArray jpositions) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    size_t      count = env->GetArrayLength(jcolors);
    const jint* colors = env->GetIntArrayElements(jcolors, NULL);

@@ -208,34 +175,43 @@ static jlong SweepGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y,
#endif

    SkShader* shader = SkGradientShader::MakeSweep(x, y,
            reinterpret_cast<const SkColor*>(colors), pos, count).release();
            reinterpret_cast<const SkColor*>(colors), pos, count, /* flags */ 0, matrix).release();
    env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors),
                                 JNI_ABORT);
    ThrowIAE_IfNull(env, shader);
    return reinterpret_cast<jlong>(shader);
}

static jlong SweepGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y,
static jlong SweepGradient_create2(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
        int color0, int color1) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkColor colors[2];
    colors[0] = color0;
    colors[1] = color1;
    SkShader* s = SkGradientShader::MakeSweep(x, y, colors, NULL, 2).release();
    SkShader* s = SkGradientShader::MakeSweep(x, y, colors, NULL, 2,
            /* flags */ 0, matrix).release();
    ThrowIAE_IfNull(env, s);
    return reinterpret_cast<jlong>(s);
}

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong ComposeShader_create(JNIEnv* env, jobject o,
        jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle)
{
static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
        jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
    SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
    SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
    SkShader* shader = SkShader::MakeComposeShader(sk_ref_sp(shaderA),
                                                   sk_ref_sp(shaderB),
                                                   mode).release();
    sk_sp<SkShader> baseShader(SkShader::MakeComposeShader(
            sk_ref_sp(shaderA), sk_ref_sp(shaderB), mode));

    SkShader* shader;

    if (matrix) {
        shader = baseShader->makeWithLocalMatrix(*matrix).release();
    } else {
        shader = baseShader.release();
    }
    return reinterpret_cast<jlong>(shader);
}

@@ -247,31 +223,30 @@ static const JNINativeMethod gColorMethods[] = {
};

static const JNINativeMethod gShaderMethods[] = {
    { "nativeDestructor",        "(J)V",    (void*)Shader_destructor        },
    { "nativeSetLocalMatrix",    "(JJ)J",   (void*)Shader_setLocalMatrix    }
    { "nativeSafeUnref",   "(J)V",    (void*)Shader_safeUnref },
};

static const JNINativeMethod gBitmapShaderMethods[] = {
    { "nativeCreate",     "(Landroid/graphics/Bitmap;II)J",  (void*)BitmapShader_constructor },
    { "nativeCreate",      "(JLandroid/graphics/Bitmap;II)J",  (void*)BitmapShader_constructor },
};

static const JNINativeMethod gLinearGradientMethods[] = {
    { "nativeCreate1",     "(FFFF[I[FI)J",  (void*)LinearGradient_create1     },
    { "nativeCreate2",     "(FFFFIII)J",    (void*)LinearGradient_create2     },
    { "nativeCreate1",     "(JFFFF[I[FI)J",  (void*)LinearGradient_create1     },
    { "nativeCreate2",     "(JFFFFIII)J",    (void*)LinearGradient_create2     },
};

static const JNINativeMethod gRadialGradientMethods[] = {
    { "nativeCreate1",     "(FFF[I[FI)J",  (void*)RadialGradient_create1     },
    { "nativeCreate2",     "(FFFIII)J",    (void*)RadialGradient_create2     },
    { "nativeCreate1",     "(JFFF[I[FI)J",  (void*)RadialGradient_create1     },
    { "nativeCreate2",     "(JFFFIII)J",    (void*)RadialGradient_create2     },
};

static const JNINativeMethod gSweepGradientMethods[] = {
    { "nativeCreate1",     "(FF[I[F)J",  (void*)SweepGradient_create1     },
    { "nativeCreate2",     "(FFII)J",    (void*)SweepGradient_create2     },
    { "nativeCreate1",     "(JFF[I[F)J",  (void*)SweepGradient_create1     },
    { "nativeCreate2",     "(JFFII)J",    (void*)SweepGradient_create2     },
};

static const JNINativeMethod gComposeShaderMethods[] = {
    { "nativeCreate",      "(JJI)J",   (void*)ComposeShader_create     },
    { "nativeCreate",      "(JJJI)J",   (void*)ComposeShader_create     },
};

int register_android_graphics_Shader(JNIEnv* env)
+43 −10
Original line number Diff line number Diff line
@@ -28,10 +28,10 @@ public class BitmapShader extends Shader {
     * @hide
     */
    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
    public final Bitmap mBitmap;
    public Bitmap mBitmap;

    private TileMode mTileX;
    private TileMode mTileY;
    private int mTileX;
    private int mTileY;

    /**
     * Call this to create a new shader that will draw with a bitmap.
@@ -40,11 +40,44 @@ public class BitmapShader extends Shader {
     * @param tileX The tiling mode for x to draw the bitmap in.
     * @param tileY The tiling mode for y to draw the bitmap in.
     */
    public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY) {
    public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
        set(bitmap, tileX, tileY);
    }

    private BitmapShader(Bitmap bitmap, int tileX, int tileY) {
        setInternal(bitmap, tileX, tileY);
    }

    /**
     * Reinitialize the BitmapShader's Bitmap and tile modes.
     *
     * @param bitmap The bitmap to use inside the shader
     * @param tileX The tiling mode for x to draw the bitmap in.
     * @param tileY The tiling mode for y to draw the bitmap in.
     */
    public void set(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
        if (tileX == null || tileY == null) {
            throw new IllegalArgumentException();
        }
        setInternal(bitmap, tileX.nativeInt, tileY.nativeInt);
    }

    private void setInternal(Bitmap bitmap, int tileX, int tileY) {
        if (bitmap == null) {
            throw new IllegalArgumentException("Bitmap must be non-null");
        }
        if (bitmap == mBitmap && tileX == mTileX && tileY == mTileY) {
            return;
        }
        discardNativeInstance();
        mBitmap = bitmap;
        mTileX = tileX;
        mTileY = tileY;
        init(nativeCreate(bitmap, tileX.nativeInt, tileY.nativeInt));
    }

    @Override
    long createNativeInstance(long nativeMatrix) {
        return nativeCreate(nativeMatrix, mBitmap, mTileX, mTileY);
    }

    /**
@@ -57,6 +90,6 @@ public class BitmapShader extends Shader {
        return copy;
    }

    private static native long nativeCreate(Bitmap bitmap, int shaderTileModeX,
            int shaderTileModeY);
    private static native long nativeCreate(long nativeMatrix, Bitmap bitmap,
            int shaderTileModeX, int shaderTileModeY);
}
Loading