Adds cogl_onscreen_show/hide functions

This adds Cogl API to show and hide onscreen framebuffers. We don't want
to go too far down the road of abstracting window system APIs with Cogl
since that would be out of its scope but the previous idea that we would
automatically map framebuffers on allocation except for those made from
foreign windows wasn't good enough. The problem is that we don't want to
make Clutter always create stages from foreign windows but with the
automatic map semantics then Clutter doesn't get an opportunity to
select for all the events it requires before mapping. This meant that we
wouldn't be delivered a mouse enter event for windows mapped underneath
the cursor which would break Clutters handling of button press events.
This commit is contained in:
Robert Bragg 2011-05-04 11:10:54 +01:00
parent 2a150003ad
commit 97243ad9ac
6 changed files with 123 additions and 4 deletions

View File

@ -1690,3 +1690,34 @@ cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
winsys->onscreen_update_swap_throttled (onscreen); winsys->onscreen_update_swap_throttled (onscreen);
} }
} }
void
cogl_onscreen_show (CoglOnscreen *onscreen)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
const CoglWinsysVtable *winsys;
if (!framebuffer->allocated)
{
if (!cogl_framebuffer_allocate (framebuffer, NULL))
return;
}
winsys = _cogl_framebuffer_get_winsys (framebuffer);
if (winsys->onscreen_set_visibility)
winsys->onscreen_set_visibility (onscreen, TRUE);
}
void
cogl_onscreen_hide (CoglOnscreen *onscreen)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
if (framebuffer->allocated)
{
const CoglWinsysVtable *winsys =
_cogl_framebuffer_get_winsys (framebuffer);
if (winsys->onscreen_set_visibility)
winsys->onscreen_set_visibility (onscreen, FALSE);
}
}

View File

@ -106,6 +106,58 @@ void
cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
gboolean throttled); gboolean throttled);
/**
* cogl_onscreen_show:
* @onscreen: The onscreen framebuffer to make visible
*
* This requests to make @onscreen visible to the user.
*
* Actually the precise semantics of this function depend on the
* window system currently in use, and if you don't have a
* multi-windowining system this function may in-fact do nothing.
*
* This function will implicitly allocate the given @onscreen
* framebuffer before showing it if it hasn't already been allocated.
*
* <note>Since Cogl doesn't explicitly track the visibility status of
* onscreen framebuffers it wont try to avoid redundant window system
* requests e.g. to show an already visible window. This also means
* that it's acceptable to alternatively use native APIs to show and
* hide windows without confusing Cogl.</note>
*
* Since: 2.0
* Stability: Unstable
*/
#define cogl_onscreen_show cogl_onscreen_show_EXP
void
cogl_onscreen_show (CoglOnscreen *onscreen);
/**
* cogl_onscreen_hide:
* @onscreen: The onscreen framebuffer to make invisible
*
* This requests to make @onscreen invisible to the user.
*
* Actually the precise semantics of this function depend on the
* window system currently in use, and if you don't have a
* multi-windowining system this function may in-fact do nothing.
*
* This function does not implicitly allocate the given @onscreen
* framebuffer before hiding it.
*
* <note>Since Cogl doesn't explicitly track the visibility status of
* onscreen framebuffers it wont try to avoid redundant window system
* requests e.g. to show an already visible window. This also means
* that it's acceptable to alternatively use native APIs to show and
* hide windows without confusing Cogl.</note>
*
* Since: 2.0
* Stability: Unstable
*/
#define cogl_onscreen_hide cogl_onscreen_hide_EXP
void
cogl_onscreen_hide (CoglOnscreen *onscreen);
#define cogl_get_draw_framebuffer cogl_get_draw_framebuffer_EXP #define cogl_get_draw_framebuffer cogl_get_draw_framebuffer_EXP
CoglFramebuffer * CoglFramebuffer *
cogl_get_draw_framebuffer (void); cogl_get_draw_framebuffer (void);

View File

@ -971,8 +971,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
XFree (xvisinfo); XFree (xvisinfo);
XMapWindow (xlib_renderer->xdpy, xwin);
XSync (xlib_renderer->xdpy, False); XSync (xlib_renderer->xdpy, False);
xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state);
if (xerror) if (xerror)
@ -1127,6 +1125,22 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
g_warning ("Error reported by eglSwapBuffersRegion"); g_warning ("Error reported by eglSwapBuffersRegion");
} }
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
static void
_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
gboolean visibility)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
CoglRendererXlib *xlib_renderer = context->display->renderer->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
if (visibility)
XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
else
XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
}
#endif
static guint32 static guint32
_cogl_winsys_get_vsync_counter (void) _cogl_winsys_get_vsync_counter (void)
{ {
@ -1229,6 +1243,9 @@ static CoglWinsysVtable _cogl_winsys_vtable =
.onscreen_bind = _cogl_winsys_onscreen_bind, .onscreen_bind = _cogl_winsys_onscreen_bind,
.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers, .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
.onscreen_swap_region = _cogl_winsys_onscreen_swap_region, .onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
#endif
.onscreen_update_swap_throttled = .onscreen_update_swap_throttled =
_cogl_winsys_onscreen_update_swap_throttled, _cogl_winsys_onscreen_update_swap_throttled,
.onscreen_x11_get_window_xid = .onscreen_x11_get_window_xid =

View File

@ -806,8 +806,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
XFree (xvisinfo); XFree (xvisinfo);
XMapWindow (xlib_renderer->xdpy, xwin);
XSync (xlib_renderer->xdpy, False); XSync (xlib_renderer->xdpy, False);
xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state);
if (xerror) if (xerror)
@ -1324,6 +1322,20 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
_cogl_winsys_onscreen_bind (onscreen); _cogl_winsys_onscreen_bind (onscreen);
} }
static void
_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
gboolean visibility)
{
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
CoglRendererXlib *xlib_renderer = context->display->renderer->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
if (visibility)
XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
else
XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
}
/* XXX: This is a particularly hacky _cogl_winsys interface... */ /* XXX: This is a particularly hacky _cogl_winsys interface... */
static XVisualInfo * static XVisualInfo *
_cogl_winsys_xlib_get_visual_info (void) _cogl_winsys_xlib_get_visual_info (void)
@ -1904,6 +1916,7 @@ static CoglWinsysVtable _cogl_winsys_vtable =
_cogl_winsys_onscreen_add_swap_buffers_callback, _cogl_winsys_onscreen_add_swap_buffers_callback,
.onscreen_remove_swap_buffers_callback = .onscreen_remove_swap_buffers_callback =
_cogl_winsys_onscreen_remove_swap_buffers_callback, _cogl_winsys_onscreen_remove_swap_buffers_callback,
.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
.get_vsync_counter = _cogl_winsys_get_vsync_counter, .get_vsync_counter = _cogl_winsys_get_vsync_counter,
/* X11 tfp support... */ /* X11 tfp support... */

View File

@ -122,6 +122,10 @@ typedef struct _CoglWinsysVtable
(*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen, (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen,
unsigned int id); unsigned int id);
void
(*onscreen_set_visibility) (CoglOnscreen *onscreen,
gboolean visibility);
guint32 guint32
(*get_vsync_counter) (void); (*get_vsync_counter) (void);

View File

@ -34,6 +34,8 @@ main (int argc, char **argv)
return 1; return 1;
} }
cogl_onscreen_show (onscreen);
cogl_push_framebuffer (fb); cogl_push_framebuffer (fb);
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES, triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,