Use GL_MESA_pack_invert if available

Use GL_MESA_pack_invert if available to avoid doing flipping in software.

https://bugzilla.gnome.org/show_bug.cgi?id=609053
This commit is contained in:
Adel Gadllah 2010-02-05 22:10:21 +01:00
parent 6f83b39ee4
commit c88d21d487

View File

@ -61,6 +61,8 @@ struct _ShellRecorder {
gboolean only_paint; /* Used to temporarily suppress recording */
gboolean have_pack_invert; /* True when GL_MESA_pack_invert is available */
char *pipeline_description;
char *filename;
gboolean filename_has_count; /* %c used: handle pausing differently */
@ -423,11 +425,14 @@ recorder_draw_cursor (ShellRecorder *recorder,
recorder->stage_height,
recorder->stage_width * 4);
/* The data we get from glReadPixels is "upside down", so transform
* our cairo drawing to match */
/* When not using GL_MESA_pack_invert the data we get from glReadPixels is "upside down",
* so transform our cairo drawing to match */
cr = cairo_create (surface);
cairo_translate(cr, 0, recorder->stage_height);
cairo_scale(cr, 1, -1);
if (!recorder->have_pack_invert)
{
cairo_translate(cr, 0, recorder->stage_height);
cairo_scale(cr, 1, -1);
}
cairo_set_source_surface (cr,
recorder->cursor_image,
@ -522,6 +527,9 @@ recorder_record_frame (ShellRecorder *recorder)
glPixelStorei (GL_PACK_SKIP_PIXELS, 0);
glPixelStorei (GL_PACK_SKIP_ROWS, 0);
if (recorder->have_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, TRUE);
glReadBuffer (GL_BACK_LEFT);
glReadPixels (0, 0,
recorder->stage_width, recorder->stage_height,
@ -529,6 +537,9 @@ recorder_record_frame (ShellRecorder *recorder)
GL_UNSIGNED_INT_8_8_8_8_REV,
data);
if (recorder->have_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, FALSE);
recorder_draw_cursor (recorder, buffer);
shell_recorder_src_add_buffer (SHELL_RECORDER_SRC (recorder->current_pipeline->src), buffer);
@ -830,6 +841,7 @@ recorder_set_stage (ShellRecorder *recorder,
if (recorder->stage)
{
int error_base;
const char *gl_extensions;
recorder->stage = stage;
g_signal_connect (recorder->stage, "destroy",
@ -853,6 +865,10 @@ recorder_set_stage (ShellRecorder *recorder,
clutter_x11_get_stage_window (stage),
XFixesDisplayCursorNotifyMask);
clutter_stage_ensure_current (stage);
gl_extensions = (const char *)glGetString (GL_EXTENSIONS);
recorder->have_pack_invert = cogl_check_extension ("GL_MESA_pack_invert", gl_extensions);
recorder_get_initial_cursor_position (recorder);
}
}
@ -1052,31 +1068,38 @@ recorder_pipeline_add_source (RecorderPipeline *pipeline)
gst_bin_add (GST_BIN (pipeline->pipeline), ffmpegcolorspace);
/* glReadPixels gives us an upside-down buffer, so we have to flip it back
* right-side up. We do this after the color space conversion in the theory
* that we might have a smaller buffer to flip; on the other hand flipping
* YUV 422 is more complicated than flipping RGB. Probably a toss-up.
* right-side up.
*
* When available MESA_pack_invert extension could be used to avoid the
* When available MESA_pack_invert extension is used to avoid the
* flip entirely, since the data is actually stored in the frame buffer
* in the order that we expect.
*
* We use gst_parse_launch to avoid having to know the enum value for flip-vertical
*/
videoflip = gst_parse_launch_full ("videoflip method=vertical-flip", NULL,
GST_PARSE_FLAG_FATAL_ERRORS,
&error);
if (videoflip == NULL)
if (!pipeline->recorder->have_pack_invert)
{
g_warning("Can't create videoflip element: %s", error->message);
g_error_free (error);
goto out;
videoflip = gst_parse_launch_full ("videoflip method=vertical-flip", NULL,
GST_PARSE_FLAG_FATAL_ERRORS,
&error);
if (videoflip == NULL)
{
g_warning("Can't create videoflip element: %s", error->message);
g_error_free (error);
goto out;
}
gst_bin_add (GST_BIN (pipeline->pipeline), videoflip);
gst_element_link_many (pipeline->src, ffmpegcolorspace, videoflip, NULL);
src_pad = gst_element_get_static_pad (videoflip, "src");
}
else
{
gst_element_link_many (pipeline->src, ffmpegcolorspace, NULL);
src_pad = gst_element_get_static_pad (ffmpegcolorspace, "src");
}
gst_bin_add (GST_BIN (pipeline->pipeline), videoflip);
gst_element_link_many (pipeline->src, ffmpegcolorspace, videoflip,
NULL);
src_pad = gst_element_get_static_pad (videoflip, "src");
if (!src_pad)
{
g_warning("ShellRecorder: can't get src pad to link into pipeline");