Skip to content

Commit 3a6cf26

Browse files
RaydanOMGrartdeell
authored andcommitted
Proper C-side ref storage instead of storing it in java and interacting through JNI
1 parent 7145c41 commit 3a6cf26

10 files changed

Lines changed: 129 additions & 127 deletions

File tree

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,17 @@
77
import android.content.Intent;
88
import android.content.pm.PackageManager;
99
import android.content.res.Configuration;
10-
import android.graphics.drawable.Drawable;
1110
import android.os.Build;
1211
import android.util.Log;
1312

1413
import androidx.core.app.ActivityCompat;
15-
import androidx.core.content.res.ResourcesCompat;
1614

17-
import net.kdt.pojavlaunch.customcontrols.mouse.CursorContainer;
1815
import net.kdt.pojavlaunch.lifecycle.ContextExecutor;
1916
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
2017
import net.kdt.pojavlaunch.tasks.AsyncAssetManager;
2118
import net.kdt.pojavlaunch.utils.FileUtils;
2219
import net.kdt.pojavlaunch.utils.LocaleUtils;
2320

24-
import org.lwjgl.glfw.CallbackBridge;
25-
2621
import java.io.File;
2722
import java.io.PrintStream;
2823
import java.text.DateFormat;
@@ -33,7 +28,6 @@
3328
import java.util.concurrent.TimeUnit;
3429

3530
import git.artdeell.mojo.BuildConfig;
36-
import git.artdeell.mojo.R;
3731

3832
public class PojavApplication extends Application {
3933
public static final String CRASH_REPORT_TAG = "PojavCrashReport";
@@ -93,16 +87,6 @@ public void onCreate() {
9387
ferrorIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
9488
startActivity(ferrorIntent);
9589
}
96-
97-
Drawable mousePointerDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_mouse_pointer, getTheme());
98-
// For some reason it's annotated as Nullable even though it doesn't seem to actually
99-
// ever return null
100-
assert mousePointerDrawable != null;
101-
mousePointerDrawable.setBounds(0, 0, 36, 54);
102-
CallbackBridge.setupDefaultCursor(new CursorContainer(
103-
mousePointerDrawable,
104-
1, 1
105-
));
10690
}
10791

10892
@Override

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/Touchpad.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,23 @@
22

33
import android.content.Context;
44
import android.graphics.Canvas;
5+
import android.graphics.drawable.Drawable;
56
import android.os.Build;
67
import android.util.AttributeSet;
78
import android.view.View;
89

910
import androidx.annotation.NonNull;
1011
import androidx.annotation.Nullable;
12+
import androidx.core.content.res.ResourcesCompat;
1113
import androidx.core.util.Consumer;
1214

1315
import net.kdt.pojavlaunch.GrabListener;
1416
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
1517

1618
import org.lwjgl.glfw.CallbackBridge;
1719

20+
import git.artdeell.mojo.R;
21+
1822
/**
1923
* Class dealing with the virtual mouse
2024
*/
@@ -24,6 +28,7 @@ public class Touchpad extends View implements GrabListener, AbstractTouchpad {
2428
/* Mouse pointer icon used by the touchpad */
2529
private float mMouseX, mMouseY;
2630
private boolean mMoveOnLayout;
31+
private Drawable mMouseCursorDrawable;
2732
private final Consumer<CursorContainer> onCursorChange = cursor->invalidate();
2833
public Touchpad(@NonNull Context context) {
2934
this(context, null);
@@ -77,10 +82,19 @@ private void updateMousePosition() {
7782
protected void onDraw(Canvas canvas) {
7883
canvas.translate(mMouseX, mMouseY);
7984
canvas.scale(LauncherPreferences.PREF_MOUSESCALE, LauncherPreferences.PREF_MOUSESCALE);
80-
CallbackBridge.getCursor().draw(canvas);
85+
if(CallbackBridge.getCursor() != null) {
86+
CallbackBridge.getCursor().draw(canvas);
87+
} else {
88+
mMouseCursorDrawable.draw(canvas);
89+
}
8190
}
8291

8392
private void init() {
93+
mMouseCursorDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_mouse_pointer, getContext().getTheme());
94+
// For some reason it's annotated as Nullable even though it doesn't seem to actually
95+
// ever return null
96+
assert mMouseCursorDrawable != null;
97+
mMouseCursorDrawable.setBounds(0, 0, 36, 54);
8498
CallbackBridge.addCursorChangeListener(onCursorChange);
8599

86100
setFocusable(false);

app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import android.view.Choreographer;
1212

1313
import androidx.annotation.Keep;
14-
import androidx.annotation.NonNull;
1514
import androidx.annotation.Nullable;
1615
import androidx.core.util.Consumer;
1716

@@ -52,10 +51,8 @@ public class CallbackBridge {
5251
public static final FloatBuffer sGamepadAxisBuffer;
5352
public static boolean sGamepadDirectInput = false;
5453

55-
@Nullable private static CursorContainer sDefaultCursor = null;
5654
@Nullable private static CursorContainer sCursor;
5755
private static Set<Consumer<CursorContainer>> cursorChangeListeners = new HashSet<>();
58-
private static Set<Long> cursorPointers = new HashSet<>();
5956

6057
public static void putMouseEventWithCoords(int button, float x, float y) {
6158
putMouseEventWithCoords(button, true, x, y);
@@ -244,29 +241,12 @@ public static void setDirectGamepadEnableHandler(DirectGamepadEnableHandler h) {
244241
sDirectGamepadEnableHandler = new WeakReference<>(h);
245242
}
246243

247-
public static void setupDefaultCursor(CursorContainer cursor) {
248-
if (sDefaultCursor != null) {
249-
throw new IllegalStateException("Default cursor already initialized!");
250-
}
251-
sDefaultCursor = cursor;
252-
}
253-
254-
// these methods should only ever be called after setupDefaultCursor
255-
public static CursorContainer getDefaultCursor() {
256-
if(sDefaultCursor == null) {
257-
throw new IllegalStateException("Default cursor not yet initialized!");
258-
}
259-
return sDefaultCursor;
260-
}
261-
244+
@Nullable
262245
public static CursorContainer getCursor() {
263-
if(sCursor == null) {
264-
setCursor(getDefaultCursor());
265-
}
266246
return sCursor;
267247
}
268248

269-
public static void setCursor(@NonNull CursorContainer cursor) {
249+
public static void setCursor(@Nullable CursorContainer cursor) {
270250
sCursor = cursor;
271251
for (Consumer<CursorContainer> listener : cursorChangeListeners) {
272252
listener.accept(cursor);
@@ -275,28 +255,14 @@ public static void setCursor(@NonNull CursorContainer cursor) {
275255

276256
@SuppressWarnings("unused")
277257
@Keep
278-
public static void removeCursor(long ptr) {
279-
CursorContainer cursor = (CursorContainer) nativeGetGlobalRef(ptr);
280-
281-
if(cursor == getDefaultCursor()) return;
282-
if(sCursor == cursor) setCursor(getDefaultCursor());
283-
284-
cursorPointers.remove(ptr);
285-
nativeDeleteGlobalRef(ptr);
286-
}
287-
288-
@SuppressWarnings("unused")
289-
@Keep
290-
public static void removeAllCursors() {
291-
setCursor(getDefaultCursor());
292-
for (long ptr : cursorPointers) {
293-
removeCursor(ptr);
294-
}
258+
private static void removeCursor(@Nullable CursorContainer cursor) {
259+
if(cursor == null) return;
260+
if(sCursor == cursor) setCursor(null);
295261
}
296262

297263
@SuppressWarnings("unused")
298264
@Keep
299-
public static long createCursor(ByteBuffer imageBuffer, int width, int height, int xHot, int yHot) {
265+
private static CursorContainer createCursor(ByteBuffer imageBuffer, int width, int height, int xHot, int yHot) {
300266
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
301267
bitmap.copyPixelsFromBuffer(imageBuffer);
302268
// using the system resources isn't really a good practice
@@ -309,9 +275,7 @@ public static long createCursor(ByteBuffer imageBuffer, int width, int height, i
309275
// does nothing
310276
drawable.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix()));
311277

312-
long cursor = nativeCreateGlobalRef(new CursorContainer(drawable, xHot, yHot));
313-
cursorPointers.add(cursor);
314-
return cursor;
278+
return new CursorContainer(drawable, xHot, yHot);
315279
}
316280

317281
public static void addCursorChangeListener(Consumer<CursorContainer> listener) {
@@ -336,9 +300,6 @@ public static void removeCursorChangeListener(Consumer<CursorContainer> listener
336300
public static native void nativeSetWindowAttrib(int attrib, int value);
337301
private static native ByteBuffer nativeCreateGamepadButtonBuffer();
338302
private static native ByteBuffer nativeCreateGamepadAxisBuffer();
339-
private static native long nativeCreateGlobalRef(Object obj);
340-
private static native Object nativeGetGlobalRef(long pointer);
341-
private static native void nativeDeleteGlobalRef(long object);
342303
static {
343304
System.loadLibrary("pojavexec");
344305
sGamepadButtonBuffer = nativeCreateGamepadButtonBuffer();

app_pojavlauncher/src/main/jni/Android.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ LOCAL_SRC_FILES := \
3535
jre_launcher.c \
3636
utils.c \
3737
stdio_is.c \
38-
driver_helper/nsbypass.c
38+
driver_helper/nsbypass.c \
39+
linkedlist.c
3940

4041
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
4142
LOCAL_CFLAGS += -DADRENO_POSSIBLE

app_pojavlauncher/src/main/jni/egl_bridge.c

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct PotatoBridge potatoBridge;
6262

6363
#include "ctxbridges/egl_loader.h"
6464
#include "ctxbridges/osmesa_loader.h"
65+
#include "linkedlist.h"
6566

6667
#define RENDERER_GL4ES 1
6768
#define RENDERER_VK_ZINK 2
@@ -89,8 +90,19 @@ EXTERNAL_API void pojavTerminate() {
8990
} break;
9091
}
9192

92-
TRY_ATTACH_ENV(env, pojav_environ->dalvikJavaVMPtr, "failed to attach env from pojavTerminate!\n", return;);
93-
(*env)->CallStaticVoidMethod(env, pojav_environ->bridgeClazz, pojav_environ->method_removeAllCursors);
93+
TRY_ATTACH_ENV(env, pojav_environ->dalvikJavaVMPtr, "Failed to attach to env from pojavTerminate!\n", return;);
94+
95+
LinkedListNode* current = pojav_environ->cursors->first;
96+
while (current) {
97+
LinkedListNode* next = current->next;
98+
(*env)->DeleteGlobalRef(env, current->value);
99+
free(current);
100+
current = next;
101+
}
102+
pojav_environ->cursors->first = NULL;
103+
pojav_environ->cursors->last = NULL;
104+
105+
(*env)->CallStaticVoidMethod(env, pojav_environ->bridgeClazz, pojav_environ->method_setCursor, NULL);
94106
}
95107

96108
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupBridgeWindow(JNIEnv* env, ABI_COMPAT jclass clazz, jobject surface) {
@@ -260,19 +272,6 @@ EXTERNAL_API void pojavSwapInterval(int interval) {
260272
br_swap_interval(interval);
261273
}
262274

263-
EXTERNAL_API void* pojavCreateStandardCursor(__attribute__((unused)) int shape) {
264-
if(pojav_environ->standardCursor != NULL) return pojav_environ->standardCursor;
265-
266-
TRY_ATTACH_ENV(env, pojav_environ->dalvikJavaVMPtr, "failed to attach env from pojavCreateStandardCursor!\n", return NULL;);
267-
jobject cursor = (*env)->CallStaticObjectMethod(env, pojav_environ->bridgeClazz,
268-
pojav_environ->method_getDefaultCursor);
269-
jobject globalCursor = (*env)->NewGlobalRef(env, cursor);
270-
(*env)->DeleteLocalRef(env, cursor);
271-
272-
pojav_environ->standardCursor = globalCursor;
273-
return pojav_environ->standardCursor;
274-
}
275-
276275
EXTERNAL_API void* pojavCreateCursor(GLFWimage* image, int xhot, int yhot) {
277276
if(image == NULL) {
278277
printf("Passed image is null!\n");
@@ -287,27 +286,20 @@ EXTERNAL_API void* pojavCreateCursor(GLFWimage* image, int xhot, int yhot) {
287286
return NULL;
288287
}
289288

290-
// creates a global ref so there is no need to create one here
291-
jlong cursor = (*env)->CallStaticLongMethod(env, pojav_environ->bridgeClazz,
289+
jobject cursor = (*env)->CallStaticObjectMethod(env, pojav_environ->bridgeClazz,
292290
pojav_environ->method_createCursor, buffer,
293291
image->width, image->height, xhot, yhot);
292+
jobject globalCursor = (*env)->NewGlobalRef(env, cursor);
294293
// not needed anymore
295294
(*env)->DeleteLocalRef(env, buffer);
296-
return (jobject)cursor;
295+
296+
linkedlist_append(pojav_environ->cursors, globalCursor);
297+
return globalCursor;
297298
}
298299

299300
EXTERNAL_API void pojavSetCursor(__attribute__((unused)) void* window, jobject cursor) {
300-
if(cursor == NULL) {
301-
void* standardCursor = pojavCreateStandardCursor(0);
302-
if(standardCursor == NULL) {
303-
printf("Failed to get standard cursor in pojavSetCursor\n");
304-
return;
305-
}
306-
cursor = standardCursor;
307-
}
308-
309301
TRY_ATTACH_ENV(env, pojav_environ->dalvikJavaVMPtr, "failed to attach env from pojavSetCursor!\n", return;);
310-
(*env)->CallStaticVoidMethod(env, pojav_environ->bridgeClazz, pojav_environ->method_setCursor, (jlong)cursor);
302+
(*env)->CallStaticVoidMethod(env, pojav_environ->bridgeClazz, pojav_environ->method_setCursor, cursor);
311303
}
312304

313305
EXTERNAL_API void pojavDestroyCursor(jobject cursor) {
@@ -317,5 +309,23 @@ EXTERNAL_API void pojavDestroyCursor(jobject cursor) {
317309
}
318310

319311
TRY_ATTACH_ENV(env, pojav_environ->dalvikJavaVMPtr, "failed to attach env from pojavDestroyCursor!\n", return;);
320-
(*env)->CallStaticVoidMethod(env, pojav_environ->bridgeClazz, pojav_environ->method_removeCursor, (jlong)cursor);
312+
(*env)->CallStaticVoidMethod(env, pojav_environ->bridgeClazz, pojav_environ->method_removeCursor, cursor);
313+
314+
LinkedListNode* current = pojav_environ->cursors->first;
315+
LinkedListNode* prev = NULL;
316+
317+
while (current) {
318+
if (current->value == cursor) {
319+
if (prev == NULL) {
320+
pojav_environ->cursors->first = current->next;
321+
} else {
322+
prev->next = current->next;
323+
}
324+
(*env)->DeleteGlobalRef(env, current->value);
325+
free(current);
326+
break;
327+
}
328+
prev = current;
329+
current = current->next;
330+
}
321331
}

app_pojavlauncher/src/main/jni/environ/environ.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <ctxbridges/common.h>
99
#include <stdatomic.h>
1010
#include <jni.h>
11+
#include "linkedlist.h"
1112

1213
/* How many events can be handled at the same time */
1314
#define EVENT_WINDOW_SIZE 8000
@@ -71,12 +72,10 @@ struct pojav_environ_s {
7172
bool shouldUpdateMonitorSize, monitorSizeConsumed;
7273
int savedWidth, savedHeight;
7374
GLFWgamepadstate gamepadState;
74-
jmethodID method_getDefaultCursor;
7575
jmethodID method_setCursor;
7676
jmethodID method_removeCursor;
7777
jmethodID method_createCursor;
78-
jmethodID method_removeAllCursors;
79-
jobject standardCursor;
78+
LinkedList* cursors;
8079
#define ADD_CALLBACK_WWIN(NAME) \
8180
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME;
8281
ADD_CALLBACK_WWIN(Char);

0 commit comments

Comments
 (0)