[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