Commit 7afdd3fd authored by Emmanuele Bassi's avatar Emmanuele Bassi

Initial implementation of GSK rendering pipeline

GSK is conceptually split into two scene graphs:

 * a simple rendering tree of operations
 * a complex set of logical layers

The latter is built on the former, and adds convenience and high level
API for application developers.

The lower layer, though, is what gets transformed into the rendering
pipeline, as it's simple and thus can be transformed into appropriate
rendering commands with minimal state changes.

The lower layer is also suitable for reuse from more complex higher
layers, like the CSS machinery in GTK, without necessarily port those
layers to the GSK high level API.

This lower layer is based on GskRenderNode instances, which represent
the tree of rendering operations; and a GskRenderer instance, which
takes the render nodes and submits them (after potentially reordering
and transforming them to a more appropriate representation) to the
underlying graphic system.
parent d519e4aa
include $(top_srcdir)/Makefile.decl
-include $(INTROSPECTION_MAKEFILE)
# Preamble
INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ARGS = \
--add-include-path=../gdk \
--warn-all
INTROSPECTION_COMPILER_ARGS = \
--includedir=$(srcdir) \
--includedir=. \
--includedir=../gdk
AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"Gsk\" \
-DGSK_COMPILATION \
-I$(top_builddir) \
-I$(top_builddir)/gsk \
-I$(top_srcdir) \
-I$(top_srcdir)/gdk \
-I$(top_builddir) \
-I$(top_builddir)/gsk \
$(GTK_DEBUG_FLAGS) \
$(GTK_WARN_FLAGS) \
$(GSK_DEP_CFLAGS)
......@@ -35,39 +24,124 @@ LDADD = \
BUILT_SOURCES =
CLEANFILES =
DISTCLEANFILES =
lib_LTLIBRARIES =
gsk_public_source_h =
gsk_private_source_h =
gsk_private_source_c =
gsk_source_c =
libgsk_3_la_SOURCES = $(all_sources)
libgsk_3_la_CFLAGS = $(AM_CFLAGS) $(GDK_HIDDEN_VISIBILITY_CFLAGS)
libgsk_3_la_LIBADD = $(GSK_DEP_LIBS) $(top_builddir)/gdk/libgdk-3.la
libgsk_3_la_LDFLAGS = $(LDADD)
lib_LTLIBRARIES += libgsk-3.la
gsk_public_source_h = \
gskenums.h \
gskrenderer.h \
gskrendernode.h \
gskrendernodeiter.h \
gsktypes.h
gsk_private_source_h = \
gskcairorendererprivate.h \
gskdebugprivate.h \
gskglrendererprivate.h \
gskrendererprivate.h \
gskrendernodeprivate.h \
gskprivate.h
gsk_private_source_c = \
gskprivate.c
gsk_built_source_h = \
gskenumtypes.h \
gskresources.h
gsk_built_source_c = \
gskenumtypes.c \
gskresources.c
gsk_source_c = \
gskcairorenderer.c \
gskdebug.c \
gskglrenderer.c \
gskrenderer.c \
gskrendernode.c \
gskrendernodeiter.c
all_sources = \
$(gsk_public_source_h) \
$(gsk_private_source_h) \
$(gsk_built_source_h) \
$(gsk_private_source_c) \
$(gsk_source_c)
BUILT_SOURCES += $(gsk_built_source_h) $(gsk_built_source_c) gsk.resources.xml
gskenumtypes.h: $(gsk_public_source_h) gskenumtypes.h.template
$(AM_V_GEN) $(GLIB_MKENUMS) --template $(filter %.template,$^) $(filter-out %.template,$^) > \
gskenumtypes.h.tmp && \
mv gskenumtypes.h.tmp gskenumtypes.h
gskenumtypes.c: $(gsk_public_source_h) gskenumtypes.c.template
$(AM_V_GEN) $(GLIB_MKENUMS) --template $(filter %.template,$^) $(filter-out %.template,$^) > \
gskenumtypes.c.tmp && \
mv gskenumtypes.c.tmp gskenumtypes.c
EXTRA_DIST += gskenumtypes.h.template gskenumtypes.c.template
DISTCLEANFILES += gskenumtypes.h gskenumtypes.c
resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(builddir)/gsk.resources.xml)
gsk.resources.xml: Makefile.am
$(AM_V_GEN) echo "<?xml version='1.0' encoding='UTF-8'?>" > $@; \
echo "<gresources>" >> $@; \
echo " <gresource prefix='/org/gtk/libgsk'>" >> $@; \
for f in $(top_srcdir)/gsk/resources/glsl/*; do \
n=`basename $$f`; \
echo " <file alias='glsl/$$n'>resources/glsl/$$n</file>" >> $@; \
done; \
echo " </gresource>" >> $@; \
echo "</gresources>" >> $@
gskresources.h: gsk.resources.xml
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< \
--target=$@ --sourcedir=$(srcdir) --c-name _gsk --generate-header --manual-register
gskresources.c: gsk.resources.xml $(resource_files)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< \
--target=$@ --sourcedir=$(srcdir) --c-name _gsk --generate-source --manual-register
EXTRA_DIST += $(resource_files)
CLEANFILES += gsk.resources.xml
DISTCLEANFILES += gskresources.h gskresources.c
libgsk_4_la_SOURCES = $(all_sources)
nodist_libgsk_4_la_SOURCES = $(gsk_built_source_h) $(gsk_built_source_c)
libgsk_4_la_CFLAGS = $(AM_CFLAGS) $(GDK_HIDDEN_VISIBILITY_CFLAGS)
libgsk_4_la_LIBADD = $(GSK_DEP_LIBS) $(top_builddir)/gdk/libgdk-4.la
libgsk_4_la_LDFLAGS = $(LDADD)
lib_LTLIBRARIES += libgsk-4.la
gskincludedir = $(includedir)/gtk-4.0/gsk
gskinclude_HEADERS = $(gsk_public_source_h) gskenumtypes.h gsk.h
gskincludedir = $(includedir)/gtk-3.0/gsk
gskinclude_HEADERS = $(gsk_public_source_h) gsk.h
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ENV = \
CC="$(CC)"
INTROSPECTION_SCANNER_ARGS = \
--add-include-path=../gdk \
--warn-all
INTROSPECTION_COMPILER_ARGS = \
--includedir=$(srcdir) \
--includedir=. \
--includedir=../gdk
if HAVE_INTROSPECTION
introspection_files = $(gsk_source_c) $(gsk_public_source_h)
introspection_files = $(filter-out $(wildcard *private.h),$(all_sources))
Gsk-3.0.gir: libgsk-3.la Makefile
Gsk_3_0_gir_SCANNERFLAGS = \
Gsk-4.0.gir: libgsk-4.la Makefile
Gsk_4_0_gir_SCANNERFLAGS = \
--add-include-path=$(top_builddir)/gdk \
--include-uninstalled=$(top_builddir)/gdk/Gdk-3.0.gir \
--include-uninstalled=$(top_builddir)/gdk/Gdk-4.0.gir \
--c-include="gsk/gsk.h"
Gsk_3_0_gir_LIBS = libgsk-3.la
Gsk_3_0_gir_FILES = $(introspection_files)
Gsk_3_0_gir_CFLAGS = $(AM_CPPFLAGS)
Gsk_3_0_gir_EXPORT_PACKAGES = gsk-3.0
Gsk_3_0_gir_INCLUDES = GObject-2.0 cairo-1.0 Graphene-1.0
INTROSPECTION_GIRS += Gsk-3.0.gir
Gsk_4_0_gir_LIBS = libgsk-4.la $(top_builddir)/gdk/libgdk-4.la
Gsk_4_0_gir_FILES = $(introspection_files)
Gsk_4_0_gir_CFLAGS = $(AM_CPPFLAGS)
Gsk_4_0_gir_EXPORT_PACKAGES = gsk-4.0
Gsk_4_0_gir_INCLUDES = GObject-2.0 cairo-1.0 Graphene-1.0
INTROSPECTION_GIRS += Gsk-4.0.gir
girdir = $(datadir)/gir-1.0
gir_DATA = $(INTROSPECTION_GIRS)
......
/* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GSK_H__
#define __GSK_H__
#define __GSK_H_INSIDE__
#include <gsk/gskenums.h>
#include <gsk/gskrenderer.h>
#include <gsk/gskrendernode.h>
#include <gsk/gskrendernodeiter.h>
#include <gsk/gsktypes.h>
#include <gsk/gskenumtypes.h>
#undef __GSK_H_INSIDE__
#endif /* __GSK_H__ */
#include "config.h"
#include "gskcairorendererprivate.h"
#include "gskdebugprivate.h"
#include "gskrendererprivate.h"
#include "gskrendernodeiter.h"
#include "gskrendernodeprivate.h"
struct _GskCairoRenderer
{
GskRenderer parent_instance;
graphene_rect_t viewport;
};
struct _GskCairoRendererClass
{
GskRendererClass parent_class;
};
G_DEFINE_TYPE (GskCairoRenderer, gsk_cairo_renderer, GSK_TYPE_RENDERER)
static gboolean
gsk_cairo_renderer_realize (GskRenderer *renderer)
{
return TRUE;
}
static void
gsk_cairo_renderer_unrealize (GskRenderer *renderer)
{
}
static void
gsk_cairo_renderer_render_node (GskCairoRenderer *self,
GskRenderNode *node,
cairo_t *cr)
{
GskRenderNodeIter iter;
GskRenderNode *child;
gboolean pop_group = FALSE;
graphene_matrix_t mvp;
cairo_matrix_t ctm;
graphene_rect_t frame;
if (gsk_render_node_is_hidden (node))
return;
cairo_save (cr);
gsk_render_node_get_world_matrix (node, &mvp);
if (graphene_matrix_to_2d (&mvp, &ctm.xx, &ctm.yx, &ctm.xy, &ctm.yy, &ctm.x0, &ctm.y0))
{
GSK_NOTE (CAIRO, g_print ("CTM = { .xx = %g, .yx = %g, .xy = %g, .yy = %g, .x0 = %g, .y0 = %g }\n",
ctm.xx, ctm.yx,
ctm.xy, ctm.yy,
ctm.x0, ctm.y0));
cairo_transform (cr, &ctm);
}
else
g_critical ("Invalid non-affine transformation for node %p", node);
gsk_render_node_get_bounds (node, &frame);
GSK_NOTE (CAIRO, g_print ("CLIP = { .x = %g, .y = %g, .width = %g, .height = %g }\n",
frame.origin.x, frame.origin.y,
frame.size.width, frame.size.height));
if (!GSK_RENDER_MODE_CHECK (GEOMETRY))
{
cairo_rectangle (cr, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
cairo_clip (cr);
}
if (!gsk_render_node_is_opaque (node) && gsk_render_node_get_opacity (node) != 1.0)
{
GSK_NOTE (CAIRO, g_print ("Pushing opacity group (opacity:%g)\n",
gsk_render_node_get_opacity (node)));
cairo_push_group (cr);
pop_group = TRUE;
}
GSK_NOTE (CAIRO, g_print ("Rendering surface %p for node %p at %g, %g\n",
gsk_render_node_get_surface (node),
node,
frame.origin.x, frame.origin.y));
cairo_set_source_surface (cr, gsk_render_node_get_surface (node), frame.origin.x, frame.origin.y);
cairo_paint (cr);
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_rectangle (cr, frame.origin.x - 1, frame.origin.y - 1, frame.size.width + 2, frame.size.height + 2);
cairo_set_line_width (cr, 2);
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
cairo_stroke (cr);
cairo_restore (cr);
}
cairo_matrix_invert (&ctm);
cairo_transform (cr, &ctm);
if (gsk_render_node_get_n_children (node) != 0)
{
GSK_NOTE (CAIRO, g_print ("Drawing %d children of node [%p]\n",
gsk_render_node_get_n_children (node),
node));
gsk_render_node_iter_init (&iter, node);
while (gsk_render_node_iter_next (&iter, &child))
gsk_cairo_renderer_render_node (self, child, cr);
}
if (pop_group)
{
cairo_pop_group_to_source (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_paint_with_alpha (cr, gsk_render_node_get_opacity (node));
}
cairo_restore (cr);
}
static void
gsk_cairo_renderer_resize_viewport (GskRenderer *renderer,
const graphene_rect_t *viewport)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
self->viewport = *viewport;
}
static void
gsk_cairo_renderer_render (GskRenderer *renderer)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
cairo_surface_t *target = gsk_renderer_get_surface (renderer);
GskRenderNode *root = gsk_renderer_get_root_node (renderer);
cairo_t *cr = cairo_create (target);
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_rectangle (cr,
self->viewport.origin.x,
self->viewport.origin.y,
self->viewport.size.width,
self->viewport.size.height);
cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5);
cairo_stroke (cr);
cairo_restore (cr);
}
gsk_cairo_renderer_render_node (self, root, cr);
cairo_destroy (cr);
}
static void
gsk_cairo_renderer_clear (GskRenderer *renderer)
{
cairo_surface_t *surface = gsk_renderer_get_surface (renderer);
cairo_t *cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
if (gsk_renderer_get_use_alpha (renderer))
cairo_set_source_rgba (cr, 0, 0, 0, 0);
else
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
}
static void
gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
{
GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass);
renderer_class->realize = gsk_cairo_renderer_realize;
renderer_class->unrealize = gsk_cairo_renderer_unrealize;
renderer_class->resize_viewport = gsk_cairo_renderer_resize_viewport;
renderer_class->clear = gsk_cairo_renderer_clear;
renderer_class->render = gsk_cairo_renderer_render;
}
static void
gsk_cairo_renderer_init (GskCairoRenderer *self)
{
}
#ifndef __GSK_CAIRO_RENDERER_PRIVATE_H__
#define __GSK_CAIRO_RENDERER_PRIVATE_H__
#include <cairo.h>
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_CAIRO_RENDERER (gsk_cairo_renderer_get_type ())
#define GSK_CAIRO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_CAIRO_RENDERER, GskCairoRenderer))
#define GSK_IS_CAIRO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_CAIRO_RENDERER))
#define GSK_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_CAIRO_RENDERER, GskCairoRendererClass))
#define GSK_IS_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_CAIRO_RENDERER))
#define GSK_CAIRO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_CAIRO_RENDERER, GskCairoRendererClass))
typedef struct _GskCairoRenderer GskCairoRenderer;
typedef struct _GskCairoRendererClass GskCairoRendererClass;
GType gsk_cairo_renderer_get_type (void) G_GNUC_CONST;
GskRenderer *gsk_cairo_renderer_new (void);
G_END_DECLS
#endif /* __GSK_CAIRO_RENDERER_PRIVATE_H__ */
#include "gskdebugprivate.h"
#ifdef G_ENABLE_DEBUG
static const GDebugKey gsk_debug_keys[] = {
{ "rendernode", GSK_DEBUG_RENDER_NODE },
{ "renderer", GSK_DEBUG_RENDERER },
{ "cairo", GSK_DEBUG_CAIRO },
{ "opengl", GSK_DEBUG_OPENGL },
};
#endif
static const GDebugKey gsk_rendering_keys[] = {
{ "geometry", GSK_RENDERING_MODE_GEOMETRY },
};
gboolean
gsk_check_debug_flags (GskDebugFlags flags)
{
#ifdef G_ENABLE_DEBUG
static volatile gsize gsk_debug_flags__set;
static guint gsk_debug_flags;
if (g_once_init_enter (&gsk_debug_flags__set))
{
const char *env = g_getenv ("GSK_DEBUG");
gsk_debug_flags = g_parse_debug_string (env,
(GDebugKey *) gsk_debug_keys,
G_N_ELEMENTS (gsk_debug_keys));
g_once_init_leave (&gsk_debug_flags__set, TRUE);
}
return (gsk_debug_flags & flags) != 0;
#else
return FALSE;
#endif
}
gboolean
gsk_check_rendering_flags (GskRenderingMode flags)
{
static volatile gsize gsk_rendering_flags__set;
static guint gsk_rendering_flags;
if (g_once_init_enter (&gsk_rendering_flags__set))
{
const char *env = g_getenv ("GSK_RENDERING_MODE");
gsk_rendering_flags = g_parse_debug_string (env,
(GDebugKey *) gsk_rendering_keys,
G_N_ELEMENTS (gsk_rendering_keys));
g_once_init_leave (&gsk_rendering_flags__set, TRUE);
}
return (gsk_rendering_flags & flags) != 0;
}
#ifndef __GSK_DEBUG_PRIVATE_H__
#define __GSK_DEBUG_PRIVATE_H__
#include <glib.h>
G_BEGIN_DECLS
typedef enum {
GSK_DEBUG_RENDER_NODE = 1 << 0,
GSK_DEBUG_RENDERER = 1 << 1,
GSK_DEBUG_CAIRO = 1 << 2,
GSK_DEBUG_OPENGL = 1 << 3
} GskDebugFlags;
typedef enum {
GSK_RENDERING_MODE_GEOMETRY = 1 << 0
} GskRenderingMode;
gboolean gsk_check_debug_flags (GskDebugFlags flags);
gboolean gsk_check_rendering_flags (GskRenderingMode flags);
#ifdef G_ENABLE_DEBUG
#define GSK_DEBUG_CHECK(type) G_UNLIKELY (gsk_check_debug_flags (GSK_DEBUG_ ## type))
#define GSK_RENDER_MODE_CHECK(type) G_UNLIKELY (gsk_check_rendering_flags (GSK_RENDERING_MODE_ ## type))
#define GSK_NOTE(type,action) G_STMT_START { \
if (GSK_DEBUG_CHECK (type)) { \
action; \
} } G_STMT_END
#else
#define GSK_RENDER_MODE_CHECK(type) 0
#define GSK_DEBUG_CHECK(type) 0
#define GSK_NOTE(type,action)
#endif
G_END_DECLS
#endif /* __GSK_DEBUG_PRIVATE_H__ */
/* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GSK_ENUMS_H__
#define __GSK_ENUMS_H__
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
#error "Only <gsk/gsk.h> can be included directly."
#endif
/**
* GskScalingFilter:
* @GSK_SCALING_FILTER_LINEAR: linear interpolation filter
* @GSK_SCALING_FILTER_NEAREST: nearest neighbor interpolation filter
* @GSK_SCALING_FILTER_TRILINEAR: linear interpolation along each axis,
* plus mipmap generation, with linear interpolation along the mipmap
* levels
*
* The filters used when scaling texture data.
*
* The actual implementation of each filter is deferred to the
* rendering pipeline.
*
* Since: 3.22
*/
typedef enum {
GSK_SCALING_FILTER_LINEAR,
GSK_SCALING_FILTER_NEAREST,
GSK_SCALING_FILTER_TRILINEAR
} GskScalingFilter;
#endif /* __GSK_TYPES_H__ */
/*** BEGIN file-header ***/
#include "config.h"
#include "gskenumtypes.h"
#include <gsk.h>
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
static volatile gsize g_define_type_id__volatile = 0;
if (g_once_init_enter (&g_define_type_id__volatile))
{
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
GType g_define_type_id =
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
}
return g_define_type_id__volatile;
}
/*** END value-tail ***/
/*** BEGIN file-header ***/
#ifndef __GSK_ENUM_TYPES_H__
#define __GSK_ENUM_TYPES_H__
#include <gdk/gdk.h>
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GDK_AVAILABLE_IN_ALL GType @enum_name@_get_type (void) G_GNUC_CONST;
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
/*** END value-header ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* __GSK_ENUM_TYPES_H__ */
/*** END file-tail ***/
This diff is collapsed.
#ifndef __GSK_GL_RENDERER_PRIVATE_H__
#define __GSK_GL_RENDERER_PRIVATE_H__
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_GL_RENDERER (gsk_gl_renderer_get_type ())
#define GSK_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_RENDERER, GskGLRenderer))
#define GSK_IS_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_RENDERER))
#define GSK_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
#define GSK_IS_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_RENDERER))
#define GSK_GL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
typedef struct _GskGLRenderer GskGLRenderer;
typedef struct _GskGLRendererClass GskGLRendererClass;
GType gsk_gl_renderer_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GSK_GL_RENDERER_PRIVATE_H__ */
#include "gskresources.h"
static gpointer
register_resources (gpointer data)
{
_gsk_register_resource ();
return NULL;
}
void
gsk_ensure_resources (void)
{
static GOnce register_resources_once = G_ONCE_INIT;
g_once (&register_resources_once, register_resources, NULL);
}
#ifndef __GSK_PRIVATE_H__
#define __GSK_PRIVATE_H__
#include <glib.h>
G_BEGIN_DECLS
void gsk_ensure_resources (void);
G_END_DECLS
#endif /* __GSK_PRIVATE_H__ */
This diff is collapsed.
/* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GSK_RENDERER_H__
#define __GSK_RENDERER_H__
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
#error "Only <gsk/gsk.h> can be included directly."
#endif
#include <gsk/gsktypes.h>
#include <gsk/gskrendernode.h>
G_BEGIN_DECLS
#define GSK_TYPE_RENDERER (gsk_renderer_get_type ())
#define GSK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_RENDERER, GskRenderer))
#define GSK_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_RENDERER))
typedef struct _GskRenderer GskRenderer;
typedef struct _GskRendererClass GskRendererClass;
GDK_AVAILABLE_IN_3_22
GType gsk_renderer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_22
GskRenderer * gsk_renderer_get_for_display (GdkDisplay *display);