gdk: Rework the GL context update

Ensure that gdk_gl_context_update() schedules an update of the viewport,
and then perform the actual update when the backend says it should. This
makes the code a bit more readable, and we can keep asking the user to
call gdk_gl_context_update() after gdk_window_move_resize() without
having to care about asynchronous updates.
This commit is contained in:
Emmanuele Bassi
2014-08-12 11:51:45 +01:00
parent d713ae6321
commit a71cec0119
4 changed files with 79 additions and 18 deletions

View File

@@ -54,6 +54,8 @@ typedef struct {
GdkVisual *visual;
gboolean swap_interval;
gboolean needs_update;
} GdkGLContextPrivate;
enum {
@@ -453,9 +455,50 @@ gdk_gl_context_get_window (GdkGLContext *context)
void
gdk_gl_context_update (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
GDK_GL_CONTEXT_GET_CLASS (context)->update (context);
if (priv->needs_update)
return;
priv->needs_update = TRUE;
}
/*< private >
* gdk_gl_context_needs_update:
* @context: a #GdkGLContext
*
* Checks whether gdk_gl_context_update() was called on @context.
*
* Platform-specific code may need to be executed to update the
* viewport in case the context requested an update.
*/
gboolean
gdk_gl_context_needs_update (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
return priv->needs_update;
}
/*< private >*
* gdk_gl_context_update_viewport:
* @context: a #GdkGLContext
* @window: a #GdkWindow
* @width: width of the viewport
* @height: height of the viewport
*
* Updates the viewport of @context in response to a size change
* of the given @window.
*/
void
gdk_gl_context_update_viewport (GdkGLContext *context,
GdkWindow *window,
int width,
int height)
{
GDK_GL_CONTEXT_GET_CLASS (context)->update_viewport (context, window, width, height);
}
/**

View File

@@ -40,13 +40,21 @@ struct _GdkGLContextClass
{
GObjectClass parent_class;
void (* set_window) (GdkGLContext *context,
GdkWindow *window);
void (* update) (GdkGLContext *context);
void (* flush_buffer) (GdkGLContext *context);
void (* set_window) (GdkGLContext *context,
GdkWindow *window);
void (* update_viewport) (GdkGLContext *context,
GdkWindow *window,
int width,
int height);
void (* flush_buffer) (GdkGLContext *context);
};
gboolean gdk_gl_context_get_swap_interval (GdkGLContext *context);
gboolean gdk_gl_context_needs_update (GdkGLContext *context);
void gdk_gl_context_update_viewport (GdkGLContext *context,
GdkWindow *window,
int width,
int height);
G_END_DECLS

View File

@@ -798,7 +798,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
{
GdkGLContext *context = gdk_window_get_gl_context (window);
gdk_gl_context_update (context);
/* only update the viewport if the context asked for it */
if (gdk_gl_context_needs_update (context))
{
GDK_NOTE (OPENGL,
g_print ("Updating viewport after a ConfigureNotify on window %lu\n",
(unsigned long) xevent->xconfigure.window));
gdk_gl_context_update_viewport (context, window,
xevent->xconfigure.width,
xevent->xconfigure.height);
}
}
return_val = FALSE;

View File

@@ -10,6 +10,8 @@
#include "gdkx11window.h"
#include "gdkx11visual.h"
#include "gdkinternals.h"
#include "gdkintl.h"
#include <GL/glx.h>
@@ -98,18 +100,13 @@ gdk_x11_gl_context_set_window (GdkGLContext *context,
}
static void
gdk_x11_gl_context_update (GdkGLContext *context)
gdk_x11_gl_context_update_viewport (GdkGLContext *context,
GdkWindow *window,
int width,
int height)
{
GdkWindow *window = gdk_gl_context_get_window (context);
int x, y, width, height;
GDK_NOTE (OPENGL, g_print ("Updating viewport to { 0, 0, %d, %d }\n", width, height));
if (window == NULL)
return;
if (!gdk_gl_context_make_current (context))
return;
gdk_window_get_geometry (window, &x, &y, &width, &height);
glViewport (0, 0, width, height);
}
@@ -157,7 +154,11 @@ gdk_x11_gl_context_flush_buffer (GdkGLContext *context)
else
drawable = gdk_x11_window_get_xid (window);
GDK_NOTE (OPENGL, g_print ("Flushing GLX buffers for %lu\n", (unsigned long) drawable));
GDK_NOTE (OPENGL,
g_print ("Flushing GLX buffers for %s drawable %lu (window: %lu)\n",
drawable == info->drawable ? "GLX" : "X11",
(unsigned long) drawable,
(unsigned long) gdk_x11_window_get_xid (window)));
/* if we are going to wait for the vertical refresh manually
* we need to flush pending redraws, and we also need to wait
@@ -204,7 +205,7 @@ gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
context_class->set_window = gdk_x11_gl_context_set_window;
context_class->update = gdk_x11_gl_context_update;
context_class->update_viewport = gdk_x11_gl_context_update_viewport;
context_class->flush_buffer = gdk_x11_gl_context_flush_buffer;
}