Avert race condition between window attachment and buffer swap
* java/org/gnu/emacs/EmacsView.java (swapBuffers): Synchronize such that code cannot execute between the bitmap's being loaded and being transferred to surfaceView. (onDetachedFromWindow): Recycle bitmap after the surface view is reset. * java/org/gnu/emacs/EmacsWindow.java (recreateActivity): * src/android.c (android_init_emacs_window) (android_recreate_activity): * src/androidfns.c (Fandroid_recreate_activity) (syms_of_androidfns): New functions for debugging window attachment. * src/androidgui.h: Update prototypes.
This commit is contained in:
parent
65829b27ca
commit
16831e290e
5 changed files with 83 additions and 13 deletions
|
@ -456,7 +456,6 @@ else if (child.getVisibility () != GONE)
|
|||
{
|
||||
Canvas canvas;
|
||||
Rect damageRect;
|
||||
Bitmap bitmap;
|
||||
|
||||
/* Make sure this function is called only from the Emacs
|
||||
thread. */
|
||||
|
@ -474,11 +473,12 @@ else if (child.getVisibility () != GONE)
|
|||
damageRect = damageRegion.getBounds ();
|
||||
damageRegion.setEmpty ();
|
||||
|
||||
bitmap = getBitmap ();
|
||||
|
||||
/* Transfer the bitmap to the surface view, then invalidate
|
||||
it. */
|
||||
surfaceView.setBitmap (bitmap, damageRect);
|
||||
synchronized (this)
|
||||
{
|
||||
/* Transfer the bitmap to the surface view, then invalidate
|
||||
it. */
|
||||
surfaceView.setBitmap (bitmap, damageRect);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -724,16 +724,19 @@ else if (child.getVisibility () != GONE)
|
|||
public synchronized void
|
||||
onDetachedFromWindow ()
|
||||
{
|
||||
Bitmap savedBitmap;
|
||||
|
||||
savedBitmap = bitmap;
|
||||
isAttachedToWindow = false;
|
||||
bitmap = null;
|
||||
canvas = null;
|
||||
|
||||
surfaceView.setBitmap (null, null);
|
||||
|
||||
/* Recycle the bitmap and call GC. */
|
||||
|
||||
if (bitmap != null)
|
||||
bitmap.recycle ();
|
||||
|
||||
bitmap = null;
|
||||
canvas = null;
|
||||
surfaceView.setBitmap (null, null);
|
||||
if (savedBitmap != null)
|
||||
savedBitmap.recycle ();
|
||||
|
||||
/* Collect the bitmap storage; it could be large. */
|
||||
Runtime.getRuntime ().gc ();
|
||||
|
|
|
@ -1784,4 +1784,32 @@ else if (type.equals (ClipDescription.MIMETYPE_TEXT_URILIST))
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Miscellaneous functions for debugging graphics code. */
|
||||
|
||||
/* Recreate the activity to which this window is attached, if any.
|
||||
This is nonfunctional on Android 2.3.7 and earlier. */
|
||||
|
||||
public void
|
||||
recreateActivity ()
|
||||
{
|
||||
final EmacsWindowAttachmentManager.WindowConsumer attached;
|
||||
|
||||
attached = this.attached;
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
|
||||
return;
|
||||
|
||||
view.post (new Runnable () {
|
||||
@Override
|
||||
public void
|
||||
run ()
|
||||
{
|
||||
if (attached instanceof EmacsActivity)
|
||||
((EmacsActivity) attached).recreate ();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -111,6 +111,7 @@ struct android_emacs_window
|
|||
jmethodID set_dont_focus_on_map;
|
||||
jmethodID define_cursor;
|
||||
jmethodID damage_rect;
|
||||
jmethodID recreate_activity;
|
||||
};
|
||||
|
||||
struct android_emacs_cursor
|
||||
|
@ -1802,12 +1803,12 @@ android_init_emacs_window (void)
|
|||
FIND_METHOD (set_dont_accept_focus, "setDontAcceptFocus", "(Z)V");
|
||||
FIND_METHOD (define_cursor, "defineCursor",
|
||||
"(Lorg/gnu/emacs/EmacsCursor;)V");
|
||||
|
||||
/* In spite of the declaration of this function being located within
|
||||
EmacsDrawable, the ID of the `damage_rect' method is retrieved
|
||||
from EmacsWindow, which avoids virtual function dispatch within
|
||||
android_damage_window. */
|
||||
FIND_METHOD (damage_rect, "damageRect", "(IIII)V");
|
||||
FIND_METHOD (recreate_activity, "recreateActivity", "()V");
|
||||
#undef FIND_METHOD
|
||||
}
|
||||
|
||||
|
@ -6638,6 +6639,24 @@ android_request_storage_access (void)
|
|||
android_exception_check ();
|
||||
}
|
||||
|
||||
/* Recreate the activity to which WINDOW is attached to debug graphics
|
||||
code executed in response to window attachment. */
|
||||
|
||||
void
|
||||
android_recreate_activity (android_window window)
|
||||
{
|
||||
jobject object;
|
||||
jmethodID method;
|
||||
|
||||
object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
|
||||
method = window_class.recreate_activity;
|
||||
|
||||
(*android_java_env)->CallNonvirtualVoidMethod (android_java_env, object,
|
||||
window_class.class,
|
||||
method);
|
||||
android_exception_check ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The thread from which a query against a thread is currently being
|
||||
|
|
|
@ -3164,6 +3164,24 @@ android_set_preeditarea (struct window *w, int x, int y)
|
|||
y + w->phys_cursor_height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Debugging. */
|
||||
|
||||
DEFUN ("android-recreate-activity", Fandroid_recreate_activity,
|
||||
Sandroid_recreate_activity, 0, 0, "",
|
||||
doc: /* Recreate the activity attached to the current frame.
|
||||
This function exists for debugging purposes and is of no interest to
|
||||
users. */)
|
||||
(void)
|
||||
{
|
||||
struct frame *f;
|
||||
|
||||
f = decode_window_system_frame (Qnil);
|
||||
android_recreate_activity (FRAME_ANDROID_WINDOW (f));
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
#endif /* !ANDROID_STUBIFY */
|
||||
|
||||
|
||||
|
@ -3550,6 +3568,7 @@ language to be US English if LANGUAGE is empty. */);
|
|||
defsubr (&Sandroid_request_directory_access);
|
||||
defsubr (&Sandroid_external_storage_available_p);
|
||||
defsubr (&Sandroid_request_storage_access);
|
||||
defsubr (&Sandroid_recreate_activity);
|
||||
|
||||
tip_timer = Qnil;
|
||||
staticpro (&tip_timer);
|
||||
|
|
|
@ -708,6 +708,7 @@ extern void android_translate_coordinates (android_window, int,
|
|||
extern int android_wc_lookup_string (android_key_pressed_event *,
|
||||
wchar_t *, int, int *,
|
||||
enum android_lookup_status *);
|
||||
extern void android_recreate_activity (android_window);
|
||||
extern void android_update_ic (android_window, ptrdiff_t, ptrdiff_t,
|
||||
ptrdiff_t, ptrdiff_t);
|
||||
extern void android_reset_ic (android_window, enum android_ic_mode);
|
||||
|
|
Loading…
Add table
Reference in a new issue