#include "config.h"
#include "gskglrenderer.h"
#include "gskgpuimageprivate.h"
#include "gskgpurendererprivate.h"
#include "gskgldeviceprivate.h"
#include "gskglframeprivate.h"
#include "gskglimageprivate.h"
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkdmabufeglprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include <glib/gi18n-lib.h>
/**
* GskGLRenderer :
*
* Renders a GSK rendernode tree with OpenGL .
*
* See [ class @ Gsk . Renderer ] .
*
* Since : 4 . 2
*/
struct _GskGLRenderer
{
GskGpuRenderer parent_instance;
};
struct _GskGLRendererClass
{
GskGpuRendererClass parent_class;
};
G_DEFINE_TYPE (GskGLRenderer, gsk_gl_renderer, GSK_TYPE_GPU_RENDERER)
static GdkDrawContext *
gsk_gl_renderer_create_context (GskGpuRenderer *renderer,
GdkDisplay *display,
GdkSurface *surface,
GskGpuOptimizations *supported,
GError **error)
{
GdkGLContext *context;
if (!gdk_display_prepare_gl (display, error))
return NULL;
context = gdk_gl_context_new (display, surface, surface != NULL);
if (!gdk_gl_context_realize (context, error))
{
g_object_unref (context);
return NULL;
}
gdk_gl_context_make_current (context);
if (!gdk_gl_context_check_version (context, "3.3" , "0.0" ))
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("OpenGL 3.3 required" ));
g_object_unref (context);
return NULL;
}
*supported = ~GSK_GPU_OPTIMIZE_PROFILE;
if (!gdk_gl_context_has_feature (context, GDK_GL_FEATURE_BLEND_FUNC_EXTENDED))
*supported &= ~GSK_GPU_OPTIMIZE_DUAL_BLEND;
return GDK_DRAW_CONTEXT (context);
}
static void
gsk_gl_renderer_make_current (GskGpuRenderer *renderer)
{
gdk_gl_context_make_current (GDK_GL_CONTEXT (gsk_gpu_renderer_get_context (renderer)));
}
static gpointer
gsk_gl_renderer_save_current (GskGpuRenderer *renderer)
{
GdkGLContext *current;
current = gdk_gl_context_get_current ();
if (current)
g_object_ref (current);
return current;
}
static void
gsk_gl_renderer_restore_current (GskGpuRenderer *renderer,
gpointer current)
{
if (current)
{
gdk_gl_context_make_current (current);
g_object_unref (current);
}
else
gdk_gl_context_clear_current ();
}
static GskGpuImage *
gsk_gl_renderer_get_backbuffer (GskGpuRenderer *renderer)
{
GdkDrawContext *context;
GdkSurface *surface;
guint width, height;
context = gsk_gpu_renderer_get_context (renderer);
surface = gdk_draw_context_get_surface (context);
gdk_draw_context_get_buffer_size (context, &width, &height);
return gsk_gl_image_new_backbuffer (GSK_GL_DEVICE (gsk_gpu_renderer_get_device (renderer)),
GDK_GL_CONTEXT (context),
GDK_MEMORY_DEFAULT /* FIXME */,
gdk_surface_get_gl_is_srgb (surface),
width,
height);
}
static void
gsk_gl_renderer_unrealize (GskRenderer *renderer)
{
gdk_gl_context_clear_current ();
GSK_RENDERER_CLASS (gsk_gl_renderer_parent_class)->unrealize (renderer);
}
static void
gsk_gl_renderer_class_init (GskGLRendererClass *klass)
{
GskGpuRendererClass *gpu_renderer_class = GSK_GPU_RENDERER_CLASS (klass);
GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass);
gpu_renderer_class->frame_type = GSK_TYPE_GL_FRAME;
gpu_renderer_class->profile_frame_type = GSK_TYPE_GL_FRAME; /* unused */
gpu_renderer_class->get_device = gsk_gl_device_get_for_display;
gpu_renderer_class->create_context = gsk_gl_renderer_create_context;
gpu_renderer_class->make_current = gsk_gl_renderer_make_current;
gpu_renderer_class->save_current = gsk_gl_renderer_save_current;
gpu_renderer_class->restore_current = gsk_gl_renderer_restore_current;
gpu_renderer_class->get_backbuffer = gsk_gl_renderer_get_backbuffer;
renderer_class->unrealize = gsk_gl_renderer_unrealize;
}
static void
gsk_gl_renderer_init (GskGLRenderer *self)
{
}
/**
* gsk_gl_renderer_new :
*
* Creates an instance of the GL renderer .
*
* Returns : ( transfer full ) : a GL renderer
*/
GskRenderer *
gsk_gl_renderer_new (void )
{
return g_object_new (GSK_TYPE_GL_RENDERER, NULL);
}
/**
* GskNglRenderer :
*
* A GL based renderer .
*
* See [ class @ Gsk . Renderer ] .
*/
typedef struct {
GskRenderer parent_instance;
} GskNglRenderer;
typedef struct {
GskRendererClass parent_class;
} GskNglRendererClass;
G_DEFINE_TYPE (GskNglRenderer, gsk_ngl_renderer, GSK_TYPE_RENDERER)
static void
gsk_ngl_renderer_init (GskNglRenderer *renderer)
{
}
static gboolean
gsk_ngl_renderer_realize (GskRenderer *renderer,
GdkDisplay *display,
GdkSurface *surface,
gboolean attach,
GError **error)
{
g_set_error_literal (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"Please use the GL renderer instead" );
return FALSE ;
}
static void
gsk_ngl_renderer_class_init (GskNglRendererClass *class )
{
GSK_RENDERER_CLASS (class )->realize = gsk_ngl_renderer_realize;
}
/**
* gsk_ngl_renderer_new :
*
* Same as gsk_gl_renderer_new ( ) .
*
* Returns : ( transfer full ) : a GL renderer
*
* Deprecated : 4 . 18 : Use gsk_gl_renderer_new ( )
*/
GskRenderer *
gsk_ngl_renderer_new (void )
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
return g_object_new (gsk_ngl_renderer_get_type (), NULL);
G_GNUC_END_IGNORE_DEPRECATIONS
}
Messung V0.5 in Prozent C=98 H=89 G=93
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland