[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/android 7fdde02f321 4/7: Work around more problems with Bitmaps
From: |
Po Lu |
Subject: |
feature/android 7fdde02f321 4/7: Work around more problems with Bitmaps |
Date: |
Mon, 29 May 2023 06:07:13 -0400 (EDT) |
branch: feature/android
commit 7fdde02f3216536aa8977fa4b396bec8fbaf994b
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Work around more problems with Bitmaps
* java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
function `blitRect'.
* java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
Use it on Android 8.x.
* src/android.c (blitRect): Implement new function.
---
java/org/gnu/emacs/EmacsNative.java | 10 ++++
java/org/gnu/emacs/EmacsSurfaceView.java | 33 +++++++++--
src/android.c | 98 ++++++++++++++++++++++++++++++++
3 files changed, 137 insertions(+), 4 deletions(-)
diff --git a/java/org/gnu/emacs/EmacsNative.java
b/java/org/gnu/emacs/EmacsNative.java
index e699dda9ad4..56c03ee38dc 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -20,6 +20,9 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
package org.gnu.emacs;
import android.content.res.AssetManager;
+
+import android.graphics.Bitmap;
+
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -216,6 +219,13 @@ public final class EmacsNative
failure. */
public static native int[] getSelection (short window);
+
+ /* Graphics functions used as a replacement for potentially buggy
+ Android APIs. */
+
+ public static native void blitRect (Bitmap src, Bitmap dest, int x1,
+ int y1, int x2, int y2);
+
static
{
/* Older versions of Android cannot link correctly with shared
diff --git a/java/org/gnu/emacs/EmacsSurfaceView.java
b/java/org/gnu/emacs/EmacsSurfaceView.java
index e0411f7f8b3..0deb930c2c2 100644
--- a/java/org/gnu/emacs/EmacsSurfaceView.java
+++ b/java/org/gnu/emacs/EmacsSurfaceView.java
@@ -57,11 +57,36 @@ public final class EmacsSurfaceView extends View
private void
copyToFrontBuffer (Bitmap bitmap, Rect damageRect)
{
- if (damageRect != null)
- bitmapCanvas.drawBitmap (bitmap, damageRect, damageRect,
- bitmapPaint);
+ EmacsService.checkEmacsThread ();
+
+ if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O
+ && Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1)
+ {
+ /* If `drawBitmap' can safely be used while a bitmap is locked
+ by another thread, continue here... */
+
+ if (damageRect != null)
+ bitmapCanvas.drawBitmap (bitmap, damageRect, damageRect,
+ bitmapPaint);
+ else
+ bitmapCanvas.drawBitmap (bitmap, 0f, 0f, bitmapPaint);
+ }
else
- bitmapCanvas.drawBitmap (bitmap, 0f, 0f, bitmapPaint);
+ {
+ /* But if it can not, as on Android 8.0 and 8.1, then use a
+ replacement function. */
+
+ if (damageRect != null)
+ EmacsNative.blitRect (bitmap, frontBuffer,
+ damageRect.left,
+ damageRect.top,
+ damageRect.right,
+ damageRect.bottom);
+ else
+ EmacsNative.blitRect (bitmap, frontBuffer, 0, 0,
+ bitmap.getWidth (),
+ bitmap.getHeight ());
+ }
}
private void
diff --git a/src/android.c b/src/android.c
index 7b9c478f212..4184be3086b 100644
--- a/src/android.c
+++ b/src/android.c
@@ -4754,6 +4754,104 @@ android_copy_area (android_drawable src,
android_drawable dest,
+JNIEXPORT void JNICALL
+NATIVE_NAME (blitRect) (JNIEnv *env, jobject object,
+ jobject src, jobject dest,
+ jint x1, jint y1, jint x2, jint y2)
+{
+ AndroidBitmapInfo src_info, dest_info;
+ unsigned char *src_data_1, *dest_data_1;
+ void *src_data, *dest_data;
+
+ /* N.B. that X2 and Y2 represent the pixel past the edge of the
+ rectangle; thus, the width is x2 - x1 and the height is y2 -
+ y1. */
+
+ memset (&src_info, 0, sizeof src_info);
+ memset (&dest_info, 0, sizeof dest_info);
+ AndroidBitmap_getInfo (env, src, &src_info);
+ AndroidBitmap_getInfo (env, dest, &dest_info);
+
+ /* If the stride is 0 after a call to `getInfo', assume it
+ failed. */
+
+ if (!src_info.stride || !dest_info.stride)
+ return;
+
+ /* If formats differ, abort. */
+ eassert (src_info.format == dest_info.format
+ && src_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888);
+
+ /* Lock the image data. */
+ src_data = NULL;
+ AndroidBitmap_lockPixels (env, src, &src_data);
+
+ if (!src_data)
+ return;
+
+ dest_data = NULL;
+ AndroidBitmap_lockPixels (env, dest, &dest_data);
+
+ if (!dest_data)
+ goto fail1;
+
+ /* Now clip the rectangle to the bounds of the source and
+ destination bitmap. */
+
+ x1 = MAX (x1, 0);
+ y1 = MAX (y1, 0);
+ x2 = MAX (x2, 0);
+ y2 = MAX (y2, 0);
+
+
+ if (x1 >= src_info.width
+ || x1 >= dest_info.width)
+ x1 = MIN (dest_info.width - 1, src_info.width - 1);
+
+ if (x2 > src_info.width
+ || x2 > dest_info.width)
+ x2 = MIN (src_info.width, dest_info.width);
+
+ if (y1 >= src_info.height
+ || y1 >= dest_info.height)
+ y1 = MIN (dest_info.height - 1, src_info.height - 1);
+
+ if (y2 > src_info.height
+ || y2 > dest_info.height)
+ y2 = MIN (src_info.height, dest_info.height);
+
+ if (x1 >= x2 || y1 >= y2)
+ goto fail2;
+
+ /* Determine the address of the first line to copy. */
+
+ src_data_1 = src_data;
+ dest_data_1 = dest_data;
+ src_data_1 += x1 * 4;
+ src_data_1 += y1 * src_info.stride;
+ dest_data_1 += x1 * 4;
+ dest_data_1 += y1 * dest_info.stride;
+
+ /* Start copying each line. */
+
+ while (y1 != y2)
+ {
+ memcpy (dest_data_1, src_data_1, (x2 - x1) * 4);
+ src_data_1 += src_info.stride;
+ dest_data_1 += dest_info.stride;
+ y1++;
+ }
+
+ /* Complete the copy and unlock the bitmap. */
+
+ fail2:
+ AndroidBitmap_unlockPixels (env, dest);
+ fail1:
+ AndroidBitmap_unlockPixels (env, src);
+}
+
+
+
void
android_free_pixmap (android_pixmap pixmap)
{
- feature/android updated (d33bf0a0afd -> 1a1cf6b86fc), Po Lu, 2023/05/29
- feature/android 327d2d01313 1/7: Add extra thread-related checking, Po Lu, 2023/05/29
- feature/android 00671b18438 2/7: Implement android_copy_area in C, Po Lu, 2023/05/29
- feature/android 787c947028c 5/7: ; * src/android.c (android_blit_copy): Fix typos., Po Lu, 2023/05/29
- feature/android 9a353545933 3/7: Update Android port, Po Lu, 2023/05/29
- feature/android 7fdde02f321 4/7: Work around more problems with Bitmaps,
Po Lu <=
- feature/android 1a1cf6b86fc 7/7: Merge remote-tracking branch 'origin/master' into feature/android, Po Lu, 2023/05/29
- feature/android 1088a8e8dab 6/7: Update Android port, Po Lu, 2023/05/29