8a312ae37cd8b752affa82790462eb393025a0c9
[dcpomatic.git] / src / wx / gpu_config_panel.cc
1
2 #include "check_box.h"
3 #include "dir_picker_ctrl.h"
4 #include "gpu_config_panel.h"
5 #include "password_entry.h"
6 #include <wx/panel.h>
7 #include <wx/wx.h>
8
9 #include <fstream>
10 #include <string>
11 #include <vector>
12
13
14 static std::vector<std::string>
15 get_gpu_names(boost::filesystem::path binary, boost::filesystem::path filename)
16 {
17         // Execute the GPU listing program and redirect its output to a file
18         std::system((binary.string() + " > " + filename.string()).c_str());
19
20         std::vector<std::string> gpu_names;
21         std::ifstream file(filename.string());
22         if (file.is_open()) {
23                 std::string line;
24                 while (std::getline(file, line)) {
25                         gpu_names.push_back(line);
26                 }
27                 file.close();
28         }
29
30         return gpu_names;
31 }
32
33
34 class GPUList : public wxPanel
35 {
36 public:
37         GPUList(wxPanel* parent)
38                 : wxPanel(parent, wxID_ANY)
39                 , _selection(0)
40         {
41                 _combo_box = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(400, -1));
42                 _combo_box->Bind(wxEVT_COMBOBOX, &GPUList::on_combo_box, this);
43                 update();
44
45                 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
46
47                 sizer->Add(_combo_box, 0, wxALIGN_CENTER_VERTICAL); // Vertically center the comboBox
48
49                 this->SetSizerAndFit(sizer);
50         }
51
52         void update()
53         {
54                 auto binary = Config::instance()->gpu_binary_location();
55                 DCPOMATIC_ASSERT(binary);
56                 auto lister_binary = *binary / "gpu_lister";
57                 auto lister_file = *binary / "gpus.txt";
58                 if (boost::filesystem::exists(lister_binary)) {
59                         auto gpu_names = get_gpu_names(lister_binary, lister_file);
60
61                         _combo_box->Clear();
62                         for (const auto& name : gpu_names) {
63                                 _combo_box->Append(name);
64                         }
65                 }
66         }
67
68         int get_selection()
69         {
70                 return _selection;
71         }
72
73         void set_selection(int sel)
74         {
75                 if ((int)_combo_box->GetCount() > sel) {
76                         _combo_box->SetSelection(sel);
77                 }
78         }
79
80 private:
81         void on_combo_box([[maybe_unused]] wxCommandEvent& event)
82         {
83                 _selection = _combo_box->GetSelection();
84                 if (_selection != wxNOT_FOUND) {
85                         Config::instance()->set_selected_gpu(_selection);
86                 }
87         }
88
89         wxComboBox* _combo_box;
90         int _selection;
91 };
92
93
94 GPUPage::GPUPage(wxSize panel_size, int border)
95         : Page(panel_size, border)
96         , _enable_gpu(nullptr)
97         , _binary_location(nullptr)
98         , _gpu_list_control(nullptr)
99 {
100
101 }
102
103
104 wxString
105 GPUPage::GetName() const
106 {
107         return _("GPU");
108 }
109
110
111 #ifdef DCPOMATIC_OSX
112 wxBitmap
113 GPUPage::GetLargeIcon() const
114 {
115         return wxBitmap(icon_path("tms"), wxBITMAP_TYPE_PNG);
116 }
117 #endif
118
119
120 void
121 GPUPage::setup()
122 {
123         auto config = Config::instance();
124
125         _enable_gpu = new CheckBox(_panel, _("Enable GPU acceleration"));
126         _panel->GetSizer()->Add(_enable_gpu, 0, wxALL | wxEXPAND, _border);
127
128         wxFlexGridSizer* table = new wxFlexGridSizer(2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
129         table->AddGrowableCol(1, 1);
130         _panel->GetSizer()->Add(table, 1, wxALL | wxEXPAND, _border);
131
132         add_label_to_sizer(table, _panel, _("Acceleration binary folder"), true, 0, wxLEFT | wxLEFT | wxALIGN_CENTRE_VERTICAL);
133         _binary_location = new DirPickerCtrl(_panel);
134         table->Add(_binary_location, 1, wxEXPAND);
135
136         add_label_to_sizer(table, _panel, _("GPU selection"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
137         _gpu_list_control = new GPUList(_panel);
138         table->Add(_gpu_list_control, 1, wxEXPAND);
139
140         add_label_to_sizer(table, _panel, _("License server"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
141         _server = new wxTextCtrl(_panel, wxID_ANY);
142         table->Add(_server, 1, wxEXPAND | wxALL);
143
144         add_label_to_sizer(table, _panel, _("Port"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
145         _port = new wxSpinCtrl(_panel, wxID_ANY);
146         _port->SetRange(0, 65535);
147         table->Add(_port);
148
149         add_label_to_sizer(table, _panel, _("License"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
150         _license = new PasswordEntry(_panel);
151         table->Add(_license->get_panel(), 1, wxEXPAND | wxALL);
152
153         _enable_gpu->bind(&GPUPage::enable_gpu_changed, this);
154         _binary_location->Bind(wxEVT_DIRPICKER_CHANGED, boost::bind(&GPUPage::binary_location_changed, this));
155         _server->Bind(wxEVT_TEXT, boost::bind(&GPUPage::server_changed, this));
156         _port->Bind(wxEVT_SPINCTRL, boost::bind(&GPUPage::port_changed, this));
157         _license->Changed.connect(boost::bind(&GPUPage::license_changed, this));
158
159         _binary_location->Enable(config->enable_gpu());
160         _gpu_list_control->Enable(config->enable_gpu());
161         _server->Enable(config->enable_gpu());
162         _port->Enable(config->enable_gpu());
163         _license->get_panel()->Enable(config->enable_gpu());
164 }
165
166
167 void GPUPage::config_changed()
168 {
169         auto config = Config::instance();
170
171         checked_set(_enable_gpu, config->enable_gpu());
172         if (auto binary = config->gpu_binary_location()) {
173                 _binary_location->SetPath(std_to_wx(binary->string()));
174         } else {
175                 _binary_location->SetPath(wxT(""));
176         }
177         _gpu_list_control->update();
178         _gpu_list_control->set_selection(config->selected_gpu());
179         checked_set(_server, config->gpu_license_server());
180         checked_set(_port, config->gpu_license_port());
181         checked_set(_license, config->gpu_license());
182 }
183
184
185 void GPUPage::enable_gpu_changed()
186 {
187         auto config = Config::instance();
188
189         config->set_enable_gpu(_enable_gpu->GetValue());
190         _binary_location->Enable(config->enable_gpu());
191         _gpu_list_control->Enable(config->enable_gpu());
192         _server->Enable(config->enable_gpu());
193         _port->Enable(config->enable_gpu());
194         _license->get_panel()->Enable(config->enable_gpu());
195 }
196
197
198 void GPUPage::binary_location_changed()
199 {
200         Config::instance()->set_gpu_binary_location(wx_to_std(_binary_location->GetPath()));
201         _gpu_list_control->update();
202 }
203
204
205 void GPUPage::server_changed()
206 {
207         Config::instance()->set_gpu_license_server(wx_to_std(_server->GetValue()));
208 }
209
210
211 void GPUPage::port_changed()
212 {
213         Config::instance()->set_gpu_license_port(_port->GetValue());
214 }
215
216
217 void GPUPage::license_changed()
218 {
219         Config::instance()->set_gpu_license(_license->get());
220 }
221