Compare commits

...
7 Commits
Author SHA1 Message Date
Chloe df513983d1 cover the license 2026-09-07 17:45:15 -07:00
Chloe a71071e3ac Merge branch 'main' into latency-test 2026-09-07 17:22:30 -07:00
Chloe 8578200db1 Merge branch 'main' into latency-test 2026-09-07 00:52:32 -07:00
Chloe adb9dcc1e9 add toggle for frame pacing 2026-09-07 00:41:18 -07:00
Chloe a32589b06c disable auto swap interval 2026-09-07 00:41:18 -07:00
Chloe 1773e54c84 fix surface update being called outside gl thread 2026-09-07 00:41:18 -07:00
Chloe 5718b73470 my evil test 2026-09-07 00:41:17 -07:00
11 changed files with 1763 additions and 43 deletions

No files matched your search

+2
View File
@@ -318,6 +318,7 @@ android {
buildFeatures { buildFeatures {
compose = true compose = true
buildConfig = true buildConfig = true
prefab = true
} }
packaging { packaging {
resources { resources {
@@ -359,6 +360,7 @@ dependencies {
implementation ("androidx.activity:activity-ktx:1.13.0") implementation ("androidx.activity:activity-ktx:1.13.0")
implementation ("androidx.appcompat:appcompat:1.8.0") implementation ("androidx.appcompat:appcompat:1.8.0")
implementation ("androidx.documentfile:documentfile:1.1.0") implementation ("androidx.documentfile:documentfile:1.1.0")
implementation ("androidx.games:games-frame-pacing:2.1.3")
implementation ("com.squareup.okio:okio:3.18.2") implementation ("com.squareup.okio:okio:3.18.2")
implementation ("com.squareup.okhttp3:okhttp:5.5.0") implementation ("com.squareup.okhttp3:okhttp:5.5.0")
+5 -2
View File
@@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 3.21)
project(launcherfix) project(launcherfix)
add_library(launcherfix SHARED launcher-fix.cpp patcher.cpp) find_package(games-frame-pacing REQUIRED CONFIG)
add_library(launcherfix SHARED launcher-fix.cpp patcher.cpp pacing.cpp)
target_compile_features(launcherfix PUBLIC cxx_std_20) target_compile_features(launcherfix PUBLIC cxx_std_20)
set_target_properties(launcherfix PROPERTIES CXX_EXTENSIONS OFF) set_target_properties(launcherfix PROPERTIES CXX_EXTENSIONS OFF)
@@ -14,4 +16,5 @@ set_target_properties(launcherfix PROPERTIES
CXX_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden
) )
target_link_libraries(launcherfix PRIVATE log) target_link_libraries(launcherfix PRIVATE log android)
target_link_libraries(launcherfix PRIVATE games-frame-pacing::swappy_static)
+65
View File
@@ -0,0 +1,65 @@
#include <swappy/swappyGL.h>
#include <swappy/swappyGL_extra.h>
#include <android/native_window_jni.h>
#include <memory>
extern "C"
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_initFramePacing(
JNIEnv *env,
jobject,
jobject activity
) {
SwappyGL_init(env, activity);
}
struct NativeWindowDeleter {
void operator()(ANativeWindow* p) const {
if (p != nullptr) ANativeWindow_release(p);
}
};
std::unique_ptr<ANativeWindow, NativeWindowDeleter> native_window = nullptr;
extern "C"
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_destroyFramePacing(JNIEnv*, jobject) {
SwappyGL_destroy();
}
extern "C"
JNIEXPORT jboolean JNICALL Java_com_geode_launcher_LauncherFix_swapFrame(
JNIEnv*,
jobject,
jlong display,
jlong surface
) {
return SwappyGL_swap(
reinterpret_cast<EGLDisplay>(display),
reinterpret_cast<EGLSurface>(surface)
);
}
extern "C"
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_setSurface(
JNIEnv* env,
jobject,
jobject surface
) {
if (surface == nullptr) {
native_window.reset();
SwappyGL_setWindow(nullptr);
return;
}
native_window.reset(ANativeWindow_fromSurface(env, surface));
SwappyGL_setWindow(native_window.get());
}
extern "C"
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_setSwapInterval(
JNIEnv* env,
jobject,
jlong interval_ns
) {
SwappyGL_setAutoSwapInterval(false);
SwappyGL_setSwapIntervalNS(interval_ns);
}
File diff suppressed because it is too large. Load diff
@@ -5,7 +5,9 @@ import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.opengl.GLSurfaceView import android.opengl.EGL14
import android.opengl.EGLConfig
import android.opengl.EGLDisplay
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
@@ -43,9 +45,6 @@ import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
import javax.microedition.khronos.egl.EGL10
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.egl.EGLDisplay
enum class DisplayMode { enum class DisplayMode {
DEFAULT, LIMITED, FULLSCREEN; DEFAULT, LIMITED, FULLSCREEN;
@@ -78,6 +77,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
private var mAspectRatio = 0.0f private var mAspectRatio = 0.0f
private var mScreenZoom = 1.0f private var mScreenZoom = 1.0f
private var mScreenZoomFit = false private var mScreenZoomFit = false
private var mNativeFramePacing = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setupUIState() setupUIState()
@@ -131,6 +131,10 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
} }
}) })
mGLSurfaceView?.manualBackEvents = true mGLSurfaceView?.manualBackEvents = true
if (mNativeFramePacing) {
LauncherFix.initFramePacing(this)
}
} }
private fun createVersionFile() { private fun createVersionFile() {
@@ -491,9 +495,11 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
val frameRate = mLimitedRefreshRate val frameRate = mLimitedRefreshRate
if (frameRate != null) { if (frameRate != null) {
renderer.limitFrameRate(frameRate) glSurfaceView.setMaxFrameRate(frameRate)
} }
glSurfaceView.nativeFramePacing = mNativeFramePacing
editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
glSurfaceView.cocos2dxEditText = editText glSurfaceView.cocos2dxEditText = editText
@@ -529,6 +535,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) { if (displayMode == DisplayMode.FULLSCREEN && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
GeodeUtils.handleSafeArea = true GeodeUtils.handleSafeArea = true
@@ -562,6 +570,10 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
FMOD.close() FMOD.close()
if (mNativeFramePacing) {
LauncherFix.destroyFramePacing()
}
} }
private fun resumeGame() { private fun resumeGame() {
@@ -733,11 +745,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
} }
} }
class EGLConfigChooser : GLSurfaceView.EGLConfigChooser { class EGLConfigChooser : ExplicitGLSurfaceView.EGLConfigChooser {
// this comes from EGL14, but is unavailable on EGL10
// also EGL14 is incompatible with EGL10. so whatever
private var EGL_OPENGL_ES2_BIT: Int = 0x04
private data class ConfigValues( private data class ConfigValues(
val redSize: Int, val redSize: Int,
val greenSize: Int, val greenSize: Int,
@@ -747,29 +755,29 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
val stencilSize: Int, val stencilSize: Int,
) )
private fun getAttribValue(egl: EGL10, display: EGLDisplay, config: EGLConfig, attrib: Int): Int { private fun getAttribValue(display: EGLDisplay, config: EGLConfig, attrib: Int): Int {
val value = IntArray(1) val value = IntArray(1)
egl.eglGetConfigAttrib(display, config, attrib, value) EGL14.eglGetConfigAttrib(display, config, attrib, value, 0)
return value[0] return value[0]
} }
private fun testConfig(egl: EGL10, display: EGLDisplay, attrib: ConfigValues): EGLConfig? { private fun testConfig(display: EGLDisplay, attrib: ConfigValues): EGLConfig? {
val attribList = intArrayOf( val attribList = intArrayOf(
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
EGL10.EGL_RED_SIZE, attrib.redSize, EGL14.EGL_RED_SIZE, attrib.redSize,
EGL10.EGL_GREEN_SIZE, attrib.greenSize, EGL14.EGL_GREEN_SIZE, attrib.greenSize,
EGL10.EGL_BLUE_SIZE, attrib.blueSize, EGL14.EGL_BLUE_SIZE, attrib.blueSize,
EGL10.EGL_ALPHA_SIZE, attrib.alphaSize, EGL14.EGL_ALPHA_SIZE, attrib.alphaSize,
EGL10.EGL_DEPTH_SIZE, attrib.depthSize, EGL14.EGL_DEPTH_SIZE, attrib.depthSize,
EGL10.EGL_STENCIL_SIZE, attrib.stencilSize, EGL14.EGL_STENCIL_SIZE, attrib.stencilSize,
EGL10.EGL_NONE EGL14.EGL_NONE
) )
val configs = arrayOfNulls<EGLConfig>(1) val configs = arrayOfNulls<EGLConfig>(1)
val numConfigs = IntArray(1) val numConfigs = IntArray(1)
val res = egl.eglChooseConfig(display, attribList, configs, configs.size, numConfigs) val res = EGL14.eglChooseConfig(display, attribList, 0, configs, 0, configs.size, numConfigs, 0)
if (res && numConfigs[0] > 0 && configs[0] != null) { if (res && numConfigs[0] > 0 && configs[0] != null) {
return configs[0] return configs[0]
} }
@@ -777,18 +785,18 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
return null return null
} }
private fun printConfig(egl: EGL10, display: EGLDisplay, config: EGLConfig) { private fun printConfig(display: EGLDisplay, config: EGLConfig) {
val id = getAttribValue(egl, display, config, EGL10.EGL_CONFIG_ID) val id = getAttribValue(display, config, EGL14.EGL_CONFIG_ID)
val red = getAttribValue(egl, display, config, EGL10.EGL_RED_SIZE) val red = getAttribValue(display, config, EGL14.EGL_RED_SIZE)
val green = getAttribValue(egl, display, config, EGL10.EGL_GREEN_SIZE) val green = getAttribValue(display, config, EGL14.EGL_GREEN_SIZE)
val blue = getAttribValue(egl, display, config, EGL10.EGL_BLUE_SIZE) val blue = getAttribValue(display, config, EGL14.EGL_BLUE_SIZE)
val alpha = getAttribValue(egl, display, config, EGL10.EGL_ALPHA_SIZE) val alpha = getAttribValue(display, config, EGL14.EGL_ALPHA_SIZE)
val depth = getAttribValue(egl, display, config, EGL10.EGL_DEPTH_SIZE) val depth = getAttribValue(display, config, EGL14.EGL_DEPTH_SIZE)
val stencil = getAttribValue(egl, display, config, EGL10.EGL_STENCIL_SIZE) val stencil = getAttribValue(display, config, EGL14.EGL_STENCIL_SIZE)
println("EGLConfig $id: (red = $red, green = $green, blue = $blue, alpha = $alpha, depth = $depth, stencil = $stencil)") println("EGLConfig $id: (red = $red, green = $green, blue = $blue, alpha = $alpha, depth = $depth, stencil = $stencil)")
} }
override fun chooseConfig(egl: EGL10, display: EGLDisplay): EGLConfig { override fun chooseConfig(display: EGLDisplay): EGLConfig {
val configs = listOf( val configs = listOf(
ConfigValues(8, 8, 8, 8, 16, 8), ConfigValues(8, 8, 8, 8, 16, 8),
ConfigValues(8, 8, 8, 0, 16, 8), ConfigValues(8, 8, 8, 0, 16, 8),
@@ -797,9 +805,9 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
) )
return configs.firstNotNullOf { return configs.firstNotNullOf {
val config = testConfig(egl, display, it) val config = testConfig(display, it)
if (config != null) { if (config != null) {
printConfig(egl, display, config) printConfig(display, config)
} }
config config
@@ -1,5 +1,7 @@
package com.geode.launcher package com.geode.launcher
import android.app.Activity
import android.view.Surface
import androidx.annotation.Keep import androidx.annotation.Keep
import com.geode.launcher.utils.Constants import com.geode.launcher.utils.Constants
@@ -16,4 +18,10 @@ object LauncherFix {
external fun enableExceptionsRenaming() external fun enableExceptionsRenaming()
external fun performPatches() external fun performPatches()
external fun initFramePacing(activity: Activity)
external fun destroyFramePacing()
external fun swapFrame(display: Long, surface: Long): Boolean
external fun setSurface(surface: Surface?)
external fun setSwapInterval(intervalNs: Long)
} }
@@ -169,6 +169,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) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
SettingsCard( SettingsCard(
@@ -150,6 +150,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
LAST_LAUNCHER_UPDATE, LAST_LAUNCHER_UPDATE,
DISABLE_UPDATE_CACHE, DISABLE_UPDATE_CACHE,
PREBUNDLED_GEODE_MIGRATION_PERFORMED, PREBUNDLED_GEODE_MIGRATION_PERFORMED,
NATIVE_FRAME_PACING,
} }
private fun defaultValueForBooleanKey(key: Key): Boolean { private fun defaultValueForBooleanKey(key: Key): Boolean {
@@ -201,6 +202,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
Key.LAST_LAUNCHER_UPDATE -> "PreferenceLastLauncherUpdate" Key.LAST_LAUNCHER_UPDATE -> "PreferenceLastLauncherUpdate"
Key.DISABLE_UPDATE_CACHE -> "PreferenceDisableUpdateCache" Key.DISABLE_UPDATE_CACHE -> "PreferenceDisableUpdateCache"
Key.PREBUNDLED_GEODE_MIGRATION_PERFORMED -> "PreferencePrebundledGeodeMigrationPerformed" Key.PREBUNDLED_GEODE_MIGRATION_PERFORMED -> "PreferencePrebundledGeodeMigrationPerformed"
Key.NATIVE_FRAME_PACING -> "PreferenceNativeFramePacing"
// Key.RELEASE_CHANNEL -> "PreferenceReleaseChannel" // Key.RELEASE_CHANNEL -> "PreferenceReleaseChannel"
// Key.LAST_DISMISSED_UPDATE -> "PreferenceLastDismissedUpdate" // Key.LAST_DISMISSED_UPDATE -> "PreferenceLastDismissedUpdate"
// Key.FORCE_HRR -> "PreferenceForceHighRefreshRate" // Key.FORCE_HRR -> "PreferenceForceHighRefreshRate"
@@ -17,15 +17,18 @@ import android.view.inputmethod.InputMethodManager
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.widget.AppCompatEditText import androidx.appcompat.widget.AppCompatEditText
import com.customRobTop.BaseRobTopActivity import com.customRobTop.BaseRobTopActivity
import com.geode.launcher.ExplicitGLSurfaceView
import com.geode.launcher.LauncherFix
import com.geode.launcher.utils.GeodeUtils import com.geode.launcher.utils.GeodeUtils
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.roundToLong
private const val HANDLER_OPEN_IME_KEYBOARD = 2 private const val HANDLER_OPEN_IME_KEYBOARD = 2
private const val HANDLER_CLOSE_IME_KEYBOARD = 3 private const val HANDLER_CLOSE_IME_KEYBOARD = 3
private const val MS_TO_NS = 1_000_000 private const val MS_TO_NS = 1_000_000
private const val SEC_TO_NS = 1_000_000_000.0 private const val SEC_TO_NS = 1_000_000_000.0
class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) { class Cocos2dxGLSurfaceView(context: Context) : ExplicitGLSurfaceView(context) {
companion object { companion object {
lateinit var cocos2dxGLSurfaceView: Cocos2dxGLSurfaceView lateinit var cocos2dxGLSurfaceView: Cocos2dxGLSurfaceView
private lateinit var handler: Handler private lateinit var handler: Handler
@@ -64,6 +67,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
var controllerEventsEnabled = false var controllerEventsEnabled = false
private set private set
var supportsResizeEvents = false var supportsResizeEvents = false
var saveNativeFramePacing = false
var cocos2dxEditText: AppCompatEditText? = null var cocos2dxEditText: AppCompatEditText? = null
set(value) { set(value) {
@@ -139,6 +143,10 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
println("updateRefreshRate: selecting refresh rate of ${chosenDisplay.refreshRate} (display ${chosenDisplay.modeId})") println("updateRefreshRate: selecting refresh rate of ${chosenDisplay.refreshRate} (display ${chosenDisplay.modeId})")
if (saveNativeFramePacing) {
LauncherFix.setSwapInterval((1_000_000_000L / chosenRefreshRate).roundToLong())
}
holder.surface.setFrameRate(chosenRefreshRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT) holder.surface.setFrameRate(chosenRefreshRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
if (isAttachedToWindow) { if (isAttachedToWindow) {
(context as Activity).window.attributes.preferredRefreshRate = chosenRefreshRate (context as Activity).window.attributes.preferredRefreshRate = chosenRefreshRate
@@ -153,6 +161,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
renderMode = RENDERMODE_CONTINUOUSLY renderMode = RENDERMODE_CONTINUOUSLY
queueEvent { cocos2dxRenderer.handleOnResume() } queueEvent { cocos2dxRenderer.handleOnResume() }
} }
@@ -533,6 +542,11 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
setRenderer(this.cocos2dxRenderer) setRenderer(this.cocos2dxRenderer)
} }
override fun setNativeFramePacing(nativeFramePacing: Boolean) {
super.setNativeFramePacing(nativeFramePacing)
saveNativeFramePacing = nativeFramePacing
}
private fun getContentText(): String { private fun getContentText(): String {
return cocos2dxRenderer.getContentText() return cocos2dxRenderer.getContentText()
} }
@@ -567,6 +581,10 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
inputManager.unregisterInputDeviceListener(InputListener) inputManager.unregisterInputDeviceListener(InputListener)
} }
fun setMaxFrameRate(rate: Int) {
cocos2dxRenderer.limitFrameRate(rate)
}
object InputListener : InputManager.InputDeviceListener { object InputListener : InputManager.InputDeviceListener {
override fun onInputDeviceAdded(deviceId: Int) { override fun onInputDeviceAdded(deviceId: Int) {
GeodeUtils.inputDeviceAdded(deviceId) GeodeUtils.inputDeviceAdded(deviceId)
@@ -1,15 +1,14 @@
package org.cocos2dx.lib package org.cocos2dx.lib
import android.opengl.GLSurfaceView import android.opengl.EGLConfig
import android.os.Build import android.os.Build
import javax.microedition.khronos.egl.EGLConfig import com.geode.launcher.ExplicitGLSurfaceView
import javax.microedition.khronos.opengles.GL10
private const val NANOSECONDS_PER_SECOND = 1000000000L private const val NANOSECONDS_PER_SECOND = 1000000000L
private const val NANOSECONDS_PER_MICROSECOND = 1000000L private const val NANOSECONDS_PER_MICROSECOND = 1000000L
@Suppress("unused", "KotlinJniMissingFunction") @Suppress("unused", "KotlinJniMissingFunction")
class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : GLSurfaceView.Renderer { class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : ExplicitGLSurfaceView.Renderer {
companion object { companion object {
@JvmStatic @JvmStatic
fun setAnimationInterval(@Suppress("UNUSED_PARAMETER") animationInterval: Double) { fun setAnimationInterval(@Suppress("UNUSED_PARAMETER") animationInterval: Double) {
@@ -80,12 +79,12 @@ class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : GLSurfaceVi
screenHeight = surfaceHeight screenHeight = surfaceHeight
} }
override fun onSurfaceCreated(gl10: GL10?, eglConfig: EGLConfig?) { override fun onSurfaceCreated(eglConfig: EGLConfig?) {
nativeInit(screenWidth, screenHeight) nativeInit(screenWidth, screenHeight)
lastTickInNanoSeconds = System.nanoTime() lastTickInNanoSeconds = System.nanoTime()
} }
override fun onSurfaceChanged(gl10: GL10?, width: Int, height: Int) { override fun onSurfaceChanged(width: Int, height: Int) {
if (setFrameRate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (setFrameRate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
handler.updateRefreshRate() handler.updateRefreshRate()
} }
@@ -93,7 +92,7 @@ class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : GLSurfaceVi
println("renderer surfaceChanged: ${width}x${height}@${handler.display.refreshRate}fps") println("renderer surfaceChanged: ${width}x${height}@${handler.display.refreshRate}fps")
} }
override fun onDrawFrame(gl: GL10?) { override fun onDrawFrame() {
val animationInterval = mAnimationInterval val animationInterval = mAnimationInterval
if (animationInterval == null) { if (animationInterval == null) {
nativeRender() nativeRender()
+3
View File
@@ -298,6 +298,9 @@
<string name="preference_profiles_delete_alt">Delete</string> <string name="preference_profiles_delete_alt">Delete</string>
<string name="preference_profiles_delete_undo_alt">Undo</string> <string name="preference_profiles_delete_undo_alt">Undo</string>
<string name="preference_native_pacing">Native frame pacing</string>
<string name="preference_native_pacing_description">Reduces latency, but may worsen frame drops.</string>
<!-- ApplicationLogsActivity strings --> <!-- ApplicationLogsActivity strings -->
<string name="title_activity_application_logs">Application logs</string> <string name="title_activity_application_logs">Application logs</string>
<string name="application_logs_no_logs">No logs available.</string> <string name="application_logs_no_logs">No logs available.</string>