示例#1
0
文件: xm_st.c 项目: Distrotech/Mesa
/**
 * Check that a framebuffer's attachments match the window's size.
 *
 * Called via st_framebuffer_iface::validate()
 *
 * \param statts  array of framebuffer attachments
 * \param count  number of framebuffer attachments in statts[]
 * \param out  returns resources for each of the attachments
 */
static boolean
xmesa_st_framebuffer_validate(struct st_context_iface *stctx,
                              struct st_framebuffer_iface *stfbi,
                              const enum st_attachment_type *statts,
                              unsigned count,
                              struct pipe_resource **out)
{
   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
   unsigned statt_mask, new_mask, i;
   boolean resized;
   boolean ret;

   /* build mask of ST_ATTACHMENT bits */
   statt_mask = 0x0;
   for (i = 0; i < count; i++)
      statt_mask |= 1 << statts[i];

   /* record newly allocated textures */
   new_mask = statt_mask & ~xstfb->texture_mask;

   /* If xmesa_strict_invalidate is not set, we will not yet have
    * called XGetGeometry().  Do so here:
    */
   if (!xmesa_strict_invalidate)
      xmesa_check_buffer_size(xstfb->buffer);

   resized = (xstfb->buffer->width != xstfb->texture_width ||
              xstfb->buffer->height != xstfb->texture_height);

   /* revalidate textures */
   if (resized || new_mask) {
      ret = xmesa_st_framebuffer_validate_textures(stfbi,
                  xstfb->buffer->width, xstfb->buffer->height, statt_mask);
      if (!ret)
         return ret;

      if (!resized) {
         enum st_attachment_type back, front;

         back = ST_ATTACHMENT_BACK_LEFT;
         front = ST_ATTACHMENT_FRONT_LEFT;
         /* copy the contents if front is newly allocated and back is not */
         if ((statt_mask & (1 << back)) &&
             (new_mask & (1 << front)) &&
             !(new_mask & (1 << back))) {
            xmesa_st_framebuffer_copy_textures(stfbi, back, front,
                  0, 0, xstfb->texture_width, xstfb->texture_height);
         }
      }
   }

   for (i = 0; i < count; i++) {
      out[i] = NULL;
      pipe_resource_reference(&out[i], xstfb->textures[statts[i]]);
   }

   return TRUE;
}
示例#2
0
文件: xm_api.c 项目: ideak/mesa
PUBLIC void
XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
                  const int *attrib_list)
{
   struct st_context_iface *st = stapi->get_current(stapi);
   struct st_framebuffer_iface* stfbi = drawable->stfb;
   struct pipe_resource *res;
   int x, y, w, h;
   enum st_attachment_type st_attachment = xmesa_attachment_type(buffer);

   x = 0;
   y = 0;
   w = drawable->width;
   h = drawable->height;

   /* We need to validate our attachments before using them,
    * in case the texture doesn't exist yet. */
   xmesa_st_framebuffer_validate_textures(stfbi, w, h, 1 << st_attachment);
   res = xmesa_get_attachment(stfbi, st_attachment);

   if (res) {
      struct pipe_context* pipe = xmesa_get_context(stfbi);
      enum pipe_format internal_format = res->format;
      struct pipe_transfer *tex_xfer;
      char *map;
      int line, ximage_stride;
      XImage *img;

      internal_format = choose_pixel_format(drawable->xm_visual);

      tex_xfer = pipe_get_transfer(pipe, res,
                                   0, 0,    /* level, layer */
                                   PIPE_TRANSFER_WRITE,
                                   x, y,
                                   w, h);
      if (!tex_xfer)
         return;

      /* Grab the XImage that we want to turn into a texture. */
      img = XGetImage(dpy,
                      drawable->ws.drawable,
                      x, y,
                      w, h,
                      AllPlanes,
                      ZPixmap);

      if (!img) {
         pipe_transfer_destroy(pipe, tex_xfer);
         return;
      }

      map = pipe_transfer_map(pipe, tex_xfer);

      if (!map) {
         pipe_transfer_destroy(pipe, tex_xfer);
         return;
      }

      /* The pipe transfer has a pitch rounded up to the nearest 64 pixels.
         We assume 32 bit pixels. */
      ximage_stride = w * 4;

      for (line = 0; line < h; line++)
         memcpy(&map[line * tex_xfer->stride],
                &img->data[line * ximage_stride],
                ximage_stride);

      pipe_transfer_unmap(pipe, tex_xfer);

      pipe_transfer_destroy(pipe, tex_xfer);

      st->teximage(st,
                   ST_TEXTURE_2D,
                   0,    /* level */
                   internal_format,
                   res,
                   FALSE /* no mipmap */);

   }
}