Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Gnome/gsk/   (Gnome Linux Desktop Version 4.23.2©)  Datei vom 30.5.2026 mit Größe 10 kB image not shown  

Quelle  gskglshadernode.c

  Sprache: C
 

/* 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/>.
 */


#include "config.h"

#include "gskglshadernode.h"

#include "gskcontainernodeprivate.h"
#include "gskrectprivate.h"
#include "gskrendernodeprivate.h"
#include "gskrenderreplay.h"

#include <gdk/gdkcairoprivate.h>

G_GNUC_BEGIN_IGNORE_DEPRECATIONS

/**
 * GskGLShaderNode:
 *
 * A render node using a GL shader when drawing its children nodes.
 */

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,
                         GskCairoData  *data)
{
  GdkRGBA pink = { 255 / 255., 105 / 255., 180 / 255., 1.0 };

  gdk_cairo_set_source_rgba_ccs (cr, data->ccs, &pink);
  gdk_cairo_rect (cr, &node->bounds);
  cairo_fill (cr);
}

static void
gsk_gl_shader_node_diff (GskRenderNode *node1,
                         GskRenderNode *node2,
                         GskDiffData   *data)
{
  GskGLShaderNode *self1 = (GskGLShaderNode *) node1;
  GskGLShaderNode *self2 = (GskGLShaderNode *) node2;

  if (gsk_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], &(GskDiffData) { child_region, data->copies, data->surface });
      if (!cairo_region_is_empty (child_region))
        gsk_render_node_diff_impossible (node1, node2, data);
      cairo_region_destroy (child_region);
    }
  else
    {
      gsk_render_node_diff_impossible (node1, node2, data);
    }
}

static GskRenderNode **
gsk_gl_shader_node_get_children (GskRenderNode *node,
                                 gsize         *n_children)
{
  GskGLShaderNode *self = (GskGLShaderNode *) node;

  *n_children = self->n_children;

  return self->children;
}

static GskRenderNode *
gsk_gl_shader_node_replay (GskRenderNode   *node,
                           GskRenderReplay *replay)
{
  GskGLShaderNode *self = (GskGLShaderNode *) node;
  GskRenderNode *result;
  GskRenderNode **children;
  gboolean changed, all_empty;
  guint i;

  children = g_new (GskRenderNode *, self->n_children);
  changed = FALSE;
  all_empty = TRUE;

  for (i = 0; i < self->n_children; i++)
    {
      children[i] = gsk_render_replay_filter_node (replay, self->children[i]);

      if (children[i] == NULL)
        children[i] = gsk_container_node_new (NULL, 0);
      else
        all_empty = FALSE;

      if (children[i] != self->children[i])
        changed = TRUE;
    }

  if (!changed)
    result = gsk_render_node_ref (node);
  else if (all_empty)
    result = NULL;
  else
    result = gsk_gl_shader_node_new (self->shader,
                                     &node->bounds,
                                     self->args,
                                     children,
                                     self->n_children);

  for (i = 0; i < self->n_children; i++)
    gsk_render_node_unref (children[i]);
  g_free (children);

  return result;
}

static void
gsk_gl_shader_node_class_init (gpointer g_class,
                               gpointer class_data)
{
  GskRenderNodeClass *node_class = g_class;

  node_class->node_type = GSK_GL_SHADER_NODE;

  node_class->finalize = gsk_gl_shader_node_finalize;
  node_class->draw = gsk_gl_shader_node_draw;
  node_class->diff = gsk_gl_shader_node_diff;
  node_class->get_children = gsk_gl_shader_node_get_children;
  node_class->replay = gsk_gl_shader_node_replay;
}

GSK_DEFINE_RENDER_NODE_TYPE (GskGLShaderNode, gsk_gl_shader_node)

/**
 * gsk_gl_shader_node_new:
 * @shader: the `GskGLShader`
 * @bounds: the rectangle to render the shader into
 * @args: Arguments for the uniforms
 * @children: (nullable) (array length=n_children): array of child nodes,
 *   these will be rendered to textures and used as input.
 * @n_children: Length of @children (currently 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
 * [method@Gsk.GLShader.format_args] or [struct@Gsk.ShaderArgsBuilder].
 *
 * See [class@Gsk.GLShader] 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
 * [method@Gsk.GLShader.compile] to ensure the @shader will work for the
 * renderer before using it.
 *
 * Returns: (transfer full) (type GskGLShaderNode): A new `GskRenderNode`
 *
 * Deprecated: 4.16: GTK's new Vulkan-focused rendering
 *   does not support this feature. Use [GtkGLArea](../gtk4/class.GLArea.html)
 *   for OpenGL rendering.
 */

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, NULL);
  g_return_val_if_fail (g_bytes_get_size (args) == gsk_gl_shader_get_args_size (shader), NULL);
  g_return_val_if_fail ((children == NULL && n_children == 0) ||
                        (n_children == gsk_gl_shader_get_n_textures (shader)), NULL);

  self = gsk_render_node_alloc (GSK_TYPE_GL_SHADER_NODE);
  node = (GskRenderNode *) self;
  node->preferred_depth = gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);

  gsk_rect_init_from_rect (&node->bounds, bounds);
  gsk_rect_normalize (&node->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]);
          node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
                                                          gsk_render_node_get_preferred_depth (children[i]));
          node->contains_subsurface_node |= gsk_render_node_contains_subsurface_node (children[i]);
          node->contains_paste_node |= gsk_render_node_contains_paste_node (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
 *
 * Deprecated: 4.16: GTK's new Vulkan-focused rendering
 *   does not support this feature. Use [GtkGLArea](../gtk4/class.GLArea.html)
 *   for OpenGL rendering.
 */

guint
gsk_gl_shader_node_get_n_children (const GskRenderNode *node)
{
  const GskGLShaderNode *self = (const GskGLShaderNode *) node;

  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
 *
 * Deprecated: 4.16: GTK's new Vulkan-focused rendering
 *   does not support this feature. Use [GtkGLArea](../gtk4/class.GLArea.html)
 *   for OpenGL rendering.
 */

GskRenderNode *
gsk_gl_shader_node_get_child (const GskRenderNode *node,
                              guint                idx)
{
  const GskGLShaderNode *self = (const GskGLShaderNode *) node;

  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
 *
 * Deprecated: 4.16
 */

GskGLShader *
gsk_gl_shader_node_get_shader (const GskRenderNode *node)
{
  const GskGLShaderNode *self = (const GskGLShaderNode *) node;

  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
 *
 * Deprecated: 4.16: GTK's new Vulkan-focused rendering
 *   does not support this feature. Use [GtkGLArea](../gtk4/class.GLArea.html)
 *   for OpenGL rendering.
 */

GBytes *
gsk_gl_shader_node_get_args (const GskRenderNode *node)
{
  const GskGLShaderNode *self = (const GskGLShaderNode *) node;

  return self->args;
}
G_GNUC_END_IGNORE_DEPRECATIONS

Messung V0.5 in Prozent
C=98 H=94 G=95

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-07-03) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.