+ auto const canvas_size = _canvas_size.load();
+ int const canvas_width = canvas_size.GetWidth();
+ int const canvas_height = canvas_size.GetHeight();
+ auto inter_position = player_video().first->inter_position();
+ auto inter_size = player_video().first->inter_size();
+ auto out_size = player_video().first->out_size();
+
+ _last_canvas_size.set_next (canvas_size);
+ _last_video_size.set_next (video->size());
+ _last_inter_position.set_next (inter_position);
+ _last_inter_size.set_next (inter_size);
+ _last_out_size.set_next (out_size);
+
+ 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;
+ };
+
+ if (_last_canvas_size.changed() || _last_inter_position.changed() || _last_inter_size.changed() || _last_out_size.changed()) {
+ float const video_x1 = x_pixels_to_gl(_optimise_for_j2k ? inter_position.x : 0);
+ float const video_x2 = x_pixels_to_gl(_optimise_for_j2k ? (inter_position.x + inter_size.width) : out_size.width);
+ float const video_y1 = y_pixels_to_gl(_optimise_for_j2k ? inter_position.y : 0);
+ float const video_y2 = y_pixels_to_gl(_optimise_for_j2k ? (inter_position.y + inter_size.height) : out_size.height);
+ float video_vertices[] = {
+ // positions // texture coords
+ video_x2, video_y2, 0.0f, 1.0f, 0.0f, // video texture top right (index 0)
+ video_x2, video_y1, 0.0f, 1.0f, 1.0f, // video texture bottom right (index 1)
+ video_x1, video_y1, 0.0f, 0.0f, 1.0f, // video texture bottom left (index 2)
+ video_x1, video_y2, 0.0f, 0.0f, 0.0f, // video texture top left (index 3)
+ };
+
+ glBufferSubData (GL_ARRAY_BUFFER, 0, sizeof(video_vertices), video_vertices);
+ check_gl_error ("glBufferSubData (video)");
+
+ float const border_x1 = x_pixels_to_gl(inter_position.x);
+ float const border_y1 = y_pixels_to_gl(inter_position.y);
+ float const border_x2 = x_pixels_to_gl(inter_position.x + inter_size.width);
+ float const border_y2 = y_pixels_to_gl(inter_position.y + inter_size.height);
+
+ float border_vertices[] = {
+ // positions // texture coords
+ 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)
+ };
+
+ glBufferSubData (GL_ARRAY_BUFFER, 8 * 5 * sizeof(float), sizeof(border_vertices), border_vertices);
+ check_gl_error ("glBufferSubData (border)");
+ }
+
+ if (_have_subtitle_to_render) {
+ float const subtitle_x1 = x_pixels_to_gl(inter_position.x + text->position.x);
+ float const subtitle_x2 = x_pixels_to_gl(inter_position.x + text->position.x + text->image->size().width);
+ float const subtitle_y1 = y_pixels_to_gl(inter_position.y + text->position.y + text->image->size().height);
+ float const subtitle_y2 = y_pixels_to_gl(inter_position.y + text->position.y);
+
+ float vertices[] = {
+ // positions // texture coords
+ subtitle_x2, subtitle_y1, 0.0f, 1.0f, 0.0f, // subtitle texture top right (index 4)
+ subtitle_x2, subtitle_y2, 0.0f, 1.0f, 1.0f, // subtitle texture bottom right (index 5)
+ subtitle_x1, subtitle_y2, 0.0f, 0.0f, 1.0f, // subtitle texture bottom left (index 6)
+ subtitle_x1, subtitle_y1, 0.0f, 0.0f, 0.0f, // subtitle texture top left (index 7)
+ };
+
+ glBufferSubData (GL_ARRAY_BUFFER, 4 * 5 * sizeof(float), sizeof(vertices), vertices);
+ check_gl_error ("glBufferSubData (subtitle)");
+ }
+
+ /* opt: where should these go? */