mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 17:50:10 +00:00
Add GskGLShaderNode and GskGLShader
A GskGLShader is an abstraction of a GLSL fragment shader that can produce pixel values given inputs: * N (currently max 4) textures * Current arguments for the shader uniform Uniform types are: float,(u)int,bool,vec234) There is also a builder for the uniform arguments which are passed around as immutable GBytes in the built form. A GskGLShaderNode is a render node that renders a GskGLShader inside a specified rectangular bounds. It renders its child nodes as textures and passes those as texture arguments to the shader. You also pass it a uniform arguments object.
This commit is contained in:
parent
6e9b58b6f0
commit
7ea755e206
@ -20,6 +20,7 @@
|
||||
<xi:include href="xml/GskRenderNode.xml" />
|
||||
<xi:include href="xml/GskRoundedRect.xml" />
|
||||
<xi:include href="xml/GskTransform.xml" />
|
||||
<xi:include href="xml/GskGLShader.xml" />
|
||||
</reference>
|
||||
|
||||
<index id="api-index-full">
|
||||
|
@ -48,6 +48,7 @@ GskShadowNode
|
||||
GskTextNode
|
||||
GskTextureNode
|
||||
GskTransformNode
|
||||
GskGLShaderNode
|
||||
gsk_render_node_ref
|
||||
gsk_render_node_unref
|
||||
GskRenderNodeType
|
||||
@ -152,6 +153,11 @@ gsk_blur_node_get_radius
|
||||
gsk_debug_node_new
|
||||
gsk_debug_node_get_child
|
||||
gsk_debug_node_get_message
|
||||
gsk_gl_shader_node_new
|
||||
gsk_gl_shader_node_get_n_children
|
||||
gsk_gl_shader_node_get_child
|
||||
gsk_gl_shader_node_get_args
|
||||
gsk_gl_shader_node_get_shader
|
||||
<SUBSECTION Standard>
|
||||
GSK_IS_RENDER_NODE
|
||||
GSK_RENDER_NODE
|
||||
@ -177,6 +183,7 @@ GSK_TYPE_SHADOW_NODE
|
||||
GSK_TYPE_TEXT_NODE
|
||||
GSK_TYPE_TEXTURE_NODE
|
||||
GSK_TYPE_TRANSFORM_NODE
|
||||
GSK_TYPE_GLSHADER_NODE
|
||||
GskRenderNodeClass
|
||||
gsk_blend_node_get_type
|
||||
gsk_blur_node_get_type
|
||||
@ -202,6 +209,7 @@ gsk_shadow_node_get_type
|
||||
gsk_text_node_get_type
|
||||
gsk_texture_node_get_type
|
||||
gsk_transform_node_get_type
|
||||
gsk_gl_shader_node_get_type
|
||||
GSK_TYPE_BLEND_MODE
|
||||
<SUBSECTION Standard>
|
||||
gsk_serialization_error_quark
|
||||
@ -266,3 +274,46 @@ gsk_transform_get_type
|
||||
gsk_transform_new
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskGLShader</FILE>
|
||||
GskGLShader
|
||||
gsk_gl_shader_new_from_bytes
|
||||
gsk_gl_shader_new_from_resource
|
||||
gsk_gl_shader_compile
|
||||
gsk_gl_shader_get_source
|
||||
gsk_gl_shader_get_n_textures
|
||||
gsk_gl_shader_get_n_uniforms
|
||||
gsk_gl_shader_get_uniform_name
|
||||
gsk_gl_shader_find_uniform_by_name
|
||||
gsk_gl_shader_get_uniform_type
|
||||
gsk_gl_shader_get_uniform_offset
|
||||
gsk_gl_shader_get_args_size
|
||||
|
||||
<SUBSECTION Uniform Data>
|
||||
gsk_gl_shader_get_arg_float
|
||||
gsk_gl_shader_get_arg_int
|
||||
gsk_gl_shader_get_arg_uint
|
||||
gsk_gl_shader_get_arg_bool
|
||||
gsk_gl_shader_get_arg_vec2
|
||||
gsk_gl_shader_get_arg_vec3
|
||||
gsk_gl_shader_get_arg_vec4
|
||||
gsk_gl_shader_format_args_va
|
||||
gsk_gl_shader_format_args
|
||||
|
||||
<SUBSECTION Shader Args Builder>
|
||||
GskShaderArgsBuilder
|
||||
|
||||
gsk_shader_args_builder_new
|
||||
gsk_shader_args_builder_to_args
|
||||
gsk_shader_args_builder_free_to_args
|
||||
gsk_shader_args_builder_unref
|
||||
gsk_shader_args_builder_ref
|
||||
|
||||
gsk_shader_args_builder_set_float
|
||||
gsk_shader_args_builder_set_int
|
||||
gsk_shader_args_builder_set_uint
|
||||
gsk_shader_args_builder_set_bool
|
||||
gsk_shader_args_builder_set_vec2
|
||||
gsk_shader_args_builder_set_vec3
|
||||
gsk_shader_args_builder_set_vec4
|
||||
</SECTION>
|
||||
|
@ -1,2 +1,3 @@
|
||||
gsk_render_node_get_type
|
||||
gsk_renderer_get_type
|
||||
gsk_gl_shader_get_type
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <gsk/gskrendernode.h>
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include <gsk/gsktransform.h>
|
||||
#include <gsk/gskglshader.h>
|
||||
|
||||
#include <gsk/gskcairorenderer.h>
|
||||
|
||||
|
@ -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_GL_UNIFORM_TYPE_NONE: No type, used for uninitialized or unspecified values.
|
||||
* @GSK_GL_UNIFORM_TYPE_FLOAT: A float uniform
|
||||
* @GSK_GL_UNIFORM_TYPE_INT: A GLSL int / gint32 uniform
|
||||
* @GSK_GL_UNIFORM_TYPE_UINT: A GLSL uint / guint32 uniform
|
||||
* @GSK_GL_UNIFORM_TYPE_BOOL: A GLSL bool / gboolean uniform
|
||||
* @GSK_GL_UNIFORM_TYPE_VEC2: A GLSL vec2 / graphene_vec2_t uniform
|
||||
* @GSK_GL_UNIFORM_TYPE_VEC3: A GLSL vec3 / graphene_vec3_t uniform
|
||||
* @GSK_GL_UNIFORM_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_GL_UNIFORM_TYPE_NONE,
|
||||
GSK_GL_UNIFORM_TYPE_FLOAT,
|
||||
GSK_GL_UNIFORM_TYPE_INT,
|
||||
GSK_GL_UNIFORM_TYPE_UINT,
|
||||
GSK_GL_UNIFORM_TYPE_BOOL,
|
||||
GSK_GL_UNIFORM_TYPE_VEC2,
|
||||
GSK_GL_UNIFORM_TYPE_VEC3,
|
||||
GSK_GL_UNIFORM_TYPE_VEC4,
|
||||
} GskGLUniformType;
|
||||
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
1394
gsk/gskglshader.c
Normal file
1394
gsk/gskglshader.c
Normal file
File diff suppressed because it is too large
Load Diff
162
gsk/gskglshader.h
Normal file
162
gsk/gskglshader.h
Normal file
@ -0,0 +1,162 @@
|
||||
/* 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_SHADER_ARGS_BUILDER (gsk_shader_args_builder_get_type ())
|
||||
|
||||
typedef struct _GskShaderArgsBuilder GskShaderArgsBuilder;
|
||||
|
||||
#define GSK_TYPE_GL_SHADER (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
|
||||
gboolean gsk_gl_shader_compile (GskGLShader *shader,
|
||||
GskRenderer *renderer,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_get_source (GskGLShader *shader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gsk_gl_shader_get_resource (GskGLShader *shader);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gsk_gl_shader_get_n_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
|
||||
gsize gsk_gl_shader_get_args_size (GskGLShader *shader);
|
||||
|
||||
|
||||
/* Helpers for managing shader args */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_format_args_va (GskGLShader *shader,
|
||||
va_list uniforms);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_format_args (GskGLShader *shader,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
float gsk_gl_shader_get_arg_float (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gint32 gsk_gl_shader_get_arg_int (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint32 gsk_gl_shader_get_arg_uint (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_gl_shader_get_arg_bool (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_gl_shader_get_arg_vec2 (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx,
|
||||
graphene_vec2_t *out_value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_gl_shader_get_arg_vec3 (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx,
|
||||
graphene_vec3_t *out_value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_gl_shader_get_arg_vec4 (GskGLShader *shader,
|
||||
GBytes *args,
|
||||
int idx,
|
||||
graphene_vec4_t *out_value);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_shader_args_builder_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskShaderArgsBuilder *gsk_shader_args_builder_new (GskGLShader *shader,
|
||||
GBytes *initial_values);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_shader_args_builder_to_args (GskShaderArgsBuilder *builder);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_shader_args_builder_free_to_args (GskShaderArgsBuilder *builder);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskShaderArgsBuilder *gsk_shader_args_builder_ref (GskShaderArgsBuilder *builder);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_unref (GskShaderArgsBuilder *builder);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_float (GskShaderArgsBuilder *builder,
|
||||
int idx,
|
||||
float value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_int (GskShaderArgsBuilder *builder,
|
||||
int idx,
|
||||
gint32 value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_uint (GskShaderArgsBuilder *builder,
|
||||
int idx,
|
||||
guint32 value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_bool (GskShaderArgsBuilder *builder,
|
||||
int idx,
|
||||
gboolean value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_vec2 (GskShaderArgsBuilder *builder,
|
||||
int idx,
|
||||
const graphene_vec2_t *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_vec3 (GskShaderArgsBuilder *builder,
|
||||
int idx,
|
||||
const graphene_vec3_t *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_shader_args_builder_set_vec4 (GskShaderArgsBuilder *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_GL_SHADER_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,24 @@ 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 *args,
|
||||
GskRenderNode **children,
|
||||
guint n_children);
|
||||
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,
|
||||
guint idx);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GBytes * gsk_gl_shader_node_get_args (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,209 @@ gsk_debug_node_get_message (GskRenderNode *node)
|
||||
return self->message;
|
||||
}
|
||||
|
||||
/*** GSK_GL_SHADER_NODE ***/
|
||||
|
||||
struct _GskGLShaderNode
|
||||
{
|
||||
GskRenderNode render_node;
|
||||
|
||||
GskGLShader *shader;
|
||||
GBytes *args;
|
||||
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_GL_SHADER_NODE));
|
||||
|
||||
for (guint i = 0; i < self->n_children; i++)
|
||||
gsk_render_node_unref (self->children[i]);
|
||||
g_free (self->children);
|
||||
|
||||
g_bytes_unref (self->args);
|
||||
|
||||
g_object_unref (self->shader);
|
||||
|
||||
parent_class->finalize (node);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_shader_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 255 / 255., 105 / 255., 180 / 255.);
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_fill (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->args, self2->args) == 0 &&
|
||||
self1->n_children == self2->n_children)
|
||||
{
|
||||
cairo_region_t *child_region = cairo_region_create();
|
||||
for (guint i = 0; i < self1->n_children; i++)
|
||||
gsk_render_node_diff (self1->children[i], self2->children[i], child_region);
|
||||
if (!cairo_region_is_empty (child_region))
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
cairo_region_destroy (child_region);
|
||||
}
|
||||
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
|
||||
* @args: Arguments for the uniforms
|
||||
* @children: (array length=n_children): array of child nodes, these will
|
||||
* be rendered to textures and used as input.
|
||||
* @n_children: Length of @children (currenly the GL backend supports
|
||||
* up to 4 children)
|
||||
*
|
||||
* Creates a #GskRenderNode that will render the given @shader into the
|
||||
* area given by @bounds. The @args 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_args() or #GskGLShaderArgBuilder.
|
||||
*
|
||||
* See #GskGLShader for details about how the shader should be written.
|
||||
*
|
||||
* All the children will be rendered into textures (if they aren't already
|
||||
* #GskTextureNodes, which will be used directly). These textures will be
|
||||
* sent as input to the shader.
|
||||
*
|
||||
* If the renderer doesn't support GL shaders, or if there is any problem
|
||||
* when compiling the shader, then the node will draw pink. You should use
|
||||
* gsk_gl_shader_compile() to ensure the @shader will work for the
|
||||
* renderer before using it.
|
||||
*
|
||||
* Returns: (transfer full) (type GskGLShaderNode): A new #GskRenderNode
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_gl_shader_node_new (GskGLShader *shader,
|
||||
const graphene_rect_t *bounds,
|
||||
GBytes *args,
|
||||
GskRenderNode **children,
|
||||
guint n_children)
|
||||
{
|
||||
GskGLShaderNode *self;
|
||||
GskRenderNode *node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_SHADER (shader), NULL);
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
g_return_val_if_fail ((args == NULL && gsk_gl_shader_get_n_uniforms (shader) == 0) ||
|
||||
(args != NULL && g_bytes_get_size (args) == gsk_gl_shader_get_args_size (shader)), NULL);
|
||||
g_return_val_if_fail ((children == NULL && n_children == 0) ||
|
||||
(children != NULL && n_children == gsk_gl_shader_get_n_textures (shader)), 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);
|
||||
|
||||
self->args = g_bytes_ref (args);
|
||||
|
||||
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_n_children:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
*
|
||||
* Returns the number of 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 children.
|
||||
*
|
||||
* Returns: (transfer none): the @idx'th child of @node
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_gl_shader_node_get_child (GskRenderNode *node,
|
||||
guint 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_args:
|
||||
* @node: (type GskGLShaderNode): a #GskRenderNode for a gl shader
|
||||
*
|
||||
* Gets args for the node.
|
||||
*
|
||||
* Returns: (transfer none): A #GBytes with the uniform arguments
|
||||
*/
|
||||
GBytes *
|
||||
gsk_gl_shader_node_get_args (GskRenderNode *node)
|
||||
{
|
||||
GskGLShaderNode *self = (GskGLShaderNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_GL_SHADER_NODE), NULL);
|
||||
|
||||
return self->args;
|
||||
}
|
||||
|
||||
GType gsk_render_node_types[GSK_RENDER_NODE_TYPE_N_TYPES];
|
||||
|
||||
#ifndef I_
|
||||
@ -4506,6 +4709,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 +5067,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,209 @@ 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;
|
||||
GskShaderArgsBuilder *args;
|
||||
} ShaderInfo;
|
||||
|
||||
static void
|
||||
clear_shader_info (gpointer data)
|
||||
{
|
||||
ShaderInfo *info = data;
|
||||
g_clear_object (&info->shader);
|
||||
g_clear_pointer (&info->args, gsk_shader_args_builder_unref);
|
||||
}
|
||||
|
||||
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,
|
||||
int idx,
|
||||
ShaderInfo *shader_info)
|
||||
{
|
||||
switch (gsk_gl_shader_get_uniform_type (shader_info->shader, idx))
|
||||
{
|
||||
case GSK_GL_UNIFORM_TYPE_FLOAT:
|
||||
{
|
||||
double f;
|
||||
if (!gtk_css_parser_consume_number (parser, &f))
|
||||
return FALSE;
|
||||
gsk_shader_args_builder_set_float (shader_info->args, idx, f);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_INT:
|
||||
{
|
||||
int i;
|
||||
if (!gtk_css_parser_consume_integer (parser, &i))
|
||||
return FALSE;
|
||||
gsk_shader_args_builder_set_int (shader_info->args, idx, i);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_UINT:
|
||||
{
|
||||
int i;
|
||||
if (!gtk_css_parser_consume_integer (parser, &i) || i < 0)
|
||||
return FALSE;
|
||||
gsk_shader_args_builder_set_uint (shader_info->args, idx, i);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_BOOL:
|
||||
{
|
||||
int i;
|
||||
if (!gtk_css_parser_consume_integer (parser, &i) || (i != 0 && i != 1))
|
||||
return FALSE;
|
||||
gsk_shader_args_builder_set_bool (shader_info->args, idx, i);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_VEC2:
|
||||
{
|
||||
double f0, f1;
|
||||
graphene_vec2_t v;
|
||||
if (!gtk_css_parser_consume_number (parser, &f0) ||
|
||||
!gtk_css_parser_consume_number (parser, &f1))
|
||||
return FALSE;
|
||||
graphene_vec2_init (&v, f0, f1);
|
||||
gsk_shader_args_builder_set_vec2 (shader_info->args, idx, &v);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_VEC3:
|
||||
{
|
||||
double f0, f1, f2;
|
||||
graphene_vec3_t v;
|
||||
if (!gtk_css_parser_consume_number (parser, &f0) ||
|
||||
!gtk_css_parser_consume_number (parser, &f1) ||
|
||||
!gtk_css_parser_consume_number (parser, &f2))
|
||||
return FALSE;
|
||||
graphene_vec3_init (&v, f0, f1, f2);
|
||||
gsk_shader_args_builder_set_vec3 (shader_info->args, idx, &v);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_VEC4:
|
||||
{
|
||||
double f0, f1, f2, f3;
|
||||
graphene_vec4_t v;
|
||||
if (!gtk_css_parser_consume_number (parser, &f0) ||
|
||||
!gtk_css_parser_consume_number (parser, &f1) ||
|
||||
!gtk_css_parser_consume_number (parser, &f2) ||
|
||||
!gtk_css_parser_consume_number (parser, &f3))
|
||||
return FALSE;
|
||||
graphene_vec4_init (&v, f0, f1, f2, f3);
|
||||
gsk_shader_args_builder_set_vec4 (shader_info->args, idx, &v);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx < gsk_gl_shader_get_n_uniforms (shader_info->shader))
|
||||
{
|
||||
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_shader_args (GtkCssParser *parser, gpointer data)
|
||||
{
|
||||
ShaderInfo *shader_info = data;
|
||||
int n_uniforms;
|
||||
int i;
|
||||
|
||||
shader_info->args = gsk_shader_args_builder_new (shader_info->shader, NULL);
|
||||
n_uniforms = gsk_gl_shader_get_n_uniforms (shader_info->shader);
|
||||
|
||||
for (i = 0; i < n_uniforms; i++)
|
||||
{
|
||||
if (!parse_uniform_value (parser, i, shader_info))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
parse_glshader_node (GtkCssParser *parser)
|
||||
{
|
||||
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 50, 50);
|
||||
GskRenderNode *child[4] = { NULL, };
|
||||
ShaderInfo shader_info = {
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
const Declaration declarations[] = {
|
||||
{ "bounds", parse_rect, NULL, &bounds },
|
||||
{ "sourcecode", parse_shader, NULL, &shader_info },
|
||||
{ "args", parse_shader_args, clear_shader_info, &shader_info },
|
||||
{ "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;
|
||||
GBytes *args = 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;
|
||||
args = gsk_shader_args_builder_free_to_args (shader_info.args);
|
||||
|
||||
node = gsk_gl_shader_node_new (shader, &bounds, args, child, len);
|
||||
|
||||
g_bytes_unref (args);
|
||||
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 +1806,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;
|
||||
@ -1914,6 +2118,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);
|
||||
_gtk_css_print_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 +2657,124 @@ render_node_print (Printer *p,
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_SHADER_NODE:
|
||||
{
|
||||
GskGLShader *shader = gsk_gl_shader_node_get_shader (node);
|
||||
GBytes *args = gsk_gl_shader_node_get_args (node);
|
||||
|
||||
start_node (p, "glshader");
|
||||
|
||||
append_rect_param (p, "bounds", &node->bounds);
|
||||
|
||||
GBytes *bytes = gsk_gl_shader_get_source (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_GL_UNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_FLOAT:
|
||||
{
|
||||
float value = gsk_gl_shader_get_arg_float (shader, args, i);
|
||||
string_append_double (data, value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_INT:
|
||||
{
|
||||
gint32 value = gsk_gl_shader_get_arg_int (shader, args, i);
|
||||
g_string_append_printf (data, "%d", value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_UINT:
|
||||
{
|
||||
guint32 value = gsk_gl_shader_get_arg_uint (shader, args, i);
|
||||
g_string_append_printf (data, "%u", value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_BOOL:
|
||||
{
|
||||
gboolean value = gsk_gl_shader_get_arg_bool (shader, args, i);
|
||||
g_string_append_printf (data, "%d", value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_VEC2:
|
||||
{
|
||||
graphene_vec2_t value;
|
||||
gsk_gl_shader_get_arg_vec2 (shader, args, 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_GL_UNIFORM_TYPE_VEC3:
|
||||
{
|
||||
graphene_vec3_t value;
|
||||
gsk_gl_shader_get_arg_vec3 (shader, args, 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_GL_UNIFORM_TYPE_VEC4:
|
||||
{
|
||||
graphene_vec4_t value;
|
||||
gsk_gl_shader_get_arg_vec4 (shader, args, 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, "args: %s;\n", data->str);
|
||||
g_string_free (data, TRUE);
|
||||
}
|
||||
|
||||
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_new (GDK_TYPE_PAINTABLE);
|
||||
|
||||
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 *args = gsk_gl_shader_node_get_args (node);
|
||||
int i;
|
||||
|
||||
add_int_row (store, "Required textures", gsk_gl_shader_get_n_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_GL_UNIFORM_TYPE_NONE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_FLOAT:
|
||||
add_float_row (store, title,
|
||||
gsk_gl_shader_get_arg_float (shader, args, i));
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_INT:
|
||||
add_int_row (store, title,
|
||||
gsk_gl_shader_get_arg_int (shader, args, i));
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_UINT:
|
||||
add_uint_row (store, title,
|
||||
gsk_gl_shader_get_arg_uint (shader, args, i));
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_BOOL:
|
||||
add_boolean_row (store, title,
|
||||
gsk_gl_shader_get_arg_bool (shader, args, i));
|
||||
break;
|
||||
|
||||
case GSK_GL_UNIFORM_TYPE_VEC2:
|
||||
{
|
||||
graphene_vec2_t v;
|
||||
gsk_gl_shader_get_arg_vec2 (shader, args, 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_GL_UNIFORM_TYPE_VEC3:
|
||||
{
|
||||
graphene_vec3_t v;
|
||||
gsk_gl_shader_get_arg_vec3 (shader, args, 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_GL_UNIFORM_TYPE_VEC4:
|
||||
{
|
||||
graphene_vec4_t v;
|
||||
gsk_gl_shader_get_arg_vec4 (shader, args, 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);
|
||||
|
Loading…
Reference in New Issue
Block a user