2016-11-28 16:22:35 +00:00
|
|
|
/* GDK - The GIMP Drawing Kit
|
|
|
|
*
|
|
|
|
* gdkdrawcontext.c: base class for rendering system support
|
|
|
|
*
|
|
|
|
* Copyright © 2016 Benjamin Otte
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "gdkdrawcontextprivate.h"
|
|
|
|
|
|
|
|
#include "gdkinternals.h"
|
|
|
|
#include "gdkintl.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION:gdkdrawcontext
|
|
|
|
* @Title: GdkDrawContext
|
|
|
|
* @Short_description: Drawing context base class
|
|
|
|
*
|
|
|
|
* #GdkDrawContext is the base object used by contexts implementing different
|
2016-12-09 19:59:46 +00:00
|
|
|
* rendering methods, such as #GdkGLContext or #GdkVulkanContext. It provides
|
2016-11-28 16:22:35 +00:00
|
|
|
* shared functionality between those contexts.
|
|
|
|
*
|
|
|
|
* You will always interact with one of those subclasses.
|
|
|
|
*/
|
|
|
|
typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
|
|
|
|
|
|
|
|
struct _GdkDrawContextPrivate {
|
|
|
|
GdkWindow *window;
|
2016-12-01 00:38:20 +00:00
|
|
|
|
|
|
|
guint is_drawing : 1;
|
2016-11-28 16:22:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
PROP_0,
|
|
|
|
|
|
|
|
PROP_DISPLAY,
|
|
|
|
PROP_WINDOW,
|
|
|
|
|
|
|
|
LAST_PROP
|
|
|
|
};
|
|
|
|
|
|
|
|
static GParamSpec *pspecs[LAST_PROP] = { NULL, };
|
|
|
|
|
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrawContext, gdk_draw_context, G_TYPE_OBJECT)
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_draw_context_dispose (GObject *gobject)
|
|
|
|
{
|
|
|
|
GdkDrawContext *context = GDK_DRAW_CONTEXT (gobject);
|
|
|
|
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_clear_object (&priv->window);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (gdk_draw_context_parent_class)->dispose (gobject);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_draw_context_set_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GdkDrawContext *context = GDK_DRAW_CONTEXT (gobject);
|
|
|
|
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_WINDOW:
|
|
|
|
priv->window = g_value_dup_object (value);
|
|
|
|
g_assert (priv->window != NULL);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_draw_context_get_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GdkDrawContext *context = GDK_DRAW_CONTEXT (gobject);
|
|
|
|
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_DISPLAY:
|
|
|
|
g_value_set_object (value, gdk_draw_context_get_display (context));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_WINDOW:
|
|
|
|
g_value_set_object (value, priv->window);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
gobject_class->set_property = gdk_draw_context_set_property;
|
|
|
|
gobject_class->get_property = gdk_draw_context_get_property;
|
|
|
|
gobject_class->dispose = gdk_draw_context_dispose;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* GdkDrawContext:display:
|
|
|
|
*
|
|
|
|
* The #GdkDisplay used to create the #GdkDrawContext.
|
|
|
|
*
|
|
|
|
* Since: 3.90
|
|
|
|
*/
|
|
|
|
pspecs[PROP_DISPLAY] =
|
|
|
|
g_param_spec_object ("display",
|
|
|
|
P_("Display"),
|
|
|
|
P_("The GDK display used to create the context"),
|
|
|
|
GDK_TYPE_DISPLAY,
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* GdkDrawContext:window:
|
|
|
|
*
|
|
|
|
* The #GdkWindow the gl context is bound to.
|
|
|
|
*
|
|
|
|
* Since: 3.90
|
|
|
|
*/
|
|
|
|
pspecs[PROP_WINDOW] =
|
|
|
|
g_param_spec_object ("window",
|
|
|
|
P_("Window"),
|
|
|
|
P_("The GDK window bound to the context"),
|
|
|
|
GDK_TYPE_WINDOW,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
g_object_class_install_properties (gobject_class, LAST_PROP, pspecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_draw_context_init (GdkDrawContext *self)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-12-01 00:38:20 +00:00
|
|
|
/*< 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;
|
|
|
|
}
|
|
|
|
|
2016-11-28 16:22:35 +00:00
|
|
|
/**
|
|
|
|
* gdk_draw_context_get_display:
|
|
|
|
* @context: a #GdkDrawContext
|
|
|
|
*
|
|
|
|
* Retrieves the #GdkDisplay the @context is created for
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer none): a #GdkDisplay or %NULL
|
|
|
|
*
|
|
|
|
* Since: 3.90
|
|
|
|
*/
|
|
|
|
GdkDisplay *
|
|
|
|
gdk_draw_context_get_display (GdkDrawContext *context)
|
|
|
|
{
|
|
|
|
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
|
|
|
|
|
|
|
|
return priv->window ? gdk_window_get_display (priv->window) : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_draw_context_get_window:
|
|
|
|
* @context: a #GdkDrawContext
|
|
|
|
*
|
|
|
|
* Retrieves the #GdkWindow used by the @context.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer none): a #GdkWindow or %NULL
|
|
|
|
*
|
|
|
|
* Since: 3.90
|
|
|
|
*/
|
|
|
|
GdkWindow *
|
|
|
|
gdk_draw_context_get_window (GdkDrawContext *context)
|
|
|
|
{
|
|
|
|
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
|
|
|
|
|
|
|
|
return priv->window;
|
|
|
|
}
|
|
|
|
|