diff options
| author | Po Lu | 2024-01-26 11:24:51 +0800 |
|---|---|---|
| committer | Po Lu | 2024-01-26 11:24:51 +0800 |
| commit | 16831e290ed29f5f70dfe144ec63c583527485e8 (patch) | |
| tree | eecc1f3de356aa04a82f4687d7dac4303282ea77 /java | |
| parent | 65829b27ca4898ff0905a8124980243977a1382f (diff) | |
| download | emacs-16831e290ed29f5f70dfe144ec63c583527485e8.tar.gz emacs-16831e290ed29f5f70dfe144ec63c583527485e8.zip | |
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.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsView.java | 27 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsWindow.java | 28 |
2 files changed, 43 insertions, 12 deletions
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 136d8abc713..8398e4b784c 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java | |||
| @@ -456,7 +456,6 @@ public final class EmacsView extends ViewGroup | |||
| 456 | { | 456 | { |
| 457 | Canvas canvas; | 457 | Canvas canvas; |
| 458 | Rect damageRect; | 458 | Rect damageRect; |
| 459 | Bitmap bitmap; | ||
| 460 | 459 | ||
| 461 | /* Make sure this function is called only from the Emacs | 460 | /* Make sure this function is called only from the Emacs |
| 462 | thread. */ | 461 | thread. */ |
| @@ -474,11 +473,12 @@ public final class EmacsView extends ViewGroup | |||
| 474 | damageRect = damageRegion.getBounds (); | 473 | damageRect = damageRegion.getBounds (); |
| 475 | damageRegion.setEmpty (); | 474 | damageRegion.setEmpty (); |
| 476 | 475 | ||
| 477 | bitmap = getBitmap (); | 476 | synchronized (this) |
| 478 | 477 | { | |
| 479 | /* Transfer the bitmap to the surface view, then invalidate | 478 | /* Transfer the bitmap to the surface view, then invalidate |
| 480 | it. */ | 479 | it. */ |
| 481 | surfaceView.setBitmap (bitmap, damageRect); | 480 | surfaceView.setBitmap (bitmap, damageRect); |
| 481 | } | ||
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | @Override | 484 | @Override |
| @@ -724,17 +724,20 @@ public final class EmacsView extends ViewGroup | |||
| 724 | public synchronized void | 724 | public synchronized void |
| 725 | onDetachedFromWindow () | 725 | onDetachedFromWindow () |
| 726 | { | 726 | { |
| 727 | isAttachedToWindow = false; | 727 | Bitmap savedBitmap; |
| 728 | |||
| 729 | /* Recycle the bitmap and call GC. */ | ||
| 730 | |||
| 731 | if (bitmap != null) | ||
| 732 | bitmap.recycle (); | ||
| 733 | 728 | ||
| 729 | savedBitmap = bitmap; | ||
| 730 | isAttachedToWindow = false; | ||
| 734 | bitmap = null; | 731 | bitmap = null; |
| 735 | canvas = null; | 732 | canvas = null; |
| 733 | |||
| 736 | surfaceView.setBitmap (null, null); | 734 | surfaceView.setBitmap (null, null); |
| 737 | 735 | ||
| 736 | /* Recycle the bitmap and call GC. */ | ||
| 737 | |||
| 738 | if (savedBitmap != null) | ||
| 739 | savedBitmap.recycle (); | ||
| 740 | |||
| 738 | /* Collect the bitmap storage; it could be large. */ | 741 | /* Collect the bitmap storage; it could be large. */ |
| 739 | Runtime.getRuntime ().gc (); | 742 | Runtime.getRuntime ().gc (); |
| 740 | 743 | ||
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 207bd22c538..304304a328b 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java | |||
| @@ -1784,4 +1784,32 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 1784 | 1784 | ||
| 1785 | return true; | 1785 | return true; |
| 1786 | } | 1786 | } |
| 1787 | |||
| 1788 | |||
| 1789 | |||
| 1790 | /* Miscellaneous functions for debugging graphics code. */ | ||
| 1791 | |||
| 1792 | /* Recreate the activity to which this window is attached, if any. | ||
| 1793 | This is nonfunctional on Android 2.3.7 and earlier. */ | ||
| 1794 | |||
| 1795 | public void | ||
| 1796 | recreateActivity () | ||
| 1797 | { | ||
| 1798 | final EmacsWindowAttachmentManager.WindowConsumer attached; | ||
| 1799 | |||
| 1800 | attached = this.attached; | ||
| 1801 | |||
| 1802 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) | ||
| 1803 | return; | ||
| 1804 | |||
| 1805 | view.post (new Runnable () { | ||
| 1806 | @Override | ||
| 1807 | public void | ||
| 1808 | run () | ||
| 1809 | { | ||
| 1810 | if (attached instanceof EmacsActivity) | ||
| 1811 | ((EmacsActivity) attached).recreate (); | ||
| 1812 | } | ||
| 1813 | }); | ||
| 1814 | } | ||
| 1787 | }; | 1815 | }; |