File xscreensaver-consider-gltexture.diff of Package xscreensaver

# From: garloff@suse.de
# Subject: [4/4] Try GL format directly
# Look whether we got the pixmap directly in GL_RGBA format, so we
# don't need any conversion. GL also supports GL_BGRA, but that is
# slower than us doing the conversion manually.

Index: xscreensaver-5.22/hacks/glx/grab-ximage.c
===================================================================
--- xscreensaver-5.22.orig/hacks/glx/grab-ximage.c
+++ xscreensaver-5.22/hacks/glx/grab-ximage.c
@@ -429,9 +429,9 @@ pixmap_to_gl_ximage (Screen *screen, Win
   return client_ximage;
 }
 
 
-# else /* ! REFORMAT_IMAGE_DATA */
+# endif /* ! REFORMAT_IMAGE_DATA */
 
 typedef struct {
   unsigned int depth, red_mask, green_mask, blue_mask;	/* when this... */
   GLint type, format;					/* ...use this. */
@@ -484,9 +484,9 @@ static const conversion_table ctable[] =
 
 
 /* Given an XImage, returns the GL settings to use its data as a texture.
  */
-static void
+static int
 gl_settings_for_ximage (XImage *image,
                         GLint *type_ret, GLint *format_ret, GLint *swap_ret)
 {
   int i;
@@ -539,17 +539,20 @@ gl_settings_for_ximage (XImage *image,
                        image->bits_per_pixel,
                        image->red_mask, image->green_mask, image->blue_mask);
             }
 
-          return;
+          return 0;
         }
     }
 
   /* Unknown RGB fields? */
-  abort();
+  if (debug_p)
+	  fprintf(stderr, "ximage unknown: %i %08lx %08lx %08lx\n", image->bits_per_pixel,
+		image->red_mask, image->green_mask, image->blue_mask);
+  return 1;
 }
 
-#endif /* ! REFORMAT_IMAGE_DATA */
+/* #endif ! REFORMAT_IMAGE_DATA */
 
 typedef struct {
   GLXContext glx_context;
   Pixmap pixmap;
@@ -810,11 +813,40 @@ load_texture_async_cb (Screen *screen, W
   if (debug_p)
     cvt_time = double_time();
 
 # ifdef REFORMAT_IMAGE_DATA
-  ximage = pixmap_to_gl_ximage (screen, window, dd.pixmap);
-  format = GL_RGBA;
-  type = GL_UNSIGNED_BYTE;
+  {
+    Window root;
+    int x, y;
+    unsigned int bw;
+    unsigned int width, height, depth;
+    GLint swap;
+    Visual *visual = DefaultVisualOfScreen (screen);
+    XImage *to;
+
+    XGetGeometry (dpy, dd.pixmap, &root, &x, &y, &width, &height, &bw, &depth);
+    ximage = XGetImage(dpy, dd.pixmap, 0, 0, width, height, ~0L, ZPixmap);
+    ximage->depth = ximage->bits_per_pixel;
+    /* Create temp image just to get masks ... */
+    to = XCreateImage (dpy, visual, ximage->depth,  /* depth */
+                             ZPixmap, 0, 0, width, height + 2,
+                             ximage->bitmap_pad, /* bitmap pad */ 0);
+    ximage->red_mask = to->red_mask;
+    ximage->green_mask = to->green_mask;
+    ximage->blue_mask = to->blue_mask;
+    XDestroyImage(to);
+    /* Fallback if we don't find a matching GL format OR if it's not GL_RGBA
+     * because then it would seem faster for us to do the conversion ourselves */
+    if (gl_settings_for_ximage (ximage, &type, &format, &swap)
+	|| format != GL_RGBA) {
+	XDestroyImage(ximage);
+        ximage = pixmap_to_gl_ximage (screen, window, dd.pixmap);
+        format = GL_RGBA;
+        type = GL_UNSIGNED_BYTE;
+        XFreePixmap (dpy, dd.pixmap);
+        dd.pixmap = 0;
+    }
+  }
 
 #else /* ! REFORMAT_IMAGE_DATA */
   {
     Visual *visual = DefaultVisualOfScreen (screen);
@@ -834,15 +866,15 @@ load_texture_async_cb (Screen *screen, W
         XDestroyImage (ximage);
         ximage = 0;
       }
 
-    gl_settings_for_ximage (ximage, &type, &format, &swap);
+    if (gl_settings_for_ximage (ximage, &type, &format, &swap))
+	abort();
     glPixelStorei (GL_UNPACK_SWAP_BYTES, !swap);
   }
-#endif /* REFORMAT_IMAGE_DATA */
-
   XFreePixmap (dpy, dd.pixmap);
   dd.pixmap = 0;
+#endif /* REFORMAT_IMAGE_DATA */
 
   if (debug_p)
     tex_time = double_time();
openSUSE Build Service is sponsored by