/* GSK - The GTK Scene Kit
*
* Copyright 2016 Endless
*
* 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 .
*/
/**
* SECTION:GskRenderer
* @title: GskRenderer
* @Short_desc: Renders a scene with a simplified graph
*
* TODO
*/
#include "config.h"
#include "gskrendererprivate.h"
#include "gskdebugprivate.h"
#include "gskglrendererprivate.h"
#include "gskrendernodeprivate.h"
#include "gskenumtypes.h"
#include
#include
#include
#ifdef GDK_WINDOWING_X11
#include
#endif
#ifdef GDK_WINDOWING_WAYLAND
#include
#endif
typedef struct
{
GObject parent_instance;
graphene_rect_t viewport;
graphene_matrix_t modelview;
graphene_matrix_t projection;
GskScalingFilter min_filter;
GskScalingFilter mag_filter;
GdkWindow *window;
GdkDrawingContext *drawing_context;
GskRenderNode *root_node;
GdkDisplay *display;
int scale_factor;
gboolean is_realized : 1;
gboolean auto_clear : 1;
gboolean use_alpha : 1;
} GskRendererPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GskRenderer, gsk_renderer, G_TYPE_OBJECT)
enum {
PROP_VIEWPORT = 1,
PROP_MODELVIEW,
PROP_PROJECTION,
PROP_MINIFICATION_FILTER,
PROP_MAGNIFICATION_FILTER,
PROP_AUTO_CLEAR,
PROP_USE_ALPHA,
PROP_SCALE_FACTOR,
PROP_WINDOW,
PROP_DISPLAY,
PROP_DRAWING_CONTEXT,
N_PROPS
};
static GParamSpec *gsk_renderer_properties[N_PROPS];
#define GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD(obj,method) \
g_critical ("Renderer of type '%s' does not implement GskRenderer::" # method, G_OBJECT_TYPE_NAME (obj))
static gboolean
gsk_renderer_real_realize (GskRenderer *self)
{
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, realize);
return FALSE;
}
static void
gsk_renderer_real_unrealize (GskRenderer *self)
{
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, unrealize);
}
static void
gsk_renderer_real_render (GskRenderer *self,
GskRenderNode *root,
GdkDrawingContext *context)
{
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render);
}
static void
gsk_renderer_dispose (GObject *gobject)
{
GskRenderer *self = GSK_RENDERER (gobject);
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
gsk_renderer_unrealize (self);
g_clear_object (&priv->window);
g_clear_object (&priv->display);
G_OBJECT_CLASS (gsk_renderer_parent_class)->dispose (gobject);
}
static void
gsk_renderer_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GskRenderer *self = GSK_RENDERER (gobject);
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
switch (prop_id)
{
case PROP_VIEWPORT:
gsk_renderer_set_viewport (self, g_value_get_boxed (value));
break;
case PROP_MODELVIEW:
gsk_renderer_set_modelview (self, g_value_get_boxed (value));
break;
case PROP_PROJECTION:
gsk_renderer_set_projection (self, g_value_get_boxed (value));
break;
case PROP_MINIFICATION_FILTER:
gsk_renderer_set_scaling_filters (self, g_value_get_enum (value), priv->mag_filter);
break;
case PROP_MAGNIFICATION_FILTER:
gsk_renderer_set_scaling_filters (self, priv->min_filter, g_value_get_enum (value));
break;
case PROP_AUTO_CLEAR:
gsk_renderer_set_auto_clear (self, g_value_get_boolean (value));
break;
case PROP_USE_ALPHA:
gsk_renderer_set_use_alpha (self, g_value_get_boolean (value));
break;
case PROP_SCALE_FACTOR:
gsk_renderer_set_scale_factor (self, g_value_get_int (value));
break;
case PROP_WINDOW:
gsk_renderer_set_window (self, g_value_get_object (value));
break;
case PROP_DISPLAY:
/* Construct-only */
priv->display = g_value_dup_object (value);
break;
}
}
static void
gsk_renderer_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GskRenderer *self = GSK_RENDERER (gobject);
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
switch (prop_id)
{
case PROP_VIEWPORT:
g_value_set_boxed (value, &priv->viewport);
break;
case PROP_MODELVIEW:
g_value_set_boxed (value, &priv->modelview);
break;
case PROP_PROJECTION:
g_value_set_boxed (value, &priv->projection);
break;
case PROP_MINIFICATION_FILTER:
g_value_set_enum (value, priv->min_filter);
break;
case PROP_MAGNIFICATION_FILTER:
g_value_set_enum (value, priv->mag_filter);
break;
case PROP_AUTO_CLEAR:
g_value_set_boolean (value, priv->auto_clear);
break;
case PROP_USE_ALPHA:
g_value_set_boolean (value, priv->use_alpha);
break;
case PROP_SCALE_FACTOR:
g_value_set_int (value, priv->scale_factor);
break;
case PROP_WINDOW:
g_value_set_object (value, priv->window);
break;
case PROP_DRAWING_CONTEXT:
g_value_set_object (value, priv->drawing_context);
break;
case PROP_DISPLAY:
g_value_set_object (value, priv->display);
break;
}
}
static void
gsk_renderer_constructed (GObject *gobject)
{
GskRenderer *self = GSK_RENDERER (gobject);
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
if (priv->display == NULL)
{
GdkDisplayManager *manager = gdk_display_manager_get ();
priv->display = gdk_display_manager_get_default_display (manager);
g_assert (priv->display != NULL);
}
G_OBJECT_CLASS (gsk_renderer_parent_class)->constructed (gobject);
}
static void
gsk_renderer_class_init (GskRendererClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->realize = gsk_renderer_real_realize;
klass->unrealize = gsk_renderer_real_unrealize;
klass->render = gsk_renderer_real_render;
gobject_class->constructed = gsk_renderer_constructed;
gobject_class->set_property = gsk_renderer_set_property;
gobject_class->get_property = gsk_renderer_get_property;
gobject_class->dispose = gsk_renderer_dispose;
/**
* GskRenderer:viewport:
*
* The visible area used by the #GskRenderer to render its contents.
*
* Since: 3.22
*/
gsk_renderer_properties[PROP_VIEWPORT] =
g_param_spec_boxed ("viewport",
"Viewport",
"The visible area used by the renderer",
GRAPHENE_TYPE_RECT,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GskRenderer:modelview:
*
* The initial modelview matrix used by the #GskRenderer.
*
* If set to %NULL, the identity matrix:
*
* |[