backend-glx: Provide copy_sub_buffer fallback
Currently glXCopySubBufferMESA is used for sub stage redraws, but in case a driver does not support GLX_MESA_copy_sub_buffer we fall back to redrawing the complete stage which isn't really optimal. So instead to directly fallback to complete redraws try using GL_EXT_framebuffer_blit to do the BACK to FRONT buffer copies. http://bugzilla.openedhand.com/show_bug.cgi?id=2128
This commit is contained in:
parent
ac3e0150ed
commit
630a2c5edc
@ -215,6 +215,7 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
|||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||||
const gchar *glx_extensions = NULL;
|
const gchar *glx_extensions = NULL;
|
||||||
|
const gchar *gl_extensions = NULL;
|
||||||
ClutterFeatureFlags flags;
|
ClutterFeatureFlags flags;
|
||||||
gboolean use_dri = FALSE;
|
gboolean use_dri = FALSE;
|
||||||
|
|
||||||
@ -242,6 +243,8 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
|||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, " GLX Extensions: %s", glx_extensions);
|
CLUTTER_NOTE (BACKEND, " GLX Extensions: %s", glx_extensions);
|
||||||
|
|
||||||
|
gl_extensions = (const gchar *)glGetString (GL_EXTENSIONS);
|
||||||
|
|
||||||
use_dri = check_vblank_env ("dri");
|
use_dri = check_vblank_env ("dri");
|
||||||
|
|
||||||
/* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
|
/* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
|
||||||
@ -363,6 +366,15 @@ vblank_setup_done:
|
|||||||
{
|
{
|
||||||
backend_glx->copy_sub_buffer =
|
backend_glx->copy_sub_buffer =
|
||||||
(CopySubBufferProc) cogl_get_proc_address ("glXCopySubBufferMESA");
|
(CopySubBufferProc) cogl_get_proc_address ("glXCopySubBufferMESA");
|
||||||
|
backend_glx->can_blit_sub_buffer = TRUE;
|
||||||
|
}
|
||||||
|
else if (_cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions))
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (BACKEND,
|
||||||
|
"Using glBlitFramebuffer fallback for sub_buffer copies");
|
||||||
|
backend_glx->blit_framebuffer =
|
||||||
|
(BlitFramebufferProc) cogl_get_proc_address ("glBlitFramebuffer");
|
||||||
|
backend_glx->can_blit_sub_buffer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "backend features checked");
|
CLUTTER_NOTE (BACKEND, "backend features checked");
|
||||||
@ -464,6 +476,29 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_backend_glx_blit_sub_buffer (ClutterBackendGLX *backend_glx,
|
||||||
|
GLXDrawable drawable,
|
||||||
|
int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);
|
||||||
|
|
||||||
|
if (backend_glx->copy_sub_buffer)
|
||||||
|
{
|
||||||
|
backend_glx->copy_sub_buffer (backend_x11->xdpy, drawable,
|
||||||
|
x, y, width, height);
|
||||||
|
}
|
||||||
|
else if (backend_glx->blit_framebuffer)
|
||||||
|
{
|
||||||
|
glDrawBuffer (GL_FRONT);
|
||||||
|
backend_glx->blit_framebuffer (x, y, x + width, y + height,
|
||||||
|
x, y, x + width, y + height,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
glDrawBuffer (GL_BACK);
|
||||||
|
glFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static XVisualInfo *
|
static XVisualInfo *
|
||||||
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11)
|
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +60,16 @@ typedef int (*SwapIntervalProc) (int interval);
|
|||||||
typedef void (*CopySubBufferProc)(Display *dpy,
|
typedef void (*CopySubBufferProc)(Display *dpy,
|
||||||
GLXDrawable drawable,
|
GLXDrawable drawable,
|
||||||
int x, int y, int width, int height);
|
int x, int y, int width, int height);
|
||||||
|
typedef void (*BlitFramebufferProc) (GLint srcX0,
|
||||||
|
GLint srcY0,
|
||||||
|
GLint srcX1,
|
||||||
|
GLint srcY1,
|
||||||
|
GLint dstX0,
|
||||||
|
GLint dstY0,
|
||||||
|
GLint dstX1,
|
||||||
|
GLint dstY1,
|
||||||
|
GLbitfield mask,
|
||||||
|
GLenum filter);
|
||||||
|
|
||||||
struct _ClutterBackendGLX
|
struct _ClutterBackendGLX
|
||||||
{
|
{
|
||||||
@ -82,7 +92,9 @@ struct _ClutterBackendGLX
|
|||||||
gint dri_fd;
|
gint dri_fd;
|
||||||
ClutterGLXVBlankType vblank_type;
|
ClutterGLXVBlankType vblank_type;
|
||||||
|
|
||||||
|
gboolean can_blit_sub_buffer;
|
||||||
CopySubBufferProc copy_sub_buffer;
|
CopySubBufferProc copy_sub_buffer;
|
||||||
|
BlitFramebufferProc blit_framebuffer;
|
||||||
|
|
||||||
/* props */
|
/* props */
|
||||||
Atom atom_WM_STATE;
|
Atom atom_WM_STATE;
|
||||||
@ -100,6 +112,11 @@ gboolean
|
|||||||
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_x11,
|
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_x11,
|
||||||
GLXFBConfig *config);
|
GLXFBConfig *config);
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_backend_glx_blit_sub_buffer (ClutterBackendGLX *backend_glx,
|
||||||
|
GLXDrawable drawable,
|
||||||
|
int x, int y, int width, int height);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_BACKEND_GLX_H__ */
|
#endif /* __CLUTTER_BACKEND_GLX_H__ */
|
||||||
|
@ -547,10 +547,10 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
|||||||
"glXSwapBuffers",
|
"glXSwapBuffers",
|
||||||
"The time spent blocked by glXSwapBuffers",
|
"The time spent blocked by glXSwapBuffers",
|
||||||
0 /* no application private data */);
|
0 /* no application private data */);
|
||||||
CLUTTER_STATIC_TIMER (copy_sub_buffer_timer,
|
CLUTTER_STATIC_TIMER (blit_sub_buffer_timer,
|
||||||
"Redrawing", /* parent */
|
"Redrawing", /* parent */
|
||||||
"glXCopySubBufferMESA",
|
"glx_blit_sub_buffer",
|
||||||
"The time spent blocked by glXCopySubBufferMESA",
|
"The time spent in _glx_blit_sub_buffer",
|
||||||
0 /* no application private data */);
|
0 /* no application private data */);
|
||||||
|
|
||||||
backend = clutter_get_default_backend ();
|
backend = clutter_get_default_backend ();
|
||||||
@ -561,7 +561,7 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
|||||||
|
|
||||||
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
|
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
|
||||||
|
|
||||||
if (backend_glx->copy_sub_buffer &&
|
if (backend_glx->can_blit_sub_buffer &&
|
||||||
/* NB: a degenerate redraw clip width == full stage redraw */
|
/* NB: a degenerate redraw clip width == full stage redraw */
|
||||||
(stage_glx->bounding_redraw_clip.width != 0) &&
|
(stage_glx->bounding_redraw_clip.width != 0) &&
|
||||||
G_LIKELY (!(clutter_paint_debug_flags &
|
G_LIKELY (!(clutter_paint_debug_flags &
|
||||||
@ -589,7 +589,7 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
|||||||
glx_wait_for_vblank (CLUTTER_BACKEND_GLX (backend));
|
glx_wait_for_vblank (CLUTTER_BACKEND_GLX (backend));
|
||||||
|
|
||||||
/* push on the screen */
|
/* push on the screen */
|
||||||
if (backend_glx->copy_sub_buffer &&
|
if (backend_glx->can_blit_sub_buffer &&
|
||||||
/* NB: a degenerate redraw clip width == full stage redraw */
|
/* NB: a degenerate redraw clip width == full stage redraw */
|
||||||
(stage_glx->bounding_redraw_clip.width != 0) &&
|
(stage_glx->bounding_redraw_clip.width != 0) &&
|
||||||
G_LIKELY (!(clutter_paint_debug_flags &
|
G_LIKELY (!(clutter_paint_debug_flags &
|
||||||
@ -599,11 +599,9 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
|||||||
ClutterGeometry copy_area;
|
ClutterGeometry copy_area;
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
CLUTTER_NOTE (BACKEND,
|
||||||
"glXCopySubBufferMESA (display: %p, "
|
"_glx_blit_sub_buffer (window: 0x%lx, "
|
||||||
"window: 0x%lx, "
|
|
||||||
"x: %d, y: %d, "
|
"x: %d, y: %d, "
|
||||||
"width: %d, height: %d)",
|
"width: %d, height: %d)",
|
||||||
backend_x11->xdpy,
|
|
||||||
(unsigned long) drawable,
|
(unsigned long) drawable,
|
||||||
stage_glx->bounding_redraw_clip.x,
|
stage_glx->bounding_redraw_clip.x,
|
||||||
stage_glx->bounding_redraw_clip.y,
|
stage_glx->bounding_redraw_clip.y,
|
||||||
@ -660,14 +658,14 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
|||||||
copy_area.width = clip->width;
|
copy_area.width = clip->width;
|
||||||
copy_area.height = clip->height;
|
copy_area.height = clip->height;
|
||||||
|
|
||||||
CLUTTER_TIMER_START (_clutter_uprof_context, copy_sub_buffer_timer);
|
CLUTTER_TIMER_START (_clutter_uprof_context, blit_sub_buffer_timer);
|
||||||
backend_glx->copy_sub_buffer (backend_x11->xdpy,
|
_clutter_backend_glx_blit_sub_buffer (backend_glx,
|
||||||
drawable,
|
drawable,
|
||||||
copy_area.x,
|
copy_area.x,
|
||||||
copy_area.y,
|
copy_area.y,
|
||||||
copy_area.width,
|
copy_area.width,
|
||||||
copy_area.height);
|
copy_area.height);
|
||||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, copy_sub_buffer_timer);
|
CLUTTER_TIMER_STOP (_clutter_uprof_context, blit_sub_buffer_timer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user