Commit e87b4721 authored by Benjamin Otte's avatar Benjamin Otte

glcontext: Make begin/end_draw() paired

This way, we can query the GL context's state via
gdk_gl_context_is_drawing().

Use this function to make GL contexts as attached and grant them access
to the front/backbuffer for rendering.

All of this is still unused because GL drawing is still disabled.
parent 182d18bc
......@@ -97,6 +97,7 @@ 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;
......@@ -368,6 +369,78 @@ 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;
int ww, wh;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
g_return_if_fail (region != NULL);
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 (priv->window) * gdk_window_get_scale_factor (priv->window);
wh = gdk_window_get_height (priv->window) * gdk_window_get_scale_factor (priv->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
......@@ -387,15 +460,24 @@ 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)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
if (priv->paint_data == NULL)
......
......@@ -89,6 +89,9 @@ 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);
......
......@@ -2715,40 +2715,6 @@ gdk_window_begin_paint_internal (GdkWindow *window,
surface_content = gdk_window_get_content (window);
#if 0
if (window->current_paint.use_gl)
{
GdkGLContext *context;
int ww = gdk_window_get_width (window) * gdk_window_get_scale_factor (window);
int wh = gdk_window_get_height (window) * gdk_window_get_scale_factor (window);
context = gdk_window_get_paint_gl_context (window, NULL);
if (context == NULL)
{
g_warning ("gl rendering failed, context: %p", context);
window->current_paint.use_gl = FALSE;
}
else
{
gdk_gl_context_make_current (context);
/* With gl we always need a surface to combine the gl
drawing with the native drawing. */
needs_surface = TRUE;
/* Also, we need the surface to include alpha */
surface_content = CAIRO_CONTENT_COLOR_ALPHA;
/* 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);
}
}
#endif
if (needs_surface)
{
window->current_paint.surface = gdk_window_create_similar_surface (window,
......@@ -2797,31 +2763,6 @@ gdk_window_end_paint_internal (GdkWindow *window)
{
cairo_surface_t *surface;
#if 0
if (window->current_paint.use_gl)
{
cairo_region_t *opaque_region = cairo_region_copy (window->current_paint.region);
gdk_gl_context_make_current (window->gl_paint_context);
if (!cairo_region_is_empty (opaque_region))
gdk_gl_texture_from_surface (window->current_paint.surface,
opaque_region);
if (!cairo_region_is_empty (window->current_paint.need_blend_region))
{
glEnable(GL_BLEND);
gdk_gl_texture_from_surface (window->current_paint.surface,
window->current_paint.need_blend_region);
glDisable(GL_BLEND);
}
cairo_region_destroy (opaque_region);
gdk_gl_context_end_frame (window->gl_paint_context,
window->current_paint.region,
window->active_update_area);
}
#endif
surface = gdk_window_ref_impl_surface (window);
cr = cairo_create (surface);
......
......@@ -631,7 +631,7 @@ gdk_mir_display_make_gl_context_current (GdkDisplay *display,
mir_context = GDK_MIR_GL_CONTEXT (context);
window = gdk_gl_context_get_window (context);
if (mir_context->is_attached)
if (mir_context->is_attached || gdk_gl_context_is_drawing (context))
{
egl_surface = _gdk_mir_window_get_egl_surface (window,
mir_context->egl_config);
......
......@@ -464,7 +464,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)
if (context_wayland->is_attached || gdk_gl_context_is_drawing (context))
egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config);
else
{
......
......@@ -175,7 +175,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
info = get_glx_drawable_info (window);
drawable = shared_x11->drawable;
drawable = shared_x11->attached_drawable;
GDK_NOTE (OPENGL,
g_message ("Flushing GLX buffers for drawable %lu (window: %lu), frame sync: %s",
......@@ -573,7 +573,6 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
GdkX11Display *display_x11;
GdkDisplay *display;
GdkX11GLContext *context_x11;
GLXWindow drawable;
XVisualInfo *xvisinfo;
Display *dpy;
DrawableInfo *info;
......@@ -736,13 +735,10 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
XFree (xvisinfo);
if (context_x11->is_attached)
drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_window_get_xid (window->impl_window);
else
drawable = info->dummy_glx ? info->dummy_glx : info->dummy_xwin;
context_x11->attached_drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_window_get_xid (window->impl_window);
context_x11->unattached_drawable = info->dummy_glx ? info->dummy_glx : info->dummy_xwin;
context_x11->is_direct = glXIsDirect (dpy, context_x11->glx_context);
context_x11->drawable = drawable;
GDK_NOTE (OPENGL,
g_message ("Realized GLX context[%p], %s",
......@@ -1248,6 +1244,7 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display,
GdkX11GLContext *context_x11;
Display *dpy = gdk_x11_display_get_xdisplay (display);
gboolean do_frame_sync = FALSE;
GLXWindow drawable;
if (context == NULL)
{
......@@ -1263,11 +1260,16 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display,
return FALSE;
}
if (context_x11->is_attached || gdk_gl_context_is_drawing (context))
drawable = context_x11->attached_drawable;
else
drawable = context_x11->unattached_drawable;
GDK_NOTE (OPENGL,
g_message ("Making GLX context current to drawable %lu",
(unsigned long) context_x11->drawable));
g_message ("Making GLX context %p current to drawable %lu",
context, (unsigned long) drawable));
if (!glXMakeContextCurrent (dpy, context_x11->drawable, context_x11->drawable,
if (!glXMakeContextCurrent (dpy, drawable, drawable,
context_x11->glx_context))
{
GDK_NOTE (OPENGL,
......
......@@ -42,7 +42,8 @@ struct _GdkX11GLContext
GLXContext glx_context;
GLXFBConfig glx_config;
GLXDrawable drawable;
GLXDrawable attached_drawable;
GLXDrawable unattached_drawable;
guint is_attached : 1;
guint is_direct : 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment