From f468c0d000b439022ee9c251e57d7a3c91308eaf Mon Sep 17 00:00:00 2001 From: "Derek J. Clark" Date: Wed, 18 Dec 2024 14:11:36 -0800 Subject: [PATCH] fix(PowerStation): Get power profiles from PowerStation - Uses dbus to read the available power profiles from PowerStation - Renamed PowerTools to Performance and moved everything from the old performance menu into it. - Adds "Advanced Mode" toggle to display CPU and GPU settings. Only the power profile will be displayed when this is set to off (default). When on, power profile is forced to the highest performance profile. If PowerStation is using RyzenAdj to set TDP, "max-performance" will sett all TDP to the hardware max milit, and "power-saving" will set all TDP to the mid point between max and min. - Modify makefile to add purge and change clean. --- Makefile | 9 +- .../state/states/quick_bar_performance.tres | 8 +- assets/state/states/quick_bar_powertools.tres | 8 - ...wertools_icon.svg => performance_icon.svg} | 0 ...svg.import => performance_icon.svg.import} | 6 +- .../performance/performance_manager.gd | 54 ++- .../performance/performance_profile.gd | 8 +- .../card_ui/quick_bar/performance_card.tscn | 22 +- .../card_ui/quick_bar/power_tools_card.tscn | 29 -- core/ui/card_ui/quick_bar/quick_bar_menu.tscn | 6 +- .../card_ui_overlay_mode.gd | 24 +- core/ui/common/quick_bar/performance_menu.gd | 376 +++++++++++++++++- .../ui/common/quick_bar/performance_menu.tscn | 179 ++++++++- core/ui/common/quick_bar/powertools_menu.gd | 273 ------------- core/ui/common/quick_bar/powertools_menu.tscn | 166 -------- extensions/core/src/dbus/powerstation/tdp.rs | 2 + .../src/performance/powerstation/gpu_card.rs | 29 +- 17 files changed, 637 insertions(+), 562 deletions(-) delete mode 100644 assets/state/states/quick_bar_powertools.tres rename assets/ui/icons/{powertools_icon.svg => performance_icon.svg} (100%) rename assets/ui/icons/{powertools_icon.svg.import => performance_icon.svg.import} (73%) delete mode 100644 core/ui/card_ui/quick_bar/power_tools_card.tscn delete mode 100644 core/ui/common/quick_bar/powertools_menu.gd delete mode 100644 core/ui/common/quick_bar/powertools_menu.tscn diff --git a/Makefile b/Makefile index 599b5a22..aa70289c 100644 --- a/Makefile +++ b/Makefile @@ -167,14 +167,17 @@ $(ALL_EXTENSIONS) &: $(ALL_EXTENSION_FILES) edit: $(IMPORT_DIR) ## Open the project in the Godot editor $(GODOT) --editor . +.PHONY: purge +purge: clean ## Remove all build artifacts including engine extensions + rm -rf $(ROOTFS) + cd ./extensions && $(MAKE) clean + .PHONY: clean -clean: ## Remove build artifacts +clean: ## Remove Godot build artifacts rm -rf build - rm -rf $(ROOTFS) rm -rf $(CACHE_DIR) rm -rf dist rm -rf $(IMPORT_DIR) - cd ./extensions && $(MAKE) clean .PHONY: run run-force run: build/opengamepad-ui.x86_64 run-force ## Run the project in gamescope diff --git a/assets/state/states/quick_bar_performance.tres b/assets/state/states/quick_bar_performance.tres index 345f38ce..811d09c6 100644 --- a/assets/state/states/quick_bar_performance.tres +++ b/assets/state/states/quick_bar_performance.tres @@ -1,8 +1,8 @@ -[gd_resource type="Resource" load_steps=2 format=3 uid="uid://xw3l4h1vt0oa"] +[gd_resource type="Resource" script_class="State" load_steps=2 format=3 uid="uid://b2ruoxboq5k6e"] -[ext_resource type="Script" path="res://core/systems/state/state.gd" id="1_pmemp"] +[ext_resource type="Script" path="res://core/systems/state/state.gd" id="1_3a3in"] [resource] -script = ExtResource("1_pmemp") -name = "performance" +script = ExtResource("1_3a3in") +name = "powertools" data = null diff --git a/assets/state/states/quick_bar_powertools.tres b/assets/state/states/quick_bar_powertools.tres deleted file mode 100644 index 811d09c6..00000000 --- a/assets/state/states/quick_bar_powertools.tres +++ /dev/null @@ -1,8 +0,0 @@ -[gd_resource type="Resource" script_class="State" load_steps=2 format=3 uid="uid://b2ruoxboq5k6e"] - -[ext_resource type="Script" path="res://core/systems/state/state.gd" id="1_3a3in"] - -[resource] -script = ExtResource("1_3a3in") -name = "powertools" -data = null diff --git a/assets/ui/icons/powertools_icon.svg b/assets/ui/icons/performance_icon.svg similarity index 100% rename from assets/ui/icons/powertools_icon.svg rename to assets/ui/icons/performance_icon.svg diff --git a/assets/ui/icons/powertools_icon.svg.import b/assets/ui/icons/performance_icon.svg.import similarity index 73% rename from assets/ui/icons/powertools_icon.svg.import rename to assets/ui/icons/performance_icon.svg.import index 360126d2..2dd445a6 100644 --- a/assets/ui/icons/powertools_icon.svg.import +++ b/assets/ui/icons/performance_icon.svg.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cqy34r7oni6d4" -path="res://.godot/imported/powertools_icon.svg-652cf7833e5f111e096aaec7055e1d3a.ctex" +path="res://.godot/imported/performance_icon.svg-5082e7fb3c41a1711d81bab95097ecfa.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/ui/icons/powertools_icon.svg" -dest_files=["res://.godot/imported/powertools_icon.svg-652cf7833e5f111e096aaec7055e1d3a.ctex"] +source_file="res://assets/ui/icons/performance_icon.svg" +dest_files=["res://.godot/imported/performance_icon.svg-5082e7fb3c41a1711d81bab95097ecfa.ctex"] [params] diff --git a/core/systems/performance/performance_manager.gd b/core/systems/performance/performance_manager.gd index 648456b5..2660d103 100644 --- a/core/systems/performance/performance_manager.gd +++ b/core/systems/performance/performance_manager.gd @@ -117,13 +117,16 @@ func create_profile(library_item: LibraryLaunchItem = null) -> PerformanceProfil for card in cards: if card.class != "integrated": continue - - profile.tdp_current = card.tdp - profile.tdp_boost_current = card.boost + if _hardware_manager.gpu: + profile.tdp_current = round(_hardware_manager.gpu.tdp_max) + profile.tdp_boost_current = round(_hardware_manager.gpu.max_boost) + else: + profile.tdp_current = card.tdp + profile.tdp_boost_current = card.boost profile.gpu_freq_min_current = card.clock_value_mhz_min profile.gpu_freq_max_current = card.clock_value_mhz_max profile.gpu_manual_enabled = card.manual_clock - #profile.gpu_power_profile = card.power_profile # TODO: Fix this + profile.gpu_power_profile = card.power_profile profile.gpu_temp_current = card.thermal_throttle_limit_c logger.debug("Created performance profile: " + profile.name) @@ -177,23 +180,12 @@ func apply_profile(profile: PerformanceProfile) -> void: if card.class != "integrated": continue logger.debug("Applying GPU performance settings from profile") - if profile.gpu_power_profile >= 0: - var power_profile := "max-performance" - if profile.gpu_power_profile == 0: - power_profile = "max-performance" - if profile.gpu_power_profile == 1: - power_profile = "power-saving" - if card.power_profile != power_profile: - logger.debug("Applying Power Profile: " + power_profile) - card.power_profile = power_profile + if card.power_profile != profile.gpu_power_profile: + logger.debug("Applying Power Profile: " + profile.gpu_power_profile) + card.power_profile = profile.gpu_power_profile if card.manual_clock != profile.gpu_manual_enabled: + logger.debug("Applying Manual Clock Enabled: " + str(profile.gpu_manual_enabled)) card.manual_clock = profile.gpu_manual_enabled - if profile.tdp_current > 0 and card.tdp != profile.tdp_current: - logger.debug("Applying TDP: " + str(profile.tdp_current)) - card.tdp = profile.tdp_current - if profile.tdp_boost_current > 0 and card.boost != profile.tdp_boost_current: - logger.debug("Applying TDP Boost: " + str(profile.tdp_boost_current)) - card.boost = profile.tdp_boost_current if profile.gpu_freq_min_current > 0 and card.clock_value_mhz_min != profile.gpu_freq_min_current: logger.debug("Applying Clock Freq Min: " + str(profile.gpu_freq_min_current)) card.clock_value_mhz_min = profile.gpu_freq_min_current @@ -204,6 +196,15 @@ func apply_profile(profile: PerformanceProfile) -> void: logger.debug("Applying Thermal Throttle Limit: " + str(profile.gpu_temp_current)) card.thermal_throttle_limit_c = profile.gpu_temp_current + # Only apply GPU TDP settings from the given profile if we're in a mode that supports it + if profile.advanced_mode or "max-performance" in get_power_profiles_available(): + if profile.tdp_current > 0 and card.tdp != profile.tdp_current: + logger.debug("Applying TDP: " + str(profile.tdp_current)) + card.tdp = profile.tdp_current + if profile.tdp_boost_current > 0 and card.boost != profile.tdp_boost_current: + logger.debug("Applying TDP Boost: " + str(profile.tdp_boost_current)) + card.boost = profile.tdp_boost_current + # Apply CPU settings from the given profile if _power_station.cpu: logger.debug("Applying CPU performance settings from profile") @@ -299,3 +300,18 @@ func _on_app_switched(_from: RunningApp, to: RunningApp) -> void: current_profile = profile profile_loaded.emit(profile) apply_profile(profile) + + +# Get the currently available power profiles +func get_power_profiles_available() -> PackedStringArray: + # Detect all GPU cards + var cards: Array[GpuCard] = [] + if _power_station.gpu: + cards = _power_station.gpu.get_cards() + + for card in cards: + if card.class != "integrated": + continue + + return card.power_profiles_available + return [] diff --git a/core/systems/performance/performance_profile.gd b/core/systems/performance/performance_profile.gd index 9fe0d444..76e80c79 100644 --- a/core/systems/performance/performance_profile.gd +++ b/core/systems/performance/performance_profile.gd @@ -10,11 +10,12 @@ class_name PerformanceProfile @export var gpu_freq_max_current: float @export var gpu_freq_min_current: float @export var gpu_manual_enabled: bool -@export var gpu_power_profile: int +@export var gpu_power_profile: String @export var gpu_temp_current: float @export var tdp_boost_current: float @export var tdp_current: float @export var thermal_profile: int +@export var advanced_mode: bool = false func _to_string() -> String: @@ -25,8 +26,9 @@ func _to_string() -> String: + "gpu_freq_max_current: " + str(gpu_freq_max_current) + ", " \ + "gpu_freq_min_current: " + str(gpu_freq_min_current) + ", " \ + "gpu_manual_enabled: " + str(gpu_manual_enabled) + ", " \ - + "gpu_power_profile: " + str(gpu_power_profile) + ", " \ + + "gpu_power_profile: " + gpu_power_profile + ", " \ + "gpu_temp_current: " + str(gpu_temp_current) + ", " \ + "tdp_boost_current: " + str(tdp_boost_current) + ", " \ + "tdp_current: " + str(tdp_current) + ", " \ - + "thermal_profile: " + str(thermal_profile) + ">" + + "thermal_profile: " + str(thermal_profile) + ", " \ + + "advanced_mode:" + str(advanced_mode) + ">" diff --git a/core/ui/card_ui/quick_bar/performance_card.tscn b/core/ui/card_ui/quick_bar/performance_card.tscn index 2e3c31f4..10c2e8a4 100644 --- a/core/ui/card_ui/quick_bar/performance_card.tscn +++ b/core/ui/card_ui/quick_bar/performance_card.tscn @@ -1,28 +1,14 @@ -[gd_scene load_steps=5 format=3 uid="uid://dycb7m0oj13ly"] +[gd_scene load_steps=3 format=3 uid="uid://dycb7m0oj13ly"] [ext_resource type="PackedScene" uid="uid://b5xnora73yd8x" path="res://core/ui/card_ui/quick_bar/qb_card.tscn" id="1_77cql"] -[ext_resource type="PackedScene" uid="uid://b7piua3snox4i" path="res://core/ui/common/quick_bar/performance_menu.tscn" id="2_k3j2r"] - -[sub_resource type="Image" id="Image_asnwl"] -data = { -"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), -"format": "RGBA8", -"height": 16, -"mipmaps": false, -"width": 16 -} - -[sub_resource type="ImageTexture" id="ImageTexture_adlkc"] -image = SubResource("Image_asnwl") +[ext_resource type="PackedScene" uid="uid://dv3dt0j3jketh" path="res://core/ui/common/quick_bar/performance_menu.tscn" id="3_e67l3"] [node name="PerformanceCard" instance=ExtResource("1_77cql")] title = "Performance" -[node name="HighlightTexture" parent="." index="4"] -texture = SubResource("ImageTexture_adlkc") - [node name="SectionLabel" parent="MarginContainer/CardVBoxContainer" index="0"] text = "Performance" -[node name="PerformanceMenu" parent="MarginContainer/CardVBoxContainer/ContentContainer" index="0" instance=ExtResource("2_k3j2r")] +[node name="Performance" parent="MarginContainer/CardVBoxContainer/ContentContainer" index="0" instance=ExtResource("3_e67l3")] layout_mode = 2 +size_flags_vertical = 0 diff --git a/core/ui/card_ui/quick_bar/power_tools_card.tscn b/core/ui/card_ui/quick_bar/power_tools_card.tscn deleted file mode 100644 index 212044ac..00000000 --- a/core/ui/card_ui/quick_bar/power_tools_card.tscn +++ /dev/null @@ -1,29 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://v751ima8r8vg"] - -[ext_resource type="PackedScene" uid="uid://b5xnora73yd8x" path="res://core/ui/card_ui/quick_bar/qb_card.tscn" id="1_6lv34"] -[ext_resource type="PackedScene" uid="uid://dv3dt0j3jketh" path="res://core/ui/common/quick_bar/powertools_menu.tscn" id="2_votl1"] - -[sub_resource type="Image" id="Image_c7ewe"] -data = { -"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), -"format": "RGBA8", -"height": 16, -"mipmaps": false, -"width": 16 -} - -[sub_resource type="ImageTexture" id="ImageTexture_ca0vc"] -image = SubResource("Image_c7ewe") - -[node name="PowerToolsCard" instance=ExtResource("1_6lv34")] -title = "Power Tools" - -[node name="HighlightTexture" parent="PanelContainer" index="0"] -texture = SubResource("ImageTexture_ca0vc") - -[node name="SectionLabel" parent="MarginContainer/CardVBoxContainer" index="0"] -text = "Power Tools" - -[node name="PowerTools" parent="MarginContainer/CardVBoxContainer/ContentContainer" index="0" instance=ExtResource("2_votl1")] -layout_mode = 2 -size_flags_vertical = 0 diff --git a/core/ui/card_ui/quick_bar/quick_bar_menu.tscn b/core/ui/card_ui/quick_bar/quick_bar_menu.tscn index f601892c..4978e0a0 100644 --- a/core/ui/card_ui/quick_bar/quick_bar_menu.tscn +++ b/core/ui/card_ui/quick_bar/quick_bar_menu.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=31 format=3 uid="uid://hroo3ll4inrb"] +[gd_scene load_steps=30 format=3 uid="uid://hroo3ll4inrb"] [ext_resource type="Script" path="res://core/ui/card_ui/quick_bar/quick_bar_menu.gd" id="1_56jo7"] [ext_resource type="PackedScene" uid="uid://shvyhrv5sx3v" path="res://core/systems/state/state_watcher.tscn" id="2_6rvrx"] @@ -29,7 +29,6 @@ [ext_resource type="PackedScene" uid="uid://bjy50kdrebgre" path="res://core/ui/card_ui/quick_bar/notifications_card.tscn" id="19_pppbi"] [ext_resource type="PackedScene" uid="uid://dxaeufuk7ump2" path="res://core/ui/card_ui/quick_bar/quick_settings_card.tscn" id="20_17ks0"] [ext_resource type="PackedScene" uid="uid://dycb7m0oj13ly" path="res://core/ui/card_ui/quick_bar/performance_card.tscn" id="21_uw510"] -[ext_resource type="PackedScene" uid="uid://v751ima8r8vg" path="res://core/ui/card_ui/quick_bar/power_tools_card.tscn" id="22_dtanu"] [node name="QuickBarMenu" type="Control" groups=["quick-bar"]] z_index = 20 @@ -236,6 +235,3 @@ layout_mode = 2 [node name="PerformanceCard" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/ScrollContainer/Viewport" instance=ExtResource("21_uw510")] layout_mode = 2 - -[node name="PowerToolsCard" parent="MarginContainer/PanelContainer/MarginContainer/VBoxContainer/ScrollContainer/Viewport" instance=ExtResource("22_dtanu")] -layout_mode = 2 diff --git a/core/ui/card_ui_overlay_mode/card_ui_overlay_mode.gd b/core/ui/card_ui_overlay_mode/card_ui_overlay_mode.gd index 252bff2e..c283d7fc 100644 --- a/core/ui/card_ui_overlay_mode/card_ui_overlay_mode.gd +++ b/core/ui/card_ui_overlay_mode/card_ui_overlay_mode.gd @@ -38,6 +38,27 @@ var underlay_window_id: int @onready var quick_bar_menu := $%QuickBarMenu @onready var settings_menu := $%SettingsMenu +# Constants + +const remove_list: PackedStringArray = [ + "KeyboardButton", + "NotifyButton", + "HelpButton", + "VolumeSlider", + "BrightnessSlider", + "PerGameToggle", + "MangoAppSlider", + "FramerateLimitSlider", + "RefreshRateSlider" + ] + +const settings_remove_list: PackedStringArray = [ + "LibraryButton", + "NetworkButton", + "BluetoothButton", + "AudioButton" + ] + # Logger var logger := Log.get_logger("Main", Log.LEVEL.INFO) @@ -164,9 +185,8 @@ func _setup_overlay_mode(args: PackedStringArray) -> void: _start_underlay_process(args, log_path) # Remove unneeded/conflicting elements from default menues - var remove_list: PackedStringArray = ["PerformanceCard", "KeyboardButton", "NotifyButton", "HelpButton", "VolumeSlider", "BrightnessSlider", "PerGameToggle"] + _remove_children(remove_list, quick_bar_menu) - var settings_remove_list: PackedStringArray = ["LibraryButton", "NetworkButton", "BluetoothButton", "AudioButton"] _remove_children(settings_remove_list, settings_menu) # Setup inputplumber to receive guide presses. diff --git a/core/ui/common/quick_bar/performance_menu.gd b/core/ui/common/quick_bar/performance_menu.gd index f0530478..9f6b9dd9 100644 --- a/core/ui/common/quick_bar/performance_menu.gd +++ b/core/ui/common/quick_bar/performance_menu.gd @@ -1,13 +1,299 @@ -extends Control +extends VBoxContainer -var logger := Log.get_logger("PerformanceMenu", Log.LEVEL.INFO) +var _hardware_manager := load("res://core/systems/hardware/hardware_manager.tres") as HardwareManager +var _platform := load("res://core/global/platform.tres") as Platform +var _performance_manager := load("res://core/systems/performance/performance_manager.tres") as PerformanceManager +var _power_station := load("res://core/systems/performance/power_station.tres") as PowerStationInstance +var _profiles_available: PackedStringArray -@onready var mangoapp_slider := $%MangoAppSlider +@onready var cpu_boost_button := $CPUBoostButton as Toggle +@onready var cpu_cores_slider := $CPUCoresSlider as ValueSlider +@onready var gpu_freq_enable := $GPUFreqButton as Toggle +@onready var gpu_freq_max_slider := $GPUFreqMaxSlider as ValueSlider +@onready var gpu_freq_min_slider := $GPUFreqMinSlider as ValueSlider +@onready var gpu_temp_slider := $GPUTempSlider as ValueSlider +@onready var power_profile_dropdown := $PowerProfileDropdown as Dropdown +@onready var tdp_boost_slider := $TDPBoostSlider as ValueSlider +@onready var tdp_slider := $TDPSlider as ValueSlider +@onready var smt_button := $SMTButton as Toggle +@onready var cpu_label := $CPUSectionLabel as Control +@onready var gpu_label := $GPUSectionLabel as Control +@onready var wait_label := $WaitLabel as Control +@onready var service_timer := $ServiceTimer as Timer +@onready var apply_timer := $ApplyTimer as Timer +@onready var mangoapp_slider := $%MangoAppSlider as ValueSlider +@onready var mode_toggle := $%ModeToggle as Toggle + +var _power_station_running := false +var _profile_loading := false +var _current_profile: PerformanceProfile +var logger := Log.get_logger("Performance", Log.LEVEL.INFO) # Called when the node enters the scene tree for the first time. +# Finds default values and current settings of the hardware. func _ready() -> void: + # Setup dropdowns + var i := 0 + _get_available_profiles() + power_profile_dropdown.clear() + for profile in _profiles_available: + power_profile_dropdown.add_item(profile, i) + i += 1 + + # Configure the interface + _on_profile_loaded(_performance_manager.current_profile) + + _performance_manager.profile_loaded.connect(_on_profile_loaded) mangoapp_slider.value_changed.connect(_on_mangoapp_changed) + mode_toggle.toggled.connect(_on_mode_toggled) + + service_timer.timeout.connect(_on_service_timer_timeout) + apply_timer.timeout.connect(_on_apply_timer_timeout) + + # Re-start the apply timer when changes happen + var on_changed := func() -> void: + if _profile_loading: + return + apply_timer.start() + cpu_boost_button.pressed.connect(on_changed) + smt_button.pressed.connect(on_changed) + gpu_freq_enable.pressed.connect(on_changed) + mode_toggle.pressed.connect(on_changed) + + # Set the total number of available cores if the SMT button is pressed + var on_smt_pressed := func() -> void: + if not _hardware_manager.cpu: + return + var cpu := _hardware_manager.cpu + if smt_button.button_pressed: + cpu_cores_slider.max_value = cpu.core_count + else: + var cores := cpu.core_count / 2 + if cpu_cores_slider.value > cores: + cpu_cores_slider.value = cores + cpu_cores_slider.max_value = cores + smt_button.pressed.connect(on_smt_pressed) + + # Restart the timer when any slider changes happen + var on_slider_changed := func(_value) -> void: + if _profile_loading: + return + apply_timer.start() + cpu_cores_slider.value_changed.connect(on_slider_changed) + tdp_slider.value_changed.connect(on_slider_changed) + tdp_boost_slider.value_changed.connect(on_slider_changed) + gpu_freq_min_slider.value_changed.connect(on_slider_changed) + gpu_freq_max_slider.value_changed.connect(on_slider_changed) + gpu_temp_slider.value_changed.connect(on_slider_changed) + + # Configure GPU frequency timers so the minimum value can never go higher + # than the maximum value slider and the maximum value can never go lower + # than the minimum value slider. + var on_gpu_freq_changed := func(_value: float, kind: String) -> void: + if kind == "min" and gpu_freq_min_slider.value > gpu_freq_max_slider.value: + gpu_freq_max_slider.value = gpu_freq_min_slider.value + return + if kind == "max" and gpu_freq_max_slider.value < gpu_freq_min_slider.value: + gpu_freq_min_slider.value = gpu_freq_max_slider.value + return + gpu_freq_min_slider.value_changed.connect(on_gpu_freq_changed.bind("min")) + gpu_freq_max_slider.value_changed.connect(on_gpu_freq_changed.bind("max")) + + # Also restart the apply timer when dropdown changes happen + var on_dropdown_changed := func(index) -> void: + if _profile_loading: + return + + var new_profile: PerformanceProfile + if _profiles_available[index] == "power-saving": + new_profile = _create_powersaving_profile() + elif _profiles_available[index] == "max-performance": + new_profile = _create_performance_profile(false) + + if new_profile: + _on_profile_loaded(new_profile) + _performance_manager.apply_and_save_profile(_current_profile) + else: + apply_timer.start() + power_profile_dropdown.item_selected.connect(on_dropdown_changed) + + # Toggle visibility when the GPU freq manual toggle is on + var on_manual_freq := func() -> void: + # Immediately apply manual GPU frequency so we can read the min/max + # values for the sliders + var card := _get_integrated_card() + if not card: + logger.warn("No integrated GPU to set manual frequency on!") + return + card.manual_clock = gpu_freq_enable.button_pressed + + # Update the slider values with the current values + gpu_freq_min_slider.visible = gpu_freq_enable.button_pressed + gpu_freq_min_slider.min_value = round(card.clock_limit_mhz_min) + gpu_freq_min_slider.max_value = round(card.clock_limit_mhz_max) + gpu_freq_min_slider.value = round(card.clock_value_mhz_min) + gpu_freq_max_slider.visible = gpu_freq_enable.button_pressed + gpu_freq_max_slider.min_value = round(card.clock_limit_mhz_min) + gpu_freq_max_slider.max_value = round(card.clock_limit_mhz_max) + gpu_freq_max_slider.value = round(card.clock_value_mhz_max) + gpu_freq_enable.pressed.connect(on_manual_freq) + + +# Triggers when the apply timer times out. The apply timer will start/restart +# whenever the user makes a change to any item. When the timer runs out, it will +# call this to apply the current profile. +func _on_apply_timer_timeout() -> void: + if not _current_profile: + logger.debug("No loaded profile to apply") + return + logger.debug("Applying and saving profile") + + # Update the profile based on the currently set values + var power_profile := _profiles_available[power_profile_dropdown.selected] + _current_profile.gpu_power_profile = power_profile + _current_profile.cpu_boost_enabled = cpu_boost_button.button_pressed + _current_profile.cpu_smt_enabled = smt_button.button_pressed + _current_profile.cpu_core_count_current = int(cpu_cores_slider.value) + _current_profile.tdp_current = tdp_slider.value + _current_profile.tdp_boost_current = tdp_boost_slider.value + _current_profile.gpu_manual_enabled = gpu_freq_enable.button_pressed + _current_profile.gpu_freq_min_current = gpu_freq_min_slider.value + _current_profile.gpu_freq_max_current = gpu_freq_max_slider.value + _current_profile.gpu_temp_current = gpu_temp_slider.value + _current_profile.advanced_mode = mode_toggle.button_pressed + + _performance_manager.apply_and_save_profile(_current_profile) + + +# Triggers every timeout to monitor the PowerStation DBus +func _on_service_timer_timeout() -> void: + var bus_running := _power_station.is_running() + if bus_running == _power_station_running: + return + + # If the state of powerstation changes, update the interface accordingly + _power_station_running = bus_running + _setup_interface() + + +## Called when a performance profile is loaded +func _on_profile_loaded(profile: PerformanceProfile) -> void: + if not _power_station.is_running(): + logger.info("Unable to load performance profile. PowerStation not detected.") + return + var core_count := 1 + if _hardware_manager.cpu: + core_count = _hardware_manager.cpu.core_count + + logger.debug("Updating UI with loaded performance profile") + # Keep track of the currently loaded profile + _current_profile = profile + + # Update UI components based on the loaded profile + _profile_loading = true + var idx := _profiles_available.find(profile.gpu_power_profile) + if idx > -1: + power_profile_dropdown.select(idx) + _setup_interface() + + cpu_boost_button.button_pressed = profile.cpu_boost_enabled + smt_button.button_pressed = profile.cpu_smt_enabled + if smt_button.button_pressed: + cpu_cores_slider.max_value = core_count + else: + var cores := core_count / 2 + if cpu_cores_slider.value > cores: + cpu_cores_slider.value = cores + cpu_cores_slider.max_value = cores + cpu_cores_slider.value = round(profile.cpu_core_count_current) + + # Update GPU UI components + tdp_slider.value = round(profile.tdp_current) + tdp_boost_slider.value = round(profile.tdp_boost_current) + gpu_freq_enable.button_pressed = profile.gpu_manual_enabled + gpu_freq_enable.pressed.emit() + gpu_freq_min_slider.value = round(profile.gpu_freq_min_current) + gpu_freq_max_slider.value = round(profile.gpu_freq_max_current) + gpu_temp_slider.value = round(profile.gpu_temp_current) + + mode_toggle.button_pressed = profile.advanced_mode + + _profile_loading = false + + +# Configure the min/max values and visibility based on detected performance +# features. +func _setup_interface() -> void: + # If powerstation is not running, hide everything + if not _power_station.is_running(): + wait_label.visible = true + for node in get_children(): + if node == wait_label: + continue + if node == Control: + (node as Control).visible = false + return + + # Configure visibility for all components + wait_label.visible = false + + var is_advanced := mode_toggle.button_pressed + + # Configure CPU components + if _power_station.cpu: + var cpu := _power_station.cpu + cpu_label.visible = is_advanced + cpu_boost_button.visible = cpu.has_feature("cpb") and is_advanced + smt_button.visible = cpu.has_feature("ht") and is_advanced + if cpu.smt_enabled: + cpu_cores_slider.max_value = cpu.cores_count + else: + cpu_cores_slider.max_value = cpu.cores_count / 2 + cpu_cores_slider.visible = is_advanced + + # Configure GPU components + if not _power_station.gpu: + return + var card := _get_integrated_card() + + # Configure based on integrated graphics card + if not card: + return + + gpu_label.visible = is_advanced + + tdp_slider.visible = is_advanced + tdp_slider.min_value = round(_hardware_manager.gpu.tdp_min) + tdp_slider.max_value = round(_hardware_manager.gpu.tdp_max) + + tdp_boost_slider.visible = is_advanced + tdp_boost_slider.max_value = round(_hardware_manager.gpu.max_boost) + + gpu_freq_enable.visible = is_advanced + + power_profile_dropdown.visible = not is_advanced + + gpu_freq_min_slider.visible = card.manual_clock and is_advanced + gpu_freq_min_slider.min_value = round(card.clock_limit_mhz_min) + gpu_freq_min_slider.max_value = round(card.clock_limit_mhz_max) + + gpu_freq_max_slider.visible = card.manual_clock and is_advanced + gpu_freq_max_slider.min_value = round(card.clock_limit_mhz_min) + gpu_freq_max_slider.max_value = round(card.clock_limit_mhz_max) + + gpu_temp_slider.visible = is_advanced + + +## Returns the primary integrated GPU instance +func _get_integrated_card() -> GpuCard: + var card: GpuCard + var cards := _power_station.gpu.get_cards() + for c in cards: + if c.class != "integrated": + continue + card = c + return card # Set the mangoapp config on slider change @@ -27,3 +313,87 @@ func _on_mangoapp_changed(value: float) -> void: if value >= 4: MangoApp.set_config(MangoApp.CONFIG_INSANE) return + + +func _create_performance_profile(is_advanced: bool) -> PerformanceProfile: + var new_profile := PerformanceProfile.new() + + # CPU Settings + new_profile.cpu_boost_enabled = true + new_profile.cpu_core_count_current = cpu_cores_slider.max_value + new_profile.cpu_smt_enabled = true + + # GPU Settings + var profiles := _performance_manager.get_power_profiles_available() as PackedStringArray + if profiles.is_empty(): + logger.error("No _platform profiles available. Unable to assume sane performance defaults.") + return null + if "custom" in profiles: + profiles.remove_at(profiles.find("custom")) + if not "max-performance" in profiles and not "performance" in profiles: + logger.error("Performance profile not found. Unable to assume sane performance defaults.") + return null + var profile_idx := profiles.find("max-performance") + if profile_idx == -1: + profile_idx = profiles.find("performance") + if profile_idx == -1: + logger.error("Performance profile not found. Unable to assume sane performance defaults.") + return null + new_profile.gpu_power_profile = profiles[profile_idx] + new_profile.gpu_freq_max_current = gpu_freq_max_slider.max_value + new_profile.gpu_freq_min_current = gpu_freq_min_slider.min_value + new_profile.gpu_manual_enabled = false + new_profile.gpu_temp_current = 95 + new_profile.tdp_boost_current = tdp_boost_slider.max_value + new_profile.tdp_current = tdp_slider.max_value + new_profile.advanced_mode = is_advanced + return new_profile + + +func _create_powersaving_profile() -> PerformanceProfile: + var new_profile := PerformanceProfile.new() + + # CPU Settings + new_profile.cpu_boost_enabled = true + new_profile.cpu_core_count_current = cpu_cores_slider.max_value + new_profile.cpu_smt_enabled = true + + # GPU Settings + _get_available_profiles() + + if _profiles_available.is_empty(): + logger.error("No _platform profiles available. Unable to assume sane performance defaults.") + return null + if not "power-saving" in _profiles_available: + logger.error("Power Saving profile not found. Unable to assume sane performance defaults.") + return null + var profile_idx := _profiles_available.find("power-saving") + if profile_idx == -1: + logger.error("Performance profile not found. Unable to assume sane performance defaults.") + return null + + new_profile.gpu_power_profile = _profiles_available[profile_idx] + new_profile.gpu_freq_max_current = gpu_freq_max_slider.max_value + new_profile.gpu_freq_min_current = gpu_freq_min_slider.min_value + new_profile.gpu_manual_enabled = false + new_profile.gpu_temp_current = 95 + var tdp_boost_mid = ((tdp_boost_slider.max_value - tdp_boost_slider.min_value) / 2) + tdp_boost_slider.min_value + new_profile.tdp_boost_current = tdp_boost_mid + var tdp_mid = ((tdp_slider.max_value - tdp_slider.min_value) / 2) + tdp_slider.min_value + new_profile.tdp_current = tdp_mid + new_profile.advanced_mode = false + return new_profile + + +# Get +func _get_available_profiles() -> void: + _profiles_available = _performance_manager.get_power_profiles_available() + if "custom" in _profiles_available: + var idx = _profiles_available.find("custom") + _profiles_available.remove_at(idx) + + +# Adjust the available options based on the mode toggle +func _on_mode_toggled(pressed: bool) -> void: + var new_profile := _create_performance_profile(pressed) + _on_profile_loaded(new_profile) diff --git a/core/ui/common/quick_bar/performance_menu.tscn b/core/ui/common/quick_bar/performance_menu.tscn index cfa5e66d..2e0b0d2c 100644 --- a/core/ui/common/quick_bar/performance_menu.tscn +++ b/core/ui/common/quick_bar/performance_menu.tscn @@ -1,46 +1,183 @@ -[gd_scene load_steps=5 format=3 uid="uid://b7piua3snox4i"] +[gd_scene load_steps=9 format=3 uid="uid://dv3dt0j3jketh"] [ext_resource type="Script" path="res://core/ui/common/quick_bar/performance_menu.gd" id="1_r31yj"] [ext_resource type="PackedScene" uid="uid://cemxrvvjgm4g" path="res://core/ui/components/slider.tscn" id="1_yptsc"] [ext_resource type="PackedScene" uid="uid://8m20p2s0v5gb" path="res://core/systems/input/focus_group.tscn" id="2_my16i"] [ext_resource type="Resource" uid="uid://dpc1o781f43ef" path="res://core/ui/card_ui/quick_bar/quick_bar_menu_focus.tres" id="3_hsr7n"] +[ext_resource type="PackedScene" uid="uid://d0u3rsa5qpj57" path="res://core/ui/components/subsection_label.tscn" id="5_hil7p"] +[ext_resource type="PackedScene" uid="uid://dithv38oqgy58" path="res://core/ui/components/section_label.tscn" id="6_ycrnf"] +[ext_resource type="PackedScene" uid="uid://d1qb7euwlu7bh" path="res://core/ui/components/toggle.tscn" id="7_j02ci"] +[ext_resource type="PackedScene" uid="uid://xei5afwefxud" path="res://core/ui/components/dropdown.tscn" id="8_j2331"] -[node name="PerformanceMenu" type="Control"] -layout_mode = 3 -anchors_preset = 15 +[node name="Performance" type="VBoxContainer"] +anchors_preset = 10 anchor_right = 1.0 -anchor_bottom = 1.0 +offset_bottom = 28.0 grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 script = ExtResource("1_r31yj") -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="FocusGroup" parent="VBoxContainer" node_paths=PackedStringArray("current_focus") instance=ExtResource("2_my16i")] -current_focus = NodePath("../MangoAppSlider") +[node name="FocusGroup" parent="." instance=ExtResource("2_my16i")] focus_stack = ExtResource("3_hsr7n") -[node name="MangoAppSlider" parent="VBoxContainer" instance=ExtResource("1_yptsc")] +[node name="ApplyTimer" type="Timer" parent="."] +wait_time = 1.5 +one_shot = true + +[node name="ServiceTimer" type="Timer" parent="."] +wait_time = 5.0 +autostart = true + +[node name="MangoAppSlider" parent="." instance=ExtResource("1_yptsc")] unique_name_in_owner = true layout_mode = 2 text = "Performance Overlay" max_value = 4.0 tick_count = 5 -[node name="FramerateLimitSlider" parent="VBoxContainer" instance=ExtResource("1_yptsc")] +[node name="FramerateLimitSlider" parent="." instance=ExtResource("1_yptsc")] visible = false layout_mode = 2 text = "FPS Limit" -[node name="RefreshRateSlider" parent="VBoxContainer" instance=ExtResource("1_yptsc")] +[node name="RefreshRateSlider" parent="." instance=ExtResource("1_yptsc")] visible = false layout_mode = 2 text = "Refresh Rate" + +[node name="ModeToggle" parent="." instance=ExtResource("7_j02ci")] +unique_name_in_owner = true +layout_mode = 2 +text = "Advanced Mode" +button_pressed = true + +[node name="WaitLabel" parent="." instance=ExtResource("5_hil7p")] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +text = "Waiting for PowerStation service..." +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 3 + +[node name="CPUSectionLabel" parent="." instance=ExtResource("6_ycrnf")] +visible = false +layout_mode = 2 +text = "CPU Settings" + +[node name="CPUBoostButton" parent="." instance=ExtResource("7_j02ci")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../GPUTempSlider") +focus_neighbor_top = NodePath("../GPUTempSlider") +focus_neighbor_right = NodePath("../SMTButton") +focus_neighbor_bottom = NodePath("../SMTButton") +focus_next = NodePath("../SMTButton") +focus_previous = NodePath("../GPUTempSlider") +text = "CPU Boost" +separator_visible = false + +[node name="SMTButton" parent="." instance=ExtResource("7_j02ci")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../CPUBoostButton") +focus_neighbor_top = NodePath("../CPUBoostButton") +focus_neighbor_right = NodePath("../CPUCoresSlider") +focus_neighbor_bottom = NodePath("../CPUCoresSlider") +focus_next = NodePath("../CPUCoresSlider") +focus_previous = NodePath("../CPUBoostButton") +text = "SMT Enabled" +separator_visible = false + +[node name="CPUCoresSlider" parent="." instance=ExtResource("1_yptsc")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../SMTButton") +focus_neighbor_top = NodePath("../SMTButton") +focus_neighbor_right = NodePath("../TDPSlider") +focus_neighbor_bottom = NodePath("../TDPSlider") +focus_next = NodePath("../TDPSlider") +focus_previous = NodePath("../SMTButton") +text = "CPU Cores" +value = 1.0 +max_value = 1.0 +min_value = 1.0 + +[node name="GPUSectionLabel" parent="." instance=ExtResource("6_ycrnf")] +visible = false +layout_mode = 2 +text = "GPU Settings" + +[node name="TDPSlider" parent="." instance=ExtResource("1_yptsc")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../CPUCoresSlider") +focus_neighbor_top = NodePath("../CPUCoresSlider") +focus_neighbor_right = NodePath("../TDPBoostSlider") +focus_neighbor_bottom = NodePath("../TDPBoostSlider") +focus_next = NodePath("../TDPBoostSlider") +focus_previous = NodePath("../CPUCoresSlider") +text = "TDP" +max_value = 0.0 + +[node name="TDPBoostSlider" parent="." instance=ExtResource("1_yptsc")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../TDPSlider") +focus_neighbor_top = NodePath("../TDPSlider") +focus_previous = NodePath("../TDPSlider") +text = "TDP Boost" +max_value = 0.0 + +[node name="GPUFreqButton" parent="." instance=ExtResource("7_j02ci")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../TDPBoostSlider") +focus_neighbor_top = NodePath("../TDPBoostSlider") +focus_neighbor_right = NodePath("../GPUFreqMinSlider") +focus_neighbor_bottom = NodePath("../GPUFreqMinSlider") +focus_next = NodePath("../GPUFreqMinSlider") +focus_previous = NodePath("../TDPBoostSlider") +text = "Manual Freq" +separator_visible = false + +[node name="GPUFreqMinSlider" parent="." instance=ExtResource("1_yptsc")] +visible = false +layout_mode = 2 +focus_neighbor_right = NodePath("../GPUFreqMaxSlider") +focus_neighbor_bottom = NodePath("../GPUFreqMaxSlider") +focus_next = NodePath("../GPUFreqMaxSlider") +text = "Min Freq" +max_value = 0.0 +step = 100.0 + +[node name="GPUFreqMaxSlider" parent="." instance=ExtResource("1_yptsc")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../GPUFreqMinSlider") +focus_neighbor_top = NodePath("../GPUFreqMinSlider") +focus_neighbor_right = NodePath("../GPUTempSlider") +focus_neighbor_bottom = NodePath("../GPUTempSlider") +focus_next = NodePath("../GPUTempSlider") +focus_previous = NodePath("../GPUFreqMinSlider") +text = "Max Freq" +max_value = 0.0 +step = 100.0 + +[node name="GPUTempSlider" parent="." instance=ExtResource("1_yptsc")] +visible = false +layout_mode = 2 +focus_neighbor_left = NodePath("../GPUFreqMaxSlider") +focus_neighbor_top = NodePath("../GPUFreqMaxSlider") +focus_neighbor_right = NodePath("../CPUBoostButton") +focus_neighbor_bottom = NodePath("../CPUBoostButton") +focus_next = NodePath("../CPUBoostButton") +focus_previous = NodePath("../GPUFreqMaxSlider") +text = "GPU Temp Limit" +value = 70.0 +max_value = 105.0 +min_value = 70.0 + +[node name="PowerProfileDropdown" parent="." instance=ExtResource("8_j2331")] +visible = false +layout_mode = 2 +title = "Power Profile" +description = "" diff --git a/core/ui/common/quick_bar/powertools_menu.gd b/core/ui/common/quick_bar/powertools_menu.gd deleted file mode 100644 index 5123d52a..00000000 --- a/core/ui/common/quick_bar/powertools_menu.gd +++ /dev/null @@ -1,273 +0,0 @@ -extends VBoxContainer - -var hardware_manager := load("res://core/systems/hardware/hardware_manager.tres") as HardwareManager -var platform := load("res://core/global/platform.tres") as Platform -var performance_manager := load("res://core/systems/performance/performance_manager.tres") as PerformanceManager -var power_station := load("res://core/systems/performance/power_station.tres") as PowerStationInstance - -@onready var cpu_boost_button := $CPUBoostButton as Toggle -@onready var cpu_cores_slider := $CPUCoresSlider as ValueSlider -@onready var gpu_freq_enable := $GPUFreqButton as Toggle -@onready var gpu_freq_max_slider := $GPUFreqMaxSlider as ValueSlider -@onready var gpu_freq_min_slider := $GPUFreqMinSlider as ValueSlider -@onready var gpu_temp_slider := $GPUTempSlider as ValueSlider -@onready var power_profile_dropdown := $PowerProfileDropdown as Dropdown -@onready var tdp_boost_slider := $TDPBoostSlider as ValueSlider -@onready var tdp_slider := $TDPSlider as ValueSlider -@onready var thermal_profile_dropdown := $ThermalProfileDropdown as Dropdown -@onready var smt_button := $SMTButton as Toggle -@onready var cpu_label := $CPUSectionLabel as Control -@onready var gpu_label := $GPUSectionLabel as Control -@onready var wait_label := $WaitLabel as Control -@onready var service_timer := $ServiceTimer as Timer -@onready var apply_timer := $ApplyTimer as Timer - -var power_station_running := false -var profile_loading := false -var current_profile: PerformanceProfile -var logger := Log.get_logger("PowerTools", Log.LEVEL.INFO) - - -# Called when the node enters the scene tree for the first time. -# Finds default values and current settings of the hardware. -func _ready() -> void: - # Listen for signals from performance manager - performance_manager.profile_loaded.connect(_on_profile_loaded) - - # Configure a timer that will monitor the PowerStation DBus service - service_timer.timeout.connect(_on_service_timer_timeout) - # Configure a timer that will apply and save the performance profile - apply_timer.timeout.connect(_on_apply_timer_timeout) - - # Configure the interface - _setup_interface() - - # Re-start the apply timer when changes happen - var on_changed := func() -> void: - if profile_loading: - return - apply_timer.start() - cpu_boost_button.pressed.connect(on_changed) - smt_button.pressed.connect(on_changed) - gpu_freq_enable.pressed.connect(on_changed) - - # Set the total number of available cores if the SMT button is pressed - var on_smt_pressed := func() -> void: - if not hardware_manager.cpu: - return - var cpu := hardware_manager.cpu - if smt_button.button_pressed: - cpu_cores_slider.max_value = cpu.core_count - else: - var cores := cpu.core_count / 2 - if cpu_cores_slider.value > cores: - cpu_cores_slider.value = cores - cpu_cores_slider.max_value = cores - smt_button.pressed.connect(on_smt_pressed) - - # Restart the timer when any slider changes happen - var on_slider_changed := func(_value) -> void: - if profile_loading: - return - apply_timer.start() - cpu_cores_slider.value_changed.connect(on_slider_changed) - tdp_slider.value_changed.connect(on_slider_changed) - tdp_boost_slider.value_changed.connect(on_slider_changed) - gpu_freq_min_slider.value_changed.connect(on_slider_changed) - gpu_freq_max_slider.value_changed.connect(on_slider_changed) - gpu_temp_slider.value_changed.connect(on_slider_changed) - - # Configure GPU frequency timers so the minimum value can never go higher - # than the maximum value slider and the maximum value can never go lower - # than the minimum value slider. - var on_gpu_freq_changed := func(_value: float, kind: String) -> void: - if kind == "min" and gpu_freq_min_slider.value > gpu_freq_max_slider.value: - gpu_freq_max_slider.value = gpu_freq_min_slider.value - return - if kind == "max" and gpu_freq_max_slider.value < gpu_freq_min_slider.value: - gpu_freq_min_slider.value = gpu_freq_max_slider.value - return - gpu_freq_min_slider.value_changed.connect(on_gpu_freq_changed.bind("min")) - gpu_freq_max_slider.value_changed.connect(on_gpu_freq_changed.bind("max")) - - # Also restart the apply timer when dropdown changes happen - var on_dropdown_changed := func(_index) -> void: - if profile_loading: - return - apply_timer.start() - power_profile_dropdown.item_selected.connect(on_dropdown_changed) - thermal_profile_dropdown.item_selected.connect(on_dropdown_changed) - - # Toggle visibility when the GPU freq manual toggle is on - var on_manual_freq := func() -> void: - # Immediately apply manual GPU frequency so we can read the min/max - # values for the sliders - var card := _get_integrated_card() - if not card: - logger.warn("No integrated GPU to set manual frequency on!") - return - card.manual_clock = gpu_freq_enable.button_pressed - - # Update the slider values with the current values - gpu_freq_min_slider.visible = gpu_freq_enable.button_pressed - gpu_freq_min_slider.min_value = round(card.clock_limit_mhz_min) - gpu_freq_min_slider.max_value = round(card.clock_limit_mhz_max) - gpu_freq_min_slider.value = round(card.clock_value_mhz_min) - gpu_freq_max_slider.visible = gpu_freq_enable.button_pressed - gpu_freq_max_slider.min_value = round(card.clock_limit_mhz_min) - gpu_freq_max_slider.max_value = round(card.clock_limit_mhz_max) - gpu_freq_max_slider.value = round(card.clock_value_mhz_max) - - gpu_freq_enable.pressed.connect(on_manual_freq) - - # Setup dropdowns - power_profile_dropdown.clear() - power_profile_dropdown.add_item("Max Performance", 0) - power_profile_dropdown.add_item("Power Saving", 1) - thermal_profile_dropdown.clear() - thermal_profile_dropdown.add_item("Balanced", 0) - thermal_profile_dropdown.add_item("Performance", 1) - thermal_profile_dropdown.add_item("Silent", 2) - - # Set the initial values - _on_profile_loaded(performance_manager.current_profile) - - -# Triggers when the apply timer times out. The apply timer will start/restart -# whenever the user makes a change to any item. When the timer runs out, it will -# call this to apply the current profile. -func _on_apply_timer_timeout() -> void: - if not current_profile: - logger.debug("No loaded profile to apply") - return - logger.debug("Applying and saving profile") - - # Update the profile based on the currently set values - current_profile.gpu_power_profile = power_profile_dropdown.selected - current_profile.cpu_boost_enabled = cpu_boost_button.button_pressed - current_profile.cpu_smt_enabled = smt_button.button_pressed - current_profile.cpu_core_count_current = int(cpu_cores_slider.value) - current_profile.tdp_current = tdp_slider.value - current_profile.tdp_boost_current = tdp_boost_slider.value - current_profile.gpu_manual_enabled = gpu_freq_enable.button_pressed - current_profile.gpu_freq_min_current = gpu_freq_min_slider.value - current_profile.gpu_freq_max_current = gpu_freq_max_slider.value - current_profile.gpu_temp_current = gpu_temp_slider.value - - performance_manager.apply_and_save_profile(current_profile) - - -# Triggers every timeout to monitor the PowerStation DBus -func _on_service_timer_timeout() -> void: - var bus_running := power_station.is_running() - if bus_running == power_station_running: - return - - # If the state of powerstation changes, update the interface accordingly - power_station_running = bus_running - _setup_interface() - - -## Called when a performance profile is loaded -func _on_profile_loaded(profile: PerformanceProfile) -> void: - if not power_station.is_running(): - logger.info("Unable to load performance profile. PowerStation not detected.") - return - var core_count := 1 - if hardware_manager.cpu: - core_count = hardware_manager.cpu.core_count - - logger.debug("Updating UI with loaded performance profile") - # Keep track of the currently loaded profile - current_profile = profile - - # Update CPU UI components based on the loaded profile - profile_loading = true - cpu_boost_button.button_pressed = profile.cpu_boost_enabled - smt_button.button_pressed = profile.cpu_smt_enabled - if smt_button.button_pressed: - cpu_cores_slider.max_value = core_count - else: - var cores := core_count / 2 - if cpu_cores_slider.value > cores: - cpu_cores_slider.value = cores - cpu_cores_slider.max_value = cores - cpu_cores_slider.value = round(profile.cpu_core_count_current) - - # Update GPU UI components - tdp_slider.value = round(profile.tdp_current) - tdp_boost_slider.value = round(profile.tdp_boost_current) - gpu_freq_enable.button_pressed = profile.gpu_manual_enabled - gpu_freq_enable.pressed.emit() - gpu_freq_min_slider.value = round(profile.gpu_freq_min_current) - gpu_freq_max_slider.value = round(profile.gpu_freq_max_current) - gpu_temp_slider.value = round(profile.gpu_temp_current) - - power_profile_dropdown.select(profile.gpu_power_profile) - thermal_profile_dropdown.select(profile.thermal_profile) - - profile_loading = false - - -# Configure the min/max values and visibility based on detected performance -# features. -func _setup_interface() -> void: - # If powerstation is not running, disable everything - if not power_station.is_running(): - wait_label.visible = true - for node in get_children(): - if node == wait_label: - continue - if node == Control: - (node as Control).visible = false - return - - # Configure visibility for all components - wait_label.visible = false - - # Configure CPU components - if power_station.cpu: - var cpu := power_station.cpu - cpu_label.visible = true - cpu_boost_button.visible = cpu.has_feature("cpb") - smt_button.visible = cpu.has_feature("ht") - if cpu.smt_enabled: - cpu_cores_slider.max_value = cpu.cores_count - else: - cpu_cores_slider.max_value = cpu.cores_count / 2 - cpu_cores_slider.visible = true - - # Configure GPU components - if power_station.gpu: - var card := _get_integrated_card() - - # Configure based on integrated graphics card - if card: - gpu_label.visible = true - tdp_slider.visible = true - tdp_slider.min_value = round(hardware_manager.gpu.tdp_min) - tdp_slider.max_value = round(hardware_manager.gpu.tdp_max) - tdp_boost_slider.visible = true - tdp_boost_slider.max_value = round(hardware_manager.gpu.max_boost) - gpu_freq_enable.visible = true - power_profile_dropdown.visible = true - if card.clock_limit_mhz_min > 0 and card.clock_limit_mhz_max > 0: - gpu_freq_min_slider.visible = card.manual_clock - gpu_freq_min_slider.min_value = round(card.clock_limit_mhz_min) - gpu_freq_min_slider.max_value = round(card.clock_limit_mhz_max) - gpu_freq_max_slider.visible = card.manual_clock - gpu_freq_max_slider.min_value = round(card.clock_limit_mhz_min) - gpu_freq_max_slider.max_value = round(card.clock_limit_mhz_max) - if card.thermal_throttle_limit_c > 0: - gpu_temp_slider.visible = true - - -## Returns the primary integrated GPU instance -func _get_integrated_card() -> GpuCard: - var card: GpuCard - var cards := power_station.gpu.get_cards() - for c in cards: - if c.class != "integrated": - continue - card = c - return card diff --git a/core/ui/common/quick_bar/powertools_menu.tscn b/core/ui/common/quick_bar/powertools_menu.tscn deleted file mode 100644 index ee0cd9d5..00000000 --- a/core/ui/common/quick_bar/powertools_menu.tscn +++ /dev/null @@ -1,166 +0,0 @@ -[gd_scene load_steps=9 format=3 uid="uid://dv3dt0j3jketh"] - -[ext_resource type="Script" path="res://core/ui/common/quick_bar/powertools_menu.gd" id="1_qncpn"] -[ext_resource type="PackedScene" uid="uid://8m20p2s0v5gb" path="res://core/systems/input/focus_group.tscn" id="2_h0jgv"] -[ext_resource type="Resource" uid="uid://dpc1o781f43ef" path="res://core/ui/card_ui/quick_bar/quick_bar_menu_focus.tres" id="3_0iyf7"] -[ext_resource type="PackedScene" uid="uid://dithv38oqgy58" path="res://core/ui/components/section_label.tscn" id="4_1pfjc"] -[ext_resource type="PackedScene" uid="uid://d1qb7euwlu7bh" path="res://core/ui/components/toggle.tscn" id="5_xig3u"] -[ext_resource type="PackedScene" uid="uid://d0u3rsa5qpj57" path="res://core/ui/components/subsection_label.tscn" id="5_yr563"] -[ext_resource type="PackedScene" uid="uid://cemxrvvjgm4g" path="res://core/ui/components/slider.tscn" id="6_7aip6"] -[ext_resource type="PackedScene" uid="uid://xei5afwefxud" path="res://core/ui/components/dropdown.tscn" id="7_0kvsa"] - -[node name="PowerTools" type="VBoxContainer"] -anchors_preset = 10 -anchor_right = 1.0 -offset_bottom = 28.0 -grow_horizontal = 2 -script = ExtResource("1_qncpn") - -[node name="FocusGroup" parent="." instance=ExtResource("2_h0jgv")] -focus_stack = ExtResource("3_0iyf7") - -[node name="ApplyTimer" type="Timer" parent="."] -wait_time = 1.5 -one_shot = true - -[node name="ServiceTimer" type="Timer" parent="."] -wait_time = 5.0 -autostart = true - -[node name="WaitLabel" parent="." instance=ExtResource("5_yr563")] -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 -text = "Waiting for PowerStation service..." -horizontal_alignment = 1 -vertical_alignment = 1 -autowrap_mode = 3 - -[node name="CPUSectionLabel" parent="." instance=ExtResource("4_1pfjc")] -visible = false -layout_mode = 2 -text = "CPU Settings" - -[node name="CPUBoostButton" parent="." instance=ExtResource("5_xig3u")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../GPUTempSlider") -focus_neighbor_top = NodePath("../GPUTempSlider") -focus_neighbor_right = NodePath("../SMTButton") -focus_neighbor_bottom = NodePath("../SMTButton") -focus_next = NodePath("../SMTButton") -focus_previous = NodePath("../GPUTempSlider") -text = "CPU Boost" -separator_visible = false - -[node name="SMTButton" parent="." instance=ExtResource("5_xig3u")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../CPUBoostButton") -focus_neighbor_top = NodePath("../CPUBoostButton") -focus_neighbor_right = NodePath("../CPUCoresSlider") -focus_neighbor_bottom = NodePath("../CPUCoresSlider") -focus_next = NodePath("../CPUCoresSlider") -focus_previous = NodePath("../CPUBoostButton") -text = "SMT Enabled" -separator_visible = false - -[node name="CPUCoresSlider" parent="." instance=ExtResource("6_7aip6")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../SMTButton") -focus_neighbor_top = NodePath("../SMTButton") -focus_neighbor_right = NodePath("../TDPSlider") -focus_neighbor_bottom = NodePath("../TDPSlider") -focus_next = NodePath("../TDPSlider") -focus_previous = NodePath("../SMTButton") -text = "CPU Cores" -value = 1.0 -max_value = 1.0 -min_value = 1.0 - -[node name="GPUSectionLabel" parent="." instance=ExtResource("4_1pfjc")] -visible = false -layout_mode = 2 -text = "GPU Settings" - -[node name="TDPSlider" parent="." instance=ExtResource("6_7aip6")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../CPUCoresSlider") -focus_neighbor_top = NodePath("../CPUCoresSlider") -focus_neighbor_right = NodePath("../TDPBoostSlider") -focus_neighbor_bottom = NodePath("../TDPBoostSlider") -focus_next = NodePath("../TDPBoostSlider") -focus_previous = NodePath("../CPUCoresSlider") -text = "TDP" -max_value = 0.0 - -[node name="TDPBoostSlider" parent="." instance=ExtResource("6_7aip6")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../TDPSlider") -focus_neighbor_top = NodePath("../TDPSlider") -focus_previous = NodePath("../TDPSlider") -text = "TDP Boost" -max_value = 0.0 - -[node name="GPUFreqButton" parent="." instance=ExtResource("5_xig3u")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../TDPBoostSlider") -focus_neighbor_top = NodePath("../TDPBoostSlider") -focus_neighbor_right = NodePath("../GPUFreqMinSlider") -focus_neighbor_bottom = NodePath("../GPUFreqMinSlider") -focus_next = NodePath("../GPUFreqMinSlider") -focus_previous = NodePath("../TDPBoostSlider") -text = "Manual Freq" -separator_visible = false - -[node name="GPUFreqMinSlider" parent="." instance=ExtResource("6_7aip6")] -visible = false -layout_mode = 2 -focus_neighbor_right = NodePath("../GPUFreqMaxSlider") -focus_neighbor_bottom = NodePath("../GPUFreqMaxSlider") -focus_next = NodePath("../GPUFreqMaxSlider") -text = "Min Freq" -max_value = 0.0 -step = 100.0 - -[node name="GPUFreqMaxSlider" parent="." instance=ExtResource("6_7aip6")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../GPUFreqMinSlider") -focus_neighbor_top = NodePath("../GPUFreqMinSlider") -focus_neighbor_right = NodePath("../GPUTempSlider") -focus_neighbor_bottom = NodePath("../GPUTempSlider") -focus_next = NodePath("../GPUTempSlider") -focus_previous = NodePath("../GPUFreqMinSlider") -text = "Max Freq" -max_value = 0.0 -step = 100.0 - -[node name="GPUTempSlider" parent="." instance=ExtResource("6_7aip6")] -visible = false -layout_mode = 2 -focus_neighbor_left = NodePath("../GPUFreqMaxSlider") -focus_neighbor_top = NodePath("../GPUFreqMaxSlider") -focus_neighbor_right = NodePath("../CPUBoostButton") -focus_neighbor_bottom = NodePath("../CPUBoostButton") -focus_next = NodePath("../CPUBoostButton") -focus_previous = NodePath("../GPUFreqMaxSlider") -text = "GPU Temp Limit" -value = 70.0 -max_value = 105.0 -min_value = 70.0 - -[node name="PowerProfileDropdown" parent="." instance=ExtResource("7_0kvsa")] -visible = false -layout_mode = 2 -title = "Power Profile" -description = "" - -[node name="ThermalProfileDropdown" parent="." instance=ExtResource("7_0kvsa")] -visible = false -layout_mode = 2 -title = "Thermal Throttle Profile" -description = "" diff --git a/extensions/core/src/dbus/powerstation/tdp.rs b/extensions/core/src/dbus/powerstation/tdp.rs index 29ce4a73..14cf8757 100644 --- a/extensions/core/src/dbus/powerstation/tdp.rs +++ b/extensions/core/src/dbus/powerstation/tdp.rs @@ -34,6 +34,8 @@ trait TDP { /// PowerProfile property #[zbus(property)] + fn power_profiles_available(&self) -> zbus::Result>; + #[zbus(property)] fn power_profile(&self) -> zbus::Result; #[zbus(property)] fn set_power_profile(&self, value: &str) -> zbus::Result<()>; diff --git a/extensions/core/src/performance/powerstation/gpu_card.rs b/extensions/core/src/performance/powerstation/gpu_card.rs index d53f7422..25fc40c9 100644 --- a/extensions/core/src/performance/powerstation/gpu_card.rs +++ b/extensions/core/src/performance/powerstation/gpu_card.rs @@ -106,6 +106,10 @@ pub struct GpuCard { #[var(get = get_boost, set = set_boost)] boost: f64, + #[allow(dead_code)] + #[var(get = get_power_profiles_available)] + power_profiles_available: PackedStringArray, + #[allow(dead_code)] #[var(get = get_power_profile, set = set_power_profile)] power_profile: GString, @@ -142,28 +146,29 @@ impl GpuCard { conn, dbus_path: path.clone().into(), rx, - connectors: HashMap::new(), + boost: Default::default(), class: Default::default(), class_id: Default::default(), clock_limit_mhz_max: Default::default(), clock_limit_mhz_min: Default::default(), clock_value_mhz_max: Default::default(), clock_value_mhz_min: Default::default(), + connectors: HashMap::new(), device: Default::default(), device_id: Default::default(), manual_clock: Default::default(), name: Default::default(), path: Default::default(), + power_profile: Default::default(), + power_profiles_available: Default::default(), revision_id: Default::default(), subdevice: Default::default(), subdevice_id: Default::default(), subvendor_id: Default::default(), - vendor: Default::default(), - vendor_id: Default::default(), - boost: Default::default(), - power_profile: Default::default(), tdp: Default::default(), thermal_throttle_limit_c: Default::default(), + vendor: Default::default(), + vendor_id: Default::default(), }; // Discover any connectors @@ -294,6 +299,20 @@ impl GpuCard { .unwrap_or_default() } + #[func] + pub fn get_power_profiles_available(&self) -> PackedStringArray { + let Some(proxy) = self.get_tdp_proxy() else { + return Default::default(); + }; + let available = proxy.power_profiles_available().unwrap_or_default(); + let mut result = PackedStringArray::new(); + for profile in available.iter() { + let godot_profile = profile.to_godot(); + result.push(&godot_profile); + } + result + } + #[func] pub fn get_power_profile(&self) -> GString { let Some(proxy) = self.get_tdp_proxy() else {