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.
This commit is contained in:
142
gsk/Makefile.am
142
gsk/Makefile.am
@@ -1,23 +1,12 @@
|
||||
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 =
|
||||
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
|
||||
|
||||
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)
|
||||
all_sources = \
|
||||
$(gsk_public_source_h) \
|
||||
$(gsk_private_source_h) \
|
||||
$(gsk_built_source_h) \
|
||||
$(gsk_private_source_c) \
|
||||
$(gsk_source_c)
|
||||
|
||||
lib_LTLIBRARIES += libgsk-3.la
|
||||
BUILT_SOURCES += $(gsk_built_source_h) $(gsk_built_source_c) gsk.resources.xml
|
||||
|
||||
gskincludedir = $(includedir)/gtk-3.0/gsk
|
||||
gskinclude_HEADERS = $(gsk_public_source_h) gsk.h
|
||||
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
|
||||
|
||||
-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)
|
||||
|
||||
33
gsk/gsk.h
Normal file
33
gsk/gsk.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* 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__ */
|
||||
195
gsk/gskcairorenderer.c
Normal file
195
gsk/gskcairorenderer.c
Normal file
@@ -0,0 +1,195 @@
|
||||
#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)
|
||||
{
|
||||
|
||||
}
|
||||
26
gsk/gskcairorendererprivate.h
Normal file
26
gsk/gskcairorendererprivate.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#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__ */
|
||||
58
gsk/gskdebug.c
Normal file
58
gsk/gskdebug.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#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;
|
||||
}
|
||||
43
gsk/gskdebugprivate.h
Normal file
43
gsk/gskdebugprivate.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#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__ */
|
||||
46
gsk/gskenums.h
Normal file
46
gsk/gskenums.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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__ */
|
||||
38
gsk/gskenumtypes.c.template
Normal file
38
gsk/gskenumtypes.c.template
Normal file
@@ -0,0 +1,38 @@
|
||||
/*** 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 ***/
|
||||
24
gsk/gskenumtypes.h.template
Normal file
24
gsk/gskenumtypes.h.template
Normal file
@@ -0,0 +1,24 @@
|
||||
/*** 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 ***/
|
||||
1092
gsk/gskglrenderer.c
Normal file
1092
gsk/gskglrenderer.c
Normal file
File diff suppressed because it is too large
Load Diff
23
gsk/gskglrendererprivate.h
Normal file
23
gsk/gskglrendererprivate.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#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__ */
|
||||
16
gsk/gskprivate.c
Normal file
16
gsk/gskprivate.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#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 (®ister_resources_once, register_resources, NULL);
|
||||
}
|
||||
12
gsk/gskprivate.h
Normal file
12
gsk/gskprivate.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#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__ */
|
||||
1377
gsk/gskrenderer.c
Normal file
1377
gsk/gskrenderer.c
Normal file
File diff suppressed because it is too large
Load Diff
113
gsk/gskrenderer.h
Normal file
113
gsk/gskrenderer.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* 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);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_viewport (GskRenderer *renderer,
|
||||
const graphene_rect_t *viewport);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_get_viewport (GskRenderer *renderer,
|
||||
graphene_rect_t *viewport);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_projection (GskRenderer *renderer,
|
||||
const graphene_matrix_t *projection);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_get_projection (GskRenderer *renderer,
|
||||
graphene_matrix_t *projection);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_modelview (GskRenderer *renderer,
|
||||
const graphene_matrix_t *modelview);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_get_modelview (GskRenderer *renderer,
|
||||
graphene_matrix_t *modelview);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_scaling_filters (GskRenderer *renderer,
|
||||
GskScalingFilter min_filter,
|
||||
GskScalingFilter mag_filter);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_get_scaling_filters (GskRenderer *renderer,
|
||||
GskScalingFilter *min_filter,
|
||||
GskScalingFilter *mag_filter);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_auto_clear (GskRenderer *renderer,
|
||||
gboolean clear);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_renderer_get_auto_clear (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_root_node (GskRenderer *renderer,
|
||||
GskRenderNode *root);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_surface (GskRenderer *renderer,
|
||||
cairo_surface_t *surface);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
cairo_surface_t * gsk_renderer_get_surface (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_window (GskRenderer *renderer,
|
||||
GdkWindow *window);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkWindow * gsk_renderer_get_window (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_draw_context (GskRenderer *renderer,
|
||||
cairo_t *cr);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
cairo_t * gsk_renderer_get_draw_context (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkDisplay * gsk_renderer_get_display (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_set_use_alpha (GskRenderer *renderer,
|
||||
gboolean use_alpha);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_renderer_get_use_alpha (GskRenderer *renderer);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_renderer_realize (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_unrealize (GskRenderer *renderer);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_renderer_render (GskRenderer *renderer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDERER_H__ */
|
||||
62
gsk/gskrendererprivate.h
Normal file
62
gsk/gskrendererprivate.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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_PRIVATE_H__
|
||||
#define __GSK_RENDERER_PRIVATE_H__
|
||||
|
||||
#include "gskrenderer.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_RENDERER, GskRendererClass))
|
||||
#define GSK_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_RENDERER))
|
||||
#define GSK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDERER, GskRendererClass))
|
||||
|
||||
struct _GskRenderer
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GskRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* realize) (GskRenderer *renderer);
|
||||
void (* unrealize) (GskRenderer *renderer);
|
||||
|
||||
void (* resize_viewport) (GskRenderer *renderer,
|
||||
const graphene_rect_t *viewport);
|
||||
void (* update) (GskRenderer *renderer,
|
||||
const graphene_matrix_t *modelview,
|
||||
const graphene_matrix_t *projection);
|
||||
void (* validate_tree) (GskRenderer *renderer,
|
||||
GskRenderNode *root);
|
||||
void (* clear) (GskRenderer *renderer);
|
||||
void (* render) (GskRenderer *renderer);
|
||||
};
|
||||
|
||||
gboolean gsk_renderer_is_realized (GskRenderer *renderer);
|
||||
|
||||
void gsk_renderer_maybe_resize_viewport (GskRenderer *renderer);
|
||||
void gsk_renderer_maybe_update (GskRenderer *renderer);
|
||||
void gsk_renderer_maybe_validate_tree (GskRenderer *renderer);
|
||||
void gsk_renderer_maybe_clear (GskRenderer *renderer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDERER_PRIVATE_H__ */
|
||||
1246
gsk/gskrendernode.c
Normal file
1246
gsk/gskrendernode.c
Normal file
File diff suppressed because it is too large
Load Diff
117
gsk/gskrendernode.h
Normal file
117
gsk/gskrendernode.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* 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_RENDER_NODE_H__
|
||||
#define __GSK_RENDER_NODE_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_RENDER_NODE (gsk_render_node_get_type ())
|
||||
|
||||
#define GSK_RENDER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_RENDER_NODE, GskRenderNode))
|
||||
#define GSK_IS_RENDER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_RENDER_NODE))
|
||||
|
||||
typedef struct _GskRenderNode GskRenderNode;
|
||||
typedef struct _GskRenderNodeClass GskRenderNodeClass;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gsk_render_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_get_parent (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_get_first_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_get_last_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_get_next_sibling (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_get_previous_sibling (GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_insert_child_at_pos (GskRenderNode *node,
|
||||
GskRenderNode *child,
|
||||
int index_);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_insert_child_before (GskRenderNode *node,
|
||||
GskRenderNode *child,
|
||||
GskRenderNode *sibling);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_insert_child_after (GskRenderNode *node,
|
||||
GskRenderNode *child,
|
||||
GskRenderNode *sibling);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_remove_child (GskRenderNode *node,
|
||||
GskRenderNode *child);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_replace_child (GskRenderNode *node,
|
||||
GskRenderNode *new_child,
|
||||
GskRenderNode *old_child);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNode * gsk_render_node_remove_all_children (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
guint gsk_render_node_get_n_children (GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_render_node_contains (GskRenderNode *node,
|
||||
GskRenderNode *descendant);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_bounds (GskRenderNode *node,
|
||||
const graphene_rect_t *bounds);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_transform (GskRenderNode *node,
|
||||
const graphene_matrix_t *transform);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_child_transform (GskRenderNode *node,
|
||||
const graphene_matrix_t *transform);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_opacity (GskRenderNode *node,
|
||||
double opacity);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_hidden (GskRenderNode *node,
|
||||
gboolean hidden);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_render_node_is_hidden (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_opaque (GskRenderNode *node,
|
||||
gboolean opaque);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_render_node_is_opaque (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_surface (GskRenderNode *node,
|
||||
cairo_surface_t *surface);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
cairo_t * gsk_render_node_get_draw_context (GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_set_name (GskRenderNode *node,
|
||||
const char *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDER_NODE_H__ */
|
||||
254
gsk/gskrendernodeiter.c
Normal file
254
gsk/gskrendernodeiter.c
Normal file
@@ -0,0 +1,254 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:GskRenderNodeIter
|
||||
* @title: GskRenderNodeIter
|
||||
* @Short_desc: Iterator helper for render nodes
|
||||
*
|
||||
* TODO
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskrendernodeiter.h"
|
||||
#include "gskrendernodeprivate.h"
|
||||
|
||||
typedef struct {
|
||||
GskRenderNode *root;
|
||||
GskRenderNode *current;
|
||||
gint64 age;
|
||||
gpointer reserved1;
|
||||
gpointer reserved2;
|
||||
} RealIter;
|
||||
|
||||
#define REAL_ITER(iter) ((RealIter *) (iter))
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_new: (constructor)
|
||||
*
|
||||
* Allocates a new #GskRenderNodeIter.
|
||||
*
|
||||
* Returns: (transfer full): the newly allocated #GskRenderNodeIter
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
GskRenderNodeIter *
|
||||
gsk_render_node_iter_new (void)
|
||||
{
|
||||
return g_slice_new (GskRenderNodeIter);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_render_node_iter_copy:
|
||||
* @src: a #GskRenderNodeIter
|
||||
*
|
||||
* Copies a #GskRenderNodeIter.
|
||||
*
|
||||
* Returns: (transfer full): a #GskRenderNodeIter
|
||||
*/
|
||||
static GskRenderNodeIter *
|
||||
gsk_render_node_iter_copy (GskRenderNodeIter *src)
|
||||
{
|
||||
return g_slice_dup (GskRenderNodeIter, src);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_free:
|
||||
* @iter: a #GskRenderNodeIter
|
||||
*
|
||||
* Frees the resources allocated by gsk_render_node_iter_new().
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
void
|
||||
gsk_render_node_iter_free (GskRenderNodeIter *iter)
|
||||
{
|
||||
g_slice_free (GskRenderNodeIter, iter);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GskRenderNodeIter, gsk_render_node_iter,
|
||||
gsk_render_node_iter_copy,
|
||||
gsk_render_node_iter_free)
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_init:
|
||||
* @iter: a #GskRenderNodeIter
|
||||
* @node: a #GskRenderNode
|
||||
*
|
||||
* Initializes a #GskRenderNodeIter for iterating over the
|
||||
* children of @node.
|
||||
*
|
||||
* It's safe to call this function multiple times on the same
|
||||
* #GskRenderNodeIter instance.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
void
|
||||
gsk_render_node_iter_init (GskRenderNodeIter *iter,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
RealIter *riter = REAL_ITER (iter);
|
||||
|
||||
g_return_if_fail (iter != NULL);
|
||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||
|
||||
riter->root = node;
|
||||
riter->age = node->age;
|
||||
riter->current = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_is_valid:
|
||||
* @iter: a #GskRenderNodeIter
|
||||
*
|
||||
* Checks whether a #GskRenderNodeIter is associated to a #GskRenderNode,
|
||||
* or whether the associated node was modified while iterating.
|
||||
*
|
||||
* Returns: %TRUE if the iterator is still valid.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
gboolean
|
||||
gsk_render_node_iter_is_valid (GskRenderNodeIter *iter)
|
||||
{
|
||||
RealIter *riter = REAL_ITER (iter);
|
||||
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
if (riter->root == NULL)
|
||||
return FALSE;
|
||||
|
||||
return riter->root->age == riter->age;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_next:
|
||||
* @iter: a #GskRenderNodeIter
|
||||
* @child: (out) (transfer none): return location for a #GskRenderNode
|
||||
*
|
||||
* Advances the @iter and retrieves the next child of the root #GskRenderNode
|
||||
* used to initialize the #GskRenderNodeIter.
|
||||
*
|
||||
* If the iterator could advance, this function returns %TRUE and sets the
|
||||
* @child argument with the child #GskRenderNode.
|
||||
*
|
||||
* If the iterator could not advance, this function returns %FALSE and the
|
||||
* contents of the @child argument are undefined.
|
||||
*
|
||||
* Returns: %TRUE if the iterator could advance, and %FALSE otherwise
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
gboolean
|
||||
gsk_render_node_iter_next (GskRenderNodeIter *iter,
|
||||
GskRenderNode **child)
|
||||
{
|
||||
RealIter *riter = REAL_ITER (iter);
|
||||
|
||||
g_return_val_if_fail (riter != NULL, FALSE);
|
||||
g_return_val_if_fail (riter->root != NULL, FALSE);
|
||||
g_return_val_if_fail (riter->root->age == riter->age, FALSE);
|
||||
|
||||
if (riter->current == NULL)
|
||||
riter->current = riter->root->first_child;
|
||||
else
|
||||
riter->current = riter->current->next_sibling;
|
||||
|
||||
if (child != NULL)
|
||||
*child = riter->current;
|
||||
|
||||
return riter->current != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_prev:
|
||||
* @iter: a #GskRenderNodeIter
|
||||
* @child: (out) (transfer none): return location for a #GskRenderNode
|
||||
*
|
||||
* Advances the @iter and retrieves the previous child of the root
|
||||
* #GskRenderNode used to initialize the #GskRenderNodeIter.
|
||||
*
|
||||
* If the iterator could advance, this function returns %TRUE and sets the
|
||||
* @child argument with the child #GskRenderNode.
|
||||
*
|
||||
* If the iterator could not advance, this function returns %FALSE and the
|
||||
* contents of the @child argument are undefined.
|
||||
*
|
||||
* Returns: %TRUE if the iterator could advance, and %FALSE otherwise
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
gboolean
|
||||
gsk_render_node_iter_prev (GskRenderNodeIter *iter,
|
||||
GskRenderNode **child)
|
||||
{
|
||||
RealIter *riter = REAL_ITER (iter);
|
||||
|
||||
g_return_val_if_fail (riter != NULL, FALSE);
|
||||
g_return_val_if_fail (riter->root != NULL, FALSE);
|
||||
g_return_val_if_fail (riter->root->age == riter->age, FALSE);
|
||||
|
||||
if (riter->current == NULL)
|
||||
riter->current = riter->root->last_child;
|
||||
else
|
||||
riter->current = riter->current->prev_sibling;
|
||||
|
||||
if (child != NULL)
|
||||
*child = riter->current;
|
||||
|
||||
return riter->current != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_iter_remove:
|
||||
* @iter: a #GskRenderNodeIter
|
||||
*
|
||||
* Removes the child #GskRenderNode currently being visited by
|
||||
* the iterator.
|
||||
*
|
||||
* Calling this function on an invalid #GskRenderNodeIter results
|
||||
* in undefined behavior.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
void
|
||||
gsk_render_node_iter_remove (GskRenderNodeIter *iter)
|
||||
{
|
||||
RealIter *riter = REAL_ITER (iter);
|
||||
GskRenderNode *tmp;
|
||||
|
||||
g_return_if_fail (riter != NULL);
|
||||
g_return_if_fail (riter->root != NULL);
|
||||
g_return_if_fail (riter->root->age == riter->age);
|
||||
g_return_if_fail (riter->current != NULL);
|
||||
|
||||
tmp = riter->current;
|
||||
|
||||
if (tmp != NULL)
|
||||
{
|
||||
riter->current = tmp->prev_sibling;
|
||||
|
||||
gsk_render_node_remove_child (riter->root, tmp);
|
||||
|
||||
riter->age += 1;
|
||||
|
||||
/* Safety net */
|
||||
g_assert (riter->age == riter->root->age);
|
||||
}
|
||||
}
|
||||
45
gsk/gskrendernodeiter.h
Normal file
45
gsk/gskrendernodeiter.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef __GSK_RENDER_NODE_ITER_H__
|
||||
#define __GSK_RENDER_NODE_ITER_H__
|
||||
|
||||
#include <gsk/gskrendernode.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_RENDER_NODE_ITER (gsk_render_node_iter_get_type())
|
||||
|
||||
typedef struct _GskRenderNodeIter GskRenderNodeIter;
|
||||
|
||||
struct _GskRenderNodeIter
|
||||
{
|
||||
/*< private >*/
|
||||
gpointer dummy1;
|
||||
gpointer dummy2;
|
||||
gint64 dummy3;
|
||||
gpointer dummy4;
|
||||
gpointer dummy5;
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gsk_render_node_iter_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GskRenderNodeIter * gsk_render_node_iter_new (void);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_iter_free (GskRenderNodeIter *iter);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_iter_init (GskRenderNodeIter *iter,
|
||||
GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_render_node_iter_is_valid (GskRenderNodeIter *iter);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_render_node_iter_prev (GskRenderNodeIter *iter,
|
||||
GskRenderNode **child);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
gboolean gsk_render_node_iter_next (GskRenderNodeIter *iter,
|
||||
GskRenderNode **child);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gsk_render_node_iter_remove (GskRenderNodeIter *iter);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GSK_RENDER_NODE_ITER_H */
|
||||
124
gsk/gskrendernodeprivate.h
Normal file
124
gsk/gskrendernodeprivate.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef __GSK_RENDER_NODE_PRIVATE_H__
|
||||
#define __GSK_RENDER_NODE_PRIVATE_H__
|
||||
|
||||
#include "gskrendernode.h"
|
||||
#include <cairo.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_RENDER_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
|
||||
#define GSK_IS_RENDER_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_RENDER_NODE))
|
||||
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
|
||||
|
||||
typedef enum {
|
||||
GSK_RENDER_NODE_CHANGES_UPDATE_BOUNDS = 1 << 0,
|
||||
GSK_RENDER_NODE_CHANGES_UPDATE_TRANSFORM = 1 << 1,
|
||||
GSK_RENDER_NODE_CHANGES_UPDATE_SURFACE = 1 << 2,
|
||||
GSK_RENDER_NODE_CHANGES_UPDATE_OPACITY = 1 << 3,
|
||||
GSK_RENDER_NODE_CHANGES_UPDATE_VISIBILITY = 1 << 4,
|
||||
GSK_RENDER_NODE_CHANEGS_UPDATE_HIERARCHY = 1 << 5
|
||||
} GskRenderNodeChanges;
|
||||
|
||||
typedef void (* GskRenderNodeInvalidateFunc) (GskRenderNode *node,
|
||||
gpointer data);
|
||||
|
||||
struct _GskRenderNode
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
/* The graph */
|
||||
GskRenderNode *parent;
|
||||
GskRenderNode *first_child;
|
||||
GskRenderNode *last_child;
|
||||
GskRenderNode *prev_sibling;
|
||||
GskRenderNode *next_sibling;
|
||||
|
||||
int n_children;
|
||||
|
||||
/* Use for debugging */
|
||||
char *name;
|
||||
|
||||
/* Tag updated when adding/removing children */
|
||||
gint64 age;
|
||||
|
||||
/* The contents of the node */
|
||||
cairo_surface_t *surface;
|
||||
|
||||
/* Paint opacity */
|
||||
double opacity;
|
||||
|
||||
/* Clip rectangle */
|
||||
graphene_rect_t bounds;
|
||||
|
||||
/* Transformations relative to the root of the scene */
|
||||
graphene_matrix_t world_matrix;
|
||||
|
||||
/* Transformations applied to the node */
|
||||
graphene_matrix_t transform;
|
||||
|
||||
/* Transformations applied to the children of the node */
|
||||
graphene_matrix_t child_transform;
|
||||
|
||||
/* Invalidation function for root node */
|
||||
GskRenderNodeInvalidateFunc invalidate_func;
|
||||
gpointer func_data;
|
||||
GDestroyNotify destroy_func_data;
|
||||
|
||||
/* Descendants that need to be validated; only for root node */
|
||||
GPtrArray *invalidated_descendants;
|
||||
|
||||
GskRenderNodeChanges last_state_change;
|
||||
|
||||
/* Bit fields; leave at the end */
|
||||
gboolean hidden : 1;
|
||||
gboolean opaque : 1;
|
||||
gboolean transform_set : 1;
|
||||
gboolean child_transform_set : 1;
|
||||
gboolean needs_resize : 1;
|
||||
gboolean needs_world_matrix_update : 1;
|
||||
gboolean needs_content_update : 1;
|
||||
gboolean needs_opacity_update : 1;
|
||||
gboolean needs_visibility_update : 1;
|
||||
};
|
||||
|
||||
struct _GskRenderNodeClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* resize) (GskRenderNode *node);
|
||||
};
|
||||
|
||||
void gsk_render_node_get_bounds (GskRenderNode *node,
|
||||
graphene_rect_t *frame);
|
||||
void gsk_render_node_get_transform (GskRenderNode *node,
|
||||
graphene_matrix_t *mv);
|
||||
double gsk_render_node_get_opacity (GskRenderNode *node);
|
||||
|
||||
cairo_surface_t *gsk_render_node_get_surface (GskRenderNode *node);
|
||||
|
||||
GskRenderNode *gsk_render_node_get_toplevel (GskRenderNode *node);
|
||||
|
||||
void gsk_render_node_update_world_matrix (GskRenderNode *node,
|
||||
gboolean force);
|
||||
|
||||
void gsk_render_node_get_world_matrix (GskRenderNode *node,
|
||||
graphene_matrix_t *mv);
|
||||
|
||||
void gsk_render_node_queue_invalidate (GskRenderNode *node,
|
||||
GskRenderNodeChanges changes);
|
||||
|
||||
void gsk_render_node_set_invalidate_func (GskRenderNode *root,
|
||||
GskRenderNodeInvalidateFunc validate_func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
void gsk_render_node_validate (GskRenderNode *node);
|
||||
|
||||
void gsk_render_node_maybe_resize (GskRenderNode *node);
|
||||
|
||||
GskRenderNodeChanges gsk_render_node_get_current_state (GskRenderNode *node);
|
||||
GskRenderNodeChanges gsk_render_node_get_last_state (GskRenderNode *node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDER_NODE_PRIVATE_H__ */
|
||||
29
gsk/gsktypes.h
Normal file
29
gsk/gsktypes.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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_TYPES_H__
|
||||
#define __GSK_TYPES_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <graphene.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gsk/gskenums.h>
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
13
gsk/resources/glsl/base-renderer-fragment.glsl
Normal file
13
gsk/resources/glsl/base-renderer-fragment.glsl
Normal file
@@ -0,0 +1,13 @@
|
||||
#version 150
|
||||
|
||||
smooth in vec2 vUv;
|
||||
|
||||
out vec4 outputColor;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform sampler2D map;
|
||||
uniform float alpha;
|
||||
|
||||
void main() {
|
||||
outputColor = texture2D(map, vUv) * vec4(alpha);
|
||||
}
|
||||
16
gsk/resources/glsl/base-renderer-vertex.glsl
Normal file
16
gsk/resources/glsl/base-renderer-vertex.glsl
Normal file
@@ -0,0 +1,16 @@
|
||||
#version 150
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform sampler2D map;
|
||||
uniform float alpha;
|
||||
|
||||
in vec2 position;
|
||||
in vec2 uv;
|
||||
|
||||
smooth out vec2 vUv;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(position, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(uv.x, 1 - uv.y);
|
||||
}
|
||||
@@ -7,6 +7,8 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir)/gdk \
|
||||
-I$(top_srcdir)/gdk \
|
||||
-I$(top_builddir)/gsk \
|
||||
-I$(top_srcdir)/gsk \
|
||||
$(GTK_DEBUG_FLAGS) \
|
||||
$(GTK_DEP_CFLAGS) \
|
||||
$(GDK_DEP_CFLAGS)
|
||||
@@ -16,6 +18,7 @@ DEPS = \
|
||||
|
||||
LDADD = \
|
||||
$(top_builddir)/gtk/libgtk-4.la \
|
||||
$(top_builddir)/gsk/libgsk-4.la \
|
||||
$(top_builddir)/gdk/libgdk-4.la \
|
||||
$(GTK_DEP_LIBS) \
|
||||
$(GDK_DEP_LIBS) \
|
||||
@@ -161,6 +164,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
listmodel \
|
||||
testpopup \
|
||||
testpopupat \
|
||||
testgskrenderer \
|
||||
$(NULL)
|
||||
|
||||
if USE_X11
|
||||
@@ -280,6 +284,7 @@ testtitlebar_DEPENDENCIES = $(TEST_DEPS)
|
||||
testwindowsize_DEPENDENCIES = $(TEST_DEPS)
|
||||
listmodel_DEPENDENCIES = $(TEST_DEPS)
|
||||
foreigndrawing_DEPENDENCIES = $(TEST_DEPS)
|
||||
testgskrenderer_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
||||
animated_resizing_SOURCES = \
|
||||
animated-resizing.c \
|
||||
@@ -494,6 +499,8 @@ listmodel_SOURCES = listmodel.c
|
||||
|
||||
foreigndrawing_SOURCES = foreigndrawing.c
|
||||
|
||||
testgskrenderer_SOURCES = testgskrenderer.c
|
||||
|
||||
EXTRA_DIST += \
|
||||
gradient1.png \
|
||||
testgtk.1 \
|
||||
|
||||
229
tests/testgskrenderer.c
Normal file
229
tests/testgskrenderer.c
Normal file
@@ -0,0 +1,229 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <cairo.h>
|
||||
#include <gsk/gsk.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define BOX_SIZE 50.f
|
||||
#define PADDING 10.f
|
||||
#define ROOT_SIZE BOX_SIZE * 2 + PADDING * 2
|
||||
|
||||
static void
|
||||
create_color_surface (cairo_t *cr, GdkRGBA *color, int w, int h)
|
||||
{
|
||||
cairo_set_source_rgba (cr, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_rectangle (cr, 0, 0, w, h);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
static GskRenderer *
|
||||
get_renderer (GtkWidget *widget)
|
||||
{
|
||||
GskRenderer *res;
|
||||
|
||||
res = g_object_get_data (G_OBJECT (widget), "-gsk-renderer");
|
||||
if (res == NULL)
|
||||
{
|
||||
res = gsk_renderer_get_for_display (gtk_widget_get_display (widget));
|
||||
|
||||
g_object_set_data_full (G_OBJECT (widget), "-gsk-renderer",
|
||||
res,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
create_scene (GskRenderer *renderer)
|
||||
{
|
||||
GskRenderNode *root, *node;
|
||||
graphene_matrix_t ctm;
|
||||
cairo_t *cr;
|
||||
|
||||
root = gsk_render_node_new ();
|
||||
gsk_render_node_set_name (root, "Root node");
|
||||
gsk_render_node_set_bounds (root, &(graphene_rect_t) {
|
||||
.origin.x = 0.f,
|
||||
.origin.y = 0.f,
|
||||
.size.width = ROOT_SIZE,
|
||||
.size.height = ROOT_SIZE
|
||||
});
|
||||
cr = gsk_render_node_get_draw_context (root);
|
||||
create_color_surface (cr, &(GdkRGBA) { .red = 1, .green = 0, .blue = 0, .alpha = 1 }, ROOT_SIZE, ROOT_SIZE);
|
||||
cairo_destroy (cr);
|
||||
gsk_renderer_set_root_node (renderer, root);
|
||||
g_object_set_data (G_OBJECT (renderer), "-gsk-renderer-root-node", root);
|
||||
|
||||
g_object_unref (root);
|
||||
|
||||
node = gsk_render_node_new ();
|
||||
gsk_render_node_set_name (node, "Green node");
|
||||
gsk_render_node_set_bounds (node, &(graphene_rect_t) {
|
||||
.origin.x = 0.f,
|
||||
.origin.y = 0.f,
|
||||
.size.width = BOX_SIZE,
|
||||
.size.height = BOX_SIZE
|
||||
});
|
||||
cr = gsk_render_node_get_draw_context (node);
|
||||
create_color_surface (cr, &(GdkRGBA) { .red = 0, .green = 1, .blue = 0, .alpha = 1 }, BOX_SIZE, BOX_SIZE);
|
||||
cairo_destroy (cr);
|
||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) { .x = -0.5, .y = -0.5, .z = 0.f });
|
||||
gsk_render_node_set_transform (node, &ctm);
|
||||
gsk_render_node_insert_child_at_pos (root, node, 0);
|
||||
g_object_unref (node);
|
||||
|
||||
node = gsk_render_node_new ();
|
||||
gsk_render_node_set_name (node, "Blue node");
|
||||
gsk_render_node_set_bounds (node, &(graphene_rect_t) {
|
||||
.origin.x = 0.f,
|
||||
.origin.y = 0.f,
|
||||
.size.width = BOX_SIZE,
|
||||
.size.height = BOX_SIZE
|
||||
});
|
||||
cr = gsk_render_node_get_draw_context (node);
|
||||
create_color_surface (cr, &(GdkRGBA) { .red = 0, .green = 0, .blue = 1, .alpha = 1 }, BOX_SIZE, BOX_SIZE);
|
||||
cairo_destroy (cr);
|
||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) { .x = 0.5, .y = 0.5, .z = 0.f });
|
||||
gsk_render_node_set_transform (node, &ctm);
|
||||
gsk_render_node_insert_child_at_pos (root, node, 1);
|
||||
g_object_unref (node);
|
||||
}
|
||||
|
||||
static void
|
||||
realize (GtkWidget *widget)
|
||||
{
|
||||
GskRenderer *renderer = get_renderer (widget);
|
||||
|
||||
gsk_renderer_set_window (renderer, gtk_widget_get_window (widget));
|
||||
gsk_renderer_set_use_alpha (renderer, TRUE);
|
||||
gsk_renderer_realize (renderer);
|
||||
|
||||
create_scene (renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
unrealize (GtkWidget *widget)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (widget), "-gsk-renderer", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
size_allocate (GtkWidget *widget, GtkAllocation *allocation)
|
||||
{
|
||||
GskRenderer *renderer = get_renderer (widget);
|
||||
GskRenderNode *root;
|
||||
graphene_matrix_t ctm;
|
||||
|
||||
gsk_renderer_set_viewport (renderer, &(graphene_rect_t) {
|
||||
.origin.x = 0,
|
||||
.origin.y = 0,
|
||||
.size.width = allocation->width,
|
||||
.size.height = allocation->height
|
||||
});
|
||||
|
||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) {
|
||||
allocation->x,
|
||||
allocation->y,
|
||||
0.f
|
||||
});
|
||||
gsk_renderer_set_modelview (renderer, &ctm);
|
||||
|
||||
root = g_object_get_data (G_OBJECT (renderer), "-gsk-renderer-root-node");
|
||||
if (root == NULL)
|
||||
{
|
||||
create_scene (renderer);
|
||||
root = g_object_get_data (G_OBJECT (renderer), "-gsk-renderer-root-node");
|
||||
}
|
||||
|
||||
graphene_matrix_init_translate (&ctm, &(graphene_point3d_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0
|
||||
});
|
||||
gsk_render_node_set_transform (root, &ctm);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw (GtkWidget *widget, cairo_t *cr)
|
||||
{
|
||||
GskRenderer *renderer = get_renderer (widget);
|
||||
|
||||
gsk_renderer_set_draw_context (renderer, cr);
|
||||
gsk_renderer_render (renderer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fade_out (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
{
|
||||
static gint64 first_frame_time;
|
||||
static gboolean flip = FALSE;
|
||||
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
|
||||
if (first_frame_time == 0)
|
||||
{
|
||||
first_frame_time = now;
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
double start = first_frame_time;
|
||||
double end = first_frame_time + (double) 1000000;
|
||||
double progress = (now - first_frame_time) / (end - start);
|
||||
|
||||
if (flip)
|
||||
progress = 1 - progress;
|
||||
|
||||
if (progress < 0 || progress >= 1)
|
||||
{
|
||||
first_frame_time = now;
|
||||
flip = !flip;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
GskRenderer *renderer = get_renderer (widget);
|
||||
GskRenderNode *root = gsk_renderer_get_root_node (renderer);
|
||||
|
||||
gsk_render_node_set_opacity (root, 1.0 - progress);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window, *area;
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "GSK Renderer");
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
area = gtk_drawing_area_new ();
|
||||
gtk_widget_set_hexpand (area, TRUE);
|
||||
gtk_widget_set_vexpand (area, TRUE);
|
||||
gtk_widget_set_has_window (GTK_WIDGET (area), FALSE);
|
||||
gtk_widget_set_app_paintable (GTK_WIDGET (area), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (window), area);
|
||||
|
||||
g_signal_connect (area, "realize", G_CALLBACK (realize), NULL);
|
||||
g_signal_connect (area, "unrealize", G_CALLBACK (unrealize), NULL);
|
||||
g_signal_connect (area, "size-allocate", G_CALLBACK (size_allocate), NULL);
|
||||
g_signal_connect (area, "draw", G_CALLBACK (draw), NULL);
|
||||
|
||||
gtk_widget_add_tick_callback (area, fade_out, NULL, NULL);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
}
|
||||
Reference in New Issue
Block a user