summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/view/GLES20Canvas.java34
-rw-r--r--core/jni/android/graphics/Shader.cpp191
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp19
3 files changed, 132 insertions, 112 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 78648ff..21e6793 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -17,21 +17,17 @@
package android.view;
import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.DrawFilter;
-import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.PorterDuff;
-import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
-import android.graphics.SweepGradient;
import android.graphics.TemporaryBuffer;
import android.text.GraphicsOperations;
import android.text.SpannableString;
@@ -593,7 +589,9 @@ class GLES20Canvas extends Canvas {
if ((index | count | (index + count) | (text.length - index - count)) < 0) {
throw new IndexOutOfBoundsException();
}
+ boolean hasShader = setupShader(paint);
nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint);
+ if (hasShader) nResetShader(mRenderer);
}
private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y,
@@ -601,6 +599,7 @@ class GLES20Canvas extends Canvas {
@Override
public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
+ boolean hasShader = setupShader(paint);
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
@@ -614,6 +613,7 @@ class GLES20Canvas extends Canvas {
nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint);
TemporaryBuffer.recycle(buf);
}
+ if (hasShader) nResetShader(mRenderer);
}
@Override
@@ -621,7 +621,9 @@ class GLES20Canvas extends Canvas {
if ((start | end | (end - start) | (text.length() - end)) < 0) {
throw new IndexOutOfBoundsException();
}
+ boolean hasShader = setupShader(paint);
nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint);
+ if (hasShader) nResetShader(mRenderer);
}
private native void nDrawText(int renderer, String text, int start, int end, float x, float y,
@@ -629,7 +631,9 @@ class GLES20Canvas extends Canvas {
@Override
public void drawText(String text, float x, float y, Paint paint) {
+ boolean hasShader = setupShader(paint);
nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, paint.mNativePaint);
+ if (hasShader) nResetShader(mRenderer);
}
@Override
@@ -665,28 +669,12 @@ class GLES20Canvas extends Canvas {
private boolean setupShader(Paint paint) {
final Shader shader = paint.getShader();
if (shader != null) {
- if (shader instanceof BitmapShader) {
- final BitmapShader bs = (BitmapShader) shader;
- nSetupBitmapShader(mRenderer, bs.native_instance, bs.mBitmap.mNativeBitmap,
- bs.mTileX, bs.mTileY, bs.mLocalMatrix);
- return true;
- } else if (shader instanceof LinearGradient) {
- final LinearGradient ls = (LinearGradient) shader;
- nSetupLinearShader(mRenderer, ls.native_instance, ls.bounds, ls.colors,
- ls.positions, ls.count, ls.tileMode, ls.mLocalMatrix);
- return true;
- } else if (shader instanceof RadialGradient) {
- // TODO: Implement
- } else if (shader instanceof SweepGradient) {
- // TODO: Implement
- }
+ nSetupShader(mRenderer, shader.native_shader);
+ return true;
}
return false;
}
- private native void nSetupLinearShader(int renderer, int shader, int bounds,
- int colors, int positions, int count, int tileMode, int localMatrix);
- private native void nSetupBitmapShader(int renderer, int shader, int bitmap,
- int tileX, int tileY, int matrix);
+ private native void nSetupShader(int renderer, int shader);
private native void nResetShader(int renderer);
}
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index eb600c4..34b4ab5 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -8,12 +8,14 @@
#include "SkTemplates.h"
#include "SkXfermode.h"
+#include <SkiaShader.h>
+
+using namespace android::uirenderer;
+
static struct {
jclass clazz;
- jfieldID bounds;
- jfieldID colors;
- jfieldID positions;
-} gLinearGradientClassInfo;
+ jfieldID shader;
+} gShaderClassInfo;
static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
if (NULL == ptr) {
@@ -48,8 +50,9 @@ static int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArra
///////////////////////////////////////////////////////////////////////////////////////////////
-static void Shader_destructor(JNIEnv* env, jobject, SkShader* shader)
+static void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader)
{
+ delete skiaShader;
shader->safeUnref();
}
@@ -58,7 +61,8 @@ static bool Shader_getLocalMatrix(JNIEnv* env, jobject, const SkShader* shader,
return shader ? shader->getLocalMatrix(matrix) : false;
}
-static void Shader_setLocalMatrix(JNIEnv* env, jobject, SkShader* shader, const SkMatrix* matrix)
+static void Shader_setLocalMatrix(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader,
+ const SkMatrix* matrix)
{
if (shader) {
if (NULL == matrix) {
@@ -67,29 +71,32 @@ static void Shader_setLocalMatrix(JNIEnv* env, jobject, SkShader* shader, const
else {
shader->setLocalMatrix(*matrix);
}
+ skiaShader->setMatrix(const_cast<SkMatrix*>(matrix));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
-static SkShader* BitmapShader_constructor(JNIEnv* env, jobject, const SkBitmap* bitmap,
+static SkShader* BitmapShader_constructor(JNIEnv* env, jobject o, const SkBitmap* bitmap,
int tileModeX, int tileModeY)
{
SkShader* s = SkShader::CreateBitmapShader(*bitmap,
(SkShader::TileMode)tileModeX,
(SkShader::TileMode)tileModeY);
+
ThrowIAE_IfNull(env, s);
return s;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-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 SkiaShader* BitmapShader_postConstructor(JNIEnv* env, jobject o, SkShader* shader,
+ SkBitmap* bitmap, int tileModeX, int tileModeY) {
+ SkiaShader* skiaShader = new SkiaBitmapShader(bitmap, shader,
+ static_cast<SkShader::TileMode>(tileModeX), static_cast<SkShader::TileMode>(tileModeY),
+ NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
+ return skiaShader;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
static SkShader* LinearGradient_create1(JNIEnv* env, jobject o,
float x0, float y0, float x1, float y1,
@@ -99,44 +106,83 @@ static SkShader* LinearGradient_create1(JNIEnv* env, jobject o,
pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0));
pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1));
- size_t count = env->GetArrayLength(colorArray);
+ size_t count = env->GetArrayLength(colorArray);
const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
SkScalar* pos = NULL;
+ if (posArray) {
+ AutoJavaFloatArray autoPos(env, posArray, count);
+ const float* posValues = autoPos.ptr();
+ pos = (SkScalar*)storage.get();
+ for (size_t i = 0; i < count; i++) {
+ pos[i] = SkFloatToScalar(posValues[i]);
+ }
+ }
+
+ SkShader* shader = SkGradientShader::CreateLinear(pts,
+ reinterpret_cast<const SkColor*>(colorValues),
+ pos, count,
+ static_cast<SkShader::TileMode>(tileMode));
+
+ env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
+ ThrowIAE_IfNull(env, shader);
+ return shader;
+}
+
+static SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
+ float x0, float y0, float x1, float y1, jintArray colorArray,
+ jfloatArray posArray, int tileMode) {
+
+ size_t count = env->GetArrayLength(colorArray);
+ const jint* colorValues = env->GetIntArrayElements(colorArray, 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];
+ uint32_t* storedColors = new uint32_t[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++) {
- 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,
- static_cast<SkShader::TileMode>(tileMode));
- env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
- JNI_ABORT);
- ThrowIAE_IfNull(env, shader);
- return shader;
+
+ SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
+ storedPositions, count, shader, static_cast<SkShader::TileMode>(tileMode), NULL,
+ (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
+
+ env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
+ return skiaShader;
+}
+
+static SkiaShader* LinearGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
+ float x0, float y0, float x1, float y1, int color0, int color1, int tileMode) {
+ 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;
+
+ SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
+ storedPositions, 2, shader, static_cast<SkShader::TileMode>(tileMode), NULL,
+ (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
+
+ return skiaShader;
}
static SkShader* LinearGradient_create2(JNIEnv* env, jobject o,
@@ -151,23 +197,8 @@ static SkShader* LinearGradient_create2(JNIEnv* env, jobject o,
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);
return s;
}
@@ -268,18 +299,38 @@ static SkShader* SweepGradient_create2(JNIEnv* env, jobject, float x, float y,
///////////////////////////////////////////////////////////////////////////////////////////////
-static SkShader* ComposeShader_create1(JNIEnv* env, jobject,
- SkShader* shaderA, SkShader* shaderB, SkXfermode* mode)
+static SkShader* ComposeShader_create1(JNIEnv* env, jobject o,
+ SkShader* shaderA, SkShader* shaderB, SkXfermode* mode)
{
return new SkComposeShader(shaderA, shaderB, mode);
}
-static SkShader* ComposeShader_create2(JNIEnv* env, jobject,
- SkShader* shaderA, SkShader* shaderB, SkPorterDuff::Mode mode)
+static SkShader* ComposeShader_create2(JNIEnv* env, jobject o,
+ SkShader* shaderA, SkShader* shaderB, SkPorterDuff::Mode porterDuffMode)
{
- SkAutoUnref au(SkPorterDuff::CreateXfermode(mode));
+ SkAutoUnref au(SkPorterDuff::CreateXfermode(porterDuffMode));
+ SkXfermode* mode = (SkXfermode*) au.get();
+ return new SkComposeShader(shaderA, shaderB, mode);
+}
+
+static SkiaShader* ComposeShader_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
+ SkiaShader* shaderA, SkiaShader* shaderB, SkPorterDuff::Mode porterDuffMode) {
+ SkAutoUnref au(SkPorterDuff::CreateXfermode(porterDuffMode));
+ SkXfermode* mode = (SkXfermode*) au.get();
+ SkXfermode::Mode skiaMode;
+ if (!SkXfermode::IsMode(mode, &skiaMode)) {
+ skiaMode = SkXfermode::kSrcOver_Mode;
+ }
+ return new SkiaComposeShader(shaderA, shaderB, skiaMode, shader);
+}
- return new SkComposeShader(shaderA, shaderB, (SkXfermode*)au.get());
+static SkiaShader* ComposeShader_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
+ SkiaShader* shaderA, SkiaShader* shaderB, SkXfermode* mode) {
+ SkXfermode::Mode skiaMode;
+ if (!SkXfermode::IsMode(mode, &skiaMode)) {
+ skiaMode = SkXfermode::kSrcOver_Mode;
+ }
+ return new SkiaComposeShader(shaderA, shaderB, skiaMode, shader);
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -290,19 +341,21 @@ static JNINativeMethod gColorMethods[] = {
};
static JNINativeMethod gShaderMethods[] = {
- { "nativeDestructor", "(I)V", (void*)Shader_destructor },
+ { "nativeDestructor", "(II)V", (void*)Shader_destructor },
{ "nativeGetLocalMatrix", "(II)Z", (void*)Shader_getLocalMatrix },
- { "nativeSetLocalMatrix", "(II)V", (void*)Shader_setLocalMatrix }
+ { "nativeSetLocalMatrix", "(III)V", (void*)Shader_setLocalMatrix }
};
static JNINativeMethod gBitmapShaderMethods[] = {
- { "nativeCreate", "(III)I", (void*)BitmapShader_constructor }
+ { "nativeCreate", "(III)I", (void*)BitmapShader_constructor },
+ { "nativePostCreate", "(IIII)I", (void*)BitmapShader_postConstructor }
};
static JNINativeMethod gLinearGradientMethods[] = {
- { "nativeDestructor", "(I)V", (void*)LinearGradient_destructor },
- { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 },
- { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 }
+ { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 },
+ { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 },
+ { "nativePostCreate1", "(IFFFF[I[FI)I", (void*)LinearGradient_postCreate1 },
+ { "nativePostCreate2", "(IFFFFIII)I", (void*)LinearGradient_postCreate2 }
};
static JNINativeMethod gRadialGradientMethods[] = {
@@ -316,8 +369,10 @@ static JNINativeMethod gSweepGradientMethods[] = {
};
static JNINativeMethod gComposeShaderMethods[] = {
- {"nativeCreate1", "(III)I", (void*)ComposeShader_create1 },
- {"nativeCreate2", "(III)I", (void*)ComposeShader_create2 }
+ {"nativeCreate1", "(III)I", (void*)ComposeShader_create1 },
+ {"nativeCreate2", "(III)I", (void*)ComposeShader_create2 },
+ {"nativePostCreate1", "(IIII)I", (void*)ComposeShader_postCreate1 },
+ {"nativePostCreate2", "(IIII)I", (void*)ComposeShader_postCreate2 }
};
#include <android_runtime/AndroidRuntime.h>
@@ -325,15 +380,6 @@ 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)
@@ -348,11 +394,6 @@ 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 1e4a66d..ece9636 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -30,6 +30,7 @@
#include <SkXfermode.h>
#include <OpenGLRenderer.h>
+#include <SkiaShader.h>
#include <Rect.h>
#include <ui/Rect.h>
@@ -235,18 +236,9 @@ static void android_view_GLES20Canvas_resetShader(JNIEnv* env, jobject canvas,
renderer->resetShader();
}
-static void android_view_GLES20Canvas_setupBitmapShader(JNIEnv* env, jobject canvas,
- OpenGLRenderer* renderer, SkShader* shader, SkBitmap* bitmap,
- SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix) {
- renderer->setupBitmapShader(bitmap, tileX, tileY, matrix,
- (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, int count, SkShader::TileMode tileMode, SkMatrix* matrix) {
- renderer->setupLinearGradientShader(shader, bounds, colors, positions, count,
- tileMode, matrix, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
+static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, SkiaShader* shader) {
+ renderer->setupShader(shader);
}
// ----------------------------------------------------------------------------
@@ -320,8 +312,7 @@ static JNINativeMethod gMethods[] = {
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nResetShader", "(I)V", (void*) android_view_GLES20Canvas_resetShader },
- { "nSetupBitmapShader", "(IIIIII)V", (void*) android_view_GLES20Canvas_setupBitmapShader },
- { "nSetupLinearShader", "(IIIIIIII)V", (void*) android_view_GLES20Canvas_setupLinearShader },
+ { "nSetupShader", "(II)V", (void*) android_view_GLES20Canvas_setupShader },
{ "nDrawText", "(I[CIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArray },
{ "nDrawText", "(ILjava/lang/String;IIFFII)V",