summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/view/GLES20Canvas.java11
-rw-r--r--core/jni/android/graphics/Shader.cpp75
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp9
3 files changed, 84 insertions, 11 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 676aae3..ef9709e 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -631,7 +631,10 @@ class GLES20Canvas extends Canvas {
bs.mTileX, bs.mTileY, bs.mLocalMatrix);
return true;
} else if (shader instanceof LinearGradient) {
- // TODO: Implement
+ final LinearGradient ls = (LinearGradient) shader;
+ nSetupLinearShader(mRenderer, ls.native_instance, ls.bounds, ls.colors,
+ ls.positions, ls.tileMode, ls.mLocalMatrix);
+ return true;
} else if (shader instanceof RadialGradient) {
// TODO: Implement
} else if (shader instanceof SweepGradient) {
@@ -640,8 +643,10 @@ class GLES20Canvas extends Canvas {
}
return false;
}
-
+
+ private native void nSetupLinearShader(int renderer, int shader, int bounds,
+ int colors, int positions, int tileMode, int localMatrix);
private native void nSetupBitmapShader(int renderer, int shader, int bitmap,
int tileX, int tileY, int matrix);
- private native void nResetShader(int renderer);
+ private native void nResetShader(int renderer);
}
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index b09c62b..eb600c4 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -8,6 +8,13 @@
#include "SkTemplates.h"
#include "SkXfermode.h"
+static struct {
+ jclass clazz;
+ jfieldID bounds;
+ jfieldID colors;
+ jfieldID positions;
+} gLinearGradientClassInfo;
+
static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
if (NULL == ptr) {
doThrowIAE(env);
@@ -77,7 +84,14 @@ static SkShader* BitmapShader_constructor(JNIEnv* env, jobject, const SkBitmap*
///////////////////////////////////////////////////////////////////////////////////////////////
-static SkShader* LinearGradient_create1(JNIEnv* env, jobject,
+static void LinearGradient_destructor(JNIEnv* env, jobject o, SkShader* shader)
+{
+ delete reinterpret_cast<jfloat*>(env->GetIntField(o, gLinearGradientClassInfo.bounds));
+ delete reinterpret_cast<jint*>(env->GetIntField(o, gLinearGradientClassInfo.colors));
+ delete reinterpret_cast<jfloat*>(env->GetIntField(o, gLinearGradientClassInfo.positions));
+}
+
+static SkShader* LinearGradient_create1(JNIEnv* env, jobject o,
float x0, float y0, float x1, float y1,
jintArray colorArray, jfloatArray posArray, int tileMode)
{
@@ -90,15 +104,31 @@ static SkShader* LinearGradient_create1(JNIEnv* env, jobject,
SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
SkScalar* pos = NULL;
-
+
+ jfloat* storedBounds = new jfloat[4];
+ storedBounds[0] = x0; storedBounds[1] = y0;
+ storedBounds[2] = x1; storedBounds[3] = y1;
+ jfloat* storedPositions = new jfloat[count];
+ jint* storedColors = new jint[count];
+ memcpy(storedColors, colorValues, count);
+
if (posArray) {
AutoJavaFloatArray autoPos(env, posArray, count);
const float* posValues = autoPos.ptr();
pos = (SkScalar*)storage.get();
- for (size_t i = 0; i < count; i++)
+ for (size_t i = 0; i < count; i++) {
pos[i] = SkFloatToScalar(posValues[i]);
+ storedPositions[i] = posValues[i];
+ }
+ } else {
+ storedPositions[0] = 0.0f;
+ storedPositions[1] = 1.0f;
}
-
+
+ env->SetIntField(o, gLinearGradientClassInfo.bounds, reinterpret_cast<jint>(storedBounds));
+ env->SetIntField(o, gLinearGradientClassInfo.colors, reinterpret_cast<jint>(storedColors));
+ env->SetIntField(o, gLinearGradientClassInfo.positions, reinterpret_cast<jint>(storedPositions));
+
SkShader* shader = SkGradientShader::CreateLinear(pts,
reinterpret_cast<const SkColor*>(colorValues),
pos, count,
@@ -109,7 +139,7 @@ static SkShader* LinearGradient_create1(JNIEnv* env, jobject,
return shader;
}
-static SkShader* LinearGradient_create2(JNIEnv* env, jobject,
+static SkShader* LinearGradient_create2(JNIEnv* env, jobject o,
float x0, float y0, float x1, float y1,
int color0, int color1, int tileMode)
{
@@ -120,6 +150,22 @@ static SkShader* LinearGradient_create2(JNIEnv* env, jobject,
SkColor colors[2];
colors[0] = color0;
colors[1] = color1;
+
+ float* storedBounds = new float[4];
+ storedBounds[0] = x0; storedBounds[1] = y0;
+ storedBounds[2] = x1; storedBounds[3] = y1;
+
+ float* storedPositions = new float[2];
+ storedPositions[0] = 0.0f;
+ storedPositions[1] = 1.0f;
+
+ uint32_t* storedColors = new uint32_t[2];
+ storedColors[0] = color0;
+ storedColors[1] = color1;
+
+ env->SetIntField(o, gLinearGradientClassInfo.bounds, reinterpret_cast<jint>(storedBounds));
+ env->SetIntField(o, gLinearGradientClassInfo.colors, reinterpret_cast<jint>(storedColors));
+ env->SetIntField(o, gLinearGradientClassInfo.positions, reinterpret_cast<jint>(storedPositions));
SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode);
ThrowIAE_IfNull(env, s);
@@ -254,8 +300,9 @@ static JNINativeMethod gBitmapShaderMethods[] = {
};
static JNINativeMethod gLinearGradientMethods[] = {
- { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 },
- { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 }
+ { "nativeDestructor", "(I)V", (void*)LinearGradient_destructor },
+ { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 },
+ { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 }
};
static JNINativeMethod gRadialGradientMethods[] = {
@@ -278,6 +325,15 @@ static JNINativeMethod gComposeShaderMethods[] = {
#define REG(env, name, array) \
result = android::AndroidRuntime::registerNativeMethods(env, name, array, SK_ARRAY_COUNT(array)); \
if (result < 0) return result
+
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className); \
+ var = jclass(env->NewGlobalRef(var));
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldType) \
+ var = env->GetFieldID(clazz, fieldName, fieldType); \
+ LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_graphics_Shader(JNIEnv* env);
int register_android_graphics_Shader(JNIEnv* env)
@@ -292,6 +348,11 @@ int register_android_graphics_Shader(JNIEnv* env)
REG(env, "android/graphics/SweepGradient", gSweepGradientMethods);
REG(env, "android/graphics/ComposeShader", gComposeShaderMethods);
+ FIND_CLASS(gLinearGradientClassInfo.clazz, "android/graphics/LinearGradient");
+ GET_FIELD_ID(gLinearGradientClassInfo.bounds, gLinearGradientClassInfo.clazz, "bounds", "I");
+ GET_FIELD_ID(gLinearGradientClassInfo.colors, gLinearGradientClassInfo.clazz, "colors", "I");
+ GET_FIELD_ID(gLinearGradientClassInfo.positions, gLinearGradientClassInfo.clazz, "positions", "I");
+
return result;
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e5aa5dd..f952702 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -201,7 +201,6 @@ static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canv
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray chunks,
float left, float top, float right, float bottom, SkPaint* paint) {
-
jbyte* storage = env->GetByteArrayElements(chunks, NULL);
Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
Res_png_9patch::deserialize(patch);
@@ -239,6 +238,13 @@ static void android_view_GLES20Canvas_setupBitmapShader(JNIEnv* env, jobject can
(shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
}
+static void android_view_GLES20Canvas_setupLinearShader(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, SkShader* shader, float* bounds, uint32_t* colors,
+ float* positions, SkShader::TileMode tileMode, SkMatrix* matrix) {
+ renderer->setupLinearGradientShader(bounds, colors, positions, tileMode, matrix,
+ (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
+}
+
// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -280,6 +286,7 @@ static JNINativeMethod gMethods[] = {
{ "nResetShader", "(I)V", (void*) android_view_GLES20Canvas_resetShader },
{ "nSetupBitmapShader", "(IIIIII)V", (void*) android_view_GLES20Canvas_setupBitmapShader },
+ { "nSetupLinearShader", "(IIIIIII)V", (void*) android_view_GLES20Canvas_setupLinearShader },
{ "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
(void*) android_view_GLES20Canvas_getClipBounds },