st/egl: clean up eglCopyBuffers
authorChia-I Wu <olv@lunarg.com>
Sat, 25 Jun 2011 06:48:24 +0000 (15:48 +0900)
committerChia-I Wu <olv@lunarg.com>
Sat, 25 Jun 2011 07:23:21 +0000 (16:23 +0900)
Add copy_to_pixmap method to native_display and use it for
eglCopyBuffers.

src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/native.h
src/gallium/state_trackers/egl/common/native_helper.c
src/gallium/state_trackers/egl/common/native_helper.h
src/gallium/state_trackers/egl/wayland/native_wayland.c
src/gallium/state_trackers/egl/x11/native_dri2.c
src/gallium/state_trackers/egl/x11/native_ximage.c

index 1d49c30..cd1c355 100644 (file)
@@ -602,21 +602,6 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
          gsurf->base.SwapInterval);
 }
 
-/**
- * Get the pipe surface of the given attachment of the native surface.
- */
-static struct pipe_resource *
-get_pipe_resource(struct native_display *ndpy, struct native_surface *nsurf,
-                  enum native_attachment natt)
-{
-   struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
-
-   textures[natt] = NULL;
-   nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
-
-   return textures[natt];
-}
-
 static EGLBoolean
 egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                      EGLNativePixmapType target)
@@ -624,43 +609,18 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
    _EGLContext *ctx = _eglGetCurrentContext();
-   struct native_surface *nsurf;
-   struct pipe_resource *ptex;
-   struct pipe_context *pipe;
 
    if (!gsurf->render_texture)
       return EGL_TRUE;
 
-   nsurf = gdpy->native->create_pixmap_surface(gdpy->native, target, NULL);
-   if (!nsurf)
-      return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
-
    /* flush if the surface is current */
    if (ctx && ctx->DrawSurface == &gsurf->base) {
       struct egl_g3d_context *gctx = egl_g3d_context(ctx);
       gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
    }
 
-   pipe = ndpy_get_copy_context(gdpy->native);
-   if (!pipe)
-      return EGL_FALSE;
-
-   ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
-   if (ptex) {
-      struct pipe_box src_box;
-
-      u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
-      pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0,
-            gsurf->render_texture, 0, &src_box);
-      pipe->flush(pipe, NULL);
-      nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
-
-      pipe_resource_reference(&ptex, NULL);
-   }
-
-   nsurf->destroy(nsurf);
-
-   return EGL_TRUE;
+   return gdpy->native->copy_to_pixmap(gdpy->native,
+         target, gsurf->render_texture);
 }
 
 static EGLBoolean
index c0b8385..8d01257 100644 (file)
@@ -180,11 +180,22 @@ struct native_display {
     *
     * 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.
+    *
+    * TODO should be get_pixmap_format() and return the pipe format of the
+    * pixmap.
     */
    boolean (*is_pixmap_supported)(struct native_display *ndpy,
                                   EGLNativePixmapType pix,
                                   const struct native_config *nconf);
 
+   /**
+    * Copy the contents of the resource to the pixmap's front-left attachment.
+    * This is used to implement eglCopyBuffers.  Required unless no config has
+    * pixmap_bit set.
+    */
+   boolean (*copy_to_pixmap)(struct native_display *ndpy,
+                             EGLNativePixmapType pix,
+                             struct pipe_resource *src);
 
    /**
     * Create a window surface.  Required unless no config has window_bit set.
index 2585730..6f2097c 100644 (file)
@@ -368,6 +368,47 @@ resource_surface_wait(struct resource_surface *rsurf)
    while (resource_surface_throttle(rsurf));
 }
 
+boolean
+native_display_copy_to_pixmap(struct native_display *ndpy,
+                              EGLNativePixmapType pix,
+                              struct pipe_resource *src)
+{
+   struct pipe_context *pipe;
+   struct native_surface *nsurf;
+   struct pipe_resource *dst;
+   struct pipe_resource *tmp[NUM_NATIVE_ATTACHMENTS];
+   const enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+   pipe = ndpy_get_copy_context(ndpy);
+   if (!pipe)
+      return FALSE;
+
+   nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL);
+   if (!nsurf)
+      return FALSE;
+
+   /* get the texutre */
+   tmp[natt] = NULL;
+   nsurf->validate(nsurf, 1 << natt, NULL, tmp, NULL, NULL);
+   dst = tmp[natt];
+
+   if (dst && dst->format == src->format) {
+      struct pipe_box src_box;
+
+      u_box_origin_2d(src->width0, src->height0, &src_box);
+      pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &src_box);
+      pipe->flush(pipe, NULL);
+      nsurf->present(nsurf, natt, FALSE, 0);
+   }
+
+   if (dst)
+      pipe_resource_reference(&dst, NULL);
+
+   nsurf->destroy(nsurf);
+
+   return TRUE;
+}
+
 #include "state_tracker/drm_driver.h"
 struct pipe_resource *
 drm_display_import_native_buffer(struct native_display *ndpy,
index f4d1099..e8d91cc 100644 (file)
@@ -106,6 +106,11 @@ resource_surface_flush(struct resource_surface *rsurf,
 void
 resource_surface_wait(struct resource_surface *rsurf);
 
+boolean
+native_display_copy_to_pixmap(struct native_display *ndpy,
+                              EGLNativePixmapType pix,
+                              struct pipe_resource *src);
+
 struct pipe_resource *
 drm_display_import_native_buffer(struct native_display *ndpy,
                                  struct native_buffer *nbuf);
index 0672c54..35d3d90 100644 (file)
@@ -477,6 +477,7 @@ native_create_display(void *dpy, boolean use_sw)
    display->base.get_param = wayland_display_get_param;
    display->base.get_configs = wayland_display_get_configs;
    display->base.is_pixmap_supported = wayland_display_is_pixmap_supported;
+   display->base.copy_to_pixmap = native_display_copy_to_pixmap;
    display->base.create_window_surface = wayland_create_window_surface;
    display->base.create_pixmap_surface = wayland_create_pixmap_surface;
 
index 2a3a106..7043527 100644 (file)
@@ -38,6 +38,7 @@
 #include "native_x11.h"
 #include "x11_screen.h"
 
+#include "common/native_helper.h"
 #ifdef HAVE_WAYLAND_BACKEND
 #include "common/native_wayland_drm_bufmgr_helper.h"
 #endif
@@ -909,6 +910,7 @@ x11_create_dri2_display(Display *dpy,
    dri2dpy->base.get_param = dri2_display_get_param;
    dri2dpy->base.get_configs = dri2_display_get_configs;
    dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
+   dri2dpy->base.copy_to_pixmap = native_display_copy_to_pixmap;
    dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
    dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
 #ifdef HAVE_WAYLAND_BACKEND
index 1bf7a19..bb5f0aa 100644 (file)
@@ -542,6 +542,7 @@ x11_create_ximage_display(Display *dpy,
 
    xdpy->base.get_configs = ximage_display_get_configs;
    xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
+   xdpy->base.copy_to_pixmap = native_display_copy_to_pixmap;
    xdpy->base.create_window_surface = ximage_display_create_window_surface;
    xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;