From 055dd99a8c29f8885196c119ba9e5c20fd2395b8 Mon Sep 17 00:00:00 2001 From: MaxsTechReview Date: Tue, 9 Jun 2026 13:36:37 -0400 Subject: [PATCH] fix: wake render thread directly to stop FPS drop during touch input requestRenderCoalesced() routed every game-frame compositor wakeup through the UI thread (mainHandler.post -> Choreographer.postFrameCallback). During touchscreen interaction the UI thread is saturated dispatching MotionEvents, so these wakeups fired late and the coalescing latch collapsed multiple guest presents into one, dropping displayed FPS. Wake the VkRenderer thread directly via xServerView.requestRender(). The render loop still coalesces (one draw per iteration) and native FIFO present still paces to vsync, so the UI-thread/Choreographer hop was redundant as well as harmful. Removes the now-unused mainHandler/renderRequested fields and Handler/Choreographer imports. --- .../runtime/display/renderer/VulkanRenderer.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/app/src/main/runtime/display/renderer/VulkanRenderer.java b/app/src/main/runtime/display/renderer/VulkanRenderer.java index f2b149cd0..8635e77fb 100644 --- a/app/src/main/runtime/display/renderer/VulkanRenderer.java +++ b/app/src/main/runtime/display/renderer/VulkanRenderer.java @@ -3,10 +3,8 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.os.Handler; import android.os.Looper; import android.util.Log; -import android.view.Choreographer; import android.view.Surface; import androidx.preference.PreferenceManager; import com.winlator.cmod.BuildConfig; @@ -119,9 +117,6 @@ public void setSwapRB(boolean v) { private final ByteBuffer sceneBuf = ByteBuffer.allocateDirect(SCENE_BUF_SIZE).order(ByteOrder.nativeOrder()); - private final Handler mainHandler = new Handler(Looper.getMainLooper()); - private final AtomicBoolean renderRequested = new AtomicBoolean(false); - // Reusable scratch — sized once, refilled per frame. private final float[] sceneXform = XForm.getInstance(); // Effect.writeParams writes into a float[]; we copy into the ByteBuffer afterwards. @@ -169,13 +164,8 @@ public void destroy() { } public void requestRenderCoalesced() { - if (renderRequested.compareAndSet(false, true)) { - mainHandler.post(() -> - Choreographer.getInstance().postFrameCallback(frameTimeNanos -> { - renderRequested.set(false); - xServerView.requestRender(); - })); - } + // Wake the render thread directly; the UI-thread/Choreographer hop stalls under touch input. + xServerView.requestRender(); } private Drawable createRootCursorDrawable() {