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);
|
||||
const gchar *glx_extensions = NULL;
|
||||
const gchar *gl_extensions = NULL;
|
||||
ClutterFeatureFlags flags;
|
||||
gboolean use_dri = FALSE;
|
||||
|
||||
@ -242,6 +243,8 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||
|
||||
CLUTTER_NOTE (BACKEND, " GLX Extensions: %s", glx_extensions);
|
||||
|
||||
gl_extensions = (const gchar *)glGetString (GL_EXTENSIONS);
|
||||
|
||||
use_dri = check_vblank_env ("dri");
|
||||
|
||||
/* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
|
||||
@ -363,6 +366,15 @@ vblank_setup_done:
|
||||
{
|
||||
backend_glx->copy_sub_buffer =
|
||||
(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");
|
||||
@ -464,6 +476,29 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
|
||||
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 *
|
||||
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
|
@ -60,6 +60,16 @@ typedef int (*SwapIntervalProc) (int interval);
|
||||
typedef void (*CopySubBufferProc)(Display *dpy,
|
||||
GLXDrawable drawable,
|
||||
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
|
||||
{
|
||||
@ -82,7 +92,9 @@ struct _ClutterBackendGLX
|
||||
gint dri_fd;
|
||||
ClutterGLXVBlankType vblank_type;
|
||||
|
||||
gboolean can_blit_sub_buffer;
|
||||
CopySubBufferProc copy_sub_buffer;
|
||||
BlitFramebufferProc blit_framebuffer;
|
||||
|
||||
/* props */
|
||||
Atom atom_WM_STATE;
|
||||
@ -100,6 +112,11 @@ gboolean
|
||||
_clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_x11,
|
||||
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
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_GLX_H__ */
|
||||
|
@ -547,10 +547,10 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
||||
"glXSwapBuffers",
|
||||
"The time spent blocked by glXSwapBuffers",
|
||||
0 /* no application private data */);
|
||||
CLUTTER_STATIC_TIMER (copy_sub_buffer_timer,
|
||||
CLUTTER_STATIC_TIMER (blit_sub_buffer_timer,
|
||||
"Redrawing", /* parent */
|
||||
"glXCopySubBufferMESA",
|
||||
"The time spent blocked by glXCopySubBufferMESA",
|
||||
"glx_blit_sub_buffer",
|
||||
"The time spent in _glx_blit_sub_buffer",
|
||||
0 /* no application private data */);
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
@ -561,7 +561,7 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
||||
|
||||
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 */
|
||||
(stage_glx->bounding_redraw_clip.width != 0) &&
|
||||
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));
|
||||
|
||||
/* 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 */
|
||||
(stage_glx->bounding_redraw_clip.width != 0) &&
|
||||
G_LIKELY (!(clutter_paint_debug_flags &
|
||||
@ -599,11 +599,9 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
||||
ClutterGeometry copy_area;
|
||||
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"glXCopySubBufferMESA (display: %p, "
|
||||
"window: 0x%lx, "
|
||||
"_glx_blit_sub_buffer (window: 0x%lx, "
|
||||
"x: %d, y: %d, "
|
||||
"width: %d, height: %d)",
|
||||
backend_x11->xdpy,
|
||||
(unsigned long) drawable,
|
||||
stage_glx->bounding_redraw_clip.x,
|
||||
stage_glx->bounding_redraw_clip.y,
|
||||
@ -660,14 +658,14 @@ clutter_stage_glx_redraw (ClutterStageGLX *stage_glx,
|
||||
copy_area.width = clip->width;
|
||||
copy_area.height = clip->height;
|
||||
|
||||
CLUTTER_TIMER_START (_clutter_uprof_context, copy_sub_buffer_timer);
|
||||
backend_glx->copy_sub_buffer (backend_x11->xdpy,
|
||||
drawable,
|
||||
copy_area.x,
|
||||
copy_area.y,
|
||||
copy_area.width,
|
||||
copy_area.height);
|
||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, copy_sub_buffer_timer);
|
||||
CLUTTER_TIMER_START (_clutter_uprof_context, blit_sub_buffer_timer);
|
||||
_clutter_backend_glx_blit_sub_buffer (backend_glx,
|
||||
drawable,
|
||||
copy_area.x,
|
||||
copy_area.y,
|
||||
copy_area.width,
|
||||
copy_area.height);
|
||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, blit_sub_buffer_timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user