264 lines
7.5 KiB
Diff
264 lines
7.5 KiB
Diff
|
From c07813452c658f1f441b104fbe836380a6ddd18d Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
|
||
|
Date: Sun, 4 Aug 2019 01:22:01 +0200
|
||
|
Subject: [PATCH 2/3] Port sdl-display to SDL2
|
||
|
|
||
|
The SDL2 Video API is split into several orthogonal parts, see
|
||
|
https://wiki.libsdl.org/MigrationGuide#Video.
|
||
|
|
||
|
Fixes half of #184
|
||
|
---
|
||
|
operations/common/display.c | 1 +
|
||
|
operations/external/Makefile.am | 6 +
|
||
|
operations/external/sdl2-display.c | 209 +++++++++++++++++++++++++++++
|
||
|
3 files changed, 216 insertions(+)
|
||
|
create mode 100644 operations/external/sdl2-display.c
|
||
|
|
||
|
diff --git a/operations/common/display.c b/operations/common/display.c
|
||
|
index 826ae4caa..9e06f1eb5 100644
|
||
|
--- a/operations/common/display.c
|
||
|
+++ b/operations/common/display.c
|
||
|
@@ -60,6 +60,7 @@ set_display_handler (GeglOperation *operation)
|
||
|
GeglOp *self = GEGL_OP (operation);
|
||
|
const gchar *known_handlers[] = {"gegl-gtk3:display",
|
||
|
"gegl-gtk2:display",
|
||
|
+ "gegl:sdl2-display",
|
||
|
"gegl:sdl-display"};
|
||
|
char *handler = NULL;
|
||
|
gchar **operations = NULL;
|
||
|
diff --git a/operations/external/Makefile.am b/operations/external/Makefile.am
|
||
|
index 498ffb062..719698401 100644
|
||
|
--- a/operations/external/Makefile.am
|
||
|
+++ b/operations/external/Makefile.am
|
||
|
@@ -81,6 +81,12 @@ exr_save_la_LIBADD = $(op_libs) $(OPENEXR_LIBS)
|
||
|
exr_save_la_CXXFLAGS = $(AM_CFLAGS) $(OPENEXR_CFLAGS)
|
||
|
endif
|
||
|
|
||
|
+if HAVE_SDL2
|
||
|
+ops += sdl2-display.la
|
||
|
+sdl2_display_la_LIBADD = $(op_libs) $(SDL2_LIBS)
|
||
|
+sdl2_display_la_CFLAGS = $(AM_CFLAGS) $(SDL2_CFLAGS)
|
||
|
+endif
|
||
|
+
|
||
|
if HAVE_SDL
|
||
|
ops += sdl-display.la
|
||
|
sdl_display_la_LIBADD = $(op_libs) $(SDL_LIBS)
|
||
|
diff --git a/operations/external/sdl2-display.c b/operations/external/sdl2-display.c
|
||
|
new file mode 100644
|
||
|
index 000000000..a3bab50a5
|
||
|
--- /dev/null
|
||
|
+++ b/operations/external/sdl2-display.c
|
||
|
@@ -0,0 +1,209 @@
|
||
|
+/* This file is an image processing operation for GEGL
|
||
|
+ *
|
||
|
+ * GEGL 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 3 of the License, or (at your option) any later version.
|
||
|
+ *
|
||
|
+ * GEGL 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 GEGL; if not, see <https://www.gnu.org/licenses/>.
|
||
|
+ *
|
||
|
+ * Copyright 2019 Stefan Brüns <stefan.bruens@rwth-aachen.de>
|
||
|
+ *
|
||
|
+ * Based on sdl-display.c:
|
||
|
+ * Copyright 2006 Øyvind Kolås <pippin@gimp.org>
|
||
|
+ */
|
||
|
+
|
||
|
+#include "config.h"
|
||
|
+#include <glib/gi18n-lib.h>
|
||
|
+
|
||
|
+
|
||
|
+#ifdef GEGL_PROPERTIES
|
||
|
+
|
||
|
+property_string (window_title, _("Window title"), "window_title")
|
||
|
+ description (_("Title to be given to output window"))
|
||
|
+#else
|
||
|
+
|
||
|
+#define GEGL_OP_SINK
|
||
|
+#define GEGL_OP_NAME sdl2_display
|
||
|
+#define GEGL_OP_C_SOURCE sdl2-display.c
|
||
|
+
|
||
|
+#include "gegl-op.h"
|
||
|
+#include <SDL.h>
|
||
|
+
|
||
|
+typedef struct {
|
||
|
+ SDL_Window *window;
|
||
|
+ SDL_Renderer *renderer;
|
||
|
+ SDL_Texture *texture;
|
||
|
+ SDL_Surface *screen;
|
||
|
+ gint width;
|
||
|
+ gint height;
|
||
|
+} SDLState;
|
||
|
+
|
||
|
+static void
|
||
|
+init_sdl (void)
|
||
|
+{
|
||
|
+ static int inited = 0;
|
||
|
+
|
||
|
+ if (!inited)
|
||
|
+ {
|
||
|
+ inited = 1;
|
||
|
+
|
||
|
+ if (SDL_Init (SDL_INIT_VIDEO) < 0)
|
||
|
+ {
|
||
|
+ fprintf (stderr, "Unable to init SDL: %s\n", SDL_GetError ());
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ atexit (SDL_Quit);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean idle (gpointer data)
|
||
|
+{
|
||
|
+ SDL_Event event;
|
||
|
+ while (SDL_PollEvent (&event))
|
||
|
+ {
|
||
|
+ switch (event.type)
|
||
|
+ {
|
||
|
+ case SDL_QUIT:
|
||
|
+ exit (0);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
+static guint handle = 0;
|
||
|
+
|
||
|
+static gboolean
|
||
|
+process (GeglOperation *operation,
|
||
|
+ GeglBuffer *input,
|
||
|
+ const GeglRectangle *result,
|
||
|
+ gint level)
|
||
|
+{
|
||
|
+ GeglProperties *o = GEGL_PROPERTIES (operation);
|
||
|
+ SDLState *state = NULL;
|
||
|
+
|
||
|
+ if(!o->user_data)
|
||
|
+ o->user_data = g_new0 (SDLState, 1);
|
||
|
+ state = o->user_data;
|
||
|
+
|
||
|
+ init_sdl ();
|
||
|
+
|
||
|
+ if (!handle)
|
||
|
+ handle = g_timeout_add (500, idle, NULL);
|
||
|
+
|
||
|
+ if (!state->window ||
|
||
|
+ state->width != result->width ||
|
||
|
+ state->height != result->height)
|
||
|
+ {
|
||
|
+
|
||
|
+ if (state->window)
|
||
|
+ {
|
||
|
+ SDL_SetWindowSize (state->window,
|
||
|
+ result->width, result->height);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ if (SDL_CreateWindowAndRenderer (result->width,
|
||
|
+ result->height, 0,
|
||
|
+ &state->window, &state->renderer))
|
||
|
+ {
|
||
|
+ fprintf (stderr, "Unable to create window: %s\n",
|
||
|
+ SDL_GetError ());
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ SDL_FreeSurface (state->screen);
|
||
|
+ state->screen = SDL_CreateRGBSurfaceWithFormat (0,
|
||
|
+ result->width, result->height, 32, SDL_PIXELFORMAT_RGBA32);
|
||
|
+ if (!state->screen)
|
||
|
+ {
|
||
|
+ fprintf (stderr, "Unable to create surface: %s\n",
|
||
|
+ SDL_GetError ());
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (state->texture)
|
||
|
+ SDL_DestroyTexture (state->texture);
|
||
|
+ state->texture = SDL_CreateTextureFromSurface (state->renderer, state->screen);
|
||
|
+ if (!state->texture)
|
||
|
+ {
|
||
|
+ fprintf (stderr, "Unable to create texture: %s\n",
|
||
|
+ SDL_GetError ());
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ state->width = result->width ;
|
||
|
+ state->height = result->height;
|
||
|
+ }
|
||
|
+
|
||
|
+ /*
|
||
|
+ * There seems to be a valid faster path to the SDL desired display format
|
||
|
+ * in B'G'R'A, perhaps babl should have been able to figure this out ito?
|
||
|
+ *
|
||
|
+ */
|
||
|
+ gegl_buffer_get (input,
|
||
|
+ NULL,
|
||
|
+ 1.0,
|
||
|
+ babl_format_new (babl_model ("R'G'B'A"),
|
||
|
+ babl_type ("u8"),
|
||
|
+ babl_component ("B'"),
|
||
|
+ babl_component ("G'"),
|
||
|
+ babl_component ("R'"),
|
||
|
+ babl_component ("A"),
|
||
|
+ NULL),
|
||
|
+ state->screen->pixels, GEGL_AUTO_ROWSTRIDE,
|
||
|
+ GEGL_ABYSS_NONE);
|
||
|
+
|
||
|
+ SDL_UpdateTexture (state->texture, NULL, state->screen->pixels, state->screen->pitch);
|
||
|
+
|
||
|
+ SDL_RenderClear (state->renderer);
|
||
|
+ SDL_RenderCopy (state->renderer, state->texture, NULL, NULL);
|
||
|
+ SDL_RenderPresent (state->renderer);
|
||
|
+ SDL_SetWindowTitle (state->window, o->window_title);
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+finalize (GObject *object)
|
||
|
+{
|
||
|
+ GeglProperties *o = GEGL_PROPERTIES (object);
|
||
|
+
|
||
|
+ g_clear_pointer (&o->user_data, g_free);
|
||
|
+
|
||
|
+ G_OBJECT_CLASS (gegl_op_parent_class)->finalize (object);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+gegl_op_class_init (GeglOpClass *klass)
|
||
|
+{
|
||
|
+ GObjectClass *object_class;
|
||
|
+ GeglOperationClass *operation_class;
|
||
|
+ GeglOperationSinkClass *sink_class;
|
||
|
+
|
||
|
+ object_class = G_OBJECT_CLASS (klass);
|
||
|
+ operation_class = GEGL_OPERATION_CLASS (klass);
|
||
|
+ sink_class = GEGL_OPERATION_SINK_CLASS (klass);
|
||
|
+
|
||
|
+ object_class->finalize = finalize;
|
||
|
+
|
||
|
+ sink_class->process = process;
|
||
|
+ sink_class->needs_full = TRUE;
|
||
|
+
|
||
|
+ gegl_operation_class_set_keys (operation_class,
|
||
|
+ "name", "gegl:sdl2-display",
|
||
|
+ "title", _("SDL2 Display"),
|
||
|
+ "categories", "display",
|
||
|
+ "description",
|
||
|
+ _("Displays the input buffer in an SDL2 window (restricted to one"
|
||
|
+ " display op/process, due to SDL2 implementation issues)."),
|
||
|
+ NULL);
|
||
|
+}
|
||
|
+#endif
|
||
|
--
|
||
|
2.22.0
|
||
|
|