diff options
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 101 | ||||
-rw-r--r-- | core/java/android/view/HardwareRenderer.java | 13 | ||||
-rw-r--r-- | core/jni/android/graphics/Shader.cpp | 8 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayout.cpp | 18 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayout.h | 3 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 126 | ||||
-rw-r--r-- | graphics/java/android/graphics/Path.java | 13 | ||||
-rw-r--r-- | graphics/java/android/graphics/Region.java | 16 | ||||
-rw-r--r-- | graphics/java/android/graphics/drawable/GradientDrawable.java | 13 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 41 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/PathCache.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 6 | ||||
-rw-r--r-- | opengl/libs/GLES2/gl2.cpp | 20 | ||||
-rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 9 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java | 40 |
17 files changed, 325 insertions, 115 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 96bd884..78836fa 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -610,9 +610,13 @@ class GLES20Canvas extends Canvas { if ((index | count | (index + count) | (text.length - index - count)) < 0) { throw new IndexOutOfBoundsException(); } + boolean hasModifier = setupModifiers(paint); - nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint); - if (hasModifier) nResetModifiers(mRenderer); + try { + nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint); + } finally { + if (hasModifier) nResetModifiers(mRenderer); + } } private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y, @@ -621,20 +625,23 @@ class GLES20Canvas extends Canvas { @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { boolean hasModifier = setupModifiers(paint); - if (text instanceof String || text instanceof SpannedString || - text instanceof SpannableString) { - nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, - paint.mNativePaint); - } else if (text instanceof GraphicsOperations) { - ((GraphicsOperations) text).drawText(this, start, end, x, y, - paint); - } else { - char[] buf = TemporaryBuffer.obtain(end - start); - TextUtils.getChars(text, start, end, buf, 0); - nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint); - TemporaryBuffer.recycle(buf); + try { + if (text instanceof String || text instanceof SpannedString || + text instanceof SpannableString) { + nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, + paint.mNativePaint); + } else if (text instanceof GraphicsOperations) { + ((GraphicsOperations) text).drawText(this, start, end, x, y, + paint); + } else { + char[] buf = TemporaryBuffer.obtain(end - start); + TextUtils.getChars(text, start, end, buf, 0); + nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint); + TemporaryBuffer.recycle(buf); + } + } finally { + if (hasModifier) nResetModifiers(mRenderer); } - if (hasModifier) nResetModifiers(mRenderer); } @Override @@ -642,9 +649,13 @@ class GLES20Canvas extends Canvas { if ((start | end | (end - start) | (text.length() - end)) < 0) { throw new IndexOutOfBoundsException(); } + boolean hasModifier = setupModifiers(paint); - nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint); - if (hasModifier) nResetModifiers(mRenderer); + try { + nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint); + } finally { + if (hasModifier) nResetModifiers(mRenderer); + } } private native void nDrawText(int renderer, String text, int start, int end, float x, float y, @@ -653,8 +664,12 @@ class GLES20Canvas extends Canvas { @Override public void drawText(String text, float x, float y, Paint paint) { boolean hasModifier = setupModifiers(paint); - nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, paint.mNativePaint); - if (hasModifier) nResetModifiers(mRenderer); + try { + nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, + paint.mNativePaint); + } finally { + if (hasModifier) nResetModifiers(mRenderer); + } } @Override @@ -671,15 +686,59 @@ class GLES20Canvas extends Canvas { @Override public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int dir, Paint paint) { - throw new UnsupportedOperationException(); + if ((index | count | text.length - index - count) < 0) { + throw new IndexOutOfBoundsException(); + } + if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { + throw new IllegalArgumentException("Unknown direction: " + dir); + } + + boolean hasModifier = setupModifiers(paint); + try { + nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, + paint.mNativePaint); + } finally { + if (hasModifier) nResetModifiers(mRenderer); + } } + private native void nDrawTextRun(int renderer, char[] text, int index, int count, + int contextIndex, int contextCount, float x, float y, int dir, int nativePaint); + @Override public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, int dir, Paint paint) { - throw new UnsupportedOperationException(); + if ((start | end | end - start | text.length() - end) < 0) { + throw new IndexOutOfBoundsException(); + } + + boolean hasModifier = setupModifiers(paint); + try { + int flags = dir == 0 ? 0 : 1; + if (text instanceof String || text instanceof SpannedString || + text instanceof SpannableString) { + nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, + contextEnd, x, y, flags, paint.mNativePaint); + } else if (text instanceof GraphicsOperations) { + ((GraphicsOperations) text).drawTextRun(this, start, end, + contextStart, contextEnd, x, y, flags, paint); + } else { + int contextLen = contextEnd - contextStart; + int len = end - start; + char[] buf = TemporaryBuffer.obtain(contextLen); + TextUtils.getChars(text, contextStart, contextEnd, buf, 0); + nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, + x, y, flags, paint.mNativePaint); + TemporaryBuffer.recycle(buf); + } + } finally { + if (hasModifier) nResetModifiers(mRenderer); + } } + private native void nDrawTextRun(int renderer, String text, int start, int end, + int contextStart, int contextEnd, float x, float y, int flags, int nativePaint); + @Override public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 60d495f..cd6b820 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -34,12 +34,23 @@ import javax.microedition.khronos.opengles.GL; * * @hide */ -abstract class HardwareRenderer { +public abstract class HardwareRenderer { private boolean mEnabled; private boolean mRequested = true; private static final String LOG_TAG = "HardwareRenderer"; /** + * Indicates whether hardware acceleration is available under any form for + * the view hierarchy. + * + * @return True if the view hierarchy can potentially be hardware accelerated, + * false otherwise + */ + public static boolean isAvailable() { + return GLES20Canvas.isAvailable(); + } + + /** * Destroys the hardware rendering context. */ abstract void destroy(); diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp index 2b98e89..36413d7 100644 --- a/core/jni/android/graphics/Shader.cpp +++ b/core/jni/android/graphics/Shader.cpp @@ -149,7 +149,9 @@ static SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader* storedBounds[2] = x1; storedBounds[3] = y1; jfloat* storedPositions = new jfloat[count]; uint32_t* storedColors = new uint32_t[count]; - memcpy(storedColors, colorValues, count); + for (size_t i = 0; i < count; i++) { + storedColors[i] = static_cast<uint32_t>(colorValues[i]); + } if (posArray) { AutoJavaFloatArray autoPos(env, posArray, count); @@ -185,8 +187,8 @@ static SkiaShader* LinearGradient_postCreate2(JNIEnv* env, jobject o, SkShader* storedPositions[1] = 1.0f; uint32_t* storedColors = new uint32_t[2]; - storedColors[0] = color0; - storedColors[1] = color1; + storedColors[0] = static_cast<uint32_t>(color0); + storedColors[1] = static_cast<uint32_t>(color1); SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors, storedPositions, 2, shader, static_cast<SkShader::TileMode>(tileMode), NULL, diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp index 716d960..147e1fa 100644 --- a/core/jni/android/graphics/TextLayout.cpp +++ b/core/jni/android/graphics/TextLayout.cpp @@ -221,6 +221,18 @@ void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len, } } +bool TextLayout::prepareRtlTextRun(const jchar* context, jsize start, jsize& count, + jsize contextCount, jchar* shaped) { + UErrorCode status = U_ZERO_ERROR; + count = shapeRtlText(context, start, count, contextCount, shaped, status); + if (U_SUCCESS(status)) { + return true; + } else { + LOG(LOG_WARN, "LAYOUT", "drawTextRun error %d\n", status); + } + return false; +} + void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, int dirFlags, jfloat x, jfloat y, SkCanvas* canvas) { @@ -231,12 +243,8 @@ void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars, uint8_t rtl = dirFlags & 0x1; if (rtl) { SkAutoSTMalloc<80, jchar> buffer(contextCount); - UErrorCode status = U_ZERO_ERROR; - count = shapeRtlText(chars, start, count, contextCount, buffer.get(), status); - if (U_SUCCESS(status)) { + if (prepareRtlTextRun(chars, start, count, contextCount, buffer.get())) { canvas->drawText(buffer.get(), count << 1, x_, y_, *paint); - } else { - LOG(LOG_WARN, "LAYOUT", "drawTextRun error %d\n", status); } } else { canvas->drawText(chars + start, count << 1, x_, y_, *paint); diff --git a/core/jni/android/graphics/TextLayout.h b/core/jni/android/graphics/TextLayout.h index 3d05e18..8f666c0 100644 --- a/core/jni/android/graphics/TextLayout.h +++ b/core/jni/android/graphics/TextLayout.h @@ -66,6 +66,9 @@ public: static bool prepareText(SkPaint *paint, const jchar* text, jsize len, jint bidiFlags, const jchar** outText, int32_t* outBytes, jchar** outBuffer); + static bool prepareRtlTextRun(const jchar* context, jsize start, jsize& count, + jsize contextCount, jchar* shaped); + private: static bool needsLayout(const jchar* text, jint len, jint bidiFlags); diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index bb1a9e3..be29433 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -27,6 +27,7 @@ #include <SkPaint.h> #include <SkRegion.h> #include <SkScalerContext.h> +#include <SkTemplates.h> #include <SkXfermode.h> #include <OpenGLRenderer.h> @@ -275,6 +276,23 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, } } +static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, + jint start, jint count, jint contextCount, jfloat x, jfloat y, + int flags, SkPaint* paint) { + uint8_t rtl = flags & 0x1; + if (rtl) { + SkAutoSTMalloc<80, jchar> buffer(contextCount); + jchar* shaped = buffer.get(); + if (TextLayout::prepareRtlTextRun(text, start, count, contextCount, shaped)) { + renderer->drawText((const char*) shaped, count << 1, count, x, y, paint); + } else { + LOGW("drawTextRun error"); + } + } else { + renderer->drawText((const char*) (text + start), count << 1, count, x, y, paint); + } +} + static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jcharArray text, int index, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { @@ -291,6 +309,28 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas, env->ReleaseStringChars(text, textArray); } +static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canvas, + OpenGLRenderer* renderer, jcharArray text, int index, int count, + int contextIndex, int contextCount, jfloat x, jfloat y, int dirFlags, + SkPaint* paint) { + jchar* textArray = env->GetCharArrayElements(text, NULL); + renderTextRun(renderer, textArray + contextIndex, index - contextIndex, + count, contextCount, x, y, dirFlags, paint); + env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); + } + +static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas, + OpenGLRenderer* renderer, jstring text, int start, int end, + int contextStart, int contextEnd, jfloat x, jfloat y, int dirFlags, + SkPaint* paint) { + const jchar* textArray = env->GetStringChars(text, NULL); + jint count = end - start; + jint contextCount = contextEnd - contextStart; + renderTextRun(renderer, textArray + contextStart, start - contextStart, + count, contextCount, x, y, dirFlags, paint); + env->ReleaseStringChars(text, textArray); +} + #endif // USE_OPENGL_RENDERER // ---------------------------------------------------------------------------- @@ -312,50 +352,54 @@ static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz const char* const kClassPathName = "android/view/GLES20Canvas"; static JNINativeMethod gMethods[] = { - { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable }, -#ifdef USE_OPENGL_RENDERER + { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable }, - { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer }, - { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, - { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport }, - { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare }, - - { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save }, - { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore }, - { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount }, - { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Canvas_getSaveCount }, - - { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayer }, - { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha }, - - { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_quickReject }, - { "nClipRect", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF }, - { "nClipRect", "(IIIIII)Z", (void*) android_view_GLES20Canvas_clipRect }, - - { "nTranslate", "(IFF)V", (void*) android_view_GLES20Canvas_translate }, - { "nRotate", "(IF)V", (void*) android_view_GLES20Canvas_rotate }, - { "nScale", "(IFF)V", (void*) android_view_GLES20Canvas_scale }, - - { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix }, - { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix }, - { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix }, - - { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap }, - { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect }, - { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, - { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch }, - { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor }, - { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect }, - { "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath }, - - { "nResetModifiers", "(I)V", (void*) android_view_GLES20Canvas_resetModifiers }, - { "nSetupShader", "(II)V", (void*) android_view_GLES20Canvas_setupShader }, - { "nSetupColorFilter", "(II)V", (void*) android_view_GLES20Canvas_setupColorFilter }, - - { "nDrawText", "(I[CIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArray }, - { "nDrawText", "(ILjava/lang/String;IIFFII)V", +#ifdef USE_OPENGL_RENDERER + { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer }, + { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, + { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport }, + { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare }, + + { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save }, + { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore }, + { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount }, + { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Canvas_getSaveCount }, + + { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayer }, + { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha }, + + { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_quickReject }, + { "nClipRect", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF }, + { "nClipRect", "(IIIIII)Z", (void*) android_view_GLES20Canvas_clipRect }, + + { "nTranslate", "(IFF)V", (void*) android_view_GLES20Canvas_translate }, + { "nRotate", "(IF)V", (void*) android_view_GLES20Canvas_rotate }, + { "nScale", "(IFF)V", (void*) android_view_GLES20Canvas_scale }, + + { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix }, + { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix }, + { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix }, + + { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap }, + { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect }, + { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, + { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch }, + { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor }, + { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect }, + { "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath }, + + { "nResetModifiers", "(I)V", (void*) android_view_GLES20Canvas_resetModifiers }, + { "nSetupShader", "(II)V", (void*) android_view_GLES20Canvas_setupShader }, + { "nSetupColorFilter", "(II)V", (void*) android_view_GLES20Canvas_setupColorFilter }, + + { "nDrawText", "(I[CIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArray }, + { "nDrawText", "(ILjava/lang/String;IIFFII)V", (void*) android_view_GLES20Canvas_drawText }, + { "nDrawTextRun", "(I[CIIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextRunArray }, + { "nDrawTextRun", "(ILjava/lang/String;IIIIFFII)V", + (void*) android_view_GLES20Canvas_drawTextRun }, + { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds }, #endif diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index cb2c6a2..8251881 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -24,6 +24,10 @@ package android.graphics; * text on a path. */ public class Path { + /** + * @hide + */ + public final int mNativePath; /** * Create an empty path @@ -537,8 +541,8 @@ public class Path { super.finalize(); } } - - /*package*/ final int ni() { + + final int ni() { return mNativePath; } @@ -592,9 +596,4 @@ public class Path { int dst_path); private static native void native_transform(int nPath, int matrix); private static native void finalizer(int nPath); - - /** - * @hide - */ - public final int mNativePath; } diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java index 489ef83..e540806 100644 --- a/graphics/java/android/graphics/Region.java +++ b/graphics/java/android/graphics/Region.java @@ -20,6 +20,10 @@ import android.os.Parcel; import android.os.Parcelable; public class Region implements Parcelable { + /** + * @hide + */ + public final int mNativeRegion; // the native values for these must match up with the enum in SkRegion.h public enum Op { @@ -329,10 +333,14 @@ public class Region implements Parcelable { } protected void finalize() throws Throwable { - nativeDestructor(mNativeRegion); + try { + nativeDestructor(mNativeRegion); + } finally { + super.finalize(); + } } - /*package*/ Region(int ni) { + Region(int ni) { if (ni == 0) { throw new RuntimeException(); } @@ -345,7 +353,7 @@ public class Region implements Parcelable { this(ni); } - /*package*/ final int ni() { + final int ni() { return mNativeRegion; } @@ -374,6 +382,4 @@ public class Region implements Parcelable { Parcel p); private static native boolean nativeEquals(int native_r1, int native_r2); - - private final int mNativeRegion; } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 33ecbea..88f6d43 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -313,18 +313,16 @@ public class GradientDrawable extends Drawable { case RECTANGLE: if (st.mRadiusArray != null) { mPath.reset(); - mPath.addRoundRect(mRect, st.mRadiusArray, - Path.Direction.CW); + mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); canvas.drawPath(mPath, mFillPaint); if (haveStroke) { canvas.drawPath(mPath, mStrokePaint); } - } - else { + } else if (st.mRadius > 0.0f) { // since the caller is only giving us 1 value, we will force // it to be square if the rect is too small in one dimension // to show it. If we did nothing, Skia would clamp the rad - // independently along each axis, giving us a thin ellips + // independently along each axis, giving us a thin ellipse // if the rect were very wide but not very tall float rad = st.mRadius; float r = Math.min(mRect.width(), mRect.height()) * 0.5f; @@ -335,6 +333,11 @@ public class GradientDrawable extends Drawable { if (haveStroke) { canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); } + } else { + canvas.drawRect(mRect, mFillPaint); + if (haveStroke) { + canvas.drawRect(mRect, mStrokePaint); + } } break; case OVAL: diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 8d00e85..e807aba 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -69,16 +69,16 @@ void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds int width = (int) glyph->mBitmapWidth; int height = (int) glyph->mBitmapHeight; - if(bounds->bottom > nPenY) { + if (bounds->bottom > nPenY) { bounds->bottom = nPenY; } - if(bounds->left > nPenX) { + if (bounds->left > nPenX) { bounds->left = nPenX; } - if(bounds->right < nPenX + width) { + if (bounds->right < nPenX + width) { bounds->right = nPenX + width; } - if(bounds->top < nPenY + height) { + if (bounds->top < nPenY + height) { bounds->top = nPenY + height; } } @@ -102,7 +102,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y) { } void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y, - uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) { + uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) { int nPenX = x + glyph->mBitmapLeft; int nPenY = y + glyph->mBitmapTop; @@ -116,7 +116,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y, int32_t bX = 0, bY = 0; for (cacheX = glyph->mStartX, bX = nPenX; cacheX < endX; cacheX++, bX++) { for (cacheY = glyph->mStartY, bY = nPenY; cacheY < endY; cacheY++, bY++) { - if(bX < 0 || bY < 0 || bX >= (int32_t)bitmapW || bY >= (int32_t)bitmapH) { + if (bX < 0 || bY < 0 || bX >= (int32_t)bitmapW || bY >= (int32_t)bitmapH) { LOGE("Skipping invalid index"); continue; } @@ -143,22 +143,19 @@ Font::CachedGlyphInfo* Font::getCachedUTFChar(SkPaint* paint, int32_t utfChar) { } void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, - int numGlyphs, int x, int y, - uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) { - if(bitmap != NULL && bitmapW > 0 && bitmapH > 0) { - renderUTF(paint, text, start, len, numGlyphs, x, y, BITMAP, - bitmap, bitmapW, bitmapH, NULL); - } - else { - renderUTF(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, - NULL, 0, 0, NULL); + int numGlyphs, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) { + if (bitmap != NULL && bitmapW > 0 && bitmapH > 0) { + renderUTF(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap, + bitmapW, bitmapH, NULL); + } else { + renderUTF(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL, 0, 0, NULL); } } void Font::measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, - int numGlyphs, Rect *bounds) { - if(bounds == NULL) { + int numGlyphs, Rect *bounds) { + if (bounds == NULL) { LOGE("No return rectangle provided to measure text"); return; } @@ -167,9 +164,8 @@ void Font::measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t } void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len, - int numGlyphs, int x, int y, RenderMode mode, - uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, - Rect *bounds) { + int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, + uint32_t bitmapW, uint32_t bitmapH,Rect *bounds) { if (numGlyphs == 0 || text == NULL || len == 0) { return; } @@ -185,7 +181,7 @@ void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t while (glyphsLeft > 0) { int32_t utfChar = SkUTF16_NextUnichar((const uint16_t**) &text); - // Reached the end of the string or encountered + // Reached the end of the string if (utfChar < 0) { break; } @@ -422,7 +418,7 @@ void FontRenderer::initTextTexture() { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Initialize texture dimentions glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, 0); + GL_ALPHA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -527,7 +523,6 @@ void FontRenderer::checkTextureUpdate() { } void FontRenderer::issueDrawCommand() { - checkTextureUpdate(); float* vtx = mTextMeshPtr; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 5d30b1a..ff00ba6 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -435,6 +435,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const S return; } + glActiveTexture(GL_TEXTURE0); const Texture* texture = mTextureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -451,6 +452,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const return; } + glActiveTexture(GL_TEXTURE0); const Texture* texture = mTextureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -466,6 +468,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, return; } + glActiveTexture(GL_TEXTURE0); const Texture* texture = mTextureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -491,6 +494,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, return; } + glActiveTexture(GL_TEXTURE0); const Texture* texture = mTextureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 4a01ffa..9a22dc0 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -162,7 +162,8 @@ void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) { glGenTextures(1, &texture->id); glBindTexture(GL_TEXTURE_2D, texture->id); - glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap.bytesPerPixel()); + // Textures are Alpha8 + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); texture->blend = true; glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap.rowBytesAsPixels(), texture->height, 0, diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 8a97b4c..2449b6d 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -376,6 +376,9 @@ void ProgramCache::generateTextureWrap(String8& shader, GLenum wrapS, GLenum wra } shader.append(" return vec2("); switch (wrapS) { + case GL_CLAMP_TO_EDGE: + shader.append("texCoords.x"); + break; case GL_REPEAT: shader.append("mod(texCoords.x, 1.0)"); break; @@ -385,6 +388,9 @@ void ProgramCache::generateTextureWrap(String8& shader, GLenum wrapS, GLenum wra } shader.append(", "); switch (wrapT) { + case GL_CLAMP_TO_EDGE: + shader.append("texCoords.y"); + break; case GL_REPEAT: shader.append("mod(texCoords.y, 1.0)"); break; diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 42c0621..15a4e88 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -89,7 +89,8 @@ void SkiaBitmapShader::describe(ProgramDescription& description, const Extension description.hasBitmap = true; // The driver does not support non-power of two mirrored/repeated // textures, so do it ourselves - if (!extensions.hasNPot() && !isPowerOfTwo(width) && !isPowerOfTwo(height)) { + if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) && + (mTileX != SkShader::kClamp_TileMode || mTileY != SkShader::kClamp_TileMode)) { description.isBitmapNpot = true; description.bitmapWrapS = gTileModes[mTileX]; description.bitmapWrapT = gTileModes[mTileY]; @@ -136,6 +137,9 @@ SkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colo SkMatrix* matrix, bool blend): SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend), mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) { + for (int i = 0; i < count; i++) { + LOGD("[GL] Gradient color %d = 0x%x", i, colors[i]); + } } SkiaLinearGradientShader::~SkiaLinearGradientShader() { diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index 924737e..a12edf2 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -39,6 +39,8 @@ using namespace android; #undef CALL_GL_API #undef CALL_GL_API_RETURN +#define DEBUG_CALL_GL_API 0 + #if USE_FAST_TLS_KEY #ifdef HAVE_ARM_TLS_REGISTER @@ -73,10 +75,24 @@ using namespace android; #define API_ENTRY(_api) _api +#if DEBUG_CALL_GL_API + + #define CALL_GL_API(_api, ...) \ + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ + _c->_api(__VA_ARGS__); \ + GLenum status = GL_NO_ERROR; \ + while ((status = glGetError()) != GL_NO_ERROR) { \ + LOGD("[" #_api "] 0x%x", status); \ + } + +#else + #define CALL_GL_API(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - _c->_api(__VA_ARGS__) - + _c->_api(__VA_ARGS__); + +#endif + #define CALL_GL_API_RETURN(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ return _c->_api(__VA_ARGS__) diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 73994f7..90c82ee 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -171,5 +171,14 @@ </intent-filter> </activity> + <activity + android:name="SimplePathsActivity" + android:label="_SimplePaths"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> </manifest> diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java new file mode 100644 index 0000000..071a118 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/SimplePathsActivity.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.test.hwui; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Gravity; +import android.widget.EditText; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class SimplePathsActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout layout = new FrameLayout(this); + EditText text = new EditText(this); + layout.addView(text, new FrameLayout.LayoutParams(600, 350, Gravity.CENTER)); + text.setText("This is an example of an EditText widget \n" + + "using simple paths to create the selection."); + //text.setSelection(0, text.getText().length()); + + setContentView(layout); + } +}
\ No newline at end of file |