Supporters update.
[dcpomatic.git] / src / wx / gl_video_view.h
1 /*
2     Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
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 #include "lib/warnings.h"
23
24 DCPOMATIC_DISABLE_WARNINGS
25 #include <wx/glcanvas.h>
26 #include <wx/wx.h>
27 DCPOMATIC_ENABLE_WARNINGS
28
29 /* The OpenGL API in wxWidgets 3.0.x is sufficiently different to make it awkward to support,
30  * and I think it may even have things missing that we require (e.g. the attributes parameter
31  * to wxGLContext).  Hence we only support the GLVideoView on wxWidgets 3.1.0 and higher
32  * (which only excludes the old macOS builds, since wxWidgets 3.1.x does not support macOS
33  * 10.9 or earlier).
34  */
35 #if wxCHECK_VERSION(3,1,0)
36
37 #include "video_view.h"
38 #include "lib/signaller.h"
39 #include "lib/position.h"
40 #include <dcp/util.h>
41 #include <boost/atomic.hpp>
42 #include <boost/thread.hpp>
43 #include <boost/thread/condition.hpp>
44 #undef None
45 #undef Success
46 #undef Status
47
48
49 class Texture
50 {
51 public:
52         Texture (GLint unpack_alignment);
53         ~Texture ();
54
55         Texture (Texture const&) = delete;
56         Texture& operator= (Texture const&) = delete;
57
58         void bind ();
59         void set (std::shared_ptr<const Image> image);
60
61 private:
62         GLuint _name;
63         GLint _unpack_alignment;
64         boost::optional<dcp::Size> _size;
65 };
66
67
68 class GLVideoView : public VideoView
69 {
70 public:
71         GLVideoView (FilmViewer* viewer, wxWindow* parent);
72         ~GLVideoView ();
73
74         wxWindow* get () const override {
75                 return _canvas;
76         }
77         void update () override;
78         void start () override;
79         void stop () override;
80
81         NextFrameResult display_next_frame (bool) override;
82
83         bool vsync_enabled () const {
84                 return _vsync_enabled;
85         }
86
87         std::map<GLenum, std::string> information () const {
88                 return _information;
89         }
90
91 private:
92         void set_image (std::shared_ptr<const PlayerVideo> pv);
93         void set_image_and_draw ();
94         void draw ();
95         void thread ();
96         void thread_playing ();
97         void request_one_shot ();
98         void check_for_butler_errors ();
99         void ensure_context ();
100         void size_changed (wxSizeEvent const &);
101         void setup_shaders ();
102         void set_border_colour (GLuint program);
103
104         wxGLCanvas* _canvas;
105         wxGLContext* _context;
106
107         template <class T>
108         class Last
109         {
110         public:
111                 void set_next (T const& next) {
112                         _next = next;
113                 }
114
115                 bool changed () const {
116                         return !_value || *_value != _next;
117                 }
118
119                 void update () {
120                         _value = _next;
121                 }
122
123         private:
124                 boost::optional<T> _value;
125                 T _next;
126         };
127
128         Last<wxSize> _last_canvas_size;
129         Last<dcp::Size> _last_video_size;
130         Last<Position<int>> _last_inter_position;
131         Last<dcp::Size> _last_inter_size;
132         Last<dcp::Size> _last_out_size;
133
134         boost::atomic<wxSize> _canvas_size;
135         std::unique_ptr<Texture> _video_texture;
136         std::unique_ptr<Texture> _subtitle_texture;
137         bool _have_subtitle_to_render = false;
138         bool _vsync_enabled;
139         boost::thread _thread;
140
141         boost::mutex _playing_mutex;
142         boost::condition _thread_work_condition;
143         boost::atomic<bool> _playing;
144         boost::atomic<bool> _one_shot;
145
146         GLuint _vao;
147         GLint _fragment_type;
148         bool _setup_shaders_done = false;
149
150         std::shared_ptr<wxTimer> _timer;
151
152         std::map<GLenum, std::string> _information;
153 };
154
155 #endif