Stale GL_UNPACK state in gl4es and a missing pre-release GPU sync caused diagonal-banded corruption in the 3D view. Synthetic key press/release must track the real controller button or touch down/up edges, not fire together in one call - fixes a typed movement key sticking forever, then a follow-up that had silently broken A-button jump and on-screen keyboard arrow keys. Also adds force-rebuild.sh for the known stageEngine stale-cache issue.
This commit is contained in:
@@ -199,11 +199,18 @@
|
||||
#include "InitMac.h"
|
||||
#include "Modding.h"
|
||||
#include "OpenGL.h"
|
||||
@@ -301,6 +305,21 @@
|
||||
@@ -301,6 +305,28 @@
|
||||
}
|
||||
|
||||
void SDLDraw() {
|
||||
+#ifdef __ANDROID__
|
||||
+ // Diagnostic: logs once per transition (including the very first
|
||||
+ // frame) between the OpenGL 3D render path and the plain
|
||||
+ // software-composited 2D path (splash/menus/cutscenes) below - so a
|
||||
+ // logcat capture immediately shows which one is active without
|
||||
+ // needing to infer it from screenshots.
|
||||
+ static int s_last_render_mode = -1; // -1 = not yet logged
|
||||
+
|
||||
+ // The true once-a-frame present hook for the immersive OpenXR path -
|
||||
+ // unlike opengl_swap_and_restore() below, this runs every frame
|
||||
+ // regardless of should_opengl_swap() (e.g. also during the splash
|
||||
@@ -221,17 +228,25 @@
|
||||
if (should_opengl_swap()) {
|
||||
// We want the UI background to be transparent!
|
||||
sdlPalette->colors[255].a = 0x00;
|
||||
@@ -310,14 +329,27 @@
|
||||
@@ -310,14 +336,35 @@
|
||||
|
||||
// Set the palette back, and we are done
|
||||
sdlPalette->colors[255].a = 0xff;
|
||||
+#ifdef __ANDROID__
|
||||
+ if (s_last_render_mode != 1) {
|
||||
+ s_last_render_mode = 1;
|
||||
+ INFO("Game rendering active: OpenGL (3D) mode");
|
||||
+ }
|
||||
+ xr_frame_end();
|
||||
+#endif
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef __ANDROID__
|
||||
+ if (s_last_render_mode != 0) {
|
||||
+ s_last_render_mode = 0;
|
||||
+ INFO("Game rendering active: software (2D) mode");
|
||||
+ }
|
||||
+ // Same software-rendered frame the desktop path below would present
|
||||
+ // via SDL_RenderCopy/SDL_RenderPresent, composited into the XR
|
||||
+ // swapchain image xr_frame_begin() bound above instead - SDL's
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--- a/src/MacSrc/OpenGL.cc 2026-08-22 09:00:00.000000000 +0200
|
||||
+++ b/src/MacSrc/OpenGL.cc 2026-08-22 09:05:00.000000000 +0200
|
||||
@@ -562,7 +562,14 @@
|
||||
static bool opengl_cache_texture(CachedTexture toCache, grs_bitmap *bm) {
|
||||
SDL_GL_MakeCurrent(window, context);
|
||||
|
||||
- glPixelStorei(GL_UNPACK_ROW_LENGTH, bm->row);
|
||||
+ // GL_UNPACK_ROW_LENGTH must describe the buffer actually passed to
|
||||
+ // glTexImage2D() below (toCache.converted->pixels, a separately
|
||||
+ // allocated SDL_PIXELFORMAT_RGBA32 surface from
|
||||
+ // SDL_ConvertSurfaceFormat()) - not bm->row, the original 8-bit
|
||||
+ // source bitmap's own unrelated row stride. Using bm->row here fed
|
||||
+ // gl4es's GL_UNPACK_ROW_LENGTH emulation the wrong stride whenever
|
||||
+ // the two differed, corrupting the texture upload.
|
||||
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, toCache.converted->pitch / 4);
|
||||
|
||||
if (texturesByBitsPtr.size() < MAX_CACHED_TEXTURES) {
|
||||
// We have enough room, generate the new texture
|
||||
@@ -696,7 +703,10 @@
|
||||
t->lastDrawTime = *tmd_ticks;
|
||||
|
||||
if (isDirty) {
|
||||
- glPixelStorei(GL_UNPACK_ROW_LENGTH, bm->row);
|
||||
+ // Same fix as opengl_cache_texture() above - t->converted->pixels
|
||||
+ // is what's actually uploaded, so its own pitch is what
|
||||
+ // GL_UNPACK_ROW_LENGTH needs to describe, not bm->row.
|
||||
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, t->converted->pitch / 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm->w, bm->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, t->converted->pixels);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
--- a/src/MacSrc/OpenGL.cc
|
||||
+++ b/src/MacSrc/OpenGL.cc
|
||||
@@ -566,7 +566,11 @@
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(tcAttrib);
|
||||
glDisableVertexAttribArray(lightAttrib);
|
||||
- glFlush();
|
||||
+ // glFinish(), not glFlush(): xr_swapchain_release() (called by our
|
||||
+ // caller right after this returns) hands the image to the OpenXR
|
||||
+ // runtime for cross-process consumption, which requires the GPU write
|
||||
+ // to have actually landed, not just be queued.
|
||||
+ glFinish();
|
||||
|
||||
SDL_FreeSurface(uiRgba);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
--- a/src/MacSrc/OpenGL.cc
|
||||
+++ b/src/MacSrc/OpenGL.cc
|
||||
@@ -525,6 +525,13 @@
|
||||
bind_texture(s_uiTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
+ // uiRgba is tightly packed, but gl4es implements GL_UNPACK_ROW_LENGTH/
|
||||
+ // GL_UNPACK_ALIGNMENT client-side and persists whatever was last set
|
||||
+ // across draw calls in the same context. Reset both to the packed
|
||||
+ // defaults here so this upload doesn't inherit unrelated unpack state
|
||||
+ // set elsewhere in the frame.
|
||||
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, uiRgba->w, uiRgba->h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
uiRgba->pixels);
|
||||
|
||||
Reference in New Issue
Block a user