a0f2a1f7fdfd8ae99f6978c37d51ca478c260cb3
[dcpomatic.git] / src / wx / grok / gpu_config_panel.h
1 /*
2     Copyright (C) 2023 Grok Image Compression Inc.
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21
22 #pragma once
23
24 static std::vector<std::string> get_gpu_names(boost::filesystem::path binary, boost::filesystem::path filename)
25 {
26     // Execute the GPU listing program and redirect its output to a file
27     if (std::system((binary.string() + " > " + filename.string()).c_str()) < 0) {
28             return {};
29     }
30
31     std::vector<std::string> gpu_names;
32     std::ifstream file(filename.c_str());
33     if (file.is_open())
34     {
35         std::string line;
36         while (std::getline(file, line))
37             gpu_names.push_back(line);
38         file.close();
39     }
40
41     return gpu_names;
42 }
43
44 class GpuList : public wxPanel
45 {
46 public:
47     GpuList(wxPanel* parent) : wxPanel(parent, wxID_ANY), selection(0) {
48         comboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(400, -1));
49         comboBox->Bind(wxEVT_COMBOBOX, &GpuList::OnComboBox, this);
50         update();
51
52         wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
53
54         sizer->Add(comboBox, 0, wxALIGN_CENTER_VERTICAL); // Vertically center the comboBox
55
56         this->SetSizerAndFit(sizer);
57     }
58     void update(void) {
59         auto cfg = Config::instance();
60         auto lister_binary = cfg->gpu_binary_location() / "gpu_lister";
61         auto lister_file = cfg->gpu_binary_location () / "gpus.txt";
62         if (boost::filesystem::exists(lister_binary)) {
63                         auto gpu_names = get_gpu_names(lister_binary, lister_file);
64
65                         comboBox->Clear();
66                         for (const auto& name : gpu_names)
67                                  comboBox->Append(name);
68         }
69     }
70
71     int getSelection(void) {
72         return selection;
73     }
74     void setSelection(int sel) {
75         if ((int)comboBox->GetCount() > sel)
76             comboBox->SetSelection(sel);
77     }
78
79 private:
80     void OnComboBox(wxCommandEvent&)
81     {
82         selection = comboBox->GetSelection();
83         if (selection != wxNOT_FOUND)
84                 Config::instance ()->set_selected_gpu(selection);
85     }
86
87     wxComboBox* comboBox;
88     int selection;
89 };
90
91 class GPUPage : public Page
92 {
93 public:
94         GPUPage (wxSize panel_size, int border)
95                 : Page (panel_size, border),
96                   _enable_gpu(nullptr), _binary_location(nullptr), _gpu_list_control(nullptr)
97         {}
98
99         wxString GetName () const override
100         {
101                 return _("GPU");
102         }
103
104 #ifdef DCPOMATIC_OSX
105         wxBitmap GetLargeIcon () const override
106         {
107                 return wxBitmap(icon_path("tms"), wxBITMAP_TYPE_PNG);
108         }
109 #endif
110
111 private:
112         void setup () override
113         {
114                 auto config = Config::instance ();
115
116                 _enable_gpu = new CheckBox(_panel, _("Enable GPU acceleration"));
117                 _panel->GetSizer()->Add (_enable_gpu, 0, wxALL | wxEXPAND, _border);
118
119                 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
120                 table->AddGrowableCol (1, 1);
121                 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
122
123                 add_label_to_sizer(table, _panel, _("Acceleration binary folder"), true, 0, wxLEFT | wxLEFT | wxALIGN_CENTRE_VERTICAL);
124                 _binary_location = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
125                 table->Add (_binary_location, 1, wxEXPAND);
126
127                 add_label_to_sizer(table, _panel, _("GPU selection"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
128                 _gpu_list_control = new GpuList(_panel);
129                 table->Add (_gpu_list_control, 1, wxEXPAND);
130
131                 add_label_to_sizer(table, _panel, _("License server"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
132                 _server = new wxTextCtrl (_panel, wxID_ANY);
133                 table->Add (_server, 1, wxEXPAND | wxALL);
134
135                 add_label_to_sizer (table, _panel, _("Port"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
136                 _port = new wxSpinCtrl (_panel, wxID_ANY);
137                 _port->SetRange (0, 65535);
138                 table->Add (_port);
139
140                 add_label_to_sizer (table, _panel, _("License"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
141                 _license = new PasswordEntry (_panel);
142                 table->Add (_license->get_panel(), 1, wxEXPAND | wxALL);
143
144                 _enable_gpu->bind(&GPUPage::enable_gpu_changed, this);
145                 _binary_location->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&GPUPage::binary_location_changed, this));
146                 _server->Bind (wxEVT_TEXT, boost::bind(&GPUPage::server_changed, this));
147                 _port->Bind (wxEVT_SPINCTRL, boost::bind(&GPUPage::port_changed, this));
148                 _license->Changed.connect (boost::bind(&GPUPage::license_changed, this));
149
150                 _binary_location->Enable(config->enable_gpu());
151                 _gpu_list_control->Enable(config->enable_gpu());
152                 _server->Enable(config->enable_gpu());
153                 _port->Enable(config->enable_gpu());
154                 _license->get_panel()->Enable(config->enable_gpu());
155         }
156
157
158         void config_changed () override
159         {
160                 auto config = Config::instance ();
161
162                 checked_set (_enable_gpu, config->enable_gpu());
163                 _binary_location->SetPath(std_to_wx(config->gpu_binary_location().string()));
164                 _gpu_list_control->update();
165                 _gpu_list_control->setSelection(config->selected_gpu());
166                 checked_set (_server, config->gpu_license_server());
167                 checked_set (_port, config->gpu_license_port());
168                 checked_set (_license, config->gpu_license());
169         }
170
171         void enable_gpu_changed ()
172         {
173                 auto config = Config::instance ();
174
175                 config->set_enable_gpu (_enable_gpu->GetValue());
176                 _binary_location->Enable(config->enable_gpu());
177                 _gpu_list_control->Enable(config->enable_gpu());
178                 _server->Enable(config->enable_gpu());
179                 _port->Enable(config->enable_gpu());
180                 _license->get_panel()->Enable(config->enable_gpu());
181         }
182
183         void binary_location_changed ()
184         {
185                 Config::instance()->set_gpu_binary_location (wx_to_std (_binary_location->GetPath ()));
186                 _gpu_list_control->update();
187         }
188
189         void server_changed ()
190         {
191                 Config::instance()->set_gpu_license_server(wx_to_std(_server->GetValue()));
192         }
193
194         void port_changed ()
195         {
196                 Config::instance()->set_gpu_license_port(_port->GetValue());
197         }
198
199         void license_changed ()
200         {
201                 Config::instance()->set_gpu_license(_license->get());
202         }
203
204         CheckBox* _enable_gpu;
205         wxDirPickerCtrl* _binary_location;
206         GpuList *_gpu_list_control;
207         wxTextCtrl* _server;
208         wxSpinCtrl* _port;
209         PasswordEntry* _license;
210 };