Remove leftover __DRI{screen,drawable,context}Private references
[mesa.git] / src / gallium / state_trackers / dri / dri_drawable.c
index 0a952f7b2840ae4b7089866a15b3a7311c481d5b..1058dd38c258c0e1eb78d6fe82e3dd1ca8cd1b7d 100644 (file)
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_inlines.h"
+#include "main/mtypes.h"
+#include "main/renderbuffer.h"
 #include "state_tracker/drm_api.h"
 #include "state_tracker/dri1_api.h"
 #include "state_tracker/st_public.h"
 #include "state_tracker/st_context.h"
 #include "state_tracker/st_cb_fbo.h"
 
+#include "util/u_format.h"
 #include "util/u_memory.h"
-
-static void
-dri_copy_to_front(__DRIdrawablePrivate * dPriv,
-                 struct pipe_surface *from,
-                 int x, int y, unsigned w, unsigned h)
-{
-   /* TODO send a message to the Xserver to copy to the real front buffer */
-}
-
+#include "util/u_rect.h"
 static struct pipe_surface *
 dri_surface_from_handle(struct drm_api *api,
                        struct pipe_screen *screen,
@@ -62,29 +58,23 @@ dri_surface_from_handle(struct drm_api *api,
    struct pipe_surface *surface = NULL;
    struct pipe_texture *texture = NULL;
    struct pipe_texture templat;
-   struct pipe_buffer *buf = NULL;
-
-   buf = api->buffer_from_handle(api, screen, "dri2 buffer", handle);
-   if (!buf)
-      return NULL;
 
    memset(&templat, 0, sizeof(templat));
    templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
    templat.target = PIPE_TEXTURE_2D;
    templat.last_level = 0;
-   templat.depth[0] = 1;
+   templat.depth0 = 1;
    templat.format = format;
-   templat.width[0] = width;
-   templat.height[0] = height;
-   pf_get_block(templat.format, &templat.block);
+   templat.width0 = width;
+   templat.height0 = height;
 
-   texture = screen->texture_blanket(screen, &templat, &pitch, buf);
+   texture = api->texture_from_shared_handle(api, screen, &templat,
+                                             "dri2 buffer", pitch, handle);
 
-   /* we don't need the buffer from this point on */
-   pipe_buffer_reference(&buf, NULL);
-
-   if (!texture)
+   if (!texture) {
+      debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
       return NULL;
+   }
 
    surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
                                     PIPE_BUFFER_USAGE_GPU_READ |
@@ -95,11 +85,40 @@ dri_surface_from_handle(struct drm_api *api,
    return surface;
 }
 
+/**
+ * Pixmaps have will have the same name of fake front and front.
+ */
+static boolean
+dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
+{
+   boolean found = FALSE;
+   boolean is_pixmap = FALSE;
+   unsigned name;
+   int i;
+
+   for (i = 0; i < count; i++) {
+      switch (buffers[i].attachment) {
+      case __DRI_BUFFER_FRONT_LEFT:
+      case __DRI_BUFFER_FAKE_FRONT_LEFT:
+         if (found) {
+            is_pixmap = buffers[i].name == name;
+         } else {
+            name = buffers[i].name;
+            found = TRUE;
+         }
+      default:
+        continue;
+      }
+   }
+
+   return is_pixmap;
+}
+
 /**
  * This will be called a drawable is known to have been resized.
  */
 void
-dri_get_buffers(__DRIdrawablePrivate * dPriv)
+dri_get_buffers(__DRIdrawable * dPriv)
 {
 
    struct dri_drawable *drawable = dri_drawable(dPriv);
@@ -153,15 +172,14 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
       memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
    }
 
+   drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
+
    for (i = 0; i < count; i++) {
       enum pipe_format format = 0;
       int index = 0;
 
       switch (buffers[i].attachment) {
       case __DRI_BUFFER_FRONT_LEFT:
-        index = ST_SURFACE_FRONT_LEFT;
-        format = drawable->color_format;
-        break;
       case __DRI_BUFFER_FAKE_FRONT_LEFT:
         index = ST_SURFACE_FRONT_LEFT;
         format = drawable->color_format;
@@ -171,12 +189,10 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
         format = drawable->color_format;
         break;
       case __DRI_BUFFER_DEPTH:
-        index = ST_SURFACE_DEPTH;
-        format = drawable->depth_format;
-        break;
+      case __DRI_BUFFER_DEPTH_STENCIL:
       case __DRI_BUFFER_STENCIL:
         index = ST_SURFACE_DEPTH;
-        format = drawable->stencil_format;
+        format = drawable->depth_stencil_format;
         break;
       case __DRI_BUFFER_ACCUM:
       default:
@@ -197,6 +213,22 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
                                        dri_drawable->w,
                                        dri_drawable->h, buffers[i].pitch);
 
+      switch (buffers[i].attachment) {
+      case __DRI_BUFFER_FRONT_LEFT:
+      case __DRI_BUFFER_FAKE_FRONT_LEFT:
+      case __DRI_BUFFER_BACK_LEFT:
+        drawable->color_format = surface->format;
+        break;
+      case __DRI_BUFFER_DEPTH:
+      case __DRI_BUFFER_DEPTH_STENCIL:
+      case __DRI_BUFFER_STENCIL:
+        drawable->depth_stencil_format = surface->format;
+        break;
+      case __DRI_BUFFER_ACCUM:
+      default:
+        assert(0);
+      }
+
       st_set_framebuffer_surface(drawable->stfb, index, surface);
       pipe_surface_reference(&surface, NULL);
    }
@@ -213,13 +245,20 @@ void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct pipe_surface *ps;
 
+   if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
+      struct gl_renderbuffer *rb =
+         st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE);
+      _mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb);
+   }
+
    dri_get_buffers(drawable->dPriv);
    st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
 
+   if (!ps)
+      return;
+
    st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
-                           ST_TEXTURE_RECT, 0,
-                           format == GLX_TEXTURE_FORMAT_RGBA_EXT ?
-                           PIPE_FORMAT_R8G8B8A8_UNORM : PIPE_FORMAT_R8G8B8X8_UNORM);
+                           ST_TEXTURE_RECT, 0, drawable->color_format);
 }
 
 void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
@@ -233,16 +272,35 @@ dri_flush_frontbuffer(struct pipe_screen *screen,
                      struct pipe_surface *surf, void *context_private)
 {
    struct dri_context *ctx = (struct dri_context *)context_private;
+   struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
+   __DRIdrawable *dri_drawable = ctx->dPriv;
+   __DRIscreen *dri_screen = ctx->sPriv;
 
-   dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height);
+   /* XXX Does this function get called with DRI1? */
+
+   if (ctx->dPriv == NULL) {
+      debug_printf("%s: no drawable bound to context\n", __func__);
+      return;
+   }
+
+#if 0
+   /* TODO if rendering to pixmaps is slow enable this code. */
+   if (drawable->is_pixmap)
+      return;
+#else
+   (void)drawable;
+#endif
+
+   (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
+                                               dri_drawable->loaderPrivate);
 }
 
 /**
  * This is called when we need to set up GL rendering to a new X window.
  */
 boolean
-dri_create_buffer(__DRIscreenPrivate * sPriv,
-                 __DRIdrawablePrivate * dPriv,
+dri_create_buffer(__DRIscreen * sPriv,
+                 __DRIdrawable * dPriv,
                  const __GLcontextModes * visual, boolean isPixmap)
 {
    struct dri_screen *screen = sPriv->private;
@@ -256,52 +314,43 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
    if (drawable == NULL)
       goto fail;
 
-   drawable->color_format = (visual->redBits == 8) ?
-      PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM;
-
-   debug_printf("Red bits is %d\n", visual->redBits);
+   if (visual->redBits == 8) {
+      if (visual->alphaBits == 8)
+         drawable->color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+      else
+         drawable->color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
+   } else {
+      drawable->color_format = PIPE_FORMAT_R5G6B5_UNORM;
+   }
 
    switch(visual->depthBits) {
    default:
    case 0:
-      debug_printf("Depth buffer 0.\n");
-      drawable->depth_format = PIPE_FORMAT_NONE;
+      drawable->depth_stencil_format = PIPE_FORMAT_NONE;
       break;
    case 16:
-      debug_printf("Depth buffer 16.\n");
-      drawable->depth_format = PIPE_FORMAT_Z16_UNORM;
+      drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
       break;
    case 24:
       if (visual->stencilBits == 0) {
-         debug_printf("Depth buffer 24. Stencil 0.\n");
-        drawable->depth_format = (screen->d_depth_bits_last) ?
+        drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
            PIPE_FORMAT_X8Z24_UNORM:
            PIPE_FORMAT_Z24X8_UNORM;
       } else {
-         debug_printf("Combined depth stencil 24 / 8.\n");
-        drawable->depth_format = (screen->sd_depth_bits_last) ?
+        drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
            PIPE_FORMAT_S8Z24_UNORM:
            PIPE_FORMAT_Z24S8_UNORM;
       }
       break;
-   }
-
-   switch(visual->stencilBits) {
-   default:
-   case 0:
-      drawable->stencil_format = PIPE_FORMAT_NONE;
-      break;
-   case 8:
-      drawable->stencil_format = (screen->sd_depth_bits_last) ?
-        PIPE_FORMAT_S8Z24_UNORM:
-         PIPE_FORMAT_Z24S8_UNORM;
+   case 32:
+      drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
       break;
    }
 
    drawable->stfb = st_create_framebuffer(visual,
                                          drawable->color_format,
-                                         drawable->depth_format,
-                                         drawable->stencil_format,
+                                         drawable->depth_stencil_format,
+                                         drawable->depth_stencil_format,
                                          dPriv->w,
                                          dPriv->h, (void *)drawable);
    if (drawable->stfb == NULL)
@@ -312,17 +361,17 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
    dPriv->driverPrivate = (void *)drawable;
 
    /* setup dri2 buffers information */
+   /* TODO incase of double buffer visual, delay fake creation */
    i = 0;
    drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-#if 0
-   /* TODO incase of double buffer visual, delay fake creation */
-   drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
-#endif
+
    if (visual->doubleBufferMode)
       drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-   if (visual->depthBits)
+   if (visual->depthBits && visual->stencilBits)
+      drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+   else if (visual->depthBits)
       drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
-   if (visual->stencilBits)
+   else if (visual->stencilBits)
       drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
    drawable->num_attachments = i;
 
@@ -367,7 +416,7 @@ dri_swap_fences_push_back(struct dri_drawable *draw,
 }
 
 void
-dri_destroy_buffer(__DRIdrawablePrivate * dPriv)
+dri_destroy_buffer(__DRIdrawable * dPriv)
 {
    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct pipe_fence_handle *fence;
@@ -385,8 +434,8 @@ dri_destroy_buffer(__DRIdrawablePrivate * dPriv)
 
 static void
 dri1_update_drawables_locked(struct dri_context *ctx,
-                            __DRIdrawablePrivate * driDrawPriv,
-                            __DRIdrawablePrivate * driReadPriv)
+                            __DRIdrawable * driDrawPriv,
+                            __DRIdrawable * driReadPriv)
 {
    if (ctx->stLostLock) {
       ctx->stLostLock = FALSE;
@@ -409,8 +458,8 @@ dri1_update_drawables_locked(struct dri_context *ctx,
 static void
 dri1_propagate_drawable_change(struct dri_context *ctx)
 {
-   __DRIdrawablePrivate *dPriv = ctx->dPriv;
-   __DRIdrawablePrivate *rPriv = ctx->rPriv;
+   __DRIdrawable *dPriv = ctx->dPriv;
+   __DRIdrawable *rPriv = ctx->rPriv;
    boolean flushed = FALSE;
 
    if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
@@ -483,7 +532,7 @@ static void
 dri1_swap_copy(struct dri_context *ctx,
               struct pipe_surface *dst,
               struct pipe_surface *src,
-              __DRIdrawablePrivate * dPriv, const struct drm_clip_rect *bbox)
+              __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
 {
    struct pipe_context *pipe = ctx->pipe;
    struct drm_clip_rect clip;
@@ -493,19 +542,28 @@ dri1_swap_copy(struct dri_context *ctx,
    cur = dPriv->pClipRects;
 
    for (i = 0; i < dPriv->numClipRects; ++i) {
-      if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox))
-        pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
-                           src,
-                           (int)clip.x1 - dPriv->x,
-                           (int)clip.y1 - dPriv->y,
-                           clip.x2 - clip.x1, clip.y2 - clip.y1);
+      if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
+         if (pipe->surface_copy) {
+            pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
+                               src,
+                               (int)clip.x1 - dPriv->x,
+                               (int)clip.y1 - dPriv->y,
+                               clip.x2 - clip.x1, clip.y2 - clip.y1);
+         } else {
+            util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
+                              src,
+                              (int)clip.x1 - dPriv->x,
+                              (int)clip.y1 - dPriv->y,
+                              clip.x2 - clip.x1, clip.y2 - clip.y1);
+         }
+      }
    }
 }
 
 static void
 dri1_copy_to_front(struct dri_context *ctx,
                   struct pipe_surface *surf,
-                  __DRIdrawablePrivate * dPriv,
+                  __DRIdrawable * dPriv,
                   const struct drm_clip_rect *sub_box,
                   struct pipe_fence_handle **fence)
 {
@@ -578,7 +636,7 @@ dri1_flush_frontbuffer(struct pipe_screen *screen,
 }
 
 void
-dri_swap_buffers(__DRIdrawablePrivate * dPriv)
+dri_swap_buffers(__DRIdrawable * dPriv)
 {
    struct dri_context *ctx;
    struct pipe_surface *back_surf;
@@ -610,7 +668,7 @@ dri_swap_buffers(__DRIdrawablePrivate * dPriv)
 }
 
 void
-dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
+dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
 {
    struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
    struct drm_clip_rect sub_bbox;