diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index 9712fe747..071b9ec88 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -1690,3 +1690,34 @@ cogl_onscreen_set_swap_throttled (CoglOnscreen *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); + } +} diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h index 120382fc3..3f4ecb8a5 100644 --- a/cogl/cogl-framebuffer.h +++ b/cogl/cogl-framebuffer.h @@ -106,6 +106,58 @@ void cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, 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. + * + * 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. + * + * 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. + * + * 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. + * + * 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 CoglFramebuffer * cogl_get_draw_framebuffer (void); diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index 61b733ecf..0ffd48b40 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -971,8 +971,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, XFree (xvisinfo); - XMapWindow (xlib_renderer->xdpy, xwin); - XSync (xlib_renderer->xdpy, False); xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); if (xerror) @@ -1127,6 +1125,22 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, 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 _cogl_winsys_get_vsync_counter (void) { @@ -1229,6 +1243,9 @@ static CoglWinsysVtable _cogl_winsys_vtable = .onscreen_bind = _cogl_winsys_onscreen_bind, .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers, .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 = _cogl_winsys_onscreen_update_swap_throttled, .onscreen_x11_get_window_xid = diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 1f115f2fe..47a207f2b 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -806,8 +806,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, XFree (xvisinfo); - XMapWindow (xlib_renderer->xdpy, xwin); - XSync (xlib_renderer->xdpy, False); xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); if (xerror) @@ -1324,6 +1322,20 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *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... */ static XVisualInfo * _cogl_winsys_xlib_get_visual_info (void) @@ -1904,6 +1916,7 @@ static CoglWinsysVtable _cogl_winsys_vtable = _cogl_winsys_onscreen_add_swap_buffers_callback, .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, /* X11 tfp support... */ diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h index e09fde99b..1e1fec042 100644 --- a/cogl/winsys/cogl-winsys-private.h +++ b/cogl/winsys/cogl-winsys-private.h @@ -122,6 +122,10 @@ typedef struct _CoglWinsysVtable (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen, unsigned int id); + void + (*onscreen_set_visibility) (CoglOnscreen *onscreen, + gboolean visibility); + guint32 (*get_vsync_counter) (void); diff --git a/examples/hello.c b/examples/hello.c index ace664fb5..62076ad0f 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -34,6 +34,8 @@ main (int argc, char **argv) return 1; } + cogl_onscreen_show (onscreen); + cogl_push_framebuffer (fb); triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,