#include "config.h"
#include "gskgpuimageprivate.h"
typedef struct _GskGpuImagePrivate GskGpuImagePrivate;
struct _GskGpuImagePrivate
{
GskGpuImageFlags flags;
GskGpuConversion conversion;
GdkShaderOp shader_op;
GdkMemoryFormat format;
gsize width;
gsize height;
};
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuImage, gsk_gpu_image, G_TYPE_OBJECT)
static void
gsk_gpu_image_get_default_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
graphene_matrix_init_ortho (out_projection,
0 , priv->width,
0 , priv->height,
ORTHO_NEAR_PLANE,
ORTHO_FAR_PLANE);
}
static void
gsk_gpu_image_texture_toggle_ref_cb (gpointer texture,
GObject *image,
gboolean is_last_ref)
{
if (is_last_ref)
g_object_unref (texture);
else
g_object_ref (texture);
}
static void
gsk_gpu_image_dispose (GObject *object)
{
GskGpuImage *self = GSK_GPU_IMAGE (object);
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
if (priv->flags & GSK_GPU_IMAGE_TOGGLE_REF)
{
priv->flags &= ~GSK_GPU_IMAGE_TOGGLE_REF;
G_OBJECT (self)->ref_count++;
g_object_remove_toggle_ref (G_OBJECT (self), gsk_gpu_image_texture_toggle_ref_cb, NULL);
}
G_OBJECT_CLASS (gsk_gpu_image_parent_class)->dispose (object);
}
static void
gsk_gpu_image_class_init (GskGpuImageClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gsk_gpu_image_dispose;
klass->get_projection_matrix = gsk_gpu_image_get_default_projection_matrix;
}
static void
gsk_gpu_image_init (GskGpuImage *self)
{
}
void
gsk_gpu_image_setup (GskGpuImage *self,
GskGpuImageFlags flags,
GskGpuConversion conversion,
GdkShaderOp shader_op,
GdkMemoryFormat format,
gsize width,
gsize height)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
priv->flags = flags;
priv->format = format;
priv->conversion = conversion;
priv->shader_op = shader_op;
priv->width = width;
priv->height = height;
}
/*
* gsk_gpu_image_toggle_ref_texture :
* @ self : a GskGpuImage
* @ texture : the texture owning @ self
*
* This function must be called whenever the texture owns the data
* used by the image . It will then add a toggle ref , so that ref ' ing
* the image will ref the texture and unrefing the image will unref it
* again .
*
* This ensures that whenever the image is used , the texture will keep
* being referenced and not go away . But once all the image ' s references
* get unref ' ed , the texture is free to go away .
**/
void
gsk_gpu_image_toggle_ref_texture (GskGpuImage *self,
GdkTexture *texture)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
g_assert ((priv->flags & GSK_GPU_IMAGE_TOGGLE_REF) == 0 );
priv->flags |= GSK_GPU_IMAGE_TOGGLE_REF;
g_object_ref (texture);
g_object_add_toggle_ref (G_OBJECT (self), gsk_gpu_image_texture_toggle_ref_cb, texture);
g_object_unref (self);
}
GdkMemoryFormat
gsk_gpu_image_get_format (GskGpuImage *self)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
return priv->format;
}
gsize
gsk_gpu_image_get_width (GskGpuImage *self)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
return priv->width;
}
gsize
gsk_gpu_image_get_height (GskGpuImage *self)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
return priv->height;
}
GskGpuImageFlags
gsk_gpu_image_get_flags (GskGpuImage *self)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
return priv->flags;
}
/*<private>
* gsk_gpu_image_get_conversion :
* @ self : the image
*
* Returns the conversion applied by the image between the actual raw
* image data and the way it ' s read in shaders / framebuffers .
*
* Returns : the conversion
**/
GskGpuConversion
gsk_gpu_image_get_conversion (GskGpuImage *self)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
return priv->conversion;
}
GdkShaderOp
gsk_gpu_image_get_shader_op (GskGpuImage *self)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
return priv->shader_op;
}
void
gsk_gpu_image_set_flags (GskGpuImage *self,
GskGpuImageFlags flags)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
priv->flags |= flags;
}
void
gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection)
{
GSK_GPU_IMAGE_GET_CLASS (self)->get_projection_matrix (self, out_projection);
}
gboolean
gsk_gpu_image_supports_sampler (GskGpuImage *self,
GskGpuSampler sampler)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
switch (sampler)
{
case GSK_GPU_SAMPLER_NEAREST:
if (priv->shader_op != GDK_SHADER_DEFAULT)
return FALSE ;
return TRUE ;
case GSK_GPU_SAMPLER_DEFAULT:
case GSK_GPU_SAMPLER_REPEAT:
case GSK_GPU_SAMPLER_REFLECT:
return (priv->flags & GSK_GPU_IMAGE_FILTERABLE) != 0 ;
case GSK_GPU_SAMPLER_TRANSPARENT:
if (gdk_memory_format_alpha (priv->format) == GDK_MEMORY_ALPHA_OPAQUE)
return FALSE ;
return (priv->flags & GSK_GPU_IMAGE_FILTERABLE) != 0 ;
case GSK_GPU_SAMPLER_MIPMAP_DEFAULT:
/* Our mipmap algorithm can't deal with this */
if (priv->shader_op != GDK_SHADER_DEFAULT)
return FALSE ;
return (priv->flags & (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_FILTERABLE)) ==
(GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_FILTERABLE);
case GSK_GPU_SAMPLER_N_SAMPLERS:
default :
g_return_val_if_reached (FALSE );
}
}
Messung V0.5 in Prozent C=99 H=98 G=98
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland