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..b360298f 100644 --- a/core/ui/common/quick_bar/performance_menu.gd +++ b/core/ui/common/quick_bar/performance_menu.gd @@ -1,13 +1,300 @@ -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: + 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) + + # 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 + + # Set the initial values + _on_profile_loaded(performance_manager.current_profile) + + # Configure the interface + _setup_interface() + + +# 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 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) + + var idx := profiles_available.find(profile.gpu_power_profile) + if idx > -1: + power_profile_dropdown.select(idx) + + 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 power_station.gpu: + var card := _get_integrated_card() + + # Configure based on integrated graphics card + if card: + 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 +314,86 @@ 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 + + +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) + _setup_interface() 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 {