From 4e46df96510335c086a3764e002c99348e0e9624 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 18 Sep 2023 10:59:55 +0800 Subject: [PATCH] Optimize damage region tracking under Android * java/org/gnu/emacs/EmacsDrawLine.java (perform): * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Call damageRect with integer coordinates in lieu of consing a new Rect. * java/org/gnu/emacs/EmacsDrawable.java (damageRect) : Declare a new variant of damageRect, accepting four integers designating the extents of the damage rectangle. * java/org/gnu/emacs/EmacsPixmap.java (damageRect) : New stub. * java/org/gnu/emacs/EmacsView.java (damageRect) : Implement this overloaded variant of damageRect. * java/org/gnu/emacs/EmacsWindow.java (damageRect): Ditto. * src/android.c (android_init_emacs_drawable) (android_init_emacs_window): Move search for `damageRect' to android_init_emacs_window. (android_damage_window): Call IIII variant of `damageRect' to avoid consing a new rectangle. Ameliorate dynamic method dispatch overhead. --- java/org/gnu/emacs/EmacsDrawLine.java | 4 +-- java/org/gnu/emacs/EmacsDrawRectangle.java | 3 +- java/org/gnu/emacs/EmacsDrawable.java | 1 + java/org/gnu/emacs/EmacsPixmap.java | 7 ++++ java/org/gnu/emacs/EmacsView.java | 10 ++++++ java/org/gnu/emacs/EmacsWindow.java | 12 ++++++- src/android.c | 38 ++++++++++------------ 7 files changed, 49 insertions(+), 26 deletions(-) diff --git a/java/org/gnu/emacs/EmacsDrawLine.java b/java/org/gnu/emacs/EmacsDrawLine.java index d367ccff9c4..be4da54c075 100644 --- a/java/org/gnu/emacs/EmacsDrawLine.java +++ b/java/org/gnu/emacs/EmacsDrawLine.java @@ -29,7 +29,6 @@ public final class EmacsDrawLine perform (EmacsDrawable drawable, EmacsGC gc, int x, int y, int x2, int y2) { - Rect rect; Canvas canvas; Paint paint; int x0, x1, y0, y1; @@ -48,7 +47,6 @@ public final class EmacsDrawLine /* And the clip rectangle. */ paint = gc.gcPaint; - rect = new Rect (x0, y0, x1, y1); canvas = drawable.lockCanvas (gc); if (canvas == null) @@ -74,6 +72,6 @@ public final class EmacsDrawLine /* DrawLine with clip mask not implemented; it is not used by Emacs. */ - drawable.damageRect (rect); + drawable.damageRect (x0, y0, x1, y1); } } diff --git a/java/org/gnu/emacs/EmacsDrawRectangle.java b/java/org/gnu/emacs/EmacsDrawRectangle.java index e1261b4a2d2..ee9110daaaf 100644 --- a/java/org/gnu/emacs/EmacsDrawRectangle.java +++ b/java/org/gnu/emacs/EmacsDrawRectangle.java @@ -114,7 +114,6 @@ public final class EmacsDrawRectangle maskBitmap.recycle (); } - drawable.damageRect (new Rect (x, y, x + width + 1, - y + height + 1)); + drawable.damageRect (x, y, x + width + 1, y + height + 1); } } diff --git a/java/org/gnu/emacs/EmacsDrawable.java b/java/org/gnu/emacs/EmacsDrawable.java index f2f8885e976..3ed72a836e5 100644 --- a/java/org/gnu/emacs/EmacsDrawable.java +++ b/java/org/gnu/emacs/EmacsDrawable.java @@ -27,6 +27,7 @@ public interface EmacsDrawable { public Canvas lockCanvas (EmacsGC gc); public void damageRect (Rect damageRect); + public void damageRect (int left, int top, int right, int bottom); public Bitmap getBitmap (); public boolean isDestroyed (); }; diff --git a/java/org/gnu/emacs/EmacsPixmap.java b/java/org/gnu/emacs/EmacsPixmap.java index 2cbf7a430cf..e02699ecba7 100644 --- a/java/org/gnu/emacs/EmacsPixmap.java +++ b/java/org/gnu/emacs/EmacsPixmap.java @@ -175,6 +175,13 @@ public final class EmacsPixmap extends EmacsHandleObject } + @Override + public void + damageRect (int left, int top, int right, int bottom) + { + + } + @Override public Bitmap getBitmap () diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 0f83af882ae..d09dcc7e50d 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -437,6 +437,16 @@ public final class EmacsView extends ViewGroup damageRegion.union (damageRect); } + /* This function enables damage to be recorded without consing a new + Rect object. */ + + public void + damageRect (int left, int top, int right, int bottom) + { + EmacsService.checkEmacsThread (); + damageRegion.op (left, top, right, bottom, Region.Op.UNION); + } + /* This method is called from both the UI thread and the Emacs thread. */ diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 3738376a6f4..1f28d5f4f53 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -514,7 +514,17 @@ public final class EmacsWindow extends EmacsHandleObject public void damageRect (Rect damageRect) { - view.damageRect (damageRect); + view.damageRect (damageRect.left, + damageRect.top, + damageRect.right, + damageRect.bottom); + } + + @Override + public void + damageRect (int left, int top, int right, int bottom) + { + view.damageRect (left, top, right, bottom); } public void diff --git a/src/android.c b/src/android.c index e07b3a99352..2cc86d8c56f 100644 --- a/src/android.c +++ b/src/android.c @@ -87,7 +87,6 @@ struct android_emacs_drawable { jclass class; jmethodID get_bitmap; - jmethodID damage_rect; }; struct android_emacs_window @@ -111,6 +110,7 @@ struct android_emacs_window jmethodID set_dont_accept_focus; jmethodID set_dont_focus_on_map; jmethodID define_cursor; + jmethodID damage_rect; }; struct android_emacs_cursor @@ -1712,7 +1712,6 @@ android_init_emacs_drawable (void) assert (drawable_class.c_name); FIND_METHOD (get_bitmap, "getBitmap", "()Landroid/graphics/Bitmap;"); - FIND_METHOD (damage_rect, "damageRect", "(Landroid/graphics/Rect;)V"); #undef FIND_METHOD } @@ -1766,6 +1765,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"); #undef FIND_METHOD } @@ -5284,25 +5289,18 @@ android_damage_window (android_drawable handle, drawable = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); - /* Now turn DAMAGE into a Java rectangle. */ - rect = (*android_java_env)->NewObject (android_java_env, - android_rect_class, - android_rect_constructor, - (jint) damage->x, - (jint) damage->y, - (jint) (damage->x - + damage->width), - (jint) (damage->y - + damage->height)); - android_exception_check (); - /* Post the damage to the drawable. */ - (*android_java_env)->CallVoidMethod (android_java_env, - drawable, - drawable_class.damage_rect, - rect); - android_exception_check_1 (rect); - ANDROID_DELETE_LOCAL_REF (rect); + (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, + drawable, + window_class.class, + window_class.damage_rect, + (jint) damage->x, + (jint) damage->y, + (jint) (damage->x + + damage->width), + (jint) (damage->y + + damage->height)); + android_exception_check (); } -- 2.39.5