st/egl_g3d: Add is_pixmap_supported to native display interface.
authorChia-I Wu <olvaffe@gmail.com>
Mon, 18 Jan 2010 07:49:20 +0000 (15:49 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Mon, 18 Jan 2010 09:04:02 +0000 (17:04 +0800)
The function may be used to support, for example,
EGL_MATCH_NATIVE_PIXMAP and EGL_KHR_image_pixmap.

src/gallium/state_trackers/egl_g3d/common/native.h
src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
src/gallium/state_trackers/egl_g3d/x11/x11_screen.h

index 6cd161bdf6cb5cc7fcce09d52a0b0e0d9f32d8e7..f374f2e4a68930021a845ca80853b955648740a8 100644 (file)
@@ -135,6 +135,17 @@ struct native_display {
    const struct native_config **(*get_configs)(struct native_display *ndpy,
                                                int *num_configs);
 
+   /**
+    * Test if a pixmap is supported by the given config.  Required unless no
+    * config has GLX_PIXMAP_BIT set.
+    *
+    * This function is usually called to find a config that supports a given
+    * pixmap.  Thus, it is usually called with the same pixmap in a row.
+    */
+   boolean (*is_pixmap_supported)(struct native_display *ndpy,
+                                  EGLNativePixmapType pix,
+                                  const struct native_config *nconf);
+
    /**
     * Create a pipe context.
     */
index f675a8e6861e979c75ff19cbb094119649146ef3..07f82d878c549cf9a1ecd987e9db202411e872d1 100644 (file)
@@ -588,6 +588,21 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
    return configs;
 }
 
+static boolean
+dri2_display_is_pixmap_supported(struct native_display *ndpy,
+                                 EGLNativePixmapType pix,
+                                 const struct native_config *nconf)
+{
+   struct dri2_display *dri2dpy = dri2_display(ndpy);
+   uint depth, nconf_depth;
+
+   depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
+   nconf_depth = util_format_get_blocksizebits(nconf->color_format);
+
+   /* simple depth match for now */
+   return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
+}
+
 static void
 dri2_display_destroy(struct native_display *ndpy)
 {
@@ -680,6 +695,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
 
    dri2dpy->base.destroy = dri2_display_destroy;
    dri2dpy->base.get_configs = dri2_display_get_configs;
+   dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
    dri2dpy->base.create_context = dri2_display_create_context;
    dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
    dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
index 1f136235c0c6cda8c01cebe33367d1a42e439df5..d76107c47f1c21df6fd569271874d0a570218966 100644 (file)
@@ -600,6 +600,34 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
    return configs;
 }
 
+static boolean
+ximage_display_is_pixmap_supported(struct native_display *ndpy,
+                                   EGLNativePixmapType pix,
+                                   const struct native_config *nconf)
+{
+   struct ximage_display *xdpy = ximage_display(ndpy);
+   enum pipe_format fmt;
+   uint depth;
+
+   depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
+   switch (depth) {
+   case 32:
+      fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+      break;
+   case 24:
+      fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+      break;
+   case 16:
+      fmt = PIPE_FORMAT_R5G6B5_UNORM;
+      break;
+   default:
+      fmt = PIPE_FORMAT_NONE;
+      break;
+   }
+
+   return (fmt == nconf->color_format);
+}
+
 static void
 ximage_display_destroy(struct native_display *ndpy)
 {
@@ -652,6 +680,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
    xdpy->base.destroy = ximage_display_destroy;
 
    xdpy->base.get_configs = ximage_display_get_configs;
+   xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
    xdpy->base.create_context = ximage_display_create_context;
    xdpy->base.create_window_surface = ximage_display_create_window_surface;
    xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
index 1e98943242a56bb7bfee7f659af20516394ed64d..bfff91db8ba0e5a1b83dc697457a96568a117949 100644 (file)
@@ -30,6 +30,7 @@
 #include <X11/extensions/XShm.h>
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/u_format.h"
 #include "xf86drm.h"
 #include "egllog.h"
 
@@ -50,6 +51,10 @@ struct x11_screen {
 
    XVisualInfo *visuals;
    int num_visuals;
+
+   /* cached values for x11_drawable_get_format */
+   Drawable last_drawable;
+   unsigned int last_depth;
 };
 
 
@@ -350,6 +355,37 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
    return (struct x11_drawable_buffer *) dri2bufs;
 }
 
+/**
+ * Return the depth of a drawable.
+ *
+ * Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
+ */
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
+{
+   unsigned int depth;
+
+   if (drawable != xscr->last_drawable) {
+      Window root;
+      int x, y;
+      unsigned int w, h, border;
+      Status ok;
+
+      ok = XGetGeometry(xscr->dpy, drawable, &root,
+            &x, &y, &w, &h, &border, &depth);
+      if (!ok)
+         depth = 0;
+
+      xscr->last_drawable = drawable;
+      xscr->last_depth = depth;
+   }
+   else {
+      depth = xscr->last_depth;
+   }
+
+   return depth;
+}
+
 /**
  * Create a mode list of the given size.
  */
index 86e8e0501a3f35b08bf9b944a1931b712fc170c9..ad42bffbe9c5fb86957068fd6509888affcc5b7d 100644 (file)
@@ -29,6 +29,7 @@
 #include <X11/Xutil.h>
 #include <X11/extensions/dri2tokens.h>
 #include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
 #include "common/native.h"
 
 enum x11_screen_extension {
@@ -96,4 +97,7 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
                          int *width, int *height, unsigned int *attachments,
                          boolean with_format, int num_ins, int *num_outs);
 
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
+
 #endif /* _X11_SCREEN_H_ */