eglglessink: Only draw black borders if the default swap behaviour of the surface is to destroy the buffer

This commit is contained in:
Sebastian Dröge 2012-10-18 10:20:26 +02:00
parent a025c80b4c
commit 147edd1fc2
2 changed files with 109 additions and 92 deletions

View file

@ -1117,6 +1117,7 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
EGLint display_par; EGLint display_par;
const gchar *texnames[3] = { NULL, }; const gchar *texnames[3] = { NULL, };
gchar *tmp_prog = NULL; gchar *tmp_prog = NULL;
EGLint swap_behavior;
GST_DEBUG_OBJECT (eglglessink, "Enter EGL surface setup"); GST_DEBUG_OBJECT (eglglessink, "Enter EGL surface setup");
@ -1131,6 +1132,16 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
goto HANDLE_EGL_ERROR_LOCKED; goto HANDLE_EGL_ERROR_LOCKED;
} }
eglglessink->eglglesctx.buffer_preserved = FALSE;
if (eglQuerySurface (eglglessink->eglglesctx.display,
eglglessink->eglglesctx.surface, EGL_SWAP_BEHAVIOR, &swap_behavior)) {
GST_DEBUG_OBJECT (eglglessink, "Buffer swap behavior %x", swap_behavior);
eglglessink->eglglesctx.buffer_preserved =
swap_behavior == EGL_BUFFER_PRESERVED;
} else {
GST_DEBUG_OBJECT (eglglessink, "Can't query buffer swap behavior");
}
if (!gst_eglglessink_context_make_current (eglglessink, TRUE)) if (!gst_eglglessink_context_make_current (eglglessink, TRUE))
goto HANDLE_EGL_ERROR_LOCKED; goto HANDLE_EGL_ERROR_LOCKED;
@ -1368,90 +1379,93 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
if (got_gl_error ("glEnableVertexAttribArray")) if (got_gl_error ("glEnableVertexAttribArray"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
/* Build shader program for black borders */ if (!eglglessink->eglglesctx.buffer_preserved) {
eglglessink->eglglesctx.vertshader[1] = glCreateShader (GL_VERTEX_SHADER); /* Build shader program for black borders */
GST_DEBUG_OBJECT (eglglessink, "Sending %s to handle %d", vert_COPY_prog, eglglessink->eglglesctx.vertshader[1] = glCreateShader (GL_VERTEX_SHADER);
eglglessink->eglglesctx.vertshader[1]); GST_DEBUG_OBJECT (eglglessink, "Sending %s to handle %d", vert_COPY_prog,
glShaderSource (eglglessink->eglglesctx.vertshader[1], 1, eglglessink->eglglesctx.vertshader[1]);
&vert_COPY_prog_no_tex, NULL); glShaderSource (eglglessink->eglglesctx.vertshader[1], 1,
if (got_gl_error ("glShaderSource vertex")) &vert_COPY_prog_no_tex, NULL);
goto HANDLE_ERROR; if (got_gl_error ("glShaderSource vertex"))
goto HANDLE_ERROR;
glCompileShader (eglglessink->eglglesctx.vertshader[1]); glCompileShader (eglglessink->eglglesctx.vertshader[1]);
if (got_gl_error ("glCompileShader vertex")) if (got_gl_error ("glCompileShader vertex"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
glGetShaderiv (eglglessink->eglglesctx.vertshader[1], GL_COMPILE_STATUS, glGetShaderiv (eglglessink->eglglesctx.vertshader[1], GL_COMPILE_STATUS,
&test);
if (test != GL_FALSE)
GST_DEBUG_OBJECT (eglglessink, "Successfully compiled vertex shader");
else {
GST_ERROR_OBJECT (eglglessink, "Couldn't compile vertex shader");
glGetShaderiv (eglglessink->eglglesctx.vertshader[1], GL_INFO_LOG_LENGTH,
&test); &test);
info_log = g_new0 (GLchar, test); if (test != GL_FALSE)
glGetShaderInfoLog (eglglessink->eglglesctx.vertshader[1], test, NULL, GST_DEBUG_OBJECT (eglglessink, "Successfully compiled vertex shader");
info_log); else {
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log); GST_ERROR_OBJECT (eglglessink, "Couldn't compile vertex shader");
g_free (info_log); glGetShaderiv (eglglessink->eglglesctx.vertshader[1], GL_INFO_LOG_LENGTH,
goto HANDLE_ERROR; &test);
} info_log = g_new0 (GLchar, test);
glGetShaderInfoLog (eglglessink->eglglesctx.vertshader[1], test, NULL,
info_log);
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log);
g_free (info_log);
goto HANDLE_ERROR;
}
eglglessink->eglglesctx.fragshader[1] = glCreateShader (GL_FRAGMENT_SHADER); eglglessink->eglglesctx.fragshader[1] = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (eglglessink->eglglesctx.fragshader[1], 1, &frag_BLACK_prog, glShaderSource (eglglessink->eglglesctx.fragshader[1], 1, &frag_BLACK_prog,
NULL); NULL);
if (got_gl_error ("glShaderSource fragment")) if (got_gl_error ("glShaderSource fragment"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
glCompileShader (eglglessink->eglglesctx.fragshader[1]); glCompileShader (eglglessink->eglglesctx.fragshader[1]);
if (got_gl_error ("glCompileShader fragment")) if (got_gl_error ("glCompileShader fragment"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
glGetShaderiv (eglglessink->eglglesctx.fragshader[1], GL_COMPILE_STATUS, glGetShaderiv (eglglessink->eglglesctx.fragshader[1], GL_COMPILE_STATUS,
&test);
if (test != GL_FALSE)
GST_DEBUG_OBJECT (eglglessink, "Successfully compiled fragment shader");
else {
GST_ERROR_OBJECT (eglglessink, "Couldn't compile fragment shader");
glGetShaderiv (eglglessink->eglglesctx.fragshader[1], GL_INFO_LOG_LENGTH,
&test); &test);
info_log = g_new0 (GLchar, test); if (test != GL_FALSE)
glGetShaderInfoLog (eglglessink->eglglesctx.fragshader[1], test, NULL, GST_DEBUG_OBJECT (eglglessink, "Successfully compiled fragment shader");
info_log); else {
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log); GST_ERROR_OBJECT (eglglessink, "Couldn't compile fragment shader");
g_free (info_log); glGetShaderiv (eglglessink->eglglesctx.fragshader[1], GL_INFO_LOG_LENGTH,
goto HANDLE_ERROR; &test);
info_log = g_new0 (GLchar, test);
glGetShaderInfoLog (eglglessink->eglglesctx.fragshader[1], test, NULL,
info_log);
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log);
g_free (info_log);
goto HANDLE_ERROR;
}
eglglessink->eglglesctx.glslprogram[1] = glCreateProgram ();
if (got_gl_error ("glCreateProgram"))
goto HANDLE_ERROR;
glAttachShader (eglglessink->eglglesctx.glslprogram[1],
eglglessink->eglglesctx.vertshader[1]);
if (got_gl_error ("glAttachShader vertices"))
goto HANDLE_ERROR;
glAttachShader (eglglessink->eglglesctx.glslprogram[1],
eglglessink->eglglesctx.fragshader[1]);
if (got_gl_error ("glAttachShader fragments"))
goto HANDLE_ERROR;
glLinkProgram (eglglessink->eglglesctx.glslprogram[1]);
glGetProgramiv (eglglessink->eglglesctx.glslprogram[1], GL_LINK_STATUS,
&test);
if (test != GL_FALSE)
GST_DEBUG_OBJECT (eglglessink, "GLES: Successfully linked program");
else {
GST_ERROR_OBJECT (eglglessink, "Couldn't link program");
goto HANDLE_ERROR;
}
eglglessink->eglglesctx.position_loc[1] =
glGetAttribLocation (eglglessink->eglglesctx.glslprogram[1],
"position");
glEnableVertexAttribArray (eglglessink->eglglesctx.position_loc[1]);
if (got_gl_error ("glEnableVertexAttribArray"))
goto HANDLE_ERROR;
} }
eglglessink->eglglesctx.glslprogram[1] = glCreateProgram ();
if (got_gl_error ("glCreateProgram"))
goto HANDLE_ERROR;
glAttachShader (eglglessink->eglglesctx.glslprogram[1],
eglglessink->eglglesctx.vertshader[1]);
if (got_gl_error ("glAttachShader vertices"))
goto HANDLE_ERROR;
glAttachShader (eglglessink->eglglesctx.glslprogram[1],
eglglessink->eglglesctx.fragshader[1]);
if (got_gl_error ("glAttachShader fragments"))
goto HANDLE_ERROR;
glLinkProgram (eglglessink->eglglesctx.glslprogram[1]);
glGetProgramiv (eglglessink->eglglesctx.glslprogram[1], GL_LINK_STATUS,
&test);
if (test != GL_FALSE)
GST_DEBUG_OBJECT (eglglessink, "GLES: Successfully linked program");
else {
GST_ERROR_OBJECT (eglglessink, "Couldn't link program");
goto HANDLE_ERROR;
}
eglglessink->eglglesctx.position_loc[1] =
glGetAttribLocation (eglglessink->eglglesctx.glslprogram[1], "position");
glEnableVertexAttribArray (eglglessink->eglglesctx.position_loc[1]);
if (got_gl_error ("glEnableVertexAttribArray"))
goto HANDLE_ERROR;
glUseProgram (eglglessink->eglglesctx.glslprogram[0]); glUseProgram (eglglessink->eglglesctx.glslprogram[0]);
/* Generate and bind texture */ /* Generate and bind texture */
@ -1891,29 +1905,31 @@ gst_eglglessink_render_and_display (GstEglGlesSink * eglglessink,
} }
} }
/* Draw black borders */ if (!eglglessink->eglglesctx.buffer_preserved) {
GST_DEBUG_OBJECT (eglglessink, "Drawing black border 1"); /* Draw black borders */
glUseProgram (eglglessink->eglglesctx.glslprogram[1]); GST_DEBUG_OBJECT (eglglessink, "Drawing black border 1");
glUseProgram (eglglessink->eglglesctx.glslprogram[1]);
glVertexAttribPointer (eglglessink->eglglesctx.position_loc[1], 3, glVertexAttribPointer (eglglessink->eglglesctx.position_loc[1], 3,
GL_FLOAT, GL_FALSE, sizeof (coord5), (gpointer) (4 * sizeof (coord5))); GL_FLOAT, GL_FALSE, sizeof (coord5), (gpointer) (4 * sizeof (coord5)));
if (got_gl_error ("glVertexAttribPointer")) if (got_gl_error ("glVertexAttribPointer"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
if (got_gl_error ("glDrawElements")) if (got_gl_error ("glDrawElements"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
GST_DEBUG_OBJECT (eglglessink, "Drawing black border 2"); GST_DEBUG_OBJECT (eglglessink, "Drawing black border 2");
glVertexAttribPointer (eglglessink->eglglesctx.position_loc[1], 3, glVertexAttribPointer (eglglessink->eglglesctx.position_loc[1], 3,
GL_FLOAT, GL_FALSE, sizeof (coord5), (gpointer) (8 * sizeof (coord5))); GL_FLOAT, GL_FALSE, sizeof (coord5), (gpointer) (8 * sizeof (coord5)));
if (got_gl_error ("glVertexAttribPointer")) if (got_gl_error ("glVertexAttribPointer"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
if (got_gl_error ("glDrawElements")) if (got_gl_error ("glDrawElements"))
goto HANDLE_ERROR; goto HANDLE_ERROR;
}
/* Draw video frame */ /* Draw video frame */
GST_DEBUG_OBJECT (eglglessink, "Drawing video frame"); GST_DEBUG_OBJECT (eglglessink, "Drawing video frame");

View file

@ -122,6 +122,7 @@ struct _GstEglGlesRenderContext
EGLDisplay display; EGLDisplay display;
EGLNativeWindowType window, used_window; EGLNativeWindowType window, used_window;
EGLSurface surface; EGLSurface surface;
gboolean buffer_preserved;
GLuint fragshader[2], vertshader[2], glslprogram[2]; GLuint fragshader[2], vertshader[2], glslprogram[2];
GLuint texture[3]; GLuint texture[3];
EGLint surface_width; EGLint surface_width;