1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-06 03:40:56 -08:00

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:
Po Lu 2024-01-26 11:24:51 +08:00
parent 65829b27ca
commit 16831e290e
5 changed files with 83 additions and 13 deletions

View file

@ -456,7 +456,6 @@ public final class EmacsView extends ViewGroup
{
Canvas canvas;
Rect damageRect;
Bitmap bitmap;
/* Make sure this function is called only from the Emacs
thread. */
@ -474,11 +473,12 @@ public final class EmacsView extends ViewGroup
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 @@ public final class EmacsView extends ViewGroup
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 ();

View file

@ -1784,4 +1784,32 @@ public final class EmacsWindow extends EmacsHandleObject
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 ();
}
});
}
};