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