]> git.eshelyaron.com Git - emacs.git/commitdiff
Disable hardware acceleration on Android
authorPo Lu <luangruo@yahoo.com>
Thu, 13 Jul 2023 04:05:50 +0000 (12:05 +0800)
committerPo Lu <luangruo@yahoo.com>
Thu, 13 Jul 2023 04:05:50 +0000 (12:05 +0800)
It serves no purpose and causes tearing.  Uploading the bitmap
to the GPU takes about as long as it does to incrementally
update the surface in software.

* java/AndroidManifest.xml.in: Disable hardware acceleration.
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): Make
lastClosedMenu static.
* java/org/gnu/emacs/EmacsDialog.java (toAlertDialog): Enable
hardware acceleration within alert dialogs.
* java/org/gnu/emacs/EmacsSurfaceView.java (onDraw): Describe
why hardware acceleration is disabled.
* java/org/gnu/emacs/EmacsWindow.java (run): Remove redundant
call.

java/AndroidManifest.xml.in
java/org/gnu/emacs/EmacsActivity.java
java/org/gnu/emacs/EmacsDialog.java
java/org/gnu/emacs/EmacsSurfaceView.java
java/org/gnu/emacs/EmacsWindow.java

index e79fb4e46e7c5c12ce957c8d71e1c92d6df9dd6c..f2aede7369c535f4e1990fcda56cf5077a1189d4 100644 (file)
@@ -77,10 +77,14 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
               @ANDROID_SHARED_USER_ID@
               android:extractNativeLibs="true">
 
+    <!-- See EmacsSurfaceView.onDraw for why hardware acceleration is
+         disabled.  -->
+
     <activity android:name="org.gnu.emacs.EmacsActivity"
              android:launchMode="singleInstance"
              android:windowSoftInputMode="adjustResize"
              android:exported="true"
+             android:hardwareAccelerated="false"
              android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
       <intent-filter>
         <action android:name="android.intent.action.MAIN" />
@@ -173,6 +177,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
     <activity android:name="org.gnu.emacs.EmacsMultitaskActivity"
              android:windowSoftInputMode="adjustResize"
              android:exported="true"
+             android:hardwareAccelerated="false"
              android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"/>
 
     <activity android:autoRemoveFromRecents="true"
index fa9bff39bb09244ca4fbfd12ccf2307bc38ee0d6..d7b51388929309c9ed93de128be3d7b6c0e7a4cc 100644 (file)
@@ -70,7 +70,7 @@ public class EmacsActivity extends Activity
   private boolean isFullscreen;
 
   /* The last context menu to be closed.  */
-  private Menu lastClosedMenu;
+  private static Menu lastClosedMenu;
 
   static
   {
index 5f48a9a5f9fd0c01d4e3202f8e0b4d06db32d5e5..42455ed78f8fa956f6b5dda322fa4cebf5ab2a68 100644 (file)
@@ -152,7 +152,7 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
   toAlertDialog (Context context)
   {
     AlertDialog dialog;
-    int size, styleId;
+    int size, styleId, flag;
     int[] attrs;
     EmacsButton button;
     EmacsDialogButtonLayout layout;
@@ -160,6 +160,7 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
     ViewGroup.LayoutParams layoutParams;
     Theme theme;
     TypedArray attributes;
+    Window window;
 
     size = buttons.size ();
     styleId = -1;
@@ -273,6 +274,17 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
          }
       }
 
+    /* Make sure the dialog is hardware accelerated.  Hardware
+       acceleration is disabled for dialogs by default, because they
+       aren't enabled in EmacsActivity either.  */
+
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+      {
+       flag = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+       window = dialog.getWindow ();
+       window.addFlags (flag);
+      }
+
     return dialog;
   }
 
index 3f62af4ab99046c256a4b2a4161c9ff764b6f91c..54fe70e1634a882a0265f6326ec176a2cfde9ff5 100644 (file)
@@ -176,7 +176,25 @@ public final class EmacsSurfaceView extends View
   onDraw (Canvas canvas)
   {
     /* Paint the view's bitmap; the bitmap might be recycled right
-       now.  */
+       now.
+
+       Hardware acceleration is disabled in AndroidManifest.xml to
+       prevent Android from uploading the front buffer to the GPU from
+       a separate thread.  This is important for two reasons: first,
+       the GPU command queue uses a massive amount of memory (dozens
+       of MiB) to upload bitmaps to the GPU, regardless of how much of
+       the bitmap has actually changed.
+
+       Secondly, asynchronous texturization leads to race conditions
+       when a buffer swap occurs before the front buffer is fully
+       uploaded to the GPU.  Normally, only slight and tolerable
+       tearing should result from this behavior, but Android does not
+       properly interlock the ``generation ID'' used to avoid
+       texturizing unchanged bitmaps with the bitmap contents,
+       consequentially leading to textures in an incomplete state
+       remaining in use to the GPU if a buffer swap happens between
+       the image data being uploaded and the ``generation ID'' being
+       read.  */
 
     if (frontBuffer != null)
       canvas.drawBitmap (frontBuffer, 0f, 0f, uiThreadPaint);
index 5e45275631b9099ca4e6dc3aabf59d1305b9f73b..0e96a8382d0bd15a0c668eef9c8cbe140643c7ed 100644 (file)
@@ -1377,7 +1377,7 @@ public final class EmacsWindow extends EmacsHandleObject
 
          if (tem != null)
            {
-             activity = (EmacsActivity) getAttachedConsumer ();
+             activity = (EmacsActivity) tem;
              activity.syncFullscreenWith (EmacsWindow.this);
            }
        }