Skip to content

Commit a57a99f

Browse files
committed
Memory cleanup and optimizations
- Returns an empty list when there's not registered plugins, thus preventing the creation of spurious iterator objects - Inline `Godot#getRotatedValues(...)` given it only had a single caller. This allows to remove the allocation of a float array on each call and replace it with float variables - Disable sensor events by default. Sensor events can fired at 10-100s Hz taking cpu and memory resources. Now the use of sensor data is behind a project setting allowing projects that have use of it to enable it, while other projects don't pay the cost for a feature they don't use - Create a pool of specialized input `Runnable` objects to prevent spurious, unbounded `Runnable` allocations - Disable showing the boot logo for Android XR projects - Delete locale references of jni strings
1 parent 2f2d1a7 commit a57a99f

File tree

14 files changed

+626
-188
lines changed

14 files changed

+626
-188
lines changed

core/config/project_settings.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,11 @@ ProjectSettings::ProjectSettings() {
15701570

15711571
GLOBAL_DEF("collada/use_ambient", false);
15721572

1573+
// Input settings
1574+
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false);
1575+
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false);
1576+
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);
1577+
15731578
// These properties will not show up in the dialog. If you want to exclude whole groups, use add_hidden_prefix().
15741579
GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray());
15751580
GLOBAL_DEF_INTERNAL("internationalization/locale/translation_remaps", PackedStringArray());

core/input/input.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,21 +513,49 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_
513513

514514
Vector3 Input::get_gravity() const {
515515
_THREAD_SAFE_METHOD_
516+
517+
#ifdef DEBUG_ENABLED
518+
if (!gravity_enabled) {
519+
WARN_PRINT_ONCE("`input_devices/sensors/enable_gravity` is not enabled in project settings.");
520+
}
521+
#endif
522+
516523
return gravity;
517524
}
518525

519526
Vector3 Input::get_accelerometer() const {
520527
_THREAD_SAFE_METHOD_
528+
529+
#ifdef DEBUG_ENABLED
530+
if (!accelerometer_enabled) {
531+
WARN_PRINT_ONCE("`input_devices/sensors/enable_accelerometer` is not enabled in project settings.");
532+
}
533+
#endif
534+
521535
return accelerometer;
522536
}
523537

524538
Vector3 Input::get_magnetometer() const {
525539
_THREAD_SAFE_METHOD_
540+
541+
#ifdef DEBUG_ENABLED
542+
if (!magnetometer_enabled) {
543+
WARN_PRINT_ONCE("`input_devices/sensors/enable_magnetometer` is not enabled in project settings.");
544+
}
545+
#endif
546+
526547
return magnetometer;
527548
}
528549

529550
Vector3 Input::get_gyroscope() const {
530551
_THREAD_SAFE_METHOD_
552+
553+
#ifdef DEBUG_ENABLED
554+
if (!gyroscope_enabled) {
555+
WARN_PRINT_ONCE("`input_devices/sensors/enable_gyroscope` is not enabled in project settings.");
556+
}
557+
#endif
558+
531559
return gyroscope;
532560
}
533561

@@ -1683,6 +1711,11 @@ Input::Input() {
16831711
// Always use standard behavior in the editor.
16841712
legacy_just_pressed_behavior = false;
16851713
}
1714+
1715+
accelerometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_accelerometer", false);
1716+
gravity_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gravity", false);
1717+
gyroscope_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gyroscope", false);
1718+
magnetometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_magnetometer", false);
16861719
}
16871720

16881721
Input::~Input() {

core/input/input.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,13 @@ class Input : public Object {
9292
RBSet<JoyButton> joy_buttons_pressed;
9393
RBMap<JoyAxis, float> _joy_axis;
9494
//RBMap<StringName,int> custom_action_press;
95+
bool gravity_enabled = false;
9596
Vector3 gravity;
97+
bool accelerometer_enabled = false;
9698
Vector3 accelerometer;
99+
bool magnetometer_enabled = false;
97100
Vector3 magnetometer;
101+
bool gyroscope_enabled = false;
98102
Vector3 gyroscope;
99103
Vector2 mouse_pos;
100104
int64_t mouse_window = 0;

doc/classes/ProjectSettings.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,18 @@
14221422
<member name="input_devices/pointing/emulate_touch_from_mouse" type="bool" setter="" getter="" default="false">
14231423
If [code]true[/code], sends touch input events when clicking or dragging the mouse.
14241424
</member>
1425+
<member name="input_devices/sensors/enable_accelerometer" type="bool" setter="" getter="" default="false">
1426+
If [code]true[/code], the accelerometer sensor is enabled and [method Input.get_accelerometer] returns valid data.
1427+
</member>
1428+
<member name="input_devices/sensors/enable_gravity" type="bool" setter="" getter="" default="false">
1429+
If [code]true[/code], the gravity sensor is enabled and [method Input.get_gravity] returns valid data.
1430+
</member>
1431+
<member name="input_devices/sensors/enable_gyroscope" type="bool" setter="" getter="" default="false">
1432+
If [code]true[/code], the gyroscope sensor is enabled and [method Input.get_gyroscope] returns valid data.
1433+
</member>
1434+
<member name="input_devices/sensors/enable_magnetometer" type="bool" setter="" getter="" default="false">
1435+
If [code]true[/code], the magnetometer sensor is enabled and [method Input.get_magnetometer] returns valid data.
1436+
</member>
14251437
<member name="internationalization/locale/fallback" type="String" setter="" getter="" default="&quot;en&quot;">
14261438
The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used.
14271439
</member>

main/main.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,9 +2942,6 @@ Error Main::setup2(bool p_show_boot_logo) {
29422942
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_mouse_from_touch", true)));
29432943
}
29442944

2945-
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false);
2946-
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false);
2947-
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);
29482945
OS::get_singleton()->benchmark_end_measure("Startup", "Setup Window and Boot");
29492946
}
29502947

platform/android/java/lib/src/org/godotengine/godot/Godot.kt

Lines changed: 59 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ import android.content.res.Configuration
3939
import android.content.res.Resources
4040
import android.graphics.Color
4141
import android.hardware.Sensor
42-
import android.hardware.SensorEvent
43-
import android.hardware.SensorEventListener
4442
import android.hardware.SensorManager
4543
import android.os.*
4644
import android.util.Log
@@ -53,6 +51,7 @@ import androidx.core.view.WindowInsetsAnimationCompat
5351
import androidx.core.view.WindowInsetsCompat
5452
import com.google.android.vending.expansion.downloader.*
5553
import org.godotengine.godot.input.GodotEditText
54+
import org.godotengine.godot.input.GodotInputHandler
5655
import org.godotengine.godot.io.directory.DirectoryAccessHandler
5756
import org.godotengine.godot.io.file.FileAccessHandler
5857
import org.godotengine.godot.plugin.GodotPluginRegistry
@@ -73,6 +72,7 @@ import java.io.InputStream
7372
import java.lang.Exception
7473
import java.security.MessageDigest
7574
import java.util.*
75+
import java.util.concurrent.atomic.AtomicBoolean
7676
import java.util.concurrent.atomic.AtomicReference
7777

7878
/**
@@ -81,7 +81,7 @@ import java.util.concurrent.atomic.AtomicReference
8181
* Can be hosted by [Activity], [Fragment] or [Service] android components, so long as its
8282
* lifecycle methods are properly invoked.
8383
*/
84-
class Godot(private val context: Context) : SensorEventListener {
84+
class Godot(private val context: Context) {
8585

8686
private companion object {
8787
private val TAG = Godot::class.java.simpleName
@@ -99,15 +99,23 @@ class Godot(private val context: Context) : SensorEventListener {
9999
private val pluginRegistry: GodotPluginRegistry by lazy {
100100
GodotPluginRegistry.getPluginRegistry()
101101
}
102+
103+
private val accelerometer_enabled = AtomicBoolean(false)
102104
private val mAccelerometer: Sensor? by lazy {
103105
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
104106
}
107+
108+
private val gravity_enabled = AtomicBoolean(false)
105109
private val mGravity: Sensor? by lazy {
106110
mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
107111
}
112+
113+
private val magnetometer_enabled = AtomicBoolean(false)
108114
private val mMagnetometer: Sensor? by lazy {
109115
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
110116
}
117+
118+
private val gyroscope_enabled = AtomicBoolean(false)
111119
private val mGyroscope: Sensor? by lazy {
112120
mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
113121
}
@@ -127,6 +135,7 @@ class Godot(private val context: Context) : SensorEventListener {
127135
val fileAccessHandler = FileAccessHandler(context)
128136
val netUtils = GodotNetUtils(context)
129137
private val commandLineFileParser = CommandLineFileParser()
138+
private val godotInputHandler = GodotInputHandler(context, this)
130139

131140
/**
132141
* Task to run when the engine terminates.
@@ -154,6 +163,17 @@ class Godot(private val context: Context) : SensorEventListener {
154163
private var renderViewInitialized = false
155164
private var primaryHost: GodotHost? = null
156165

166+
/**
167+
* Tracks whether we're in the RESUMED lifecycle state.
168+
* See [onResume] and [onPause]
169+
*/
170+
private var resumed = false
171+
172+
/**
173+
* Tracks whether [onGodotSetupCompleted] fired.
174+
*/
175+
private val godotMainLoopStarted = AtomicBoolean(false)
176+
157177
var io: GodotIO? = null
158178

159179
private var commandLine : MutableList<String> = ArrayList<String>()
@@ -416,10 +436,10 @@ class Godot(private val context: Context) : SensorEventListener {
416436
if (!meetsVulkanRequirements(activity.packageManager)) {
417437
throw IllegalStateException(activity.getString(R.string.error_missing_vulkan_requirements_message))
418438
}
419-
GodotVulkanRenderView(host, this)
439+
GodotVulkanRenderView(host, this, godotInputHandler)
420440
} else {
421441
// Fallback to openGl
422-
GodotGLRenderView(host, this, xrMode, useDebugOpengl)
442+
GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl)
423443
}
424444

425445
if (host == primaryHost) {
@@ -520,23 +540,13 @@ class Godot(private val context: Context) : SensorEventListener {
520540

521541
fun onResume(host: GodotHost) {
522542
Log.v(TAG, "OnResume: $host")
543+
resumed = true
523544
if (host != primaryHost) {
524545
return
525546
}
526547

527548
renderView?.onActivityResumed()
528-
if (mAccelerometer != null) {
529-
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
530-
}
531-
if (mGravity != null) {
532-
mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME)
533-
}
534-
if (mMagnetometer != null) {
535-
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME)
536-
}
537-
if (mGyroscope != null) {
538-
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME)
539-
}
549+
registerSensorsIfNeeded()
540550
if (useImmersive) {
541551
val window = requireActivity().window
542552
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
@@ -551,14 +561,34 @@ class Godot(private val context: Context) : SensorEventListener {
551561
}
552562
}
553563

564+
private fun registerSensorsIfNeeded() {
565+
if (!resumed || !godotMainLoopStarted.get()) {
566+
return
567+
}
568+
569+
if (accelerometer_enabled.get() && mAccelerometer != null) {
570+
mSensorManager.registerListener(godotInputHandler, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
571+
}
572+
if (gravity_enabled.get() && mGravity != null) {
573+
mSensorManager.registerListener(godotInputHandler, mGravity, SensorManager.SENSOR_DELAY_GAME)
574+
}
575+
if (magnetometer_enabled.get() && mMagnetometer != null) {
576+
mSensorManager.registerListener(godotInputHandler, mMagnetometer, SensorManager.SENSOR_DELAY_GAME)
577+
}
578+
if (gyroscope_enabled.get() && mGyroscope != null) {
579+
mSensorManager.registerListener(godotInputHandler, mGyroscope, SensorManager.SENSOR_DELAY_GAME)
580+
}
581+
}
582+
554583
fun onPause(host: GodotHost) {
555584
Log.v(TAG, "OnPause: $host")
585+
resumed = false
556586
if (host != primaryHost) {
557587
return
558588
}
559589

560590
renderView?.onActivityPaused()
561-
mSensorManager.unregisterListener(this)
591+
mSensorManager.unregisterListener(godotInputHandler)
562592
for (plugin in pluginRegistry.allPlugins) {
563593
plugin.onMainPause()
564594
}
@@ -659,6 +689,16 @@ class Godot(private val context: Context) : SensorEventListener {
659689
*/
660690
private fun onGodotMainLoopStarted() {
661691
Log.v(TAG, "OnGodotMainLoopStarted")
692+
godotMainLoopStarted.set(true)
693+
694+
accelerometer_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_accelerometer")))
695+
gravity_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gravity")))
696+
gyroscope_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gyroscope")))
697+
magnetometer_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_magnetometer")))
698+
699+
runOnUiThread {
700+
registerSensorsIfNeeded()
701+
}
662702

663703
for (plugin in pluginRegistry.allPlugins) {
664704
plugin.onGodotMainLoopStarted()
@@ -858,77 +898,6 @@ class Godot(private val context: Context) : SensorEventListener {
858898
}
859899
}
860900

861-
private fun getRotatedValues(values: FloatArray?): FloatArray? {
862-
if (values == null || values.size != 3) {
863-
return null
864-
}
865-
val rotatedValues = FloatArray(3)
866-
when (windowManager.defaultDisplay.rotation) {
867-
Surface.ROTATION_0 -> {
868-
rotatedValues[0] = values[0]
869-
rotatedValues[1] = values[1]
870-
rotatedValues[2] = values[2]
871-
}
872-
Surface.ROTATION_90 -> {
873-
rotatedValues[0] = -values[1]
874-
rotatedValues[1] = values[0]
875-
rotatedValues[2] = values[2]
876-
}
877-
Surface.ROTATION_180 -> {
878-
rotatedValues[0] = -values[0]
879-
rotatedValues[1] = -values[1]
880-
rotatedValues[2] = values[2]
881-
}
882-
Surface.ROTATION_270 -> {
883-
rotatedValues[0] = values[1]
884-
rotatedValues[1] = -values[0]
885-
rotatedValues[2] = values[2]
886-
}
887-
}
888-
return rotatedValues
889-
}
890-
891-
override fun onSensorChanged(event: SensorEvent) {
892-
if (renderView == null) {
893-
return
894-
}
895-
896-
val rotatedValues = getRotatedValues(event.values)
897-
898-
when (event.sensor.type) {
899-
Sensor.TYPE_ACCELEROMETER -> {
900-
rotatedValues?.let {
901-
renderView?.queueOnRenderThread {
902-
GodotLib.accelerometer(-it[0], -it[1], -it[2])
903-
}
904-
}
905-
}
906-
Sensor.TYPE_GRAVITY -> {
907-
rotatedValues?.let {
908-
renderView?.queueOnRenderThread {
909-
GodotLib.gravity(-it[0], -it[1], -it[2])
910-
}
911-
}
912-
}
913-
Sensor.TYPE_MAGNETIC_FIELD -> {
914-
rotatedValues?.let {
915-
renderView?.queueOnRenderThread {
916-
GodotLib.magnetometer(-it[0], -it[1], -it[2])
917-
}
918-
}
919-
}
920-
Sensor.TYPE_GYROSCOPE -> {
921-
rotatedValues?.let {
922-
renderView?.queueOnRenderThread {
923-
GodotLib.gyroscope(it[0], it[1], it[2])
924-
}
925-
}
926-
}
927-
}
928-
}
929-
930-
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
931-
932901
/**
933902
* Used by the native code (java_godot_wrapper.h) to vibrate the device.
934903
* @param durationMs
@@ -1063,7 +1032,7 @@ class Godot(private val context: Context) : SensorEventListener {
10631032

10641033
@Keep
10651034
private fun initInputDevices() {
1066-
renderView?.initInputDevices()
1035+
godotInputHandler.initInputDevices()
10671036
}
10681037

10691038
@Keep

0 commit comments

Comments
 (0)