diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 11 | ||||
-rw-r--r-- | core/jni/android/graphics/Shader.cpp | 75 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 9 |
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 }, |