Add GskGLShaderNode
This is a rendernode that is supposed to run a GLSL fragment shader with a set of inputs and produce outputs. The inputs are: * A GskGLShader object with the source and uniforms definitions computed from the source. * A the data for the uniforms, formated according to the GskGLShader * a list of render nodes that are rendered to textures Additionally there is a fallback node which is used in case OpenGL is not supported or there is some kind of failure with the shader code.
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
* @GSK_TEXT_NODE: A node containing a glyph string
|
||||
* @GSK_BLUR_NODE: A node that applies a blur
|
||||
* @GSK_DEBUG_NODE: Debug information that does not affect the rendering
|
||||
* @GSK_GL_SHADER_NODE: A node that uses OpenGL fragment shaders to render
|
||||
|
||||
* The type of a node determines what the node is rendering.
|
||||
*/
|
||||
@@ -75,7 +76,8 @@ typedef enum {
|
||||
GSK_CROSS_FADE_NODE,
|
||||
GSK_TEXT_NODE,
|
||||
GSK_BLUR_NODE,
|
||||
GSK_DEBUG_NODE
|
||||
GSK_DEBUG_NODE,
|
||||
GSK_GL_SHADER_NODE
|
||||
} GskRenderNodeType;
|
||||
|
||||
/**
|
||||
@@ -218,4 +220,32 @@ typedef enum
|
||||
GSK_TRANSFORM_CATEGORY_IDENTITY
|
||||
} GskTransformCategory;
|
||||
|
||||
/**
|
||||
* GskGLUniformType:
|
||||
* @GSK_GLUNIFORM_TYPE_NONE: No type, used for uninitialized or unspecified values.
|
||||
* @GSK_GLUNIFORM_TYPE_FLOAT: A float uniform
|
||||
* @GSK_GLUNIFORM_TYPE_INT: A GLSL int / gint32 uniform
|
||||
* @GSK_GLUNIFORM_TYPE_UINT: A GLSL uint / guint32 uniform
|
||||
* @GSK_GLUNIFORM_TYPE_BOOL: A GLSL bool / gboolean uniform
|
||||
* @GSK_GLUNIFORM_TYPE_VEC2: A GLSL vec2 / graphene_vec2_t uniform
|
||||
* @GSK_GLUNIFORM_TYPE_VEC3: A GLSL vec3 / graphene_vec3_t uniform
|
||||
* @GSK_GLUNIFORM_TYPE_VEC4: A GLSL vec4 / graphene_vec4_t uniform
|
||||
*
|
||||
* This defines the types of the uniforms that #GskGLShaders
|
||||
* declare. It defines both what the type is called in the GLSL shader
|
||||
* code, and what the corresponding C type is on the Gtk side.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GSK_GLUNIFORM_TYPE_NONE,
|
||||
GSK_GLUNIFORM_TYPE_FLOAT,
|
||||
GSK_GLUNIFORM_TYPE_INT,
|
||||
GSK_GLUNIFORM_TYPE_UINT,
|
||||
GSK_GLUNIFORM_TYPE_BOOL,
|
||||
GSK_GLUNIFORM_TYPE_VEC2,
|
||||
GSK_GLUNIFORM_TYPE_VEC3,
|
||||
GSK_GLUNIFORM_TYPE_VEC4,
|
||||
} GskGLUniformType;
|
||||
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
||||
1134
gsk/gskglshader.c
Normal file
1134
gsk/gskglshader.c
Normal file
File diff suppressed because it is too large
Load Diff
153
gsk/gskglshader.h
Normal file
153
gsk/gskglshader.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
*
|
||||
* Copyright 2020 Red Hat Inc
|
||||
*
|
||||
* 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_GL_SHADER_H__
|
||||
#define __GSK_GL_SHADER_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
#include <gsk/gskenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_GLSHADER (gsk_gl_shader_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GskGLShader, gsk_gl_shader, GSK, GL_SHADER, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskGLShader * gsk_gl_shader_new_from_bytes (GBytes *sourcecode);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskGLShader * gsk_gl_shader_new_from_resource (const char *resource_path);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_get_bytes (GskGLShader *shader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gsk_gl_shader_get_n_required_textures (GskGLShader *shader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gsk_gl_shader_get_n_uniforms (GskGLShader *shader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gsk_gl_shader_get_uniform_name (GskGLShader *shader,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gsk_gl_shader_find_uniform_by_name (GskGLShader *shader,
|
||||
const char *name);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskGLUniformType gsk_gl_shader_get_uniform_type (GskGLShader *shader,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gsk_gl_shader_get_uniform_offset (GskGLShader *shader,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gsk_gl_shader_get_uniforms_size (GskGLShader *shader);
|
||||
|
||||
|
||||
/* Helpers for managing uniform data */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
float gsk_gl_shader_get_uniform_data_float (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gint32 gsk_gl_shader_get_uniform_data_int (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint32 gsk_gl_shader_get_uniform_data_uint (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_gl_shader_get_uniform_data_bool (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_gl_shader_get_uniform_data_vec2 (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx,
|
||||
graphene_vec2_t *out_value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_gl_shader_get_uniform_data_vec3 (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx,
|
||||
graphene_vec3_t *out_value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_gl_shader_get_uniform_data_vec4 (GskGLShader *shader,
|
||||
GBytes *uniform_data,
|
||||
int idx,
|
||||
graphene_vec4_t *out_value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_format_uniform_data_va (GskGLShader *shader,
|
||||
va_list uniforms);
|
||||
|
||||
typedef struct _GskUniformDataBuilder GskUniformDataBuilder;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskUniformDataBuilder *gsk_gl_shader_build_uniform_data (GskGLShader *shader);
|
||||
|
||||
|
||||
#define GSK_TYPE_UNIFORM_DATA_BUILDER (gsk_uniform_data_builder_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_uniform_data_builder_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_uniform_data_builder_finish (GskUniformDataBuilder *builder);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_free (GskUniformDataBuilder *builder);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskUniformDataBuilder *gsk_uniform_data_builder_copy (GskUniformDataBuilder *builder);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_float (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
float value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_int (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
gint32 value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_uint (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
guint32 value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_bool (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
gboolean value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_vec2 (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
const graphene_vec2_t *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_vec3 (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
const graphene_vec3_t *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_uniform_data_builder_set_vec4 (GskUniformDataBuilder *builder,
|
||||
int idx,
|
||||
const graphene_vec4_t *value);
|
||||
|
||||
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_GL_SHADER_H__ */
|
||||
19
gsk/gskglshaderprivate.h
Normal file
19
gsk/gskglshaderprivate.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __GSK_GLSHADER_PRIVATE_H__
|
||||
#define __GSK_GLSHADER_PRIVATE_H__
|
||||
|
||||
#include <gsk/gskglshader.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
GskGLUniformType type;
|
||||
gsize offset;
|
||||
} GskGLUniform;
|
||||
|
||||
const GskGLUniform *gsk_gl_shader_get_uniforms (GskGLShader *shader,
|
||||
int *n_uniforms);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_GLSHADER_PRIVATE_H__ */
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include <gsk/gsktypes.h>
|
||||
#include <gsk/gskglshader.h>
|
||||
#include <gtk/css/gtkcss.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -122,6 +123,7 @@ GskRenderNode * gsk_render_node_deserialize (GBytes
|
||||
#define GSK_TYPE_CROSS_FADE_NODE (gsk_cross_fade_node_get_type())
|
||||
#define GSK_TYPE_TEXT_NODE (gsk_text_node_get_type())
|
||||
#define GSK_TYPE_BLUR_NODE (gsk_blur_node_get_type())
|
||||
#define GSK_TYPE_GLSHADER_NODE (gsk_gl_shader_node_get_type())
|
||||
|
||||
typedef struct _GskDebugNode GskDebugNode;
|
||||
typedef struct _GskColorNode GskColorNode;
|
||||
@@ -146,6 +148,7 @@ typedef struct _GskBlendNode GskBlendNode;
|
||||
typedef struct _GskCrossFadeNode GskCrossFadeNode;
|
||||
typedef struct _GskTextNode GskTextNode;
|
||||
typedef struct _GskBlurNode GskBlurNode;
|
||||
typedef struct _GskGLShaderNode GskGLShaderNode;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_debug_node_get_type (void) G_GNUC_CONST;
|
||||
@@ -451,6 +454,28 @@ GskRenderNode * gsk_blur_node_get_child (GskRenderNode
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
float gsk_blur_node_get_radius (GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_gl_shader_node_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_gl_shader_node_new (GskGLShader *shader,
|
||||
const graphene_rect_t *bounds,
|
||||
GBytes *uniform_data,
|
||||
GskRenderNode *fallback,
|
||||
GskRenderNode **children,
|
||||
int n_children);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_gl_shader_node_get_fallback_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gsk_gl_shader_node_get_n_children (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_gl_shader_node_get_child (GskRenderNode *node,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_node_get_uniform_data (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskGLShader * gsk_gl_shader_node_get_shader (GskRenderNode *node);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDER_NODE_H__ */
|
||||
|
||||
@@ -4470,6 +4470,229 @@ gsk_debug_node_get_message (GskRenderNode *node)
|
||||
return self->message;
|
||||
}
|
||||
|
||||
/*** GSK_GL_SHADER_NODE ***/
|
||||
|
||||
struct _GskGLShaderNode
|
||||
{
|
||||
GskRenderNode render_node;
|
||||
|
||||
GskGLShader *shader;
|
||||
GBytes *uniform_data;
|
||||
GskRenderNode *fallback;
|
||||
GskRenderNode **children;
|
||||
guint n_children;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gl_shader_node_finalize (GskRenderNode *node)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_GLSHADER_NODE));
|
||||
|
||||
for (guint i = 0; i < self->n_children; i++)
|
||||
gsk_render_node_unref (self->children[i]);
|
||||
g_free (self->children);
|
||||
|
||||
gsk_render_node_unref (self->fallback);
|
||||
g_bytes_unref (self->uniform_data);
|
||||
|
||||
g_object_unref (self->shader);
|
||||
|
||||
parent_class->finalize (node);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_shader_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
gsk_render_node_draw (self->fallback, cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_shader_node_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GskGLShaderNode *self1 = (GskGLShaderNode *) node1;
|
||||
GskGLShaderNode *self2 = (GskGLShaderNode *) node2;
|
||||
|
||||
if (graphene_rect_equal (&node1->bounds, &node2->bounds) &&
|
||||
self1->shader == self2->shader &&
|
||||
g_bytes_compare (self1->uniform_data, self2->uniform_data) == 0 &&
|
||||
self1->n_children == self2->n_children)
|
||||
{
|
||||
gsk_render_node_diff (self1->fallback, self2->fallback, region);
|
||||
|
||||
for (guint i = 0; i < self1->n_children; i++)
|
||||
{
|
||||
if (self1->children[i] != self2->children[i])
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_shader_node_new:
|
||||
* @shader: the #GskGLShader
|
||||
* @bounds: the rectangle to render the shader into
|
||||
* @uniform_data: Data for the uniforms
|
||||
* @fallback: Render node to use if OpenGL is not supported
|
||||
* @children: List of child nodes, these will be rendered to textures and used as input.
|
||||
* @n_children: Length of @children (currenly the GL backend only supports max 4 children)
|
||||
*
|
||||
* Creates a #GskRenderNode that will render the given @gl_program into the area given by @bounds.
|
||||
* The @uniform_data is a block of data to use for uniform input, as per types and offsets
|
||||
* defined by the @shader. Normally this is generated by gsk_gl_shader_format_uniform_data_va().
|
||||
*
|
||||
* See #GskGLShader for details about how the shader should be written.
|
||||
*
|
||||
* All the children will be rendered into textures, if they aren't already #GskTextureNode:s
|
||||
* then they will be used directly. These textures will be sent as input to the shader.
|
||||
*
|
||||
* If the backend doesn't support GL shaders, or if there is any problem when compiling
|
||||
* the shader, then the fallback shader node will be used instead.
|
||||
*
|
||||
* Returns: (transfer full) (type GskGLShaderNode): A new #GskRenderNode
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_gl_shader_node_new (GskGLShader *shader,
|
||||
const graphene_rect_t *bounds,
|
||||
GBytes *uniform_data,
|
||||
GskRenderNode *fallback,
|
||||
GskRenderNode **children,
|
||||
int n_children)
|
||||
{
|
||||
GskGLShaderNode *self;
|
||||
GskRenderNode *node;
|
||||
int uniforms_size;
|
||||
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
|
||||
self = gsk_render_node_alloc (GSK_GL_SHADER_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
self->shader = g_object_ref (shader);
|
||||
|
||||
uniforms_size = gsk_gl_shader_get_uniforms_size (shader);
|
||||
g_assert (g_bytes_get_size (uniform_data) == uniforms_size);
|
||||
|
||||
self->uniform_data = g_bytes_ref (uniform_data);
|
||||
self->fallback = gsk_render_node_ref (fallback);
|
||||
|
||||
self->n_children = n_children;
|
||||
if (n_children > 0)
|
||||
{
|
||||
self->children = g_malloc_n (n_children, sizeof (GskRenderNode *));
|
||||
for (guint i = 0; i < n_children; i++)
|
||||
self->children[i] = gsk_render_node_ref (children[i]);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_shader_node_get_fallback_child:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
*
|
||||
* Gets the fallback child node
|
||||
*
|
||||
* Returns: (transfer none): The fallback node
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_gl_shader_node_get_fallback_child (GskRenderNode *node)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_GL_SHADER_NODE), NULL);
|
||||
|
||||
return self->fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_shader_node_get_n_children:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
*
|
||||
* Returns the number of (non-fallback) children
|
||||
*
|
||||
* Returns: The number of children
|
||||
*/
|
||||
guint
|
||||
gsk_gl_shader_node_get_n_children (GskRenderNode *node)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_GL_SHADER_NODE), 0);
|
||||
|
||||
return self->n_children;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_shader_node_get_child:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
* @idx: the position of the child to get
|
||||
*
|
||||
* Gets one of the (non-fallback) children.
|
||||
*
|
||||
* Returns: (transfer none): the @idx'th child of @node
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_gl_shader_node_get_child (GskRenderNode *node,
|
||||
int idx)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_GL_SHADER_NODE), NULL);
|
||||
g_return_val_if_fail (idx < self->n_children, NULL);
|
||||
|
||||
return self->children[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_shader_node_get_shader:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
*
|
||||
* Gets shader code for the node.
|
||||
*
|
||||
* Returns: (transfer none): the #GskGLShader shader
|
||||
*/
|
||||
GskGLShader *
|
||||
gsk_gl_shader_node_get_shader (GskRenderNode *node)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_GL_SHADER_NODE), 0);
|
||||
|
||||
return self->shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_shader_node_get_uniform_data:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
*
|
||||
* Gets args for the node.
|
||||
*
|
||||
* Returns: (transfer none): A #GBytes with the uniform data
|
||||
*/
|
||||
GBytes *
|
||||
gsk_gl_shader_node_get_uniform_data (GskRenderNode *node)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_GL_SHADER_NODE), NULL);
|
||||
|
||||
return self->uniform_data;
|
||||
}
|
||||
|
||||
GType gsk_render_node_types[GSK_RENDER_NODE_TYPE_N_TYPES];
|
||||
|
||||
#ifndef I_
|
||||
@@ -4506,6 +4729,7 @@ GSK_DEFINE_RENDER_NODE_TYPE (gsk_blend_node, GSK_BLEND_NODE)
|
||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_cross_fade_node, GSK_CROSS_FADE_NODE)
|
||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_text_node, GSK_TEXT_NODE)
|
||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_blur_node, GSK_BLUR_NODE)
|
||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_gl_shader_node, GSK_GL_SHADER_NODE)
|
||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_debug_node, GSK_DEBUG_NODE)
|
||||
|
||||
static void
|
||||
@@ -4863,6 +5087,22 @@ gsk_render_node_init_types_once (void)
|
||||
gsk_render_node_types[GSK_BLUR_NODE] = node_type;
|
||||
}
|
||||
|
||||
{
|
||||
const GskRenderNodeTypeInfo node_info =
|
||||
{
|
||||
GSK_GL_SHADER_NODE,
|
||||
sizeof (GskGLShaderNode),
|
||||
NULL,
|
||||
gsk_gl_shader_node_finalize,
|
||||
gsk_gl_shader_node_draw,
|
||||
NULL,
|
||||
gsk_gl_shader_node_diff,
|
||||
};
|
||||
|
||||
GType node_type = gsk_render_node_type_register_static (I_("GskGLShaderNode"), &node_info);
|
||||
gsk_render_node_types[GSK_GL_SHADER_NODE] = node_type;
|
||||
}
|
||||
|
||||
{
|
||||
const GskRenderNodeTypeInfo node_info =
|
||||
{
|
||||
|
||||
@@ -824,9 +824,9 @@ clear_node (gpointer inout_node)
|
||||
static GskRenderNode *
|
||||
parse_container_node (GtkCssParser *parser)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
GPtrArray *nodes;
|
||||
const GtkCssToken *token;
|
||||
GskRenderNode *node;
|
||||
|
||||
nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
|
||||
|
||||
@@ -1089,6 +1089,235 @@ parse_inset_shadow_node (GtkCssParser *parser)
|
||||
return gsk_inset_shadow_node_new (&outline, &color, dx, dy, spread, blur);
|
||||
}
|
||||
|
||||
typedef union {
|
||||
gint32 i;
|
||||
double v[4];
|
||||
} UniformValue;
|
||||
|
||||
typedef struct {
|
||||
GskGLShader *shader;
|
||||
GArray *uniform_values;
|
||||
} ShaderInfo;
|
||||
|
||||
static void
|
||||
clear_shader_info (gpointer data)
|
||||
{
|
||||
ShaderInfo *info = data;
|
||||
g_array_set_size (info->uniform_values, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_shader (GtkCssParser *parser,
|
||||
gpointer out_shader_info)
|
||||
{
|
||||
ShaderInfo *shader_info = out_shader_info;
|
||||
char *sourcecode = NULL;
|
||||
GBytes *bytes;
|
||||
GskGLShader *shader;
|
||||
|
||||
if (!parse_string (parser, &sourcecode))
|
||||
return FALSE;
|
||||
|
||||
bytes = g_bytes_new_take (sourcecode, strlen (sourcecode));
|
||||
shader = gsk_gl_shader_new_from_bytes (bytes);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
shader_info->shader = shader;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_uniform_value (GtkCssParser *parser,
|
||||
GskGLUniformType uniform_type,
|
||||
UniformValue *value)
|
||||
{
|
||||
switch (uniform_type)
|
||||
{
|
||||
case GSK_GLUNIFORM_TYPE_FLOAT:
|
||||
if (!gtk_css_parser_consume_number (parser, &value->v[0]))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_INT:
|
||||
if (!gtk_css_parser_consume_integer (parser, &value->i))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_UINT:
|
||||
if (!gtk_css_parser_consume_integer (parser, &value->i) ||
|
||||
value->i < 0)
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_BOOL:
|
||||
if (!gtk_css_parser_consume_integer (parser, &value->i) ||
|
||||
(value->i != 0 && value->i != 1))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC2:
|
||||
if (!gtk_css_parser_consume_number (parser, &value->v[0]) ||
|
||||
!gtk_css_parser_consume_number (parser, &value->v[1]))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC3:
|
||||
if (!gtk_css_parser_consume_number (parser, &value->v[0]) ||
|
||||
!gtk_css_parser_consume_number (parser, &value->v[1]) ||
|
||||
!gtk_css_parser_consume_number (parser, &value->v[2]))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC4:
|
||||
if (!gtk_css_parser_consume_number (parser, &value->v[0]) ||
|
||||
!gtk_css_parser_consume_number (parser, &value->v[1]) ||
|
||||
!gtk_css_parser_consume_number (parser, &value->v[2]) ||
|
||||
!gtk_css_parser_consume_number (parser, &value->v[3]))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_uniform_data (GtkCssParser *parser, gpointer data)
|
||||
{
|
||||
ShaderInfo *shader_info = data;
|
||||
int n_uniforms = gsk_gl_shader_get_n_uniforms (shader_info->shader);
|
||||
int i;
|
||||
|
||||
g_array_set_size (shader_info->uniform_values, n_uniforms);
|
||||
|
||||
for (i = 0; i < n_uniforms; i++)
|
||||
{
|
||||
GskGLUniformType uniform_type = gsk_gl_shader_get_uniform_type (shader_info->shader, i);
|
||||
UniformValue *uniform_value = &g_array_index (shader_info->uniform_values, UniformValue, i);
|
||||
|
||||
if (!parse_uniform_value (parser, uniform_type, uniform_value))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
parse_glshader_node (GtkCssParser *parser)
|
||||
{
|
||||
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 50, 50);
|
||||
GskRenderNode *fallback = NULL;
|
||||
GskRenderNode *child[4] = { NULL, };
|
||||
ShaderInfo shader_info = {
|
||||
NULL,
|
||||
g_array_new (FALSE, FALSE, sizeof (UniformValue))
|
||||
};
|
||||
const Declaration declarations[] = {
|
||||
{ "bounds", parse_rect, NULL, &bounds },
|
||||
{ "sourcecode", parse_shader, NULL, &shader_info },
|
||||
{ "uniform-data", parse_uniform_data, clear_shader_info, &shader_info },
|
||||
{ "fallback", parse_node, clear_node, &fallback },
|
||||
{ "child1", parse_node, clear_node, &child[0] },
|
||||
{ "child2", parse_node, clear_node, &child[1] },
|
||||
{ "child3", parse_node, clear_node, &child[2] },
|
||||
{ "child4", parse_node, clear_node, &child[3] },
|
||||
};
|
||||
GskGLShader *shader;
|
||||
GskRenderNode *node;
|
||||
GskUniformDataBuilder *builder;
|
||||
GBytes *uniform_data = NULL;
|
||||
int len, i;
|
||||
|
||||
parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
|
||||
|
||||
for (len = 0; len < 4; len++)
|
||||
{
|
||||
if (child[len] == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
shader = shader_info.shader;
|
||||
|
||||
builder = gsk_gl_shader_build_uniform_data (shader);
|
||||
for (i = 0; i < shader_info.uniform_values->len; i++)
|
||||
{
|
||||
GskGLUniformType uniform_type = gsk_gl_shader_get_uniform_type (shader, i);
|
||||
UniformValue *value = &g_array_index (shader_info.uniform_values, UniformValue, i);
|
||||
|
||||
switch (uniform_type)
|
||||
{
|
||||
case GSK_GLUNIFORM_TYPE_FLOAT:
|
||||
gsk_uniform_data_builder_set_float (builder, i, value->v[0]);
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_INT:
|
||||
gsk_uniform_data_builder_set_int (builder, i, value->i);
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_UINT:
|
||||
gsk_uniform_data_builder_set_uint (builder, i, value->i);
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_BOOL:
|
||||
gsk_uniform_data_builder_set_bool (builder, i, value->i);
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC2:
|
||||
{
|
||||
graphene_vec2_t v;
|
||||
graphene_vec2_init (&v, value->v[0], value->v[1]);
|
||||
gsk_uniform_data_builder_set_vec2 (builder, i, &v);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC3:
|
||||
{
|
||||
graphene_vec3_t v;
|
||||
graphene_vec3_init (&v, value->v[0], value->v[1], value->v[2]);
|
||||
gsk_uniform_data_builder_set_vec3 (builder, i, &v);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC4:
|
||||
{
|
||||
graphene_vec4_t v;
|
||||
graphene_vec4_init (&v, value->v[0], value->v[1], value->v[2], value->v[3]);
|
||||
gsk_uniform_data_builder_set_vec4 (builder, i, &v);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
uniform_data = gsk_uniform_data_builder_finish (builder);
|
||||
gsk_uniform_data_builder_free (builder);
|
||||
|
||||
node = gsk_gl_shader_node_new (shader, &bounds, uniform_data,
|
||||
fallback, child, len);
|
||||
|
||||
g_array_unref (shader_info.uniform_values);
|
||||
g_bytes_unref (uniform_data);
|
||||
g_object_unref (shader);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (child[i])
|
||||
gsk_render_node_unref (child[i]);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
parse_border_node (GtkCssParser *parser)
|
||||
{
|
||||
@@ -1603,6 +1832,7 @@ parse_node (GtkCssParser *parser,
|
||||
{ "text", parse_text_node },
|
||||
{ "texture", parse_texture_node },
|
||||
{ "transform", parse_transform_node },
|
||||
{ "glshader", parse_glshader_node },
|
||||
};
|
||||
GskRenderNode **node_p = out_node;
|
||||
guint i;
|
||||
@@ -1837,6 +2067,51 @@ append_point (GString *str,
|
||||
string_append_double (str, p->y);
|
||||
}
|
||||
|
||||
static void
|
||||
append_string (GString *str,
|
||||
const char *string)
|
||||
{
|
||||
gsize len;
|
||||
|
||||
g_return_if_fail (str != NULL);
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
g_string_append_c (str, '"');
|
||||
|
||||
do {
|
||||
len = strcspn (string, "\\\"\n\r\f");
|
||||
g_string_append_len (str, string, len);
|
||||
string += len;
|
||||
switch (*string)
|
||||
{
|
||||
case '\0':
|
||||
goto out;
|
||||
case '\n':
|
||||
g_string_append (str, "\\A ");
|
||||
break;
|
||||
case '\r':
|
||||
g_string_append (str, "\\D ");
|
||||
break;
|
||||
case '\f':
|
||||
g_string_append (str, "\\C ");
|
||||
break;
|
||||
case '\"':
|
||||
g_string_append (str, "\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
g_string_append (str, "\\\\");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
string++;
|
||||
} while (*string);
|
||||
|
||||
out:
|
||||
g_string_append_c (str, '"');
|
||||
}
|
||||
|
||||
static void
|
||||
append_vec4 (GString *str,
|
||||
const graphene_vec4_t *v)
|
||||
@@ -1914,6 +2189,18 @@ append_point_param (Printer *p,
|
||||
g_string_append_c (p->str, '\n');
|
||||
}
|
||||
|
||||
static void
|
||||
append_string_param (Printer *p,
|
||||
const char *param_name,
|
||||
const char *value)
|
||||
{
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "%s: ", param_name);
|
||||
append_string (p->str, value);
|
||||
g_string_append_c (p->str, ';');
|
||||
g_string_append_c (p->str, '\n');
|
||||
}
|
||||
|
||||
static void
|
||||
append_vec4_param (Printer *p,
|
||||
const char *param_name,
|
||||
@@ -2441,6 +2728,125 @@ render_node_print (Printer *p,
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_SHADER_NODE:
|
||||
{
|
||||
GskGLShader *shader = gsk_gl_shader_node_get_shader (node);
|
||||
GBytes *uniform_data = gsk_gl_shader_node_get_uniform_data (node);
|
||||
|
||||
start_node (p, "glshader");
|
||||
|
||||
append_rect_param (p, "bounds", &node->bounds);
|
||||
|
||||
GBytes *bytes = gsk_gl_shader_get_bytes (shader);
|
||||
/* Ensure we are zero-terminated */
|
||||
char *sourcecode = g_strndup (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
|
||||
append_string_param (p, "sourcecode", sourcecode);
|
||||
g_free (sourcecode);
|
||||
|
||||
if (gsk_gl_shader_get_n_uniforms (shader) > 0)
|
||||
{
|
||||
GString *data = g_string_new ("");
|
||||
|
||||
for (guint i = 0; i < gsk_gl_shader_get_n_uniforms (shader); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (data, ", ");
|
||||
|
||||
switch (gsk_gl_shader_get_uniform_type (shader, i))
|
||||
{
|
||||
case GSK_GLUNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_FLOAT:
|
||||
{
|
||||
float value = gsk_gl_shader_get_uniform_data_float (shader, uniform_data, i);
|
||||
string_append_double (data, value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_INT:
|
||||
{
|
||||
gint32 value = gsk_gl_shader_get_uniform_data_int (shader, uniform_data, i);
|
||||
g_string_append_printf (data, "%d", value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_UINT:
|
||||
{
|
||||
guint32 value = gsk_gl_shader_get_uniform_data_uint (shader, uniform_data, i);
|
||||
g_string_append_printf (data, "%u", value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_BOOL:
|
||||
{
|
||||
gboolean value = gsk_gl_shader_get_uniform_data_bool (shader, uniform_data, i);
|
||||
g_string_append_printf (data, "%d", value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC2:
|
||||
{
|
||||
graphene_vec2_t value;
|
||||
gsk_gl_shader_get_uniform_data_vec2 (shader, uniform_data, i,
|
||||
&value);
|
||||
string_append_double (data, graphene_vec2_get_x (&value));
|
||||
g_string_append (data, " ");
|
||||
string_append_double (data, graphene_vec2_get_y (&value));
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC3:
|
||||
{
|
||||
graphene_vec3_t value;
|
||||
gsk_gl_shader_get_uniform_data_vec3 (shader, uniform_data, i,
|
||||
&value);
|
||||
string_append_double (data, graphene_vec3_get_x (&value));
|
||||
g_string_append (data, " ");
|
||||
string_append_double (data, graphene_vec3_get_y (&value));
|
||||
g_string_append (data, " ");
|
||||
string_append_double (data, graphene_vec3_get_z (&value));
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC4:
|
||||
{
|
||||
graphene_vec4_t value;
|
||||
gsk_gl_shader_get_uniform_data_vec4 (shader, uniform_data, i,
|
||||
&value);
|
||||
string_append_double (data, graphene_vec4_get_x (&value));
|
||||
g_string_append (data, " ");
|
||||
string_append_double (data, graphene_vec4_get_y (&value));
|
||||
g_string_append (data, " ");
|
||||
string_append_double (data, graphene_vec4_get_z (&value));
|
||||
g_string_append (data, " ");
|
||||
string_append_double (data, graphene_vec4_get_w (&value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "uniform-data: %s;\n", data->str);
|
||||
g_string_free (data, TRUE);
|
||||
}
|
||||
|
||||
append_node_param (p, "fallback", gsk_gl_shader_node_get_fallback_child (node));
|
||||
for (guint i = 0; i < gsk_gl_shader_node_get_n_children (node); i ++)
|
||||
{
|
||||
GskRenderNode *child = gsk_gl_shader_node_get_child (node, i);
|
||||
char *name;
|
||||
|
||||
name = g_strdup_printf ("child%d", i + 1);
|
||||
append_node_param (p, name, child);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
end_node (p);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_REPEAT_NODE:
|
||||
{
|
||||
GskRenderNode *child = gsk_repeat_node_get_child (node);
|
||||
|
||||
@@ -13,7 +13,7 @@ typedef struct _GskRenderNodeClass GskRenderNodeClass;
|
||||
* We don't add an "n-types" value to avoid having to handle
|
||||
* it in every single switch.
|
||||
*/
|
||||
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_DEBUG_NODE + 1)
|
||||
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_GL_SHADER_NODE + 1)
|
||||
|
||||
extern GType gsk_render_node_types[];
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ gsk_private_gl_shaders = [
|
||||
gsk_public_sources = files([
|
||||
'gskdiff.c',
|
||||
'gskcairorenderer.c',
|
||||
'gskglshader.c',
|
||||
'gskrenderer.c',
|
||||
'gskrendernode.c',
|
||||
'gskrendernodeimpl.c',
|
||||
@@ -52,6 +53,7 @@ gsk_private_sources = files([
|
||||
gsk_public_headers = files([
|
||||
'gskcairorenderer.h',
|
||||
'gskenums.h',
|
||||
'gskglshader.h',
|
||||
'gskrenderer.h',
|
||||
'gskrendernode.h',
|
||||
'gskroundedrect.h',
|
||||
|
||||
@@ -171,6 +171,25 @@ create_list_model_for_render_node (GskRenderNode *node)
|
||||
return create_render_node_list_model ((GskRenderNode *[2]) { gsk_cross_fade_node_get_start_child (node),
|
||||
gsk_cross_fade_node_get_end_child (node) }, 2);
|
||||
|
||||
case GSK_GL_SHADER_NODE:
|
||||
{
|
||||
GListStore *store = G_LIST_STORE (create_render_node_list_model ((GskRenderNode *[1]) { gsk_gl_shader_node_get_fallback_child (node) }, 1));
|
||||
|
||||
for (guint i = 0; i < gsk_gl_shader_node_get_n_children (node); i++)
|
||||
{
|
||||
GskRenderNode *child = gsk_gl_shader_node_get_child (node, i);
|
||||
graphene_rect_t bounds;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
gsk_render_node_get_bounds (child, &bounds);
|
||||
paintable = gtk_render_node_paintable_new (child, &bounds);
|
||||
g_list_store_append (store, paintable);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
return G_LIST_MODEL (store);
|
||||
}
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
{
|
||||
GListStore *store;
|
||||
@@ -270,6 +289,8 @@ node_type_name (GskRenderNodeType type)
|
||||
return "Text";
|
||||
case GSK_BLUR_NODE:
|
||||
return "Blur";
|
||||
case GSK_GL_SHADER_NODE:
|
||||
return "GL Shader";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,6 +322,7 @@ node_name (GskRenderNode *node)
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_GL_SHADER_NODE:
|
||||
return g_strdup (node_type_name (gsk_render_node_get_node_type (node)));
|
||||
|
||||
case GSK_DEBUG_NODE:
|
||||
@@ -511,6 +533,34 @@ add_color_row (GtkListStore *store,
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
add_int_row (GtkListStore *store,
|
||||
const char *name,
|
||||
int value)
|
||||
{
|
||||
char *text = g_strdup_printf ("%d", value);
|
||||
add_text_row (store, name, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
add_uint_row (GtkListStore *store,
|
||||
const char *name,
|
||||
guint value)
|
||||
{
|
||||
char *text = g_strdup_printf ("%u", value);
|
||||
add_text_row (store, name, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
add_boolean_row (GtkListStore *store,
|
||||
const char *name,
|
||||
gboolean value)
|
||||
{
|
||||
add_text_row (store, name, value ? "TRUE" : "FALSE");
|
||||
}
|
||||
|
||||
static void
|
||||
add_float_row (GtkListStore *store,
|
||||
const char *name,
|
||||
@@ -759,6 +809,92 @@ populate_render_node_properties (GtkListStore *store,
|
||||
add_float_row (store, "Radius", gsk_blur_node_get_radius (node));
|
||||
break;
|
||||
|
||||
case GSK_GL_SHADER_NODE:
|
||||
{
|
||||
GskGLShader *shader = gsk_gl_shader_node_get_shader (node);
|
||||
GBytes *uniform_data = gsk_gl_shader_node_get_uniform_data (node);
|
||||
int i;
|
||||
|
||||
add_int_row (store, "Required textures", gsk_gl_shader_get_n_required_textures (shader));
|
||||
for (i = 0; i < gsk_gl_shader_get_n_uniforms (shader); i++)
|
||||
{
|
||||
const char *name;
|
||||
char *title;
|
||||
|
||||
name = gsk_gl_shader_get_uniform_name (shader, i);
|
||||
title = g_strdup_printf ("Uniform %s", name);
|
||||
|
||||
switch (gsk_gl_shader_get_uniform_type (shader, i))
|
||||
{
|
||||
case GSK_GLUNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_FLOAT:
|
||||
add_float_row (store, title,
|
||||
gsk_gl_shader_get_uniform_data_float (shader, uniform_data, i));
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_INT:
|
||||
add_int_row (store, title,
|
||||
gsk_gl_shader_get_uniform_data_int (shader, uniform_data, i));
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_UINT:
|
||||
add_uint_row (store, title,
|
||||
gsk_gl_shader_get_uniform_data_uint (shader, uniform_data, i));
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_BOOL:
|
||||
add_boolean_row (store, title,
|
||||
gsk_gl_shader_get_uniform_data_bool (shader, uniform_data, i));
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC2:
|
||||
{
|
||||
graphene_vec2_t v;
|
||||
gsk_gl_shader_get_uniform_data_vec2 (shader, uniform_data, i, &v);
|
||||
float x = graphene_vec2_get_x (&v);
|
||||
float y = graphene_vec2_get_x (&v);
|
||||
char *s = g_strdup_printf ("%.2f %.2f", x, y);
|
||||
add_text_row (store, title, s);
|
||||
g_free (s);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC3:
|
||||
{
|
||||
graphene_vec3_t v;
|
||||
gsk_gl_shader_get_uniform_data_vec3 (shader, uniform_data, i, &v);
|
||||
float x = graphene_vec3_get_x (&v);
|
||||
float y = graphene_vec3_get_y (&v);
|
||||
float z = graphene_vec3_get_z (&v);
|
||||
char *s = g_strdup_printf ("%.2f %.2f %.2f", x, y, z);
|
||||
add_text_row (store, title, s);
|
||||
g_free (s);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GLUNIFORM_TYPE_VEC4:
|
||||
{
|
||||
graphene_vec4_t v;
|
||||
gsk_gl_shader_get_uniform_data_vec4 (shader, uniform_data, i, &v);
|
||||
float x = graphene_vec4_get_x (&v);
|
||||
float y = graphene_vec4_get_y (&v);
|
||||
float z = graphene_vec4_get_z (&v);
|
||||
float w = graphene_vec4_get_w (&v);
|
||||
char *s = g_strdup_printf ("%.2f %.2f %.2f %.2f", x, y, z, w);
|
||||
add_text_row (store, title, s);
|
||||
g_free (s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
g_free (title);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_INSET_SHADOW_NODE:
|
||||
{
|
||||
const GdkRGBA *color = gsk_inset_shadow_node_peek_color (node);
|
||||
|
||||
Reference in New Issue
Block a user