Move event polling into CoglRenderer
This updates the cogl_poll_ apis to allow dispatching events before we have a CoglContext and to also enables pollfd state to be changed in a more add-hoc way by different Cogl components by replacing the winsys->get_poll_info with _cogl_poll_renderer_add/remove_fd functions and a winsys->get_dispatch_timeout vfunc. One of the intentions here is that applications should be able to run their mainloop before creating a CoglContext to potentially get events relating to CoglOutputs. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 667e58c9cb2662aef5f44e580a9eda42dc8d0176)
This commit is contained in:
parent
816a5bc437
commit
ed90c6fed9
@ -416,6 +416,7 @@ cogl_sources_c = \
|
|||||||
$(srcdir)/cogl-boxed-value.c \
|
$(srcdir)/cogl-boxed-value.c \
|
||||||
$(srcdir)/cogl-snippet-private.h \
|
$(srcdir)/cogl-snippet-private.h \
|
||||||
$(srcdir)/cogl-snippet.c \
|
$(srcdir)/cogl-snippet.c \
|
||||||
|
$(srcdir)/cogl-poll-private.h \
|
||||||
$(srcdir)/cogl-poll.c \
|
$(srcdir)/cogl-poll.c \
|
||||||
$(srcdir)/gl-prototypes/cogl-all-functions.h \
|
$(srcdir)/gl-prototypes/cogl-all-functions.h \
|
||||||
$(srcdir)/gl-prototypes/cogl-gles1-functions.h \
|
$(srcdir)/gl-prototypes/cogl-gles1-functions.h \
|
||||||
|
@ -206,6 +206,18 @@ cogl_context_new (CoglDisplay *display,
|
|||||||
|
|
||||||
context->display = display;
|
context->display = display;
|
||||||
|
|
||||||
|
/* Add a back reference to the context from the renderer because
|
||||||
|
* event dispatching is handled by the renderer and we don't
|
||||||
|
* currently have a generalized way of registering idle functions
|
||||||
|
* and such things internally so cogl_poll_renderer_dispatch()
|
||||||
|
* needs to poke inside the context if one is available to check
|
||||||
|
* if there are pending onscreen framebuffer events.
|
||||||
|
*
|
||||||
|
* FIXME: once we have a generalized way of registering idle
|
||||||
|
* functions then we can remove this back-reference.
|
||||||
|
*/
|
||||||
|
display->renderer->context = context;
|
||||||
|
|
||||||
/* This is duplicated data, but it's much more convenient to have
|
/* This is duplicated data, but it's much more convenient to have
|
||||||
the driver attached to the context and the value is accessed a
|
the driver attached to the context and the value is accessed a
|
||||||
lot throughout Cogl */
|
lot throughout Cogl */
|
||||||
@ -607,6 +619,12 @@ cogl_context_get_display (CoglContext *context)
|
|||||||
return context->display;
|
return context->display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoglRenderer *
|
||||||
|
cogl_context_get_renderer (CoglContext *context)
|
||||||
|
{
|
||||||
|
return context->display->renderer;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_SUPPORT
|
#ifdef COGL_HAS_EGL_SUPPORT
|
||||||
EGLDisplay
|
EGLDisplay
|
||||||
cogl_egl_context_get_egl_display (CoglContext *context)
|
cogl_egl_context_get_egl_display (CoglContext *context)
|
||||||
|
@ -125,6 +125,25 @@ cogl_context_new (CoglDisplay *display,
|
|||||||
CoglDisplay *
|
CoglDisplay *
|
||||||
cogl_context_get_display (CoglContext *context);
|
cogl_context_get_display (CoglContext *context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_context_get_renderer:
|
||||||
|
* @context: A #CoglContext pointer
|
||||||
|
*
|
||||||
|
* Retrieves the #CoglRenderer that is internally associated with the
|
||||||
|
* given @context. This will return the same #CoglRenderer that was
|
||||||
|
* passed to cogl_display_new() or if %NULL was passed to
|
||||||
|
* cogl_display_new() or cogl_context_new() then this function returns
|
||||||
|
* a pointer to the renderer that was automatically connected
|
||||||
|
* internally.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): The #CoglRenderer associated with the
|
||||||
|
* given @context.
|
||||||
|
* Since: 1.16
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
CoglRenderer *
|
||||||
|
cogl_context_get_renderer (CoglContext *context);
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
|
||||||
/**
|
/**
|
||||||
* cogl_android_set_native_window:
|
* cogl_android_set_native_window:
|
||||||
|
@ -32,31 +32,14 @@ typedef struct _CoglGLibSource
|
|||||||
{
|
{
|
||||||
GSource source;
|
GSource source;
|
||||||
|
|
||||||
CoglContext *context;
|
CoglRenderer *renderer;
|
||||||
|
|
||||||
GArray *poll_fds;
|
GArray *poll_fds;
|
||||||
|
int poll_fds_age;
|
||||||
|
|
||||||
int64_t expiration_time;
|
int64_t expiration_time;
|
||||||
} CoglGLibSource;
|
} CoglGLibSource;
|
||||||
|
|
||||||
static CoglBool
|
|
||||||
cogl_glib_source_poll_fds_changed (CoglGLibSource *cogl_source,
|
|
||||||
const CoglPollFD *poll_fds,
|
|
||||||
int n_poll_fds)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (cogl_source->poll_fds->len != n_poll_fds)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
for (i = 0; i < n_poll_fds; i++)
|
|
||||||
if (g_array_index (cogl_source->poll_fds, CoglPollFD, i).fd !=
|
|
||||||
poll_fds[i].fd)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
cogl_glib_source_prepare (GSource *source, int *timeout)
|
cogl_glib_source_prepare (GSource *source, int *timeout)
|
||||||
{
|
{
|
||||||
@ -64,18 +47,19 @@ cogl_glib_source_prepare (GSource *source, int *timeout)
|
|||||||
CoglPollFD *poll_fds;
|
CoglPollFD *poll_fds;
|
||||||
int n_poll_fds;
|
int n_poll_fds;
|
||||||
int64_t cogl_timeout;
|
int64_t cogl_timeout;
|
||||||
|
int age;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cogl_poll_get_info (cogl_source->context,
|
age = cogl_poll_renderer_get_info (cogl_source->renderer,
|
||||||
&poll_fds,
|
&poll_fds,
|
||||||
&n_poll_fds,
|
&n_poll_fds,
|
||||||
&cogl_timeout);
|
&cogl_timeout);
|
||||||
|
|
||||||
/* We have to be careful not to call g_source_add/remove_poll unless
|
/* We have to be careful not to call g_source_add/remove_poll unless
|
||||||
the FDs have changed because it will cause the main loop to
|
* the FDs have changed because it will cause the main loop to
|
||||||
immediately wake up. If we call it every time the source is
|
* immediately wake up. If we call it every time the source is
|
||||||
prepared it will effectively never go idle. */
|
* prepared it will effectively never go idle. */
|
||||||
if (cogl_glib_source_poll_fds_changed (cogl_source, poll_fds, n_poll_fds))
|
if (age != cogl_source->poll_fds_age)
|
||||||
{
|
{
|
||||||
/* Remove any existing polls before adding the new ones */
|
/* Remove any existing polls before adding the new ones */
|
||||||
for (i = 0; i < cogl_source->poll_fds->len; i++)
|
for (i = 0; i < cogl_source->poll_fds->len; i++)
|
||||||
@ -94,6 +78,8 @@ cogl_glib_source_prepare (GSource *source, int *timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cogl_source->poll_fds_age = age;
|
||||||
|
|
||||||
/* Update the events */
|
/* Update the events */
|
||||||
for (i = 0; i < n_poll_fds; i++)
|
for (i = 0; i < n_poll_fds; i++)
|
||||||
{
|
{
|
||||||
@ -147,7 +133,7 @@ cogl_glib_source_dispatch (GSource *source,
|
|||||||
CoglPollFD *poll_fds =
|
CoglPollFD *poll_fds =
|
||||||
(CoglPollFD *) &g_array_index (cogl_source->poll_fds, GPollFD, 0);
|
(CoglPollFD *) &g_array_index (cogl_source->poll_fds, GPollFD, 0);
|
||||||
|
|
||||||
cogl_poll_dispatch (cogl_source->context,
|
cogl_poll_renderer_dispatch (cogl_source->renderer,
|
||||||
poll_fds,
|
poll_fds,
|
||||||
cogl_source->poll_fds->len);
|
cogl_source->poll_fds->len);
|
||||||
|
|
||||||
@ -172,7 +158,7 @@ cogl_glib_source_funcs =
|
|||||||
};
|
};
|
||||||
|
|
||||||
GSource *
|
GSource *
|
||||||
cogl_glib_source_new (CoglContext *context,
|
cogl_glib_renderer_source_new (CoglRenderer *renderer,
|
||||||
int priority)
|
int priority)
|
||||||
{
|
{
|
||||||
GSource *source;
|
GSource *source;
|
||||||
@ -182,7 +168,7 @@ cogl_glib_source_new (CoglContext *context,
|
|||||||
sizeof (CoglGLibSource));
|
sizeof (CoglGLibSource));
|
||||||
cogl_source = (CoglGLibSource *) source;
|
cogl_source = (CoglGLibSource *) source;
|
||||||
|
|
||||||
cogl_source->context = context;
|
cogl_source->renderer = renderer;
|
||||||
cogl_source->poll_fds = g_array_new (FALSE, FALSE, sizeof (GPollFD));
|
cogl_source->poll_fds = g_array_new (FALSE, FALSE, sizeof (GPollFD));
|
||||||
|
|
||||||
if (priority != G_PRIORITY_DEFAULT)
|
if (priority != G_PRIORITY_DEFAULT)
|
||||||
@ -190,3 +176,13 @@ cogl_glib_source_new (CoglContext *context,
|
|||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSource *
|
||||||
|
cogl_glib_source_new (CoglContext *context,
|
||||||
|
int priority)
|
||||||
|
{
|
||||||
|
return cogl_glib_renderer_source_new (cogl_context_get_renderer (context),
|
||||||
|
priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,11 +40,21 @@ G_BEGIN_DECLS
|
|||||||
*
|
*
|
||||||
* Creates a #GSource which handles Cogl's internal system event
|
* Creates a #GSource which handles Cogl's internal system event
|
||||||
* processing. This can be used as a convenience instead of
|
* processing. This can be used as a convenience instead of
|
||||||
* cogl_poll_get_info() and cogl_poll_dispatch() in applications that
|
* cogl_poll_renderer_get_info() and cogl_poll_renderer_dispatch() in
|
||||||
* are already using the GLib main loop. After this is called the
|
* applications that are already using the GLib main loop. After this
|
||||||
* #GSource should be attached to the main loop using
|
* is called the #GSource should be attached to the main loop using
|
||||||
* g_source_attach().
|
* g_source_attach().
|
||||||
*
|
*
|
||||||
|
* Applications that manually connect to a #CoglRenderer before they
|
||||||
|
* create a #CoglContext should instead use
|
||||||
|
* cogl_glib_renderer_source_new() so that events may be dispatched
|
||||||
|
* before a context has been created. In that case you don't need to
|
||||||
|
* use this api in addition later, it is simply enough to use
|
||||||
|
* cogl_glib_renderer_source_new() instead.
|
||||||
|
*
|
||||||
|
* <note>This api is actually just a thin convenience wrapper around
|
||||||
|
* cogl_glib_renderer_source_new()</note>
|
||||||
|
*
|
||||||
* Return value: a new #GSource
|
* Return value: a new #GSource
|
||||||
*
|
*
|
||||||
* Stability: unstable
|
* Stability: unstable
|
||||||
@ -54,6 +64,27 @@ GSource *
|
|||||||
cogl_glib_source_new (CoglContext *context,
|
cogl_glib_source_new (CoglContext *context,
|
||||||
int priority);
|
int priority);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_glib_renderer_source_new:
|
||||||
|
* @context: A #CoglContext
|
||||||
|
* @priority: The priority of the #GSource
|
||||||
|
*
|
||||||
|
* Creates a #GSource which handles Cogl's internal system event
|
||||||
|
* processing. This can be used as a convenience instead of
|
||||||
|
* cogl_poll_renderer_get_info() and cogl_poll_renderer_dispatch() in
|
||||||
|
* applications that are already using the GLib main loop. After this
|
||||||
|
* is called the #GSource should be attached to the main loop using
|
||||||
|
* g_source_attach().
|
||||||
|
*
|
||||||
|
* Return value: a new #GSource
|
||||||
|
*
|
||||||
|
* Stability: unstable
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
GSource *
|
||||||
|
cogl_glib_renderer_source_new (CoglRenderer *renderer,
|
||||||
|
int priority);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_GSOURCE_H__ */
|
#endif /* __COGL_GSOURCE_H__ */
|
||||||
|
@ -50,9 +50,6 @@ typedef struct _CoglGLXDisplay
|
|||||||
GLXContext glx_context;
|
GLXContext glx_context;
|
||||||
GLXWindow dummy_glxwin;
|
GLXWindow dummy_glxwin;
|
||||||
Window dummy_xwin;
|
Window dummy_xwin;
|
||||||
CoglBool pending_sync_notify;
|
|
||||||
CoglBool pending_complete_notify;
|
|
||||||
CoglBool pending_resize_notify;
|
|
||||||
} CoglGLXDisplay;
|
} CoglGLXDisplay;
|
||||||
|
|
||||||
#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */
|
#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */
|
||||||
|
@ -54,6 +54,13 @@ typedef struct _CoglGLXRenderer
|
|||||||
/* GModule pointing to libGL which we use to get glX functions out of */
|
/* GModule pointing to libGL which we use to get glX functions out of */
|
||||||
GModule *libgl_module;
|
GModule *libgl_module;
|
||||||
|
|
||||||
|
/* Events get dispatched from the CoglRenderer and these are
|
||||||
|
* high-level flags that let us quickly check if there are any
|
||||||
|
* pending events to dispatch. */
|
||||||
|
CoglBool pending_sync_notify;
|
||||||
|
CoglBool pending_complete_notify;
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
|
|
||||||
/* Copy of the winsys features that are based purely on the
|
/* Copy of the winsys features that are based purely on the
|
||||||
* information we can get without using a GL context. We want to
|
* information we can get without using a GL context. We want to
|
||||||
* determine this before we have a context so that we can use the
|
* determine this before we have a context so that we can use the
|
||||||
|
@ -667,8 +667,8 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen);
|
|||||||
*
|
*
|
||||||
* <note>A resize callback will only ever be called while dispatching
|
* <note>A resize callback will only ever be called while dispatching
|
||||||
* Cogl events from the system mainloop; so for example during
|
* Cogl events from the system mainloop; so for example during
|
||||||
* cogl_poll_dispatch(). This is so that callbacks shouldn't occur
|
* cogl_poll_renderer_dispatch(). This is so that callbacks shouldn't
|
||||||
* while an application might have arbitrary locks held for
|
* occur while an application might have arbitrary locks held for
|
||||||
* example.</note>
|
* example.</note>
|
||||||
*
|
*
|
||||||
* Since: 2.0
|
* Since: 2.0
|
||||||
@ -716,8 +716,8 @@ typedef struct _CoglOnscreenResizeClosure CoglOnscreenResizeClosure;
|
|||||||
*
|
*
|
||||||
* <note>A resize callback will only ever be called while dispatching
|
* <note>A resize callback will only ever be called while dispatching
|
||||||
* Cogl events from the system mainloop; so for example during
|
* Cogl events from the system mainloop; so for example during
|
||||||
* cogl_poll_dispatch(). This is so that callbacks shouldn't occur
|
* cogl_poll_renderer_dispatch(). This is so that callbacks shouldn't
|
||||||
* while an application might have arbitrary locks held for
|
* occur while an application might have arbitrary locks held for
|
||||||
* example.</note>
|
* example.</note>
|
||||||
*
|
*
|
||||||
* Return value: a #CoglOnscreenResizeClosure pointer that can be used to
|
* Return value: a #CoglOnscreenResizeClosure pointer that can be used to
|
||||||
|
36
cogl/cogl-poll-private.h
Normal file
36
cogl/cogl-poll-private.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_POLL_PRIVATE_H__
|
||||||
|
#define __COGL_POLL_PRIVATE_H__
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
||||||
|
int fd,
|
||||||
|
CoglPollFDEvent events);
|
||||||
|
|
||||||
|
#endif /* __COGL_POLL_PRIVATE_H__ */
|
109
cogl/cogl-poll.c
109
cogl/cogl-poll.c
@ -28,57 +28,116 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cogl-poll.h"
|
#include "cogl-poll.h"
|
||||||
|
#include "cogl-poll-private.h"
|
||||||
#include "cogl-winsys-private.h"
|
#include "cogl-winsys-private.h"
|
||||||
|
#include "cogl-renderer-private.h"
|
||||||
#include "cogl-context-private.h"
|
#include "cogl-context-private.h"
|
||||||
|
|
||||||
void
|
int
|
||||||
cogl_poll_get_info (CoglContext *context,
|
cogl_poll_renderer_get_info (CoglRenderer *renderer,
|
||||||
CoglPollFD **poll_fds,
|
CoglPollFD **poll_fds,
|
||||||
int *n_poll_fds,
|
int *n_poll_fds,
|
||||||
int64_t *timeout)
|
int64_t *timeout)
|
||||||
{
|
{
|
||||||
const CoglWinsysVtable *winsys;
|
const CoglWinsysVtable *winsys;
|
||||||
|
|
||||||
_COGL_RETURN_IF_FAIL (cogl_is_context (context));
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), 0);
|
||||||
_COGL_RETURN_IF_FAIL (poll_fds != NULL);
|
_COGL_RETURN_VAL_IF_FAIL (poll_fds != NULL, 0);
|
||||||
_COGL_RETURN_IF_FAIL (n_poll_fds != NULL);
|
_COGL_RETURN_VAL_IF_FAIL (n_poll_fds != NULL, 0);
|
||||||
_COGL_RETURN_IF_FAIL (timeout != NULL);
|
_COGL_RETURN_VAL_IF_FAIL (timeout != NULL, 0);
|
||||||
|
|
||||||
winsys = _cogl_context_get_winsys (context);
|
*poll_fds = (void *)renderer->poll_fds->data;
|
||||||
|
*n_poll_fds = renderer->poll_fds->len;
|
||||||
|
|
||||||
if (winsys->poll_get_info)
|
/* NB: This will be NULL until the renderer has been connected,
|
||||||
|
* associated with a CoglDisplay and then a CoglContext is
|
||||||
|
* created from that display. */
|
||||||
|
if (renderer->context)
|
||||||
{
|
{
|
||||||
winsys->poll_get_info (context,
|
if (!COGL_TAILQ_EMPTY (&renderer->context->onscreen_events_queue))
|
||||||
poll_fds,
|
|
||||||
n_poll_fds,
|
|
||||||
timeout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* By default we'll assume Cogl doesn't need to block on anything */
|
|
||||||
*poll_fds = NULL;
|
|
||||||
*n_poll_fds = 0;
|
|
||||||
*timeout = -1; /* no timeout */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!COGL_TAILQ_EMPTY (&context->onscreen_events_queue))
|
|
||||||
*timeout = 0;
|
*timeout = 0;
|
||||||
|
return renderer->poll_fds_age;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
winsys = renderer->winsys_vtable;
|
||||||
|
|
||||||
|
if (winsys->get_dispatch_timeout)
|
||||||
|
*timeout = winsys->get_dispatch_timeout (renderer);
|
||||||
|
else
|
||||||
|
*timeout = -1;
|
||||||
|
|
||||||
|
return renderer->poll_fds_age;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_poll_dispatch (CoglContext *context,
|
cogl_poll_renderer_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
const CoglWinsysVtable *winsys;
|
const CoglWinsysVtable *winsys;
|
||||||
|
|
||||||
_COGL_RETURN_IF_FAIL (cogl_is_context (context));
|
_COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer));
|
||||||
|
|
||||||
|
/* FIXME: arbitrary cogl components should just be able to queue
|
||||||
|
* idle functions so that we don't have to explicitly poke into
|
||||||
|
* CoglContext here and understand about the CoglOnscreen event
|
||||||
|
* queue... */
|
||||||
|
if (renderer->context)
|
||||||
|
{
|
||||||
|
CoglContext *context = renderer->context;
|
||||||
|
|
||||||
if (!COGL_TAILQ_EMPTY (&context->onscreen_events_queue))
|
if (!COGL_TAILQ_EMPTY (&context->onscreen_events_queue))
|
||||||
_cogl_dispatch_onscreen_events (context);
|
_cogl_dispatch_onscreen_events (context);
|
||||||
|
}
|
||||||
|
|
||||||
winsys = _cogl_context_get_winsys (context);
|
winsys = renderer->winsys_vtable;
|
||||||
|
|
||||||
if (winsys->poll_dispatch)
|
if (winsys->poll_dispatch)
|
||||||
winsys->poll_dispatch (context, poll_fds, n_poll_fds);
|
winsys->poll_dispatch (renderer, poll_fds, n_poll_fds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_pollfd (CoglRenderer *renderer, int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < renderer->poll_fds->len; i++)
|
||||||
|
{
|
||||||
|
CoglPollFD *pollfd = &g_array_index (renderer->poll_fds, CoglPollFD, i);
|
||||||
|
|
||||||
|
if (pollfd->fd == fd)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd)
|
||||||
|
{
|
||||||
|
int i = find_pollfd (renderer, fd);
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_array_remove_index_fast (renderer->poll_fds, i);
|
||||||
|
renderer->poll_fds_age++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_poll_renderer_add_fd (CoglRenderer *renderer,
|
||||||
|
int fd,
|
||||||
|
CoglPollFDEvent events)
|
||||||
|
{
|
||||||
|
CoglPollFD pollfd = {
|
||||||
|
fd,
|
||||||
|
events
|
||||||
|
};
|
||||||
|
|
||||||
|
_cogl_poll_renderer_remove_fd (renderer, fd);
|
||||||
|
|
||||||
|
g_array_append_val (renderer->poll_fds, pollfd);
|
||||||
|
renderer->poll_fds_age++;
|
||||||
}
|
}
|
||||||
|
@ -104,19 +104,23 @@ typedef struct {
|
|||||||
} CoglPollFD;
|
} CoglPollFD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_poll_get_info:
|
* cogl_poll_renderer_get_info:
|
||||||
* @context: A #CoglContext
|
* @renderer: A #CoglRenderer
|
||||||
* @poll_fds: A return location for a pointer to an array
|
* @poll_fds: A return location for a pointer to an array
|
||||||
* of #CoglPollFD<!-- -->s
|
* of #CoglPollFD<!-- -->s
|
||||||
* @n_poll_fds: A return location for the number of entries in *@poll_fds
|
* @n_poll_fds: A return location for the number of entries in *@poll_fds
|
||||||
* @timeout: A return location for the maximum length of time to wait
|
* @timeout: A return location for the maximum length of time to wait
|
||||||
* in microseconds, or -1 to wait indefinitely.
|
* in microseconds, or -1 to wait indefinitely.
|
||||||
*
|
*
|
||||||
* This should be called whenever an application is about to go idle
|
* Is used to integrate Cogl with an application mainloop that is based
|
||||||
* so that Cogl has a chance to describe what state it needs to be
|
* on the unix poll(2) api (or select() or something equivalent). This
|
||||||
* woken up on. The assumption is that the application is using a main
|
* api should be called whenever an application is about to go idle so
|
||||||
* loop with something like the poll function call on Unix or the GLib
|
* that Cogl has a chance to describe what file descriptor events it
|
||||||
* main loop.
|
* needs to be woken up for.
|
||||||
|
*
|
||||||
|
* <note>If your application is using the Glib mainloop then you
|
||||||
|
* should jump to the cogl_glib_source_new() api as a more convenient
|
||||||
|
* way of integrating Cogl with the mainloop.</note>
|
||||||
*
|
*
|
||||||
* After the function is called *@poll_fds will contain a pointer to
|
* After the function is called *@poll_fds will contain a pointer to
|
||||||
* an array of #CoglPollFD structs describing the file descriptors
|
* an array of #CoglPollFD structs describing the file descriptors
|
||||||
@ -124,8 +128,12 @@ typedef struct {
|
|||||||
* accordingly. After the application has completed its idle it is
|
* accordingly. After the application has completed its idle it is
|
||||||
* expected to either update the revents members directly in this
|
* expected to either update the revents members directly in this
|
||||||
* array or to create a copy of the array and update them
|
* array or to create a copy of the array and update them
|
||||||
* there. Either way it should pass a pointer to either array back to
|
* there.
|
||||||
* Cogl when calling cogl_poll_dispatch().
|
*
|
||||||
|
* When the application mainloop returns from calling poll(2) (or its
|
||||||
|
* equivalent) then it should call cogl_poll_renderer_dispatch()
|
||||||
|
* passing a pointer the array of CoglPollFD<!-- -->s with updated
|
||||||
|
* revent values.
|
||||||
*
|
*
|
||||||
* When using the %COGL_WINSYS_ID_WGL winsys (where file descriptors
|
* When using the %COGL_WINSYS_ID_WGL winsys (where file descriptors
|
||||||
* don't make any sense) or %COGL_WINSYS_ID_SDL (where the event
|
* don't make any sense) or %COGL_WINSYS_ID_SDL (where the event
|
||||||
@ -134,21 +142,29 @@ typedef struct {
|
|||||||
*
|
*
|
||||||
* @timeout will contain a maximum amount of time to wait in
|
* @timeout will contain a maximum amount of time to wait in
|
||||||
* microseconds before the application should wake up or -1 if the
|
* microseconds before the application should wake up or -1 if the
|
||||||
* application should wait indefinitely. This can also be 0 zero if
|
* application should wait indefinitely. This can also be 0 if
|
||||||
* Cogl needs to be woken up immediately.
|
* Cogl needs to be woken up immediately.
|
||||||
*
|
*
|
||||||
|
* Return value: A "poll fd state age" that changes whenever the set
|
||||||
|
* of poll_fds has changed. If this API is being used to
|
||||||
|
* integrate with another system mainloop api then
|
||||||
|
* knowing if the set of file descriptors and events has
|
||||||
|
* really changed can help avoid redundant work
|
||||||
|
* depending the api. The age isn't guaranteed to change
|
||||||
|
* when the timeout changes.
|
||||||
|
*
|
||||||
* Stability: unstable
|
* Stability: unstable
|
||||||
* Since: 1.10
|
* Since: 1.16
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
cogl_poll_get_info (CoglContext *context,
|
cogl_poll_renderer_get_info (CoglRenderer *renderer,
|
||||||
CoglPollFD **poll_fds,
|
CoglPollFD **poll_fds,
|
||||||
int *n_poll_fds,
|
int *n_poll_fds,
|
||||||
int64_t *timeout);
|
int64_t *timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_poll_dispatch:
|
* cogl_poll_renderer_dispatch:
|
||||||
* @context: A #CoglContext
|
* @renderer: A #CoglRenderer
|
||||||
* @poll_fds: An array of #CoglPollFD<!-- -->s describing the events
|
* @poll_fds: An array of #CoglPollFD<!-- -->s describing the events
|
||||||
* that have occurred since the application went idle.
|
* that have occurred since the application went idle.
|
||||||
* @n_poll_fds: The length of the @poll_fds array.
|
* @n_poll_fds: The length of the @poll_fds array.
|
||||||
@ -157,15 +173,19 @@ cogl_poll_get_info (CoglContext *context,
|
|||||||
* going idle in its main loop. The @poll_fds array should contain a
|
* going idle in its main loop. The @poll_fds array should contain a
|
||||||
* list of file descriptors matched with the events that occurred in
|
* list of file descriptors matched with the events that occurred in
|
||||||
* revents. The events field is ignored. It is safe to pass in extra
|
* revents. The events field is ignored. It is safe to pass in extra
|
||||||
* file descriptors that Cogl didn't request from
|
* file descriptors that Cogl didn't request when calling
|
||||||
* cogl_context_begin_idle() or a shorter array missing some file
|
* cogl_poll_renderer_get_info() or a shorter array missing some file
|
||||||
* descriptors that Cogl requested.
|
* descriptors that Cogl requested.
|
||||||
*
|
*
|
||||||
|
* <note>If your application didn't originally create a #CoglRenderer
|
||||||
|
* manually then you can easily get a #CoglRenderer pointer by calling
|
||||||
|
* cogl_get_renderer().</note>
|
||||||
|
*
|
||||||
* Stability: unstable
|
* Stability: unstable
|
||||||
* Since: 1.10
|
* Since: 1.16
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cogl_poll_dispatch (CoglContext *context,
|
cogl_poll_renderer_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds);
|
int n_poll_fds);
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "cogl-winsys-private.h"
|
#include "cogl-winsys-private.h"
|
||||||
#include "cogl-driver.h"
|
#include "cogl-driver.h"
|
||||||
#include "cogl-texture-driver.h"
|
#include "cogl-texture-driver.h"
|
||||||
|
#include "cogl-context.h"
|
||||||
|
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
@ -50,6 +51,24 @@ struct _CoglRenderer
|
|||||||
CoglWinsysID winsys_id_override;
|
CoglWinsysID winsys_id_override;
|
||||||
GList *constraints;
|
GList *constraints;
|
||||||
|
|
||||||
|
GArray *poll_fds;
|
||||||
|
int poll_fds_age;
|
||||||
|
|
||||||
|
/* NB: Currently a CoglContext can only be associated with 1
|
||||||
|
* CoglDisplay which itself can only be associated with 1
|
||||||
|
* CoglRenderer.
|
||||||
|
*
|
||||||
|
* We currently do event dispatching from the renderer but once we
|
||||||
|
* have fully setup a context then we need to refer to the context
|
||||||
|
* to dispatch context events.
|
||||||
|
*
|
||||||
|
* This gives us a back-reference to the CoglContext that can be
|
||||||
|
* referenced during event dispatching.
|
||||||
|
*
|
||||||
|
* We always need to consider that this may be NULL.
|
||||||
|
*/
|
||||||
|
CoglContext *context;
|
||||||
|
|
||||||
GList *outputs;
|
GList *outputs;
|
||||||
|
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
|
@ -168,6 +168,8 @@ _cogl_renderer_free (CoglRenderer *renderer)
|
|||||||
NULL);
|
NULL);
|
||||||
g_slist_free (renderer->event_filters);
|
g_slist_free (renderer->event_filters);
|
||||||
|
|
||||||
|
g_array_free (renderer->poll_fds, TRUE);
|
||||||
|
|
||||||
g_free (renderer);
|
g_free (renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +183,8 @@ cogl_renderer_new (void)
|
|||||||
renderer->connected = FALSE;
|
renderer->connected = FALSE;
|
||||||
renderer->event_filters = NULL;
|
renderer->event_filters = NULL;
|
||||||
|
|
||||||
|
renderer->poll_fds = g_array_new (FALSE, TRUE, sizeof (CoglPollFD));
|
||||||
|
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
renderer->xlib_enable_event_retrieval = TRUE;
|
renderer->xlib_enable_event_retrieval = TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
@ -69,15 +69,18 @@ void
|
|||||||
cogl_sdl_handle_event (CoglContext *context, SDL_Event *event)
|
cogl_sdl_handle_event (CoglContext *context, SDL_Event *event)
|
||||||
{
|
{
|
||||||
const CoglWinsysVtable *winsys;
|
const CoglWinsysVtable *winsys;
|
||||||
|
CoglRenderer *renderer;
|
||||||
|
|
||||||
_COGL_RETURN_IF_FAIL (cogl_is_context (context));
|
_COGL_RETURN_IF_FAIL (cogl_is_context (context));
|
||||||
|
|
||||||
winsys = _cogl_context_get_winsys (context);
|
renderer = context->display->renderer;
|
||||||
|
|
||||||
_cogl_renderer_handle_native_event (context->display->renderer, event);
|
winsys = renderer->winsys_vtable;
|
||||||
|
|
||||||
|
_cogl_renderer_handle_native_event (renderer, event);
|
||||||
|
|
||||||
if (winsys->poll_dispatch)
|
if (winsys->poll_dispatch)
|
||||||
winsys->poll_dispatch (context, NULL, 0);
|
winsys->poll_dispatch (renderer, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -40,9 +40,6 @@ typedef struct _CoglXlibRenderer
|
|||||||
these is expected to be allocated on the stack by the caller */
|
these is expected to be allocated on the stack by the caller */
|
||||||
CoglXlibTrapState *trap_state;
|
CoglXlibTrapState *trap_state;
|
||||||
|
|
||||||
/* A poll FD for handling event retrieval within Cogl */
|
|
||||||
CoglPollFD poll_fd;
|
|
||||||
|
|
||||||
unsigned long outputs_update_serial;
|
unsigned long outputs_update_serial;
|
||||||
} CoglXlibRenderer;
|
} CoglXlibRenderer;
|
||||||
|
|
||||||
@ -84,11 +81,8 @@ _cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
|
|||||||
CoglXlibRenderer *
|
CoglXlibRenderer *
|
||||||
_cogl_xlib_renderer_get_data (CoglRenderer *renderer);
|
_cogl_xlib_renderer_get_data (CoglRenderer *renderer);
|
||||||
|
|
||||||
void
|
int64_t
|
||||||
_cogl_xlib_renderer_poll_get_info (CoglRenderer *renderer,
|
_cogl_xlib_renderer_get_dispatch_timeout (CoglRenderer *renderer);
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_xlib_renderer_poll_dispatch (CoglRenderer *renderer,
|
_cogl_xlib_renderer_poll_dispatch (CoglRenderer *renderer,
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "cogl-x11-renderer-private.h"
|
#include "cogl-x11-renderer-private.h"
|
||||||
#include "cogl-winsys-private.h"
|
#include "cogl-winsys-private.h"
|
||||||
#include "cogl-error-private.h"
|
#include "cogl-error-private.h"
|
||||||
|
#include "cogl-poll-private.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/Xdamage.h>
|
#include <X11/extensions/Xdamage.h>
|
||||||
@ -497,8 +498,12 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, CoglError **error)
|
|||||||
|
|
||||||
xlib_renderer->trap_state = NULL;
|
xlib_renderer->trap_state = NULL;
|
||||||
|
|
||||||
xlib_renderer->poll_fd.fd = ConnectionNumber (xlib_renderer->xdpy);
|
if (renderer->xlib_enable_event_retrieval)
|
||||||
xlib_renderer->poll_fd.events = COGL_POLL_FD_EVENT_IN;
|
{
|
||||||
|
_cogl_poll_renderer_add_fd (renderer,
|
||||||
|
ConnectionNumber (xlib_renderer->xdpy),
|
||||||
|
COGL_POLL_FD_EVENT_IN);
|
||||||
|
}
|
||||||
|
|
||||||
XRRSelectInput(xlib_renderer->xdpy,
|
XRRSelectInput(xlib_renderer->xdpy,
|
||||||
DefaultRootWindow (xlib_renderer->xdpy),
|
DefaultRootWindow (xlib_renderer->xdpy),
|
||||||
@ -568,29 +573,20 @@ cogl_xlib_renderer_remove_filter (CoglRenderer *renderer,
|
|||||||
(CoglNativeFilterFunc)func, data);
|
(CoglNativeFilterFunc)func, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int64_t
|
||||||
_cogl_xlib_renderer_poll_get_info (CoglRenderer *renderer,
|
_cogl_xlib_renderer_get_dispatch_timeout (CoglRenderer *renderer)
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout)
|
|
||||||
{
|
{
|
||||||
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
||||||
|
|
||||||
if (renderer->xlib_enable_event_retrieval)
|
if (renderer->xlib_enable_event_retrieval)
|
||||||
{
|
{
|
||||||
*n_poll_fds = 1;
|
|
||||||
*poll_fds = &xlib_renderer->poll_fd;
|
|
||||||
if (XPending (xlib_renderer->xdpy))
|
if (XPending (xlib_renderer->xdpy))
|
||||||
*timeout = 0;
|
return 0;
|
||||||
else
|
else
|
||||||
*timeout = -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return -1;
|
||||||
*n_poll_fds = 0;
|
|
||||||
*poll_fds = NULL;
|
|
||||||
*timeout = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -650,8 +650,8 @@ cogl_pixel_buffer_set_region
|
|||||||
#endif
|
#endif
|
||||||
cogl_pixel_format_get_type
|
cogl_pixel_format_get_type
|
||||||
|
|
||||||
cogl_poll_dispatch
|
cogl_poll_renderer_get_info
|
||||||
cogl_poll_get_info
|
cogl_poll_renderer_dispatch
|
||||||
|
|
||||||
cogl_polygon
|
cogl_polygon
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "cogl-kms-display.h"
|
#include "cogl-kms-display.h"
|
||||||
#include "cogl-version.h"
|
#include "cogl-version.h"
|
||||||
#include "cogl-error-private.h"
|
#include "cogl-error-private.h"
|
||||||
|
#include "cogl-poll-private.h"
|
||||||
|
|
||||||
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ typedef struct _CoglRendererKMS
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct gbm_device *gbm;
|
struct gbm_device *gbm;
|
||||||
CoglPollFD poll_fd;
|
|
||||||
|
CoglBool pending_swap_notify;
|
||||||
} CoglRendererKMS;
|
} CoglRendererKMS;
|
||||||
|
|
||||||
typedef struct _CoglOutputKMS
|
typedef struct _CoglOutputKMS
|
||||||
@ -80,7 +82,6 @@ typedef struct _CoglDisplayKMS
|
|||||||
GList *outputs;
|
GList *outputs;
|
||||||
int width, height;
|
int width, height;
|
||||||
CoglBool pending_set_crtc;
|
CoglBool pending_set_crtc;
|
||||||
CoglBool pending_swap_notify;
|
|
||||||
struct gbm_surface *dummy_gbm_surface;
|
struct gbm_surface *dummy_gbm_surface;
|
||||||
} CoglDisplayKMS;
|
} CoglDisplayKMS;
|
||||||
|
|
||||||
@ -159,8 +160,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||||||
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
|
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
|
||||||
goto egl_terminate;
|
goto egl_terminate;
|
||||||
|
|
||||||
kms_renderer->poll_fd.fd = kms_renderer->fd;
|
_cogl_poll_renderer_add_fd (renderer,
|
||||||
kms_renderer->poll_fd.events = COGL_POLL_FD_EVENT_IN;
|
kms_renderer->fd,
|
||||||
|
COGL_POLL_FD_EVENT_IN);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -609,23 +611,25 @@ page_flip_handler (int fd,
|
|||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
CoglFlipKMS *flip = data;
|
CoglFlipKMS *flip = data;
|
||||||
CoglOnscreen *onscreen = flip->onscreen;
|
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
|
||||||
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
|
|
||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
|
||||||
CoglDisplay *display = context->display;
|
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
|
||||||
CoglDisplayKMS *kms_display = egl_display->platform;
|
|
||||||
|
|
||||||
/* We're only ready to dispatch a swap notification once all outputs
|
/* We're only ready to dispatch a swap notification once all outputs
|
||||||
* have flipped... */
|
* have flipped... */
|
||||||
flip->pending--;
|
flip->pending--;
|
||||||
if (flip->pending == 0)
|
if (flip->pending == 0)
|
||||||
{
|
{
|
||||||
/* We only want to notify that the swap is complete when the application
|
CoglOnscreen *onscreen = flip->onscreen;
|
||||||
* calls cogl_context_dispatch so instead of immediately notifying we'll
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
* set a flag to remember to notify later */
|
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
|
||||||
kms_display->pending_swap_notify = TRUE;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
|
CoglRenderer *renderer = context->display->renderer;
|
||||||
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
|
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||||
|
|
||||||
|
/* We only want to notify that the swap is complete when the
|
||||||
|
* application calls cogl_context_dispatch so instead of
|
||||||
|
* immediately notifying we'll set a flag to remember to notify
|
||||||
|
* later */
|
||||||
|
kms_renderer->pending_swap_notify = TRUE;
|
||||||
kms_onscreen->pending_swap_notify = TRUE;
|
kms_onscreen->pending_swap_notify = TRUE;
|
||||||
|
|
||||||
free_current_bo (onscreen);
|
free_current_bo (onscreen);
|
||||||
@ -863,25 +867,15 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|||||||
onscreen->winsys = NULL;
|
onscreen->winsys = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int64_t
|
||||||
_cogl_winsys_poll_get_info (CoglContext *context,
|
_cogl_winsys_get_dispatch_timeout (CoglRenderer *renderer)
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout)
|
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
|
||||||
CoglDisplayKMS *kms_display = egl_display->platform;
|
|
||||||
CoglRenderer *renderer = display->renderer;
|
|
||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||||
|
|
||||||
*poll_fds = &kms_renderer->poll_fd;
|
|
||||||
*n_poll_fds = 1;
|
|
||||||
|
|
||||||
/* If we've already got a pending swap notify then we'll dispatch
|
/* If we've already got a pending swap notify then we'll dispatch
|
||||||
immediately */
|
* immediately */
|
||||||
*timeout = kms_display->pending_swap_notify ? 0 : -1;
|
return kms_renderer->pending_swap_notify ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -910,14 +904,10 @@ flush_pending_swap_notify_cb (void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_poll_dispatch (CoglContext *context,
|
_cogl_winsys_poll_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
|
||||||
CoglDisplayKMS *kms_display = egl_display->platform;
|
|
||||||
CoglRenderer *renderer = display->renderer;
|
|
||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||||
int i;
|
int i;
|
||||||
@ -931,12 +921,21 @@ _cogl_winsys_poll_dispatch (CoglContext *context,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kms_display->pending_swap_notify)
|
/* FIXME: instead of requiring event dispatching which is handled at
|
||||||
|
* the CoglRenderer level to have to know about CoglContext we
|
||||||
|
* should have a generalized way of queuing an idle function */
|
||||||
|
if (renderer->context &&
|
||||||
|
kms_renderer->pending_swap_notify)
|
||||||
{
|
{
|
||||||
|
CoglContext *context = renderer->context;
|
||||||
|
|
||||||
|
/* This needs to be cleared before invoking the callbacks in
|
||||||
|
* case the callbacks cause it to be set again */
|
||||||
|
kms_renderer->pending_swap_notify = FALSE;
|
||||||
|
|
||||||
g_list_foreach (context->framebuffers,
|
g_list_foreach (context->framebuffers,
|
||||||
flush_pending_swap_notify_cb,
|
flush_pending_swap_notify_cb,
|
||||||
NULL);
|
NULL);
|
||||||
kms_display->pending_swap_notify = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,7 +976,7 @@ _cogl_winsys_egl_kms_get_vtable (void)
|
|||||||
vtable.onscreen_swap_region = NULL;
|
vtable.onscreen_swap_region = NULL;
|
||||||
vtable.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers;
|
vtable.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers;
|
||||||
|
|
||||||
vtable.poll_get_info = _cogl_winsys_poll_get_info;
|
vtable.get_dispatch_timeout = _cogl_winsys_get_dispatch_timeout;
|
||||||
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
||||||
|
|
||||||
vtable_inited = TRUE;
|
vtable_inited = TRUE;
|
||||||
|
@ -82,6 +82,8 @@ typedef struct _CoglRendererEGL
|
|||||||
EGLint egl_version_major;
|
EGLint egl_version_major;
|
||||||
EGLint egl_version_minor;
|
EGLint egl_version_minor;
|
||||||
|
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
|
|
||||||
/* Data specific to the EGL platform */
|
/* Data specific to the EGL platform */
|
||||||
void *platform;
|
void *platform;
|
||||||
/* vtable for platform specific parts */
|
/* vtable for platform specific parts */
|
||||||
@ -115,8 +117,6 @@ typedef struct _CoglDisplayEGL
|
|||||||
EGLSurface current_draw_surface;
|
EGLSurface current_draw_surface;
|
||||||
EGLContext current_context;
|
EGLContext current_context;
|
||||||
|
|
||||||
CoglBool pending_resize_notify;
|
|
||||||
|
|
||||||
/* Platform specific display data */
|
/* Platform specific display data */
|
||||||
void *platform;
|
void *platform;
|
||||||
} CoglDisplayEGL;
|
} CoglDisplayEGL;
|
||||||
|
@ -601,29 +601,17 @@ cogl_wayland_onscreen_resize (CoglOnscreen *onscreen,
|
|||||||
_cogl_framebuffer_winsys_update_size (fb, width, height);
|
_cogl_framebuffer_winsys_update_size (fb, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int64_t
|
||||||
_cogl_winsys_poll_get_info (CoglContext *context,
|
_cogl_winsys_get_dispatch_timeout (CoglRenderer *renderer)
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout)
|
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
return -1;
|
||||||
CoglRenderer *renderer = display->renderer;
|
|
||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
||||||
CoglRendererWayland *wayland_renderer = egl_renderer->platform;
|
|
||||||
|
|
||||||
*poll_fds = &wayland_renderer->poll_fd;
|
|
||||||
*n_poll_fds = 1;
|
|
||||||
*timeout = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_poll_dispatch (CoglContext *context,
|
_cogl_winsys_poll_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
|
||||||
CoglRenderer *renderer = display->renderer;
|
|
||||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglRendererWayland *wayland_renderer = egl_renderer->platform;
|
CoglRendererWayland *wayland_renderer = egl_renderer->platform;
|
||||||
int i;
|
int i;
|
||||||
@ -671,7 +659,7 @@ _cogl_winsys_egl_wayland_get_vtable (void)
|
|||||||
|
|
||||||
vtable.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers;
|
vtable.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers;
|
||||||
|
|
||||||
vtable.poll_get_info = _cogl_winsys_poll_get_info;
|
vtable.get_dispatch_timeout = _cogl_winsys_get_dispatch_timeout;
|
||||||
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
||||||
|
|
||||||
vtable_inited = TRUE;
|
vtable_inited = TRUE;
|
||||||
|
@ -96,11 +96,11 @@ notify_resize (CoglContext *context,
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
|
CoglRenderer *renderer = context->display->renderer;
|
||||||
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglOnscreen *onscreen = find_onscreen_for_xid (context, drawable);
|
CoglOnscreen *onscreen = find_onscreen_for_xid (context, drawable);
|
||||||
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
CoglDisplay *display = context->display;
|
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
|
||||||
CoglOnscreenEGL *egl_onscreen;
|
|
||||||
|
|
||||||
if (!onscreen)
|
if (!onscreen)
|
||||||
return;
|
return;
|
||||||
@ -110,9 +110,9 @@ notify_resize (CoglContext *context,
|
|||||||
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
||||||
|
|
||||||
/* We only want to notify that a resize happened when the
|
/* We only want to notify that a resize happened when the
|
||||||
application calls cogl_context_dispatch so instead of immediately
|
* application calls cogl_context_dispatch so instead of immediately
|
||||||
notifying we'll set a flag to remember to notify later */
|
* notifying we'll set a flag to remember to notify later */
|
||||||
egl_display->pending_resize_notify = TRUE;
|
egl_renderer->pending_resize_notify = TRUE;
|
||||||
egl_onscreen->pending_resize_notify = TRUE;
|
egl_onscreen->pending_resize_notify = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,22 +623,15 @@ _cogl_winsys_xlib_get_visual_info (void)
|
|||||||
return get_visual_info (ctx->display, egl_display->egl_config);
|
return get_visual_info (ctx->display, egl_display->egl_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int64_t
|
||||||
_cogl_winsys_poll_get_info (CoglContext *context,
|
_cogl_winsys_get_dispatch_timeout (CoglRenderer *renderer)
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout)
|
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
|
||||||
|
|
||||||
_cogl_xlib_renderer_poll_get_info (context->display->renderer,
|
if (egl_renderer->pending_resize_notify)
|
||||||
poll_fds,
|
return 0;
|
||||||
n_poll_fds,
|
|
||||||
timeout);
|
|
||||||
|
|
||||||
if (egl_display->pending_resize_notify)
|
return _cogl_xlib_renderer_get_dispatch_timeout (renderer);
|
||||||
*timeout = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -661,23 +654,31 @@ flush_pending_notifications_cb (void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_poll_dispatch (CoglContext *context,
|
_cogl_winsys_poll_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||||
CoglDisplayEGL *egl_display = display->winsys;
|
|
||||||
|
|
||||||
_cogl_xlib_renderer_poll_dispatch (context->display->renderer,
|
_cogl_xlib_renderer_poll_dispatch (renderer,
|
||||||
poll_fds,
|
poll_fds,
|
||||||
n_poll_fds);
|
n_poll_fds);
|
||||||
|
|
||||||
if (egl_display->pending_resize_notify)
|
/* FIXME: instead of requiring event dispatching which is handled at
|
||||||
|
* the CoglRenderer level to have to know about CoglContext we
|
||||||
|
* should have a generalized way of queuing an idle function */
|
||||||
|
if (renderer->context &&
|
||||||
|
egl_renderer->pending_resize_notify)
|
||||||
{
|
{
|
||||||
|
CoglContext *context = renderer->context;
|
||||||
|
|
||||||
|
/* This needs to be cleared before invoking the callbacks in
|
||||||
|
* case the callbacks cause it to be set again */
|
||||||
|
egl_renderer->pending_resize_notify = FALSE;
|
||||||
|
|
||||||
g_list_foreach (context->framebuffers,
|
g_list_foreach (context->framebuffers,
|
||||||
flush_pending_notifications_cb,
|
flush_pending_notifications_cb,
|
||||||
NULL);
|
NULL);
|
||||||
egl_display->pending_resize_notify = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,7 +828,7 @@ _cogl_winsys_egl_xlib_get_vtable (void)
|
|||||||
|
|
||||||
vtable.xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info;
|
vtable.xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info;
|
||||||
|
|
||||||
vtable.poll_get_info = _cogl_winsys_poll_get_info;
|
vtable.get_dispatch_timeout = _cogl_winsys_get_dispatch_timeout;
|
||||||
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
||||||
|
|
||||||
#ifdef EGL_KHR_image_pixmap
|
#ifdef EGL_KHR_image_pixmap
|
||||||
|
@ -308,9 +308,9 @@ set_sync_pending (CoglOnscreen *onscreen)
|
|||||||
{
|
{
|
||||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
CoglGLXDisplay *glx_display = context->display->winsys;
|
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||||
|
|
||||||
glx_display->pending_sync_notify = TRUE;
|
glx_renderer->pending_sync_notify = TRUE;
|
||||||
glx_onscreen->pending_sync_notify = TRUE;
|
glx_onscreen->pending_sync_notify = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,9 +319,9 @@ set_complete_pending (CoglOnscreen *onscreen)
|
|||||||
{
|
{
|
||||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
CoglGLXDisplay *glx_display = context->display->winsys;
|
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||||
|
|
||||||
glx_display->pending_complete_notify = TRUE;
|
glx_renderer->pending_complete_notify = TRUE;
|
||||||
glx_onscreen->pending_complete_notify = TRUE;
|
glx_onscreen->pending_complete_notify = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,8 +388,7 @@ notify_resize (CoglContext *context,
|
|||||||
CoglOnscreen *onscreen = find_onscreen_for_xid (context,
|
CoglOnscreen *onscreen = find_onscreen_for_xid (context,
|
||||||
configure_event->window);
|
configure_event->window);
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
CoglDisplay *display = context->display;
|
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||||
CoglGLXDisplay *glx_display = display->winsys;
|
|
||||||
CoglOnscreenGLX *glx_onscreen;
|
CoglOnscreenGLX *glx_onscreen;
|
||||||
CoglOnscreenXlib *xlib_onscreen;
|
CoglOnscreenXlib *xlib_onscreen;
|
||||||
|
|
||||||
@ -406,7 +405,7 @@ notify_resize (CoglContext *context,
|
|||||||
/* We only want to notify that a resize happened when the
|
/* We only want to notify that a resize happened when the
|
||||||
application calls cogl_context_dispatch so instead of immediately
|
application calls cogl_context_dispatch so instead of immediately
|
||||||
notifying we'll set a flag to remember to notify later */
|
notifying we'll set a flag to remember to notify later */
|
||||||
glx_display->pending_resize_notify = TRUE;
|
glx_renderer->pending_resize_notify = TRUE;
|
||||||
glx_onscreen->pending_resize_notify = TRUE;
|
glx_onscreen->pending_resize_notify = TRUE;
|
||||||
|
|
||||||
if (!xlib_onscreen->is_foreign_xwin)
|
if (!xlib_onscreen->is_foreign_xwin)
|
||||||
@ -2510,26 +2509,19 @@ _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
|
|||||||
return glx_tex_pixmap->glx_tex;
|
return glx_tex_pixmap->glx_tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int64_t
|
||||||
_cogl_winsys_poll_get_info (CoglContext *context,
|
_cogl_winsys_get_dispatch_timeout (CoglRenderer *renderer)
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout)
|
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
CoglGLXRenderer *glx_renderer = renderer->winsys;
|
||||||
CoglGLXDisplay *glx_display = display->winsys;
|
|
||||||
|
|
||||||
_cogl_xlib_renderer_poll_get_info (context->display->renderer,
|
|
||||||
poll_fds,
|
|
||||||
n_poll_fds,
|
|
||||||
timeout);
|
|
||||||
|
|
||||||
/* If we've already got a pending swap notify then we'll dispatch
|
/* If we've already got a pending swap notify then we'll dispatch
|
||||||
immediately */
|
* immediately */
|
||||||
if (glx_display->pending_sync_notify ||
|
if (glx_renderer->pending_sync_notify ||
|
||||||
glx_display->pending_resize_notify ||
|
glx_renderer->pending_resize_notify ||
|
||||||
glx_display->pending_complete_notify)
|
glx_renderer->pending_complete_notify)
|
||||||
*timeout = 0;
|
return 0;
|
||||||
|
|
||||||
|
return _cogl_xlib_renderer_get_dispatch_timeout (renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2576,32 +2568,39 @@ flush_pending_notifications_cb (void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_poll_dispatch (CoglContext *context,
|
_cogl_winsys_poll_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
CoglGLXRenderer *glx_renderer = renderer->winsys;
|
||||||
CoglGLXDisplay *glx_display = display->winsys;
|
|
||||||
|
|
||||||
_cogl_xlib_renderer_poll_dispatch (context->display->renderer,
|
_cogl_xlib_renderer_poll_dispatch (renderer,
|
||||||
poll_fds,
|
poll_fds,
|
||||||
n_poll_fds);
|
n_poll_fds);
|
||||||
|
|
||||||
if (glx_display->pending_sync_notify ||
|
/* FIXME: instead of requiring event dispatching which is handled at
|
||||||
glx_display->pending_resize_notify ||
|
* the CoglRenderer level to have to know about CoglContext we
|
||||||
glx_display->pending_complete_notify)
|
* should have a generalized way of queuing an idle function */
|
||||||
|
if (renderer->context)
|
||||||
|
{
|
||||||
|
CoglContext *context = renderer->context;
|
||||||
|
|
||||||
|
if (glx_renderer->pending_sync_notify ||
|
||||||
|
glx_renderer->pending_resize_notify ||
|
||||||
|
glx_renderer->pending_complete_notify)
|
||||||
{
|
{
|
||||||
/* These need to be cleared before invoking the callbacks in
|
/* These need to be cleared before invoking the callbacks in
|
||||||
* case the callbacks cause them to be set again */
|
* case the callbacks cause them to be set again */
|
||||||
glx_display->pending_sync_notify = FALSE;
|
glx_renderer->pending_sync_notify = FALSE;
|
||||||
glx_display->pending_resize_notify = FALSE;
|
glx_renderer->pending_resize_notify = FALSE;
|
||||||
glx_display->pending_complete_notify = FALSE;
|
glx_renderer->pending_complete_notify = FALSE;
|
||||||
|
|
||||||
g_list_foreach (context->framebuffers,
|
g_list_foreach (context->framebuffers,
|
||||||
flush_pending_notifications_cb,
|
flush_pending_notifications_cb,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static CoglWinsysVtable _cogl_winsys_vtable =
|
static CoglWinsysVtable _cogl_winsys_vtable =
|
||||||
{
|
{
|
||||||
@ -2634,7 +2633,7 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
|||||||
.onscreen_set_resizable =
|
.onscreen_set_resizable =
|
||||||
_cogl_winsys_onscreen_set_resizable,
|
_cogl_winsys_onscreen_set_resizable,
|
||||||
|
|
||||||
.poll_get_info = _cogl_winsys_poll_get_info,
|
.get_dispatch_timeout = _cogl_winsys_get_dispatch_timeout,
|
||||||
.poll_dispatch = _cogl_winsys_poll_dispatch,
|
.poll_dispatch = _cogl_winsys_poll_dispatch,
|
||||||
|
|
||||||
/* X11 tfp support... */
|
/* X11 tfp support... */
|
||||||
|
@ -154,13 +154,11 @@ typedef struct _CoglWinsysVtable
|
|||||||
(*onscreen_win32_get_window) (CoglOnscreen *onscreen);
|
(*onscreen_win32_get_window) (CoglOnscreen *onscreen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
(*get_dispatch_timeout) (CoglRenderer *renderer);
|
||||||
|
|
||||||
void
|
void
|
||||||
(*poll_get_info) (CoglContext *context,
|
(*poll_dispatch) (CoglRenderer *renderer,
|
||||||
CoglPollFD **poll_fds,
|
|
||||||
int *n_poll_fds,
|
|
||||||
int64_t *timeout);
|
|
||||||
void
|
|
||||||
(*poll_dispatch) (CoglContext *context,
|
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds);
|
int n_poll_fds);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
typedef struct _CoglRendererSdl
|
typedef struct _CoglRendererSdl
|
||||||
{
|
{
|
||||||
int stub;
|
CoglBool pending_resize_notify;
|
||||||
} CoglRendererSdl;
|
} CoglRendererSdl;
|
||||||
|
|
||||||
typedef struct _CoglDisplaySdl
|
typedef struct _CoglDisplaySdl
|
||||||
@ -49,7 +49,6 @@ typedef struct _CoglDisplaySdl
|
|||||||
SDL_Surface *surface;
|
SDL_Surface *surface;
|
||||||
CoglOnscreen *onscreen;
|
CoglOnscreen *onscreen;
|
||||||
Uint32 video_mode_flags;
|
Uint32 video_mode_flags;
|
||||||
CoglBool pending_resize_notify;
|
|
||||||
} CoglDisplaySdl;
|
} CoglDisplaySdl;
|
||||||
|
|
||||||
static CoglFuncPtr
|
static CoglFuncPtr
|
||||||
@ -218,6 +217,7 @@ sdl_event_filter_cb (SDL_Event *event, void *data)
|
|||||||
CoglContext *context = data;
|
CoglContext *context = data;
|
||||||
CoglDisplay *display = context->display;
|
CoglDisplay *display = context->display;
|
||||||
CoglDisplaySdl *sdl_display = display->winsys;
|
CoglDisplaySdl *sdl_display = display->winsys;
|
||||||
|
CoglRendererSdl *sdl_renderer = display->renderer->winsys;
|
||||||
float width = event->resize.w;
|
float width = event->resize.w;
|
||||||
float height = event->resize.h;
|
float height = event->resize.h;
|
||||||
CoglFramebuffer *framebuffer;
|
CoglFramebuffer *framebuffer;
|
||||||
@ -233,9 +233,10 @@ sdl_event_filter_cb (SDL_Event *event, void *data)
|
|||||||
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
||||||
|
|
||||||
/* We only want to notify that a resize happened when the
|
/* We only want to notify that a resize happened when the
|
||||||
application calls cogl_context_dispatch so instead of immediately
|
* application calls cogl_context_dispatch so instead of
|
||||||
notifying we'll set a flag to remember to notify later */
|
* immediately notifying we'll set a flag to remember to notify
|
||||||
sdl_display->pending_resize_notify = TRUE;
|
* later */
|
||||||
|
sdl_renderer->pending_resize_notify = TRUE;
|
||||||
|
|
||||||
return COGL_FILTER_CONTINUE;
|
return COGL_FILTER_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -378,22 +379,27 @@ _cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_poll_dispatch (CoglContext *context,
|
_cogl_winsys_poll_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
CoglRendererSdl *sdl_renderer = renderer->winsys;
|
||||||
CoglDisplaySdl *sdl_display = display->winsys;
|
|
||||||
|
|
||||||
if (sdl_display->pending_resize_notify)
|
/* FIXME: instead of requiring event dispatching which is handled at
|
||||||
|
* the CoglRenderer level to have to know about CoglContext we
|
||||||
|
* should have a generalized way of queuing an idle function */
|
||||||
|
if (renderer->context &&
|
||||||
|
sdl_renderer->pending_resize_notify)
|
||||||
{
|
{
|
||||||
|
CoglContext *context = renderer->context;
|
||||||
|
CoglDisplaySdl *sdl_display = context->display->winsys;
|
||||||
CoglOnscreen *onscreen = sdl_display->onscreen;
|
CoglOnscreen *onscreen = sdl_display->onscreen;
|
||||||
|
|
||||||
g_return_if_fail (onscreen != NULL);
|
g_return_if_fail (onscreen != NULL);
|
||||||
|
|
||||||
_cogl_onscreen_notify_resize (onscreen);
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
|
|
||||||
sdl_display->pending_resize_notify = FALSE;
|
sdl_renderer->pending_resize_notify = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,14 +47,13 @@ typedef struct _CoglContextSdl2
|
|||||||
|
|
||||||
typedef struct _CoglRendererSdl2
|
typedef struct _CoglRendererSdl2
|
||||||
{
|
{
|
||||||
int stub;
|
CoglBool pending_resize_notify;
|
||||||
} CoglRendererSdl2;
|
} CoglRendererSdl2;
|
||||||
|
|
||||||
typedef struct _CoglDisplaySdl2
|
typedef struct _CoglDisplaySdl2
|
||||||
{
|
{
|
||||||
SDL_Window *dummy_window;
|
SDL_Window *dummy_window;
|
||||||
SDL_GLContext *context;
|
SDL_GLContext *context;
|
||||||
CoglBool pending_resize_notify;
|
|
||||||
} CoglDisplaySdl2;
|
} CoglDisplaySdl2;
|
||||||
|
|
||||||
typedef struct _CoglOnscreenSdl2
|
typedef struct _CoglOnscreenSdl2
|
||||||
@ -274,7 +273,7 @@ sdl_event_filter_cb (SDL_Event *event, void *data)
|
|||||||
{
|
{
|
||||||
CoglContext *context = data;
|
CoglContext *context = data;
|
||||||
CoglDisplay *display = context->display;
|
CoglDisplay *display = context->display;
|
||||||
CoglDisplaySdl2 *sdl_display = display->winsys;
|
CoglRendererSdl2 *sdl_renderer = display->renderer->winsys;
|
||||||
float width = event->window.data1;
|
float width = event->window.data1;
|
||||||
float height = event->window.data2;
|
float height = event->window.data2;
|
||||||
CoglFramebuffer *framebuffer;
|
CoglFramebuffer *framebuffer;
|
||||||
@ -296,9 +295,10 @@ sdl_event_filter_cb (SDL_Event *event, void *data)
|
|||||||
sdl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
|
sdl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
|
||||||
|
|
||||||
/* We only want to notify that a resize happened when the
|
/* We only want to notify that a resize happened when the
|
||||||
application calls cogl_context_dispatch so instead of immediately
|
* application calls cogl_context_dispatch so instead of
|
||||||
notifying we'll set a flag to remember to notify later */
|
* immediately notifying we'll set a flag to remember to notify
|
||||||
sdl_display->pending_resize_notify = TRUE;
|
* later */
|
||||||
|
sdl_renderer->pending_resize_notify = TRUE;
|
||||||
sdl_onscreen->pending_resize_notify = TRUE;
|
sdl_onscreen->pending_resize_notify = TRUE;
|
||||||
|
|
||||||
return COGL_FILTER_CONTINUE;
|
return COGL_FILTER_CONTINUE;
|
||||||
@ -506,19 +506,24 @@ flush_pending_notifications_cb (void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_poll_dispatch (CoglContext *context,
|
_cogl_winsys_poll_dispatch (CoglRenderer *renderer,
|
||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
CoglDisplay *display = context->display;
|
CoglRendererSdl2 *sdl_renderer = renderer->winsys;
|
||||||
CoglDisplaySdl2 *sdl_display = display->winsys;
|
|
||||||
|
|
||||||
if (sdl_display->pending_resize_notify)
|
/* FIXME: instead of requiring event dispatching which is handled at
|
||||||
|
* the CoglRenderer level to have to know about CoglContext we
|
||||||
|
* should have a generalized way of queuing an idle function */
|
||||||
|
if (renderer->context &&
|
||||||
|
sdl_renderer->pending_resize_notify)
|
||||||
{
|
{
|
||||||
|
CoglContext *context = renderer->context;
|
||||||
|
|
||||||
g_list_foreach (context->framebuffers,
|
g_list_foreach (context->framebuffers,
|
||||||
flush_pending_notifications_cb,
|
flush_pending_notifications_cb,
|
||||||
NULL);
|
NULL);
|
||||||
sdl_display->pending_resize_notify = FALSE;
|
sdl_renderer->pending_resize_notify = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,12 +236,13 @@ COGL_PREMULT_BIT
|
|||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>cogl-poll</FILE>
|
<FILE>cogl-poll</FILE>
|
||||||
<TITLE>Main loop integeration</TITLE>
|
<TITLE>Main loop integration</TITLE>
|
||||||
CoglPollFDEvent
|
CoglPollFDEvent
|
||||||
CoglPollFD
|
CoglPollFD
|
||||||
cogl_poll_get_info
|
cogl_poll_renderer_get_info
|
||||||
cogl_poll_dispatch
|
cogl_poll_renderer_dispatch
|
||||||
cogl_glib_source_new
|
cogl_glib_source_new
|
||||||
|
cogl_glib_renderer_source_new
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
@ -274,6 +274,7 @@ main (int argc, char **argv)
|
|||||||
&data,
|
&data,
|
||||||
NULL); /* destroy notify */
|
NULL); /* destroy notify */
|
||||||
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
CoglPollFD *poll_fds;
|
CoglPollFD *poll_fds;
|
||||||
@ -286,12 +287,14 @@ main (int argc, char **argv)
|
|||||||
cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
|
cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
|
cogl_poll_renderer_get_info (cogl_context_get_renderer (ctx),
|
||||||
|
&poll_fds, &n_poll_fds, &timeout);
|
||||||
|
|
||||||
g_poll ((GPollFD *) poll_fds, n_poll_fds,
|
g_poll ((GPollFD *) poll_fds, n_poll_fds,
|
||||||
timeout == -1 ? -1 : timeout / 1000);
|
timeout == -1 ? -1 : timeout / 1000);
|
||||||
|
|
||||||
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
|
cogl_poll_renderer_dispatch (cogl_context_get_renderer (ctx),
|
||||||
|
poll_fds, n_poll_fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -105,9 +105,11 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
cogl_onscreen_swap_buffers (onscreen);
|
cogl_onscreen_swap_buffers (onscreen);
|
||||||
|
|
||||||
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
|
cogl_poll_renderer_get_info (cogl_context_get_renderer (ctx),
|
||||||
|
&poll_fds, &n_poll_fds, &timeout);
|
||||||
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
|
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
|
||||||
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
|
cogl_poll_renderer_dispatch (cogl_context_get_renderer (ctx),
|
||||||
|
poll_fds, n_poll_fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -188,9 +188,11 @@ main (int argc, char **argv)
|
|||||||
* then allow Cogl to dispatch any corresponding event
|
* then allow Cogl to dispatch any corresponding event
|
||||||
* callbacks, such as resize notification callbacks...
|
* callbacks, such as resize notification callbacks...
|
||||||
*/
|
*/
|
||||||
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
|
cogl_poll_renderer_get_info (cogl_context_get_renderer (ctx),
|
||||||
|
&poll_fds, &n_poll_fds, &timeout);
|
||||||
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
|
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
|
||||||
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
|
cogl_poll_renderer_dispatch (cogl_context_get_renderer (ctx),
|
||||||
|
poll_fds, n_poll_fds);
|
||||||
|
|
||||||
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
|
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
|
||||||
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
|
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
|
||||||
|
Loading…
Reference in New Issue
Block a user