Commit ca78f5d3 authored by Benjamin Otte's avatar Benjamin Otte

gdk: Make gdk_window_begin_draw_frame() take a draw context

... instead of a gl context.

This requires some refactoring in the way we mark the shared context as
drawing: We now call begin_frame/end_frame() on it and ignore the call
on the main context.
Unfortunately we need to do this check in all vfuncs, which sucks. But I
haven't found a better way.
parent 60567db4
......@@ -31,7 +31,7 @@
* @Short_description: Drawing context base class
*
* #GdkDrawContext is the base object used by contexts implementing different
* rendering methods, such as #GdkGLContext or #GdkVulkanContext. They provide
* rendering methods, such as #GdkDrawContext or #GdkVulkanContext. They provide
* shared functionality between those contexts.
*
* You will always interact with one of those subclasses.
......@@ -40,6 +40,8 @@ typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
struct _GdkDrawContextPrivate {
GdkWindow *window;
guint is_drawing : 1;
};
enum {
......@@ -159,6 +161,87 @@ gdk_draw_context_init (GdkDrawContext *self)
{
}
/*< private >
* gdk_draw_context_is_drawing:
* @context: a #GdkDrawContext
*
* Returns %TRUE if @context is in the process of drawing to its window. In such
* cases, it will have access to the window's backbuffer to render the new frame
* onto it.
*
* Returns: %TRUE if the context is between begin_frame() and end_frame() calls.
*
* Since: 3.90
*/
gboolean
gdk_draw_context_is_drawing (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
return priv->is_drawing;
}
/*< private >
* gdk_draw_context_begin_frame:
* @context: a #GdkDrawContext
* @region: (inout): The clip region that needs to be repainted
*
* Sets up @context and @drawing for a new drawing.
*
* The @context is free to update @region to the size that actually needs to
* be repainted. Contexts that do not support partial blits for example may
* want to invalidate the whole window instead.
*
* The function does not clear the background. Clearing the backgroud is the
* job of the renderer. The contents of the backbuffer are undefined after this
* function call.
*
* Since: 3.90
*/
void
gdk_draw_context_begin_frame (GdkDrawContext *context,
cairo_region_t *region)
{
GdkDrawContextPrivate *priv;
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
g_return_if_fail (region != NULL);
priv = gdk_draw_context_get_instance_private (context);
priv->is_drawing = TRUE;
GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, region);
}
/*< private >
* gdk_draw_context_end_frame:
* @context: a #GdkDrawContext
* @painted: The area that has been redrawn this frame
* @damage: The area that we know is actually different from the last frame
*
* Copies the back buffer to the front buffer.
*
* This function may call `glFlush()` implicitly before returning; it
* is not recommended to call `glFlush()` explicitly before calling
* this function.
*
* Since: 3.16
*/
void
gdk_draw_context_end_frame (GdkDrawContext *context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkDrawContextPrivate *priv;
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage);
priv = gdk_draw_context_get_instance_private (context);
priv->is_drawing = FALSE;
}
/**
* gdk_draw_context_get_display:
* @context: a #GdkDrawContext
......
......@@ -39,8 +39,21 @@ struct _GdkDrawContext
struct _GdkDrawContextClass
{
GObjectClass parent_class;
void (* begin_frame) (GdkDrawContext *context,
cairo_region_t *update_area);
void (* end_frame) (GdkDrawContext *context,
cairo_region_t *painted,
cairo_region_t *damage);
};
gboolean gdk_draw_context_is_drawing (GdkDrawContext *context);
void gdk_draw_context_begin_frame (GdkDrawContext *context,
cairo_region_t *region);
void gdk_draw_context_end_frame (GdkDrawContext *context,
cairo_region_t *painted,
cairo_region_t *damage);
G_END_DECLS
#endif /* __GDK__DRAW_CONTEXT_PRIVATE__ */
......@@ -50,7 +50,7 @@ typedef struct _GdkDrawingContextPrivate GdkDrawingContextPrivate;
struct _GdkDrawingContextPrivate {
GdkWindow *window;
GdkGLContext *paint_context;
GdkDrawContext *paint_context;
cairo_region_t *clip;
cairo_t *cr;
......@@ -191,13 +191,13 @@ gdk_drawing_context_class_init (GdkDrawingContextClass *klass)
/**
* GdkDrawingContext:paint-context:
*
* The #GdkGLContext used to draw or %NULL if Cairo is used.
* The #GdkDrawContext used to draw or %NULL if Cairo is used.
*
* Since: 3.90
*/
obj_property[PROP_PAINT_CONTEXT] =
g_param_spec_object ("paint-context", "Paint context", "The context used to draw",
GDK_TYPE_GL_CONTEXT,
GDK_TYPE_DRAW_CONTEXT,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
......@@ -244,7 +244,7 @@ gdk_cairo_get_drawing_context (cairo_t *cr)
*
* Retrieves a Cairo context to be used to draw on the #GdkWindow
* that created the #GdkDrawingContext. The @context must have been
* created without a #GdkGLContext for this function to work. If
* created without a #GdkDrawContext for this function to work. If
* gdk_drawing_context_get_paint_context() does not return %NULL,
* then this function will.
*
......@@ -318,11 +318,11 @@ gdk_drawing_context_get_window (GdkDrawingContext *context)
*
* Retrieves the paint context used to draw with.
*
* Returns: (transfer none): a #GdkGLContext or %NULL
* Returns: (transfer none): a #GdkDrawContext or %NULL
*
* Since: 3.90
*/
GdkGLContext *
GdkDrawContext *
gdk_drawing_context_get_paint_context (GdkDrawingContext *context)
{
GdkDrawingContextPrivate *priv = gdk_drawing_context_get_instance_private (context);
......
......@@ -39,7 +39,7 @@ GType gdk_drawing_context_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_22
GdkWindow * gdk_drawing_context_get_window (GdkDrawingContext *context);
GDK_AVAILABLE_IN_3_90
GdkGLContext* gdk_drawing_context_get_paint_context (GdkDrawingContext *context);
GdkDrawContext* gdk_drawing_context_get_paint_context (GdkDrawingContext *context);
GDK_AVAILABLE_IN_3_22
cairo_region_t *gdk_drawing_context_get_clip (GdkDrawingContext *context);
......
......@@ -95,7 +95,6 @@ typedef struct {
int gl_version;
guint realized : 1;
guint is_drawing : 1;
guint use_texture_rectangle : 1;
guint has_gl_framebuffer_blit : 1;
guint has_frame_terminator : 1;
......@@ -256,13 +255,64 @@ gdk_gl_context_real_realize (GdkGLContext *self,
return FALSE;
}
static void
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *region)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWindow *window;
GdkGLContext *shared;
int ww, wh;
shared = gdk_gl_context_get_shared_context (context);
if (shared)
{
gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (shared), region);
return;
}
window = gdk_draw_context_get_window (draw_context);
ww = gdk_window_get_width (window) * gdk_window_get_scale_factor (window);
wh = gdk_window_get_height (window) * gdk_window_get_scale_factor (window);
gdk_gl_context_make_current (context);
/* Initial setup */
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glDisable (GL_DEPTH_TEST);
glDisable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glViewport (0, 0, ww, wh);
}
static void
gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkGLContext *shared;
shared = gdk_gl_context_get_shared_context (context);
if (shared)
{
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (shared), painted, damage);
return;
}
}
static void
gdk_gl_context_class_init (GdkGLContextClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
klass->realize = gdk_gl_context_real_realize;
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
draw_context_class->end_frame = gdk_gl_context_real_end_frame;
/**
* GdkGLContext:shared-context:
*
......@@ -295,115 +345,6 @@ gdk_gl_context_init (GdkGLContext *self)
priv->use_es = -1;
}
/*< private >
* gdk_gl_context_is_drawing:
* @context: a #GdkGLContext
*
* Returns %TRUE if @context is in the process of drawing to its window. In such
* cases, it will have access to the window's backbuffer to render the new frame
* onto it.
*
* Returns: %TRUE if the context is between begin_frame() and end_frame() calls.
*
* Since: 3.90
*/
gboolean
gdk_gl_context_is_drawing (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
return priv->is_drawing;
}
/*< private >
* gdk_gl_context_begin_frame:
* @context: a #GdkGLContext
* @region: (inout): The clip region that needs to be repainted
*
* Sets up @context and @drawing for a new drawing.
*
* The @context is free to update @region to the size that actually needs to
* be repainted. Contexts that do not support partial blits for example may
* want to invalidate the whole window instead.
*
* The function does not clear the background. Clearing the backgroud is the
* job of the renderer. The contents of the backbuffer are undefined after this
* function call.
*
* Since: 3.90
*/
void
gdk_gl_context_begin_frame (GdkGLContext *context,
cairo_region_t *region)
{
GdkGLContextPrivate *priv, *shared_priv;
GdkGLContext *shared;
GdkWindow *window;
int ww, wh;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
g_return_if_fail (region != NULL);
window = gdk_draw_context_get_window (GDK_DRAW_CONTEXT (context));
priv = gdk_gl_context_get_instance_private (context);
priv->is_drawing = TRUE;
shared = gdk_gl_context_get_shared_context (context);
shared_priv = gdk_gl_context_get_instance_private (shared);
shared_priv->is_drawing = TRUE;
GDK_GL_CONTEXT_GET_CLASS (context)->begin_frame (context, region);
ww = gdk_window_get_width (window) * gdk_window_get_scale_factor (window);
wh = gdk_window_get_height (window) * gdk_window_get_scale_factor (window);
gdk_gl_context_make_current (shared);
/* Initial setup */
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glDisable (GL_DEPTH_TEST);
glDisable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glViewport (0, 0, ww, wh);
}
/*< private >
* gdk_gl_context_end_frame:
* @context: a #GdkGLContext
* @painted: The area that has been redrawn this frame
* @damage: The area that we know is actually different from the last frame
*
* Copies the back buffer to the front buffer.
*
* This function may call `glFlush()` implicitly before returning; it
* is not recommended to call `glFlush()` explicitly before calling
* this function.
*
* Since: 3.16
*/
void
gdk_gl_context_end_frame (GdkGLContext *context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkGLContextPrivate *priv, *shared_priv;
GdkGLContext *shared;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
GDK_GL_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage);
priv = gdk_gl_context_get_instance_private (context);
priv->is_drawing = FALSE;
shared = gdk_gl_context_get_shared_context (context);
shared_priv = gdk_gl_context_get_instance_private (shared);
shared_priv->is_drawing = FALSE;
}
GdkGLContextPaintData *
gdk_gl_context_get_paint_data (GdkGLContext *context)
{
......
......@@ -44,11 +44,6 @@ struct _GdkGLContextClass
gboolean (* realize) (GdkGLContext *context,
GError **error);
void (* begin_frame) (GdkGLContext *context,
cairo_region_t *update_area);
void (* end_frame) (GdkGLContext *context,
cairo_region_t *painted,
cairo_region_t *damage);
gboolean (* texture_from_surface) (GdkGLContext *context,
cairo_surface_t *surface,
cairo_region_t *region);
......@@ -90,12 +85,6 @@ gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
gboolean gdk_gl_context_is_drawing (GdkGLContext *context);
void gdk_gl_context_begin_frame (GdkGLContext *context,
cairo_region_t *region);
void gdk_gl_context_end_frame (GdkGLContext *context,
cairo_region_t *painted,
cairo_region_t *damage);
G_END_DECLS
......
......@@ -2816,7 +2816,7 @@ gdk_window_end_paint_internal (GdkWindow *window)
*/
GdkDrawingContext *
gdk_window_begin_draw_frame (GdkWindow *window,
GdkGLContext *gl_context,
GdkDrawContext *draw_context,
const cairo_region_t *region)
{
GdkDrawingContext *context;
......@@ -2826,10 +2826,10 @@ gdk_window_begin_draw_frame (GdkWindow *window,
g_return_val_if_fail (gdk_window_has_native (window), NULL);
g_return_val_if_fail (gdk_window_is_toplevel (window), NULL);
g_return_val_if_fail (region != NULL, NULL);
if (gl_context != NULL)
if (draw_context != NULL)
{
g_return_val_if_fail (GDK_IS_GL_CONTEXT (gl_context), NULL);
g_return_val_if_fail (gdk_gl_context_get_window (gl_context) == window, NULL);
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (draw_context), NULL);
g_return_val_if_fail (gdk_draw_context_get_window (draw_context) == window, NULL);
}
if (GDK_WINDOW_DESTROYED (window))
......@@ -2845,14 +2845,14 @@ gdk_window_begin_draw_frame (GdkWindow *window,
real_region = cairo_region_copy (region);
if (gl_context)
gdk_gl_context_begin_frame (gl_context, real_region);
if (draw_context)
gdk_draw_context_begin_frame (draw_context, real_region);
else
gdk_window_begin_paint_internal (window, real_region);
context = g_object_new (GDK_TYPE_DRAWING_CONTEXT,
"window", window,
"paint-context", gl_context,
"paint-context", draw_context,
"clip", real_region,
NULL);
......@@ -2883,7 +2883,7 @@ void
gdk_window_end_draw_frame (GdkWindow *window,
GdkDrawingContext *context)
{
GdkGLContext *paint_context;
GdkDrawContext *paint_context;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context));
......@@ -2903,9 +2903,9 @@ gdk_window_end_draw_frame (GdkWindow *window,
paint_context = gdk_drawing_context_get_paint_context (context);
if (paint_context)
{
gdk_gl_context_end_frame (paint_context,
gdk_drawing_context_get_clip (context),
window->active_update_area);
gdk_draw_context_end_frame (paint_context,
gdk_drawing_context_get_clip (context),
window->active_update_area);
}
else
{
......
......@@ -628,7 +628,7 @@ void gdk_window_mark_paint_from_clip (GdkWindow *window,
GDK_AVAILABLE_IN_3_90
GdkDrawingContext *gdk_window_begin_draw_frame (GdkWindow *window,
GdkGLContext *context,
GdkDrawContext *context,
const cairo_region_t *region);
GDK_AVAILABLE_IN_3_22
void gdk_window_end_draw_frame (GdkWindow *window,
......
......@@ -98,12 +98,17 @@ gdk_mir_gl_context_realize (GdkGLContext *context,
}
static void
gdk_mir_gl_context_begin_frame (GdkGLContext *context,
gdk_mir_gl_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *update_area)
{
GdkDisplay *display = gdk_gl_context_get_display (window);
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkDisplay *display = gdk_draw_context_get_display (draw_context);
GdkWindow *window;
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->begin_frame (draw_context, update_area);
if (gdk_gl_context_get_shared_context (context))
return;
if (_gdk_mir_display_have_egl_swap_buffers_with_damage (display))
return;
......@@ -121,12 +126,17 @@ gdk_mir_gl_context_end_frame (GdkGLContext *context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWindow *window = gdk_gl_context_get_window (context);
GdkDisplay *display = gdk_window_get_display (window);
GdkMirGLContext *context_mir = GDK_MIR_GL_CONTEXT (context);
EGLDisplay egl_display = _gdk_mir_display_get_egl_display (display);
EGLSurface egl_surface;
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->end_frame (draw_context, painted, damage);
if (gdk_gl_context_get_shared_context (context))
return;
gdk_gl_context_make_current (context);
egl_surface = _gdk_mir_window_get_egl_surface (window,
......
......@@ -35,14 +35,19 @@
G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT)
static void gdk_x11_gl_context_dispose (GObject *gobject);
static void gdk_wayland_gl_context_dispose (GObject *gobject);
static void
gdk_wayland_gl_context_begin_frame (GdkGLContext *context,
gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *update_area)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWindow *window;
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, update_area);
if (gdk_gl_context_get_shared_context (context))
return;
/* If nothing else is known, repaint everything so that the back
buffer is fully up-to-date for the swapbuffer */
window = gdk_gl_context_get_window (context);
......@@ -171,21 +176,25 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
}
static void
gdk_wayland_gl_context_end_frame (GdkGLContext *context,
gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWindow *window = gdk_gl_context_get_window (context);
GdkDisplay *display = gdk_window_get_display (window);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
GdkWaylandGLContext *shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared);
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
EGLSurface egl_surface;
gdk_gl_context_make_current (shared);
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted, damage);
if (gdk_gl_context_get_shared_context (context))
return;
gdk_gl_context_make_current (context);
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
shared_wayland->egl_config);
context_wayland->egl_config);
if (display_wayland->have_egl_swap_buffers_with_damage)
{
......@@ -213,13 +222,15 @@ static void
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
gobject_class->dispose = gdk_x11_gl_context_dispose;
gobject_class->dispose = gdk_wayland_gl_context_dispose;
draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
context_class->realize = gdk_wayland_gl_context_realize;
context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
context_class->end_frame = gdk_wayland_gl_context_end_frame;
}
static void
......@@ -419,7 +430,7 @@ gdk_wayland_window_create_gl_context (GdkWindow *window,
}
static void
gdk_x11_gl_context_dispose (GObject *gobject)
gdk_wayland_gl_context_dispose (GObject *gobject)
{
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (gobject);
......@@ -463,7 +474,7 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
window = gdk_gl_context_get_window (context);
if (context_wayland->is_attached || gdk_gl_context_is_drawing (context))
if (context_wayland->is_attached || gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context)))
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config);
else
{
......
......@@ -101,15 +101,20 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
}
static void
gdk_win32_gl_context_end_frame (GdkGLContext *context,
gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
GdkWindow *window = gdk_gl_context_get_window (context);
GdkWin32Display *display = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
gboolean can_wait = display->hasWglOMLSyncControl;
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->end_frame (draw_context, painted, damage);
if (gdk_gl_context_get_shared_context (context))
return;
gdk_gl_context_make_current (context);
if (context_win32->do_frame_sync)
......@@ -156,11 +161,16 @@ gdk_win32_gl_context_end_frame (GdkGLContext *context,
}
static void
gdk_win32_gl_context_begin_frame (GdkGLContext *context,
gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *update_area)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWindow *window;
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->begin_frame (draw_context, update_area);
if (gdk_gl_context_get_shared_context (context))
return;
if (gdk_gl_context_has_framebuffer_blit (context))
return;
......
......@@ -120,11 +120,16 @@ maybe_wait_for_vblank (GdkDisplay *display,
}
static void
gdk_x11_gl_context_begin_frame (GdkGLContext *context,
gdk_x11_gl_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *update_area)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWindow *window;
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->begin_frame (draw_context, update_area);
if (gdk_gl_context_get_shared_context (context))
return;
if (gdk_gl_context_has_framebuffer_blit (context))
return;
......@@ -157,12 +162,12 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
}
static void
gdk_x11_gl_context_end_frame (GdkGLContext *context,
gdk_x11_gl_context_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted,
cairo_region_t *damage)
{
GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
GdkX11GLContext *shared_x11 = GDK_X11_GL_CONTEXT (shared);
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
GdkWindow *window = gdk_gl_context_get_window (context);
GdkDisplay *display = gdk_gl_context_get_display (context);
Display *dpy = gdk_x11_display_get_xdisplay (display);
......@@ -171,17 +176,21 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
DrawableInfo *info;
GLXDrawable drawable;
gdk_gl_context_make_current (shared);
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->end_frame (draw_context, painted, damage);
if (gdk_gl_context_get_shared_context (context))
return;
gdk_gl_context_make_current (context);
info = get_glx_drawable_info (window);
drawable = shared_x11->attached_drawable;
drawable = context_x11->attached_drawable;
GDK_NOTE (OPENGL,
g_message ("Flushing GLX buffers for drawable %lu (window: %lu), frame sync: %s",
(unsigned long) drawable,
(unsigned long) gdk_x11_window_get_xid (window),
shared_x11->do_frame_sync ? "yes" : "no"));
context_x11->do_frame_sync ? "yes" : "no"));
/* if we are going to wait for the vertical refresh manually
* we need to flush pending redraws, and we also need to wait
......@@ -191,7 +200,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
* GLX_SGI_swap_control, and we ask the driver to do the right
* thing.
*/
if (shared_x11->do_frame_sync)
if (context_x11->do_frame_sync)
{
guint32 end_frame_counter = 0;
gboolean has_counter = display_x11->has_glx_video_sync;
......@@ -200,7 +209,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
if (display_x11->has_glx_video_sync)
glXGetVideoSyncSGI (&end_frame_counter);
if (shared_x11->do_frame_sync && !display_x11->has_glx_swap_interval)
if (context_x11->do_frame_sync && !display_x11->has_glx_swap_interval)
{
glFinish ();
......@@ -221,7 +230,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
{
glXSwapBuffers (dpy, drawable);
}
else if (gdk_gl_context_has_framebuffer_blit (shared))
else if (gdk_gl_context_has_framebuffer_blit (context))
{
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_BACK);
......@@ -229,7 +238,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
glDrawBuffer(GL_BACK);
glFlush();
if (gdk_gl_context_has_frame_terminator (shared))
if (gdk_gl_context_has_frame_terminator (context))
glFrameTerminatorGREMEDY ();
}
else
......@@ -238,7 +247,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
glXSwapBuffers (dpy, drawable);
}
if (shared_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync)
if (context_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync)
glXGetVideoSyncSGI (&info->last_frame_counter);
}
......@@ -774,13 +783,15 @@ static void
gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
{
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);