[Cogl] [PATCH 4/5] examples/cogl-x11-tfp: Add a --gears option to run glxgears
otaylor at redhat.com
otaylor at redhat.com
Thu Jul 3 10:51:11 PDT 2014
From: "Owen W. Taylor" <otaylor at fishsoup.net>
If --gears is passed on the command line, glxgears is run, and
is used for the source window rather than drawing solid rectangles
into a window we create outselves.
---
examples/cogl-x11-tfp.c | 193 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 167 insertions(+), 26 deletions(-)
diff --git a/examples/cogl-x11-tfp.c b/examples/cogl-x11-tfp.c
index 6a24b27..ea0a0b0 100644
--- a/examples/cogl-x11-tfp.c
+++ b/examples/cogl-x11-tfp.c
@@ -3,9 +3,14 @@
#include <cogl/winsys/cogl-texture-pixmap-x11.h>
#include <glib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
@@ -19,6 +24,84 @@
#define TFP_XWIN_WIDTH 200
#define TFP_XWIN_HEIGHT 200
+static pid_t gears_pid = 0;
+
+static void
+spawn_gears (void)
+{
+ pid_t pid = fork();
+
+ if (pid == 0)
+ execlp ("glxgears", "glxgears",
+ NULL);
+
+ gears_pid = pid;
+}
+
+static XID
+find_gears_toplevel (Display *xdpy,
+ Window window)
+{
+ Atom window_state = XInternAtom (xdpy, "WM_STATE", False);
+ Atom type;
+ int format;
+ unsigned long n_items;
+ unsigned long bytes_after;
+ unsigned char *data;
+ CoglBool result = FALSE;
+
+ if (window == None)
+ window = DefaultRootWindow (xdpy);
+
+ XGetWindowProperty (xdpy, window, window_state,
+ 0, G_MAXLONG, False, window_state,
+ &type, &format, &n_items, &bytes_after, &data);
+
+ if (type == window_state)
+ {
+ XFree (data);
+
+ XGetWindowProperty (xdpy, window, XA_WM_NAME,
+ 0, G_MAXLONG, False, XA_STRING,
+ &type, &format, &n_items, &bytes_after, &data);
+
+ if (type == XA_STRING)
+ {
+ if (format == 8 && strcmp ((char *)data, "glxgears") == 0)
+ result = window;
+
+ XFree (data);
+ }
+ }
+ else
+ {
+ Window root, parent;
+ Window *children;
+ unsigned int n_children;
+ unsigned int i;
+
+ XQueryTree (xdpy, window,
+ &root, &parent, &children, &n_children);
+
+ for (i = 0; i < n_children; i++)
+ {
+ result = find_gears_toplevel (xdpy, children[i]);
+ if (result != None)
+ break;
+ }
+
+ XFree (children);
+ }
+
+ return result;
+}
+
+static void
+kill_gears (void)
+{
+ kill (gears_pid, SIGTERM);
+}
+
static void
update_cogl_x11_event_mask (CoglOnscreen *onscreen,
uint32_t event_mask,
@@ -59,10 +142,24 @@ main (int argc, char **argv)
Atom atom_wm_protocols;
Atom atom_wm_delete_window;
int screen;
- Window tfp_xwin;
+ CoglBool gears = FALSE;
+ Window tfp_xwin = None;
Pixmap pixmap;
CoglTexturePixmapX11 *tfp;
- GC gc;
+ CoglTexture *right_texture;
+ GC gc = None;
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--gears") == 0)
+ gears = TRUE;
+ else
+ {
+ g_printerr ("Usage: cogl-x11-tfp [--gears]\n");
+ return 1;
+ }
+ }
g_print ("NB: Don't use this example as a benchmark since there is "
"no synchonization between X window updates and onscreen "
@@ -89,6 +186,19 @@ main (int argc, char **argv)
}
}
+ if (gears)
+ {
+ spawn_gears ();
+ while (TRUE)
+ {
+ tfp_xwin = find_gears_toplevel (xdpy, None);
+ if (tfp_xwin != None)
+ break;
+
+ g_usleep (10000);
+ }
+ }
+
/* Conceptually choose a GPU... */
renderer = cogl_renderer_new ();
/* FIXME: This should conceptually be part of the configuration of
@@ -101,13 +211,15 @@ main (int argc, char **argv)
}
chain = cogl_swap_chain_new ();
- cogl_swap_chain_set_has_alpha (chain, TRUE);
+ cogl_swap_chain_set_has_alpha (chain, FALSE);
/* Conceptually declare upfront the kinds of windows we anticipate
* creating so that when we configure the display pipeline we can avoid
* having an impedance miss-match between the format of windows and the
* format the display pipeline expects. */
onscreen_template = cogl_onscreen_template_new (chain);
+ if (stereo)
+ cogl_onscreen_template_set_stereo_enabled (onscreen_template, TRUE);
cogl_object_unref (chain);
/* Conceptually setup a display pipeline */
@@ -173,25 +285,37 @@ main (int argc, char **argv)
xdpy);
XMapWindow (xdpy, xwin);
-
- XCompositeRedirectSubwindows (xdpy, xwin, CompositeRedirectManual);
+ cogl_onscreen_show (onscreen);
screen = DefaultScreen (xdpy);
- tfp_xwin = XCreateSimpleWindow (xdpy, xwin,
- 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT,
- 0,
- WhitePixel (xdpy, screen),
- WhitePixel (xdpy, screen));
- XMapWindow (xdpy, tfp_xwin);
-
- gc = XCreateGC (xdpy, tfp_xwin, 0, NULL);
- while (TRUE)
+ if (gears)
{
- XWindowEvent (xdpy, xwin, StructureNotifyMask, &xev);
+ XCompositeRedirectWindow (xdpy, tfp_xwin, CompositeRedirectAutomatic);
+ }
+ else
+ {
+ XEvent xev;
+
+ XCompositeRedirectSubwindows (xdpy, xwin, CompositeRedirectManual);
- if (xev.xany.type == MapNotify)
- break;
+ tfp_xwin = XCreateSimpleWindow (xdpy, xwin,
+ 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT,
+ 0,
+ WhitePixel (xdpy, screen),
+ WhitePixel (xdpy, screen));
+
+ XMapWindow (xdpy, tfp_xwin);
+
+ while (TRUE)
+ {
+ XWindowEvent (xdpy, xwin, StructureNotifyMask, &xev);
+
+ if (xev.xany.type == MapNotify)
+ break;
+ }
+
+ gc = XCreateGC (xdpy, tfp_xwin, 0, NULL);
}
pixmap = XCompositeNameWindowPixmap (xdpy, tfp_xwin);
@@ -221,7 +345,7 @@ main (int argc, char **argv)
case KeyRelease:
keysym = XLookupKeysym (&event.xkey, 0);
if (keysym == XK_q || keysym == XK_Q || keysym == XK_Escape)
- return 0;
+ goto out;
break;
case ClientMessage:
if (event.xclient.message_type == atom_wm_protocols &&
@@ -232,22 +356,39 @@ main (int argc, char **argv)
cogl_xlib_renderer_handle_event (renderer, &event);
}
- pixel =
- g_random_int_range (0, 255) << 24 |
- g_random_int_range (0, 255) << 16 |
- g_random_int_range (0, 255) << 8;
- g_random_int_range (0, 255);
- XSetForeground (xdpy, gc, pixel);
- XFillRectangle (xdpy, tfp_xwin, gc, 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT);
- XFlush (xdpy);
+ if (!gears)
+ {
+ pixel =
+ g_random_int_range (0, 255) << 24 |
+ g_random_int_range (0, 255) << 16 |
+ g_random_int_range (0, 255) << 8;
+ g_random_int_range (0, 255);
+ XSetForeground (xdpy, gc, pixel);
+ XFillRectangle (xdpy, tfp_xwin, gc, 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT);
+ XFlush (xdpy);
+ }
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
+
pipeline = cogl_pipeline_new (ctx);
+
+ cogl_framebuffer_set_stereo_mode (onscreen, COGL_STEREO_LEFT);
cogl_pipeline_set_layer_texture (pipeline, 0, tfp);
cogl_framebuffer_draw_rectangle (fb, pipeline, -0.8, 0.8, 0.8, -0.8);
+
+ if (stereo)
+ {
+ cogl_framebuffer_set_stereo_mode (onscreen, COGL_STEREO_RIGHT);
+ cogl_pipeline_set_layer_texture (pipeline, 0, right_texture);
+ cogl_framebuffer_draw_rectangle (fb, pipeline, -0.8, 0.8, 0.8, -0.8);
+ }
+
cogl_object_unref (pipeline);
+
cogl_onscreen_swap_buffers (onscreen);
}
+ out:
+ kill_gears ();
return 0;
}
--
1.9.3
More information about the Cogl
mailing list