/* Copyright (C) 2023 Grok Image Compression Inc. This file is part of DCP-o-matic. DCP-o-matic is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. DCP-o-matic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DCP-o-matic. If not, see . */ #include "check_box.h" #include "dir_picker_ctrl.h" #include "gpu_config_panel.h" #include "password_entry.h" #include #include #include #include #include static std::vector get_gpu_names(boost::filesystem::path binary, boost::filesystem::path filename) { // Execute the GPU listing program and redirect its output to a file std::system((binary.string() + " > " + filename.string()).c_str()); std::vector gpu_names; std::ifstream file(filename.string()); if (file.is_open()) { std::string line; while (std::getline(file, line)) { gpu_names.push_back(line); } file.close(); } return gpu_names; } class GPUList : public wxPanel { public: GPUList(wxPanel* parent) : wxPanel(parent, wxID_ANY) , _selection(0) { _combo_box = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(400, -1)); _combo_box->Bind(wxEVT_COMBOBOX, &GPUList::on_combo_box, this); update(); wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(_combo_box, 0, wxALIGN_CENTER_VERTICAL); // Vertically center the comboBox this->SetSizerAndFit(sizer); } void update() { auto binary = Config::instance()->gpu_binary_location(); DCPOMATIC_ASSERT(binary); auto lister_binary = *binary / "gpu_lister"; auto lister_file = *binary / "gpus.txt"; if (boost::filesystem::exists(lister_binary)) { auto gpu_names = get_gpu_names(lister_binary, lister_file); _combo_box->Clear(); for (const auto& name : gpu_names) { _combo_box->Append(name); } } } int get_selection() { return _selection; } void set_selection(int sel) { if ((int)_combo_box->GetCount() > sel) { _combo_box->SetSelection(sel); } } private: void on_combo_box([[maybe_unused]] wxCommandEvent& event) { _selection = _combo_box->GetSelection(); if (_selection != wxNOT_FOUND) { Config::instance()->set_selected_gpu(_selection); } } wxComboBox* _combo_box; int _selection; }; GPUPage::GPUPage(wxSize panel_size, int border) : Page(panel_size, border) , _enable_gpu(nullptr) , _binary_location(nullptr) , _gpu_list_control(nullptr) { } wxString GPUPage::GetName() const { return _("GPU"); } #ifdef DCPOMATIC_OSX wxBitmap GPUPage::GetLargeIcon() const { return wxBitmap(icon_path("tms"), wxBITMAP_TYPE_PNG); } #endif void GPUPage::setup() { auto config = Config::instance(); _enable_gpu = new CheckBox(_panel, _("Enable GPU acceleration")); _panel->GetSizer()->Add(_enable_gpu, 0, wxALL | wxEXPAND, _border); wxFlexGridSizer* table = new wxFlexGridSizer(2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); table->AddGrowableCol(1, 1); _panel->GetSizer()->Add(table, 1, wxALL | wxEXPAND, _border); add_label_to_sizer(table, _panel, _("Acceleration binary folder"), true, 0, wxLEFT | wxLEFT | wxALIGN_CENTRE_VERTICAL); _binary_location = new DirPickerCtrl(_panel); table->Add(_binary_location, 1, wxEXPAND); add_label_to_sizer(table, _panel, _("GPU selection"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); _gpu_list_control = new GPUList(_panel); table->Add(_gpu_list_control, 1, wxEXPAND); add_label_to_sizer(table, _panel, _("License server"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); _server = new wxTextCtrl(_panel, wxID_ANY); table->Add(_server, 1, wxEXPAND | wxALL); add_label_to_sizer(table, _panel, _("Port"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); _port = new wxSpinCtrl(_panel, wxID_ANY); _port->SetRange(0, 65535); table->Add(_port); add_label_to_sizer(table, _panel, _("License"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL); _license = new PasswordEntry(_panel); table->Add(_license->get_panel(), 1, wxEXPAND | wxALL); _enable_gpu->bind(&GPUPage::enable_gpu_changed, this); _binary_location->Bind(wxEVT_DIRPICKER_CHANGED, boost::bind(&GPUPage::binary_location_changed, this)); _server->Bind(wxEVT_TEXT, boost::bind(&GPUPage::server_changed, this)); _port->Bind(wxEVT_SPINCTRL, boost::bind(&GPUPage::port_changed, this)); _license->Changed.connect(boost::bind(&GPUPage::license_changed, this)); _binary_location->Enable(config->enable_gpu()); _gpu_list_control->Enable(config->enable_gpu()); _server->Enable(config->enable_gpu()); _port->Enable(config->enable_gpu()); _license->get_panel()->Enable(config->enable_gpu()); } void GPUPage::config_changed() { auto config = Config::instance(); checked_set(_enable_gpu, config->enable_gpu()); if (auto binary = config->gpu_binary_location()) { _binary_location->SetPath(std_to_wx(binary->string())); } else { _binary_location->SetPath(wxT("")); } _gpu_list_control->update(); _gpu_list_control->set_selection(config->selected_gpu()); checked_set(_server, std_to_wx(config->gpu_license_server().get_value_or(""))); checked_set(_port, config->gpu_license_port()); checked_set(_license, config->gpu_license().get_value_or("")); } void GPUPage::enable_gpu_changed() { auto config = Config::instance(); config->set_enable_gpu(_enable_gpu->GetValue()); _binary_location->Enable(config->enable_gpu()); _gpu_list_control->Enable(config->enable_gpu()); _server->Enable(config->enable_gpu()); _port->Enable(config->enable_gpu()); _license->get_panel()->Enable(config->enable_gpu()); } void GPUPage::binary_location_changed() { Config::instance()->set_gpu_binary_location(wx_to_std(_binary_location->GetPath())); _gpu_list_control->update(); } void GPUPage::server_changed() { Config::instance()->set_gpu_license_server(wx_to_std(_server->GetValue())); } void GPUPage::port_changed() { Config::instance()->set_gpu_license_port(_port->GetValue()); } void GPUPage::license_changed() { Config::instance()->set_gpu_license(_license->get()); }