am 9fce8535: Merge "AArch64: Make AssetAtlasService 64-bit compatible"

* commit '9fce8535851fc696997bd3c251d00e34179d6482':
  AArch64: Make AssetAtlasService 64-bit compatible
This commit is contained in:
Narayan Kamath
2014-02-20 04:58:45 -08:00
committed by Android Git Automerger
8 changed files with 61 additions and 58 deletions

View File

@ -392,11 +392,11 @@ class GLES20Canvas extends HardwareCanvas {
// Atlas // Atlas
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
static void initAtlas(GraphicBuffer buffer, int[] map) { static void initAtlas(GraphicBuffer buffer, long[] map) {
nInitAtlas(buffer, map, map.length); 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 // Display list

View File

@ -1981,7 +1981,7 @@ public abstract class HardwareRenderer {
if (atlas.isCompatible(android.os.Process.myPpid())) { if (atlas.isCompatible(android.os.Process.myPpid())) {
GraphicBuffer buffer = atlas.getBuffer(); GraphicBuffer buffer = atlas.getBuffer();
if (buffer != null) { if (buffer != null) {
int[] map = atlas.getMap(); long[] map = atlas.getMap();
if (map != null) { if (map != null) {
GLES20Canvas.initAtlas(buffer, map); GLES20Canvas.initAtlas(buffer, map);
} }

View File

@ -45,10 +45,10 @@ interface IAssetAtlas {
* if the atlas is not available yet. * if the atlas is not available yet.
* *
* Each bitmap is represented by several entries in the array: * Each bitmap is represented by several entries in the array:
* int0: SkBitmap*, the native bitmap object * long0: SkBitmap*, the native bitmap object
* int1: x position * long1: x position
* int2: y position * long2: y position
* int3: rotated, 1 if the bitmap must be rotated, 0 otherwise * long3: rotated, 1 if the bitmap must be rotated, 0 otherwise
*/ */
int[] getMap(); long[] getMap();
} }

View File

@ -118,14 +118,12 @@ static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static void android_view_GLES20Canvas_initAtlas(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<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer); sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
jint* atlasMap = env->GetIntArrayElements(atlasMapArray, NULL); jlong* jAtlasMap = env->GetLongArrayElements(atlasMapArray, NULL);
Caches::getInstance().assetAtlas.init(buffer, jAtlasMap, count);
Caches::getInstance().assetAtlas.init(buffer, atlasMap, count); env->ReleaseLongArrayElements(atlasMapArray, jAtlasMap, 0);
env->ReleaseIntArrayElements(atlasMapArray, atlasMap, 0);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -1163,7 +1161,7 @@ static JNINativeMethod gMethods[] = {
{ "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches }, { "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches },
{ "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches }, { "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches },
{ "nInitAtlas", "(Landroid/view/GraphicBuffer;[II)V", { "nInitAtlas", "(Landroid/view/GraphicBuffer;[JI)V",
(void*) android_view_GLES20Canvas_initAtlas }, (void*) android_view_GLES20Canvas_initAtlas },
{ "nCreateRenderer", "()J", (void*) android_view_GLES20Canvas_createRenderer }, { "nCreateRenderer", "()J", (void*) android_view_GLES20Canvas_createRenderer },

View File

@ -28,7 +28,7 @@ namespace uirenderer {
// Lifecycle // Lifecycle
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) { void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) {
if (mImage) { if (mImage) {
return; return;
} }
@ -108,14 +108,19 @@ private:
/** /**
* TODO: This method does not take the rotation flag into account * 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 width = float(mTexture->width);
const float height = float(mTexture->height); const float height = float(mTexture->height);
for (int i = 0; i < count; ) { for (int i = 0; i < count; ) {
SkBitmap* bitmap = (SkBitmap*) map[i++]; SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(map[i++]);
int x = map[i++]; // NOTE: We're converting from 64 bit signed values to 32 bit
int y = map[i++]; // 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<int>(map[i++]);
const int y = static_cast<int>(map[i++]);
bool rotated = map[i++] > 0; bool rotated = map[i++] > 0;
// Bitmaps should never be null, we're just extra paranoid // Bitmaps should never be null, we're just extra paranoid

View File

@ -121,7 +121,7 @@ public:
* initialized. To re-initialize the atlas, you must * initialized. To re-initialize the atlas, you must
* first call terminate(). * first call terminate().
*/ */
ANDROID_API void init(sp<GraphicBuffer> buffer, int* map, int count); ANDROID_API void init(sp<GraphicBuffer> buffer, int64_t* map, int count);
/** /**
* Destroys the atlas texture. This object can be * Destroys the atlas texture. This object can be
@ -176,7 +176,7 @@ public:
} }
private: private:
void createEntries(Caches& caches, int* map, int count); void createEntries(Caches& caches, int64_t* map, int count);
Texture* mTexture; Texture* mTexture;
Image* mImage; Image* mImage;

View File

@ -114,12 +114,11 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
// Describes how bitmaps are placed in the atlas. Each bitmap is // Describes how bitmaps are placed in the atlas. Each bitmap is
// represented by several entries in the array: // represented by several entries in the array:
// int0: SkBitmap*, the native bitmap object // long0: SkBitmap*, the native bitmap object
// int1: x position // long1: x position
// int2: y position // long2: y position
// int3: rotated, 1 if the bitmap must be rotated, 0 otherwise // long3: rotated, 1 if the bitmap must be rotated, 0 otherwise
// NOTE: This will need to be handled differently to support 64 bit pointers private long[] mAtlasMap;
private int[] mAtlasMap;
/** /**
* Creates a new service. Upon creating, the service will gather the list of * 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<Bitmap> mBitmaps; private final ArrayList<Bitmap> mBitmaps;
private final int mPixelCount; private final int mPixelCount;
private int mNativeBitmap; private long mNativeBitmap;
// Used for debugging only // Used for debugging only
private Bitmap mAtlasBitmap; private Bitmap mAtlasBitmap;
@ -260,8 +259,8 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
final Atlas.Entry entry = new Atlas.Entry(); final Atlas.Entry entry = new Atlas.Entry();
mAtlasMap = new int[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT]; mAtlasMap = new long[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT];
int[] atlasMap = mAtlasMap; long[] atlasMap = mAtlasMap;
int mapIndex = 0; int mapIndex = 0;
boolean result = false; boolean result = false;
@ -288,8 +287,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
} }
canvas.drawBitmap(bitmap, 0.0f, 0.0f, null); canvas.drawBitmap(bitmap, 0.0f, 0.0f, null);
canvas.restore(); canvas.restore();
// TODO: Change mAtlasMap to long[] to support 64-bit systems atlasMap[mapIndex++] = bitmap.mNativeBitmap;
atlasMap[mapIndex++] = (int) bitmap.mNativeBitmap;
atlasMap[mapIndex++] = entry.x; atlasMap[mapIndex++] = entry.x;
atlasMap[mapIndex++] = entry.y; atlasMap[mapIndex++] = entry.y;
atlasMap[mapIndex++] = entry.rotated ? 1 : 0; 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 long nAcquireAtlasCanvas(Canvas canvas, int width, int height);
private static native void nReleaseAtlasCanvas(Canvas canvas, int bitmap); private static native void nReleaseAtlasCanvas(Canvas canvas, long bitmap);
private static native boolean nUploadAtlas(GraphicBuffer buffer, int bitmap); private static native boolean nUploadAtlas(GraphicBuffer buffer, long bitmap);
@Override @Override
public boolean isCompatible(int ppid) { public boolean isCompatible(int ppid) {
@ -380,7 +378,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
} }
@Override @Override
public int[] getMap() throws RemoteException { public long[] getMap() throws RemoteException {
return mAtlasReady.get() ? mAtlasMap : null; return mAtlasReady.get() ? mAtlasMap : null;
} }

View File

@ -73,7 +73,7 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa
SkSafeUnref(previousCanvas); 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) { jobject canvas, jint width, jint height) {
SkBitmap* bitmap = new SkBitmap; SkBitmap* bitmap = new SkBitmap;
@ -84,12 +84,13 @@ static SkBitmap* com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env,
SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (*bitmap)); SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (*bitmap));
swapCanvasPtr(env, canvas, nativeCanvas); swapCanvasPtr(env, canvas, nativeCanvas);
return bitmap; return reinterpret_cast<jlong>(bitmap);
} }
static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobject, static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobject,
jobject canvas, SkBitmap* bitmap) { jobject canvas, jlong bitmapHandle) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
SkCanvas* nativeCanvas = SkNEW(SkCanvas); SkCanvas* nativeCanvas = SkNEW(SkCanvas);
swapCanvasPtr(env, canvas, nativeCanvas); swapCanvasPtr(env, canvas, nativeCanvas);
@ -108,21 +109,22 @@ static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobj
return result; return result;
static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject, static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject,
jobject graphicBuffer, SkBitmap* bitmap) { jobject graphicBuffer, jlong bitmapHandle) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
// The goal of this method is to copy the bitmap into the GraphicBuffer // The goal of this method is to copy the bitmap into the GraphicBuffer
// using the GPU to swizzle the texture content // using the GPU to swizzle the texture content
sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer)); sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer));
if (buffer != NULL) { if (buffer != NULL) {
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) return false; if (display == EGL_NO_DISPLAY) return JNI_FALSE;
EGLint major; EGLint major;
EGLint minor; EGLint minor;
if (!eglInitialize(display, &major, &minor)) { if (!eglInitialize(display, &major, &minor)) {
ALOGW("Could not initialize EGL"); ALOGW("Could not initialize EGL");
return false; return JNI_FALSE;
} }
// We're going to use a 1x1 pbuffer surface later on // 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"); ALOGW("Could not select EGL configuration");
eglReleaseThread(); eglReleaseThread();
eglTerminate(display); eglTerminate(display);
return false; return JNI_FALSE;
} }
if (configCount <= 0) { if (configCount <= 0) {
ALOGW("Could not find EGL configuration"); ALOGW("Could not find EGL configuration");
eglReleaseThread(); eglReleaseThread();
eglTerminate(display); eglTerminate(display);
return false; return JNI_FALSE;
} }
// These objects are initialized below but the default "null" // 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); EGLContext context = eglCreateContext(display, configs[0], EGL_NO_CONTEXT, attrs);
if (context == EGL_NO_CONTEXT) { if (context == EGL_NO_CONTEXT) {
ALOGW("Could not create EGL context"); ALOGW("Could not create EGL context");
CLEANUP_GL_AND_RETURN(false); CLEANUP_GL_AND_RETURN(JNI_FALSE);
} }
// Create the 1x1 pbuffer // Create the 1x1 pbuffer
@ -172,12 +174,12 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
surface = eglCreatePbufferSurface(display, configs[0], surfaceAttrs); surface = eglCreatePbufferSurface(display, configs[0], surfaceAttrs);
if (surface == EGL_NO_SURFACE) { if (surface == EGL_NO_SURFACE) {
ALOGW("Could not create EGL surface"); ALOGW("Could not create EGL surface");
CLEANUP_GL_AND_RETURN(false); CLEANUP_GL_AND_RETURN(JNI_FALSE);
} }
if (!eglMakeCurrent(display, surface, surface, context)) { if (!eglMakeCurrent(display, surface, surface, context)) {
ALOGW("Could not change current EGL 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 // 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); EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
if (image == EGL_NO_IMAGE_KHR) { if (image == EGL_NO_IMAGE_KHR) {
ALOGW("Could not create EGL image"); ALOGW("Could not create EGL image");
CLEANUP_GL_AND_RETURN(false); CLEANUP_GL_AND_RETURN(JNI_FALSE);
} }
glGenTextures(1, &texture); glGenTextures(1, &texture);
@ -196,7 +198,7 @@ static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
if (glGetError() != GL_NO_ERROR) { if (glGetError() != GL_NO_ERROR) {
ALOGW("Could not create/bind texture"); 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 // 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()); GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());
if (glGetError() != GL_NO_ERROR) { if (glGetError() != GL_NO_ERROR) {
ALOGW("Could not upload to texture"); 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 // 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); fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
if (fence == EGL_NO_SYNC_KHR) { if (fence == EGL_NO_SYNC_KHR) {
ALOGW("Could not create sync fence %#x", eglGetError()); 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 // 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); EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
if (waitStatus != EGL_CONDITION_SATISFIED_KHR) { if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
ALOGW("Failed to wait for the fence %#x", eglGetError()); 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"; const char* const kClassPathName = "com/android/server/AssetAtlasService";
static JNINativeMethod gMethods[] = { static JNINativeMethod gMethods[] = {
{ "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)I", { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)J",
(void*) com_android_server_AssetAtlasService_acquireCanvas }, (void*) com_android_server_AssetAtlasService_acquireCanvas },
{ "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;I)V", { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;J)V",
(void*) com_android_server_AssetAtlasService_releaseCanvas }, (void*) com_android_server_AssetAtlasService_releaseCanvas },
{ "nUploadAtlas", "(Landroid/view/GraphicBuffer;I)Z", { "nUploadAtlas", "(Landroid/view/GraphicBuffer;J)Z",
(void*) com_android_server_AssetAtlasService_upload }, (void*) com_android_server_AssetAtlasService_upload },
}; };