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 <dcp/warnings.h>
23 LIBDCP_DISABLE_WARNINGS
24 #include <wx/glcanvas.h>
25 #include <wx/wx.h>
26 LIBDCP_ENABLE_WARNINGS
27
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_outline_content_colour (GLuint program);
103         void set_crop_guess_colour (GLuint program);
104
105         wxGLCanvas* _canvas;
106         wxGLContext* _context;
107
108         template <class T>
109         class Last
110         {
111         public:
112                 void set_next (T const& next) {
113                         _next = next;
114                 }
115
116                 bool changed () const {
117                         return !_value || *_value != _next;
118                 }
119
120                 void update () {
121                         _value = _next;
122                 }
123
124         private:
125                 boost::optional<T> _value;
126                 T _next;
127         };
128
129         Last<wxSize> _last_canvas_size;
130         Last<dcp::Size> _last_video_size;
131         Last<Position<int>> _last_inter_position;
132         Last<dcp::Size> _last_inter_size;
133         Last<dcp::Size> _last_out_size;
134         Last<boost::optional<dcpomatic::Rect<float>>> _last_crop_guess;
135
136         boost::atomic<wxSize> _canvas_size;
137         boost::atomic<bool> _rec2020;
138         std::unique_ptr<Texture> _video_texture;
139         std::unique_ptr<Texture> _subtitle_texture;
140         bool _have_subtitle_to_render = false;
141         bool _vsync_enabled;
142         boost::thread _thread;
143
144         boost::mutex _playing_mutex;
145         boost::condition _thread_work_condition;
146         boost::atomic<bool> _playing;
147         boost::atomic<bool> _one_shot;
148
149         GLuint _vao;
150         GLint _fragment_type;
151         bool _setup_shaders_done = false;
152
153         std::shared_ptr<wxTimer> _timer;
154
155         std::map<GLenum, std::string> _information;
156 };
157
158 #endif