From 4de3f481bc59ab4b766dc027e41aff7cda9d62f7 Mon Sep 17 00:00:00 2001 From: Ashok Bhat Date: Mon, 27 Jan 2014 16:00:23 +0000 Subject: AArch64: Make AssetAtlasService 64-bit compatible Changes in this patch include [x] Long(64-bit) is used to store native pointers in AssetAtlasService and related classes as they can be 64-bit. [x] Some minor changes have been done to conform with standard JNI practice (e.g. use of jint instead of int in JNI function prototypes) Change-Id: Ib4c77c134e3ad5b21732e20cde9a54a0b16bdab1 Signed-off-by: Ashok Bhat --- core/java/android/view/GLES20Canvas.java | 4 +- core/java/android/view/HardwareRenderer.java | 2 +- core/java/android/view/IAssetAtlas.aidl | 10 ++--- core/jni/android_view_GLES20Canvas.cpp | 12 +++--- libs/hwui/AssetAtlas.cpp | 15 +++++--- libs/hwui/AssetAtlas.h | 4 +- .../java/com/android/server/AssetAtlasService.java | 28 +++++++------- .../jni/com_android_server_AssetAtlasService.cpp | 44 +++++++++++----------- 8 files changed, 61 insertions(+), 58 deletions(-) diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 6a15fa6..d533060 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -392,11 +392,11 @@ class GLES20Canvas extends HardwareCanvas { // Atlas /////////////////////////////////////////////////////////////////////////// - static void initAtlas(GraphicBuffer buffer, int[] map) { + static void initAtlas(GraphicBuffer buffer, long[] map) { nInitAtlas(buffer, map, map.length); } - private static native void nInitAtlas(GraphicBuffer buffer, int[] map, int count); + private static native void nInitAtlas(GraphicBuffer buffer, long[] map, int count); /////////////////////////////////////////////////////////////////////////// // Display list diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 3781bdb..f09a111 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -1981,7 +1981,7 @@ public abstract class HardwareRenderer { if (atlas.isCompatible(android.os.Process.myPpid())) { GraphicBuffer buffer = atlas.getBuffer(); if (buffer != null) { - int[] map = atlas.getMap(); + long[] map = atlas.getMap(); if (map != null) { GLES20Canvas.initAtlas(buffer, map); } diff --git a/core/java/android/view/IAssetAtlas.aidl b/core/java/android/view/IAssetAtlas.aidl index 5f1e238..edce059 100644 --- a/core/java/android/view/IAssetAtlas.aidl +++ b/core/java/android/view/IAssetAtlas.aidl @@ -45,10 +45,10 @@ interface IAssetAtlas { * if the atlas is not available yet. * * Each bitmap is represented by several entries in the array: - * int0: SkBitmap*, the native bitmap object - * int1: x position - * int2: y position - * int3: rotated, 1 if the bitmap must be rotated, 0 otherwise + * long0: SkBitmap*, the native bitmap object + * long1: x position + * long2: y position + * long3: rotated, 1 if the bitmap must be rotated, 0 otherwise */ - int[] getMap(); + long[] getMap(); } diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 118af1b..86d5099 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -118,14 +118,12 @@ static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz // ---------------------------------------------------------------------------- static void android_view_GLES20Canvas_initAtlas(JNIEnv* env, jobject clazz, - jobject graphicBuffer, jintArray atlasMapArray, jint count) { + jobject graphicBuffer, jlongArray atlasMapArray, jint count) { sp buffer = graphicBufferForJavaObject(env, graphicBuffer); - jint* atlasMap = env->GetIntArrayElements(atlasMapArray, NULL); - - Caches::getInstance().assetAtlas.init(buffer, atlasMap, count); - - env->ReleaseIntArrayElements(atlasMapArray, atlasMap, 0); + jlong* jAtlasMap = env->GetLongArrayElements(atlasMapArray, NULL); + Caches::getInstance().assetAtlas.init(buffer, jAtlasMap, count); + env->ReleaseLongArrayElements(atlasMapArray, jAtlasMap, 0); } // ---------------------------------------------------------------------------- @@ -1163,7 +1161,7 @@ static JNINativeMethod gMethods[] = { { "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches }, { "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches }, - { "nInitAtlas", "(Landroid/view/GraphicBuffer;[II)V", + { "nInitAtlas", "(Landroid/view/GraphicBuffer;[JI)V", (void*) android_view_GLES20Canvas_initAtlas }, { "nCreateRenderer", "()J", (void*) android_view_GLES20Canvas_createRenderer }, diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp index eb8bb9f..e8c3d3c 100644 --- a/libs/hwui/AssetAtlas.cpp +++ b/libs/hwui/AssetAtlas.cpp @@ -28,7 +28,7 @@ namespace uirenderer { // Lifecycle /////////////////////////////////////////////////////////////////////////////// -void AssetAtlas::init(sp buffer, int* map, int count) { +void AssetAtlas::init(sp buffer, int64_t* map, int count) { if (mImage) { return; } @@ -108,14 +108,19 @@ private: /** * TODO: This method does not take the rotation flag into account */ -void AssetAtlas::createEntries(Caches& caches, int* map, int count) { +void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) { const float width = float(mTexture->width); const float height = float(mTexture->height); for (int i = 0; i < count; ) { - SkBitmap* bitmap = (SkBitmap*) map[i++]; - int x = map[i++]; - int y = map[i++]; + SkBitmap* bitmap = reinterpret_cast(map[i++]); + // NOTE: We're converting from 64 bit signed values to 32 bit + // signed values. This is guaranteed to be safe because the "x" + // and "y" coordinate values are guaranteed to be representable + // with 32 bits. The array is 64 bits wide so that it can carry + // pointers on 64 bit architectures. + const int x = static_cast(map[i++]); + const int y = static_cast(map[i++]); bool rotated = map[i++] > 0; // Bitmaps should never be null, we're just extra paranoid diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h index a28efc6..163bdbc 100644 --- a/libs/hwui/AssetAtlas.h +++ b/libs/hwui/AssetAtlas.h @@ -121,7 +121,7 @@ public: * initialized. To re-initialize the atlas, you must * first call terminate(). */ - ANDROID_API void init(sp buffer, int* map, int count); + ANDROID_API void init(sp buffer, int64_t* map, int count); /** * Destroys the atlas texture. This object can be @@ -176,7 +176,7 @@ public: } private: - void createEntries(Caches& caches, int* map, int count); + void createEntries(Caches& caches, int64_t* map, int count); Texture* mTexture; Image* mImage; diff --git a/services/java/com/android/server/AssetAtlasService.java b/services/java/com/android/server/AssetAtlasService.java index 3fb006b..fc4838c 100644 --- a/services/java/com/android/server/AssetAtlasService.java +++ b/services/java/com/android/server/AssetAtlasService.java @@ -114,12 +114,11 @@ public class AssetAtlasService extends IAssetAtlas.Stub { // Describes how bitmaps are placed in the atlas. Each bitmap is // represented by several entries in the array: - // int0: SkBitmap*, the native bitmap object - // int1: x position - // int2: y position - // int3: rotated, 1 if the bitmap must be rotated, 0 otherwise - // NOTE: This will need to be handled differently to support 64 bit pointers - private int[] mAtlasMap; + // long0: SkBitmap*, the native bitmap object + // long1: x position + // long2: y position + // long3: rotated, 1 if the bitmap must be rotated, 0 otherwise + private long[] mAtlasMap; /** * Creates a new service. Upon creating, the service will gather the list of @@ -196,7 +195,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub { private final ArrayList mBitmaps; private final int mPixelCount; - private int mNativeBitmap; + private long mNativeBitmap; // Used for debugging only private Bitmap mAtlasBitmap; @@ -260,8 +259,8 @@ public class AssetAtlasService extends IAssetAtlas.Stub { final Atlas.Entry entry = new Atlas.Entry(); - mAtlasMap = new int[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT]; - int[] atlasMap = mAtlasMap; + mAtlasMap = new long[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT]; + long[] atlasMap = mAtlasMap; int mapIndex = 0; boolean result = false; @@ -288,8 +287,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub { } canvas.drawBitmap(bitmap, 0.0f, 0.0f, null); canvas.restore(); - // TODO: Change mAtlasMap to long[] to support 64-bit systems - atlasMap[mapIndex++] = (int) bitmap.mNativeBitmap; + atlasMap[mapIndex++] = bitmap.mNativeBitmap; atlasMap[mapIndex++] = entry.x; atlasMap[mapIndex++] = entry.y; atlasMap[mapIndex++] = entry.rotated ? 1 : 0; @@ -365,9 +363,9 @@ public class AssetAtlasService extends IAssetAtlas.Stub { } } - private static native int nAcquireAtlasCanvas(Canvas canvas, int width, int height); - private static native void nReleaseAtlasCanvas(Canvas canvas, int bitmap); - private static native boolean nUploadAtlas(GraphicBuffer buffer, int bitmap); + private static native long nAcquireAtlasCanvas(Canvas canvas, int width, int height); + private static native void nReleaseAtlasCanvas(Canvas canvas, long bitmap); + private static native boolean nUploadAtlas(GraphicBuffer buffer, long bitmap); @Override public boolean isCompatible(int ppid) { @@ -380,7 +378,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub { } @Override - public int[] getMap() throws RemoteException { + public long[] getMap() throws RemoteException { return mAtlasReady.get() ? mAtlasMap : null; } diff --git a/services/jni/com_android_server_AssetAtlasService.cpp b/services/jni/com_android_server_AssetAtlasService.cpp index 4a1b55d..163692b 100644 --- a/services/jni/com_android_server_AssetAtlasService.cpp +++ b/services/jni/com_android_server_AssetAtlasService.cpp @@ -73,7 +73,7 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa SkSafeUnref(previousCanvas); } -static SkBitmap* com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, jobject, +static jlong com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, jobject, jobject canvas, jint width, jint height) { SkBitmap* bitmap = new SkBitmap; @@ -84,12 +84,13 @@ static SkBitmap* com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (*bitmap)); swapCanvasPtr(env, canvas, nativeCanvas); - return bitmap; + return reinterpret_cast(bitmap); } static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobject, - jobject canvas, SkBitmap* bitmap) { + jobject canvas, jlong bitmapHandle) { + SkBitmap* bitmap = reinterpret_cast(bitmapHandle); SkCanvas* nativeCanvas = SkNEW(SkCanvas); swapCanvasPtr(env, canvas, nativeCanvas); @@ -108,21 +109,22 @@ static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobj return result; static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject, - jobject graphicBuffer, SkBitmap* bitmap) { + jobject graphicBuffer, jlong bitmapHandle) { + SkBitmap* bitmap = reinterpret_cast(bitmapHandle); // The goal of this method is to copy the bitmap into the GraphicBuffer // using the GPU to swizzle the texture content sp buffer(graphicBufferForJavaObject(env, graphicBuffer)); if (buffer != NULL) { EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (display == EGL_NO_DISPLAY) return false; + if (display == EGL_NO_DISPLAY) return JNI_FALSE; EGLint major; EGLint minor; if (!eglInitialize(display, &major, &minor)) { ALOGW("Could not initialize EGL"); - return false; + return JNI_FALSE; } // We're going to use a 1x1 pbuffer surface later on @@ -143,13 +145,13 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject ALOGW("Could not select EGL configuration"); eglReleaseThread(); eglTerminate(display); - return false; + return JNI_FALSE; } if (configCount <= 0) { ALOGW("Could not find EGL configuration"); eglReleaseThread(); eglTerminate(display); - return false; + return JNI_FALSE; } // These objects are initialized below but the default "null" @@ -164,7 +166,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject EGLContext context = eglCreateContext(display, configs[0], EGL_NO_CONTEXT, attrs); if (context == EGL_NO_CONTEXT) { ALOGW("Could not create EGL context"); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } // Create the 1x1 pbuffer @@ -172,12 +174,12 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject surface = eglCreatePbufferSurface(display, configs[0], surfaceAttrs); if (surface == EGL_NO_SURFACE) { ALOGW("Could not create EGL surface"); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } if (!eglMakeCurrent(display, surface, surface, context)) { ALOGW("Could not change current EGL context"); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } // We use an EGLImage to access the content of the GraphicBuffer @@ -188,7 +190,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs); if (image == EGL_NO_IMAGE_KHR) { ALOGW("Could not create EGL image"); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } glGenTextures(1, &texture); @@ -196,7 +198,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); if (glGetError() != GL_NO_ERROR) { ALOGW("Could not create/bind texture"); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } // Upload the content of the bitmap in the GraphicBuffer @@ -205,7 +207,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels()); if (glGetError() != GL_NO_ERROR) { ALOGW("Could not upload to texture"); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } // The fence is used to wait for the texture upload to finish @@ -214,7 +216,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL); if (fence == EGL_NO_SYNC_KHR) { ALOGW("Could not create sync fence %#x", eglGetError()); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a @@ -223,13 +225,13 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT); if (waitStatus != EGL_CONDITION_SATISFIED_KHR) { ALOGW("Failed to wait for the fence %#x", eglGetError()); - CLEANUP_GL_AND_RETURN(false); + CLEANUP_GL_AND_RETURN(JNI_FALSE); } - CLEANUP_GL_AND_RETURN(true); + CLEANUP_GL_AND_RETURN(JNI_TRUE); } - return false; + return JNI_FALSE; } // ---------------------------------------------------------------------------- @@ -247,11 +249,11 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject const char* const kClassPathName = "com/android/server/AssetAtlasService"; static JNINativeMethod gMethods[] = { - { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)I", + { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)J", (void*) com_android_server_AssetAtlasService_acquireCanvas }, - { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;I)V", + { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;J)V", (void*) com_android_server_AssetAtlasService_releaseCanvas }, - { "nUploadAtlas", "(Landroid/view/GraphicBuffer;I)Z", + { "nUploadAtlas", "(Landroid/view/GraphicBuffer;J)Z", (void*) com_android_server_AssetAtlasService_upload }, }; -- cgit v1.1