- auto const canvas_size = _canvas_size.load();
- int const canvas_width = canvas_size.GetWidth();
- int const canvas_height = canvas_size.GetHeight();
-
- float const image_x = float(_size->width) / canvas_width;
- float const image_y = float(_size->height) / canvas_height;
-
- auto x_pixels_to_gl = [canvas_width](int x) {
- return (x * 2.0f / canvas_width) - 1.0f;
- };
-
- auto y_pixels_to_gl = [canvas_height](int y) {
- return (y * 2.0f / canvas_height) - 1.0f;
- };
-
- auto inter_position = player_video().first->inter_position();
- auto inter_size = player_video().first->inter_size();
-
- float const border_x1 = x_pixels_to_gl (inter_position.x) + 1.0f - image_x;
- float const border_y1 = y_pixels_to_gl (inter_position.y) + 1.0f - image_y;
- float const border_x2 = x_pixels_to_gl (inter_position.x + inter_size.width) + 1.0f - image_x;
- float const border_y2 = y_pixels_to_gl (inter_position.y + inter_size.height) + 1.0f - image_y;
-
- float vertices[] = {
- // positions // texture coords
- image_x, image_y, 0.0f, 1.0f, 0.0f, // top right (index 0)
- image_x, -image_y, 0.0f, 1.0f, 1.0f, // bottom right (index 1)
- -image_x, -image_y, 0.0f, 0.0f, 1.0f, // bottom left (index 2)
- -image_x, image_y, 0.0f, 0.0f, 0.0f, // top left (index 3)
- border_x1, border_y1, 0.0f, 0.0f, 0.0f, // border bottom left (index 4)
- border_x1, border_y2, 0.0f, 0.0f, 0.0f, // border top left (index 5)
- border_x2, border_y2, 0.0f, 0.0f, 0.0f, // border top right (index 6)
- border_x2, border_y1, 0.0f, 0.0f, 0.0f, // border bottom right (index 7)
- };
-
- /* Set the vertex shader's input data (GL_ARRAY_BUFFER) */
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
- check_gl_error ("glBufferData");
-
- _have_storage = true;
+ int const size () const {
+ return sizeof(_vertices);
+ }
+
+ private:
+ /* @param x x position in pixels where 0 is left and canvas_width is right on screen */
+ float x_pixels_to_gl(int x) const {
+ return (x * 2.0f / _canvas_size.GetWidth()) - 1.0f;
+ }
+
+ /* @param y y position in pixels where 0 is top and canvas_height is bottom on screen */
+ float y_pixels_to_gl(int y) const {
+ return 1.0f - (y * 2.0f / _canvas_size.GetHeight());
+ }
+
+ wxSize _canvas_size;
+ float _vertices[20];
+ };
+
+ auto const sizing_changed = _last_canvas_size.changed() || _last_inter_position.changed() || _last_inter_size.changed() || _last_out_size.changed();
+
+ if (sizing_changed) {
+ const auto video = _optimise_for_j2k ?
+ Rectangle(canvas_size, inter_position.x + x_offset, inter_position.y + y_offset, inter_size)
+ : Rectangle(canvas_size, x_offset, y_offset, out_size);
+
+ glBufferSubData (GL_ARRAY_BUFFER, array_buffer_video_offset, video.size(), video.vertices());
+ check_gl_error ("glBufferSubData (video)");
+
+ const auto outline_content = Rectangle(canvas_size, inter_position.x + x_offset, inter_position.y + y_offset, inter_size);
+ glBufferSubData (GL_ARRAY_BUFFER, array_buffer_outline_content_offset, outline_content.size(), outline_content.vertices());
+ check_gl_error ("glBufferSubData (outline_content)");
+ }
+
+ if ((sizing_changed || _last_crop_guess.changed()) && crop_guess) {
+ auto const crop_guess_rectangle = Rectangle(
+ canvas_size,
+ inter_position.x + x_offset + inter_size.width * crop_guess->x,
+ inter_position.y + y_offset + inter_size.height * crop_guess->y,
+ dcp::Size(inter_size.width * crop_guess->width, inter_size.height * crop_guess->height)
+ );
+ glBufferSubData (GL_ARRAY_BUFFER, array_buffer_crop_guess_offset, crop_guess_rectangle.size(), crop_guess_rectangle.vertices());
+ check_gl_error ("glBufferSubData (crop_guess_rectangle)");
+ }
+
+ if (_have_subtitle_to_render) {
+ const auto subtitle = Rectangle(canvas_size, inter_position.x + x_offset + text->position.x, inter_position.y + y_offset + text->position.y, text->image->size());
+ glBufferSubData (GL_ARRAY_BUFFER, array_buffer_subtitle_offset, subtitle.size(), subtitle.vertices());
+ check_gl_error ("glBufferSubData (subtitle)");