add toggle for frame pacing

This commit is contained in:
Chloe committed 2026-09-07 00:41:18 -07:00
1 parent a32589b06c
commit adb9dcc1e9
6 files changed
+86 -18

No files matched your search

@@ -325,6 +325,9 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
public int getRenderMode() {
return mGLThread.getRenderMode();
}
public void setNativeFramePacing(boolean nativeFramePacing) { mGLThread.setNativeFramePacing(nativeFramePacing); }
public boolean getNativeFramePacing() { return mGLThread.getNativeFramePacing(); }
/**
* Request that the renderer render a frame.
* This method is typically used when the render mode has been set to
@@ -739,6 +742,7 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
private static class EglHelper {
public EglHelper(WeakReference<ExplicitGLSurfaceView> glSurfaceViewWeakRef) {
mGLSurfaceViewWeakRef = glSurfaceViewWeakRef;
mNativeFramePacing = false;
}
/**
* Initialize EGL for a given configuration spec.
@@ -814,12 +818,16 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
if (view != null) {
mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface(
mEglDisplay, mEglConfig, view.getHolder());
// NOTE: this diverges from GLSurfaceView
LauncherFix.INSTANCE.setSurface(view.getHolder().getSurface());
if (mNativeFramePacing) {
LauncherFix.INSTANCE.setSurface(view.getHolder().getSurface());
}
} else {
mEglSurface = null;
// NOTE: this diverges from GLSurfaceView
LauncherFix.INSTANCE.setSurface(null);
if (mNativeFramePacing) {
LauncherFix.INSTANCE.setSurface(null);
}
}
if (mEglSurface == null || mEglSurface == EGL14.EGL_NO_SURFACE) {
int error = EGL14.eglGetError();
@@ -848,11 +856,16 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
* @return the EGL error code from eglSwapBuffers.
*/
public int swap() {
// NOTE: this diverges from GLSurfaceView
// if (! EGL14.eglSwapBuffers(mEglDisplay, mEglSurface)) {
if (!LauncherFix.INSTANCE.swapFrame(mEglDisplay.getNativeHandle(), mEglSurface.getNativeHandle())) {
return EGL14.eglGetError();
if (mNativeFramePacing) {
if (!LauncherFix.INSTANCE.swapFrame(mEglDisplay.getNativeHandle(), mEglSurface.getNativeHandle())) {
return EGL14.eglGetError();
}
} else {
if (!EGL14.eglSwapBuffers(mEglDisplay, mEglSurface)) {
return EGL14.eglGetError();
}
}
return EGL14.EGL_SUCCESS;
}
public void destroySurface() {
@@ -871,6 +884,10 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
view.mEGLWindowSurfaceFactory.destroySurface(mEglDisplay, mEglSurface);
}
mEglSurface = null;
if (mNativeFramePacing) {
LauncherFix.INSTANCE.setSurface(null);
}
}
}
public void finish() {
@@ -911,6 +928,8 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
EGLSurface mEglSurface;
EGLConfig mEglConfig;
EGLContext mEglContext;
boolean mNativeFramePacing;
}
/**
* A generic GL Thread. Takes care of initializing EGL and GL. Delegates
@@ -930,6 +949,7 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
mRenderMode = RENDERMODE_CONTINUOUSLY;
mWantRenderNotification = false;
mGLSurfaceViewWeakRef = glSurfaceViewWeakRef;
mNativeFramePacing = false;
}
@Override
public void run() {
@@ -968,6 +988,7 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
}
private void guardedRun() throws InterruptedException {
mEglHelper = new EglHelper(mGLSurfaceViewWeakRef);
mEglHelper.mNativeFramePacing = mNativeFramePacing;
mHaveEglContext = false;
mHaveEglSurface = false;
mWantRenderNotification = false;
@@ -1218,8 +1239,6 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
finishDrawingRunnable.run();
finishDrawingRunnable = null;
}
// NOTE: this diverges from GLSurfaceView
requestRender();
} finally {
// Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
@@ -1251,6 +1270,11 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
doRenderNotification = true;
wantRenderNotification = false;
}
// request new frame prior to swap
if (mNativeFramePacing) {
requestRender();
}
}
} finally {
/*
@@ -1279,6 +1303,21 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
sGLThreadManager.notifyAll();
}
}
public void setNativeFramePacing(boolean nativeFramePacing) {
synchronized(sGLThreadManager) {
if (mEglHelper != null) {
mEglHelper.mNativeFramePacing = nativeFramePacing;
}
mNativeFramePacing = nativeFramePacing;
sGLThreadManager.notifyAll();
}
}
public boolean getNativeFramePacing() {
synchronized(sGLThreadManager) {
return mNativeFramePacing;
}
}
public int getRenderMode() {
synchronized(sGLThreadManager) {
return mRenderMode;
@@ -1475,6 +1514,8 @@ public class ExplicitGLSurfaceView extends SurfaceView implements SurfaceHolder.
private Runnable mFinishDrawingRunnable = null;
// End of member variables protected by the sGLThreadManager monitor.
private EglHelper mEglHelper;
private boolean mNativeFramePacing;
/**
* Set once at thread construction time, nulled out when the parent view is garbage
* called. This weak reference allows the GLSurfaceView to be garbage collected while
@@ -77,6 +77,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
private var mAspectRatio = 0.0f
private var mScreenZoom = 1.0f
private var mScreenZoomFit = false
private var mNativeFramePacing = false
override fun onCreate(savedInstanceState: Bundle?) {
setupUIState()
@@ -131,7 +132,9 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
})
mGLSurfaceView?.manualBackEvents = true
LauncherFix.initFramePacing(this)
if (mNativeFramePacing) {
LauncherFix.initFramePacing(this)
}
}
private fun createVersionFile() {
@@ -475,9 +478,11 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
val frameRate = mLimitedRefreshRate
if (frameRate != null) {
glSurfaceView.setMaxFramerate(frameRate)
glSurfaceView.setMaxFrameRate(frameRate)
}
glSurfaceView.nativeFramePacing = mNativeFramePacing
editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
glSurfaceView.cocos2dxEditText = editText
@@ -513,6 +518,8 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
}
}
mNativeFramePacing = preferenceUtils.getBoolean(PreferenceUtils.Key.NATIVE_FRAME_PACING)
if (displayMode == DisplayMode.FULLSCREEN && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
GeodeUtils.handleSafeArea = true
@@ -547,7 +554,9 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
super.onDestroy()
FMOD.close()
LauncherFix.destroyFramePacing()
if (mNativeFramePacing) {
LauncherFix.destroyFramePacing()
}
}
private fun resumeGame() {
@@ -168,6 +168,12 @@ fun DeveloperSettingsScreen(onBackPressedDispatcher: OnBackPressedDispatcher?) {
}
)
SettingsCard(
title = stringResource(R.string.preference_native_pacing),
description = stringResource(R.string.preference_native_pacing_description),
preferenceKey = PreferenceUtils.Key.NATIVE_FRAME_PACING,
)
/*
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
SettingsCard(
@@ -149,6 +149,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
LAST_UPDATE_CHECK_TIME,
LAST_LAUNCHER_UPDATE,
DISABLE_UPDATE_CACHE,
NATIVE_FRAME_PACING,
}
private fun defaultValueForBooleanKey(key: Key): Boolean {
@@ -199,6 +200,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
Key.LAST_UPDATE_CHECK_TIME -> "PreferenceLastUpdateCheckTime"
Key.LAST_LAUNCHER_UPDATE -> "PreferenceLastLauncherUpdate"
Key.DISABLE_UPDATE_CACHE -> "PreferenceDisableUpdateCache"
Key.NATIVE_FRAME_PACING -> "PreferenceNativeFramePacing"
// Key.RELEASE_CHANNEL -> "PreferenceReleaseChannel"
// Key.LAST_DISMISSED_UPDATE -> "PreferenceLastDismissedUpdate"
// Key.FORCE_HRR -> "PreferenceForceHighRefreshRate"