Commit 9f9b4d7d authored by Roberto Leinardi's avatar Roberto Leinardi

Some ground work for multi-gpu support

parent e5fd824f
...@@ -62,17 +62,19 @@ class EditOverclockProfilePresenter: ...@@ -62,17 +62,19 @@ class EditOverclockProfilePresenter:
self._profile = OverclockProfile() self._profile = OverclockProfile()
self._overclock = Overclock() self._overclock = Overclock()
self._scheduler: SchedulerBase = ThreadPoolScheduler(multiprocessing.cpu_count()) self._scheduler: SchedulerBase = ThreadPoolScheduler(multiprocessing.cpu_count())
self._gpu_index: int = 0
def show_add(self, overclock: Overclock) -> None: def show_add(self, overclock: Overclock, gpu_index: int) -> None:
profile = OverclockProfile() profile = OverclockProfile()
profile.name = 'New profile' profile.name = 'New profile'
profile.save() profile.save()
self.show_edit(profile, overclock) self.show_edit(profile, overclock, gpu_index)
def show_edit(self, profile: OverclockProfile, overclock: Overclock) -> None: def show_edit(self, profile: OverclockProfile, overclock: Overclock, gpu_index: int) -> None:
self._profile = profile self._profile = profile
self._overclock = overclock self._overclock = overclock
self.view.show(profile, overclock) self.view.show(profile, overclock)
self._gpu_index = gpu_index
def on_dialog_delete_event(self, widget: Gtk.Widget, *_: Any) -> Any: def on_dialog_delete_event(self, widget: Gtk.Widget, *_: Any) -> Any:
self._save_profile_name() self._save_profile_name()
...@@ -83,9 +85,8 @@ class EditOverclockProfilePresenter: ...@@ -83,9 +85,8 @@ class EditOverclockProfilePresenter:
self.view.hide() self.view.hide()
def on_apply_offsets_button_clicked(self, *_: Any) -> None: def on_apply_offsets_button_clicked(self, *_: Any) -> None:
gpu_index = 0
self._composite_disposable.add(self._set_overclock_interactor.execute( self._composite_disposable.add(self._set_overclock_interactor.execute(
gpu_index, self._overclock.perf_level_max, self.view.get_gpu_offset(), self.view.get_memory_offset()) self._gpu_index, self._overclock.perf_level_max, self.view.get_gpu_offset(), self.view.get_memory_offset())
.subscribe_on(self._scheduler) .subscribe_on(self._scheduler)
.observe_on(GtkScheduler()) .observe_on(GtkScheduler())
.subscribe(on_next=self._handle_set_overclock_result, .subscribe(on_next=self._handle_set_overclock_result,
......
...@@ -49,6 +49,9 @@ class HistoricalDataViewInterface: ...@@ -49,6 +49,9 @@ class HistoricalDataViewInterface:
def hide(self) -> None: def hide(self) -> None:
raise NotImplementedError() raise NotImplementedError()
def reset_graphs(self) -> None:
raise NotImplementedError()
def refresh_graphs(self, data: Dict[GraphType, Tuple[int, float, str, float, float]]) -> None: def refresh_graphs(self, data: Dict[GraphType, Tuple[int, float, str, float, float]]) -> None:
raise NotImplementedError() raise NotImplementedError()
...@@ -62,10 +65,14 @@ class HistoricalDataPresenter: ...@@ -62,10 +65,14 @@ class HistoricalDataPresenter:
LOG.debug("init HistoricalDataPresenter ") LOG.debug("init HistoricalDataPresenter ")
self._settings_interactor = settings_interactor self._settings_interactor = settings_interactor
self.view: HistoricalDataViewInterface = HistoricalDataViewInterface() self.view: HistoricalDataViewInterface = HistoricalDataViewInterface()
self._gpu_index: int = 0
def add_status(self, new_status: Status) -> None: def add_status(self, new_status: Status, gpu_index: int) -> None:
if is_dazzle_version_supported(): if is_dazzle_version_supported():
gpu_index = 0 if self._gpu_index != gpu_index:
self._gpu_index = gpu_index
self.view.reset_graphs()
data: Dict[GraphType, Tuple[int, float, str, float, float]] = {} data: Dict[GraphType, Tuple[int, float, str, float, float]] = {}
time = GLib.get_monotonic_time() time = GLib.get_monotonic_time()
gpu_status = new_status.gpu_status_list[gpu_index] gpu_status = new_status.gpu_status_list[gpu_index]
......
...@@ -46,7 +46,7 @@ class MainViewInterface: ...@@ -46,7 +46,7 @@ class MainViewInterface:
def toggle_window_visibility(self) -> None: def toggle_window_visibility(self) -> None:
raise NotImplementedError() raise NotImplementedError()
def refresh_status(self, status: Optional[Status]) -> None: def refresh_status(self, status: Optional[Status], gpu_index: int) -> None:
raise NotImplementedError() raise NotImplementedError()
def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None: def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]], active: Optional[int]) -> None:
...@@ -125,6 +125,7 @@ class MainPresenter: ...@@ -125,6 +125,7 @@ class MainPresenter:
self._overclock_profile_applied: Optional[OverclockProfile] = None self._overclock_profile_applied: Optional[OverclockProfile] = None
self.application_quit: Callable = lambda *args: None # will be set by the Application self.application_quit: Callable = lambda *args: None # will be set by the Application
self._latest_status: Optional[Status] = None self._latest_status: Optional[Status] = None
self._gpu_index: int = 0
def on_start(self) -> None: def on_start(self) -> None:
self._refresh_fan_profile_ui(True) self._refresh_fan_profile_ui(True)
...@@ -151,33 +152,30 @@ class MainPresenter: ...@@ -151,33 +152,30 @@ class MainPresenter:
LOG.error('Profile is None!') LOG.error('Profile is None!')
def on_fan_apply_button_clicked(self, *_: Any) -> None: def on_fan_apply_button_clicked(self, *_: Any) -> None:
gpu_index = 0
if self._fan_profile_selected: if self._fan_profile_selected:
self._fan_profile_applied = self._fan_profile_selected self._fan_profile_applied = self._fan_profile_selected
if self._fan_profile_selected.type == FanProfileType.AUTO.value: if self._fan_profile_selected.type == FanProfileType.AUTO.value:
self._set_fan_speed(gpu_index, manual_control=False) self._set_fan_speed(self._gpu_index, manual_control=False)
self._refresh_fan_profile_ui(profile_id=self._fan_profile_selected.id) self._refresh_fan_profile_ui(profile_id=self._fan_profile_selected.id)
self._update_current_fan_profile(self._fan_profile_selected) self._update_current_fan_profile(self._fan_profile_selected)
def on_overclock_edit_button_clicked(self, *_: Any) -> None: def on_overclock_edit_button_clicked(self, *_: Any) -> None:
gpu_index = 0
profile = self._overclock_profile_selected profile = self._overclock_profile_selected
assert self._latest_status is not None assert self._latest_status is not None
overclock = self._latest_status.gpu_status_list[gpu_index].overclock overclock = self._latest_status.gpu_status_list[self._gpu_index].overclock
if profile: if profile:
self._edit_overclock_profile_presenter.show_edit(profile, overclock) self._edit_overclock_profile_presenter.show_edit(profile, overclock, self._gpu_index)
else: else:
LOG.error('Profile is None!') LOG.error('Profile is None!')
def on_overclock_apply_button_clicked(self, *_: Any) -> None: def on_overclock_apply_button_clicked(self, *_: Any) -> None:
gpu_index = 0
if self._overclock_profile_selected: if self._overclock_profile_selected:
self._overclock_profile_applied = self._overclock_profile_selected self._overclock_profile_applied = self._overclock_profile_selected
self._refresh_overclock_profile_ui(profile_id=self._overclock_profile_selected.id) self._refresh_overclock_profile_ui(profile_id=self._overclock_profile_selected.id)
assert self._latest_status is not None assert self._latest_status is not None
self._composite_disposable.add(self._set_overclock_interactor.execute( self._composite_disposable.add(self._set_overclock_interactor.execute(
gpu_index, self._gpu_index,
self._latest_status.gpu_status_list[gpu_index].overclock.perf_level_max, self._latest_status.gpu_status_list[self._gpu_index].overclock.perf_level_max,
self._overclock_profile_applied.gpu, self._overclock_profile_applied.gpu,
self._overclock_profile_applied.memory) self._overclock_profile_applied.memory)
.subscribe_on(self._scheduler) .subscribe_on(self._scheduler)
...@@ -260,27 +258,26 @@ class MainPresenter: ...@@ -260,27 +258,26 @@ class MainPresenter:
) )
def _on_status_updated(self, status: Optional[Status]) -> None: def _on_status_updated(self, status: Optional[Status]) -> None:
gpu_index = 0
if status is not None: if status is not None:
was_latest_status_none = self._latest_status is None was_latest_status_none = self._latest_status is None
self._latest_status = status self._latest_status = status
if was_latest_status_none: if was_latest_status_none:
self._refresh_overclock_profile_ui(True) self._refresh_overclock_profile_ui(True)
gpu_status = status.gpu_status_list[gpu_index] self._update_fan(status)
self._update_fan(gpu_status) self.main_view.refresh_status(status, self._gpu_index)
self.main_view.refresh_status(status) self._historical_data_presenter.add_status(status, self._gpu_index)
self._historical_data_presenter.add_status(status)
else: else:
self._set_fan_speed(gpu_index, manual_control=False) self._set_fan_speed(self._gpu_index, manual_control=False)
def _update_fan(self, gpu_status: GpuStatus) -> None: def _update_fan(self, status: Status) -> None:
fan = gpu_status.fan fan = status.gpu_status_list[self._gpu_index].fan
if fan.control_allowed: if fan.control_allowed:
if self._fan_profile_selected is None and not fan.manual_control: if self._fan_profile_selected is None and not fan.manual_control:
fan_profile = FanProfile.get(FanProfile.type == FanProfileType.AUTO.value) fan_profile = FanProfile.get(FanProfile.type == FanProfileType.AUTO.value)
self._fan_profile_applied = fan_profile self._fan_profile_applied = fan_profile
self._refresh_fan_profile_ui(profile_id=fan_profile.id) self._refresh_fan_profile_ui(profile_id=fan_profile.id)
elif self._fan_profile_applied and self._fan_profile_applied.type != FanProfileType.AUTO.value: elif self._fan_profile_applied and self._fan_profile_applied.type != FanProfileType.AUTO.value:
gpu_status = status.gpu_status_list[self._gpu_index]
if not self._fan_profile_applied.steps: if not self._fan_profile_applied.steps:
self._set_fan_speed(gpu_status.index, manual_control=False) self._set_fan_speed(gpu_status.index, manual_control=False)
elif gpu_status.temp.gpu: elif gpu_status.temp.gpu:
...@@ -359,11 +356,10 @@ class MainPresenter: ...@@ -359,11 +356,10 @@ class MainPresenter:
self.main_view.set_statusbar_text(f'{profile.name} fan profile selected') self.main_view.set_statusbar_text(f'{profile.name} fan profile selected')
def _refresh_overclock_profile_ui(self, init: bool = False, profile_id: Optional[int] = None) -> None: def _refresh_overclock_profile_ui(self, init: bool = False, profile_id: Optional[int] = None) -> None:
gpu_index = 0
current: Optional[CurrentOverclockProfile] = None current: Optional[CurrentOverclockProfile] = None
assert self._latest_status is not None assert self._latest_status is not None
if init and self._settings_interactor.get_bool('settings_load_last_profile') \ if init and self._settings_interactor.get_bool('settings_load_last_profile') \
and self._latest_status.gpu_status_list[gpu_index].overclock.available: and self._latest_status.gpu_status_list[self._gpu_index].overclock.available:
current = CurrentOverclockProfile.get_or_none() current = CurrentOverclockProfile.get_or_none()
if current is not None: if current is not None:
self._overclock_profile_selected = current.profile self._overclock_profile_selected = current.profile
...@@ -388,12 +384,12 @@ class MainPresenter: ...@@ -388,12 +384,12 @@ class MainPresenter:
self.main_view.refresh_overclock_profile_combobox(data, active) self.main_view.refresh_overclock_profile_combobox(data, active)
def _select_overclock_profile(self, profile_id: int) -> None: def _select_overclock_profile(self, profile_id: int) -> None:
gpu_index = 0
assert self._latest_status is not None assert self._latest_status is not None
if profile_id == _ADD_NEW_PROFILE_INDEX: if profile_id == _ADD_NEW_PROFILE_INDEX:
self.main_view.set_apply_overclock_profile_button_enabled(False) self.main_view.set_apply_overclock_profile_button_enabled(False)
self.main_view.set_edit_overclock_profile_button_enabled(False) self.main_view.set_edit_overclock_profile_button_enabled(False)
self._edit_overclock_profile_presenter.show_add(self._latest_status.gpu_status_list[gpu_index].overclock) self._edit_overclock_profile_presenter.show_add(
self._latest_status.gpu_status_list[self._gpu_index].overclock, self._gpu_index)
else: else:
profile: OverclockProfile = OverclockProfile.get(id=profile_id) profile: OverclockProfile = OverclockProfile.get(id=profile_id)
self._overclock_profile_selected = profile self._overclock_profile_selected = profile
......
...@@ -49,51 +49,54 @@ class HistoricalDataView(HistoricalDataViewInterface): ...@@ -49,51 +49,54 @@ class HistoricalDataView(HistoricalDataViewInterface):
def _init_widgets(self) -> None: def _init_widgets(self) -> None:
self._dialog: Gtk.Dialog = self._builder.get_object('dialog') self._dialog: Gtk.Dialog = self._builder.get_object('dialog')
if is_dazzle_version_supported(): self._init_graphs()
self._init_graphs()
def set_transient_for(self, window: Gtk.Window) -> None: def set_transient_for(self, window: Gtk.Window) -> None:
self._dialog.set_transient_for(window) self._dialog.set_transient_for(window)
# pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init
def _init_graphs(self) -> None: def _init_graphs(self) -> None:
self._graph_views: Dict[GraphType, Tuple[Gtk.Label, Gtk.Label, Gtk.Label]] = {} if is_dazzle_version_supported():
self._graph_models: Dict[GraphType, Dazzle.GraphModel] = {} self._graph_views: Dict[GraphType, Tuple[Gtk.Label, Gtk.Label, Gtk.Label]] = {}
for graph_type in GraphType: self._graph_models: Dict[GraphType, Dazzle.GraphModel] = {}
self._graph_container: Gtk.Frame = self._builder.get_object(f'graph_container_{graph_type.value}') for graph_type in GraphType:
self._graph_views[graph_type] = (self._builder.get_object(f'graph_min_value_{graph_type.value}'), self._graph_container: Gtk.Frame = self._builder.get_object(f'graph_container_{graph_type.value}')
self._builder.get_object(f'graph_max_value_{graph_type.value}'), self._graph_views[graph_type] = (self._builder.get_object(f'graph_min_value_{graph_type.value}'),
self._builder.get_object(f'graph_max_axis_{graph_type.value}')) self._builder.get_object(f'graph_max_value_{graph_type.value}'),
graph_views = Dazzle.GraphView() self._builder.get_object(f'graph_max_axis_{graph_type.value}'))
graph_model = Dazzle.GraphModel() graph_views = Dazzle.GraphView()
graph_renderer = GraphStackedRenderer() graph_model = Dazzle.GraphModel()
graph_views.set_hexpand(True) graph_renderer = GraphStackedRenderer()
graph_views.props.height_request = 80 graph_views.set_hexpand(True)
graph_renderer.set_line_width(1.5) graph_views.props.height_request = 80
stroke_color = Gdk.RGBA() graph_renderer.set_line_width(1.5)
stroke_color.parse(GRAPH_COLOR_HEX) stroke_color = Gdk.RGBA()
stacked_color = Gdk.RGBA() stroke_color.parse(GRAPH_COLOR_HEX)
stacked_color.parse(GRAPH_COLOR_HEX) stacked_color = Gdk.RGBA()
stacked_color.alpha = 0.5 stacked_color.parse(GRAPH_COLOR_HEX)
graph_renderer.set_stroke_color_rgba(stroke_color) stacked_color.alpha = 0.5
graph_renderer.set_stacked_color_rgba(stacked_color) graph_renderer.set_stroke_color_rgba(stroke_color)
graph_model.set_timespan(MONITORING_INTERVAL * 1000 * 1000) graph_renderer.set_stacked_color_rgba(stacked_color)
graph_model.set_max_samples(MONITORING_INTERVAL / self._presenter.get_refresh_interval() + 1) graph_model.set_timespan(MONITORING_INTERVAL * 1000 * 1000)
graph_model.props.value_max = 100.0 graph_model.set_max_samples(MONITORING_INTERVAL / self._presenter.get_refresh_interval() + 1)
graph_model.props.value_min = 0.0 graph_model.props.value_max = 100.0
graph_model.props.value_min = 0.0
column_ram = Dazzle.GraphColumn().new("Col0", TYPE_DOUBLE)
graph_model.add_column(column_ram) column_ram = Dazzle.GraphColumn().new("Col0", TYPE_DOUBLE)
graph_model.add_column(column_ram)
graph_views.set_model(graph_model)
graph_views.add_renderer(graph_renderer) graph_views.set_model(graph_model)
graph_views.add_renderer(graph_renderer)
self._graph_container.add(graph_views)
self._graph_container.add(graph_views)
graph_model_iter = graph_model.push(GLib.get_monotonic_time())
graph_model.iter_set(graph_model_iter, 0, 0.0) graph_model_iter = graph_model.push(GLib.get_monotonic_time())
graph_model.iter_set(graph_model_iter, 0, 0.0)
self._graph_models[graph_type] = graph_model
self._graph_models[graph_type] = graph_model
def reset_graphs(self) -> None:
self._init_graphs()
def refresh_graphs(self, data_dict: Dict[GraphType, Tuple[int, float, str, float, float]]) -> None: def refresh_graphs(self, data_dict: Dict[GraphType, Tuple[int, float, str, float, float]]) -> None:
time1 = time.time() time1 = time.time()
......
...@@ -209,9 +209,8 @@ class MainView(MainViewInterface): ...@@ -209,9 +209,8 @@ class MainView(MainViewInterface):
self._statusbar.remove_all(self._context) self._statusbar.remove_all(self._context)
self._statusbar.push(self._context, text) self._statusbar.push(self._context, text)
def refresh_status(self, status: Optional[Status]) -> None: def refresh_status(self, status: Optional[Status], gpu_index: int) -> None:
LOG.debug('view status') LOG.debug('view status')
gpu_index = 0
if status: if status:
gpu_status = status.gpu_status_list[gpu_index] gpu_status = status.gpu_status_list[gpu_index]
if self._first_refresh: if self._first_refresh:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment