Esempio n. 1
0
/** dri3_free_buffers
 *
 * Free the front bufffer or all of the back buffers. Used
 * when the application changes which buffers it needs
 */
static void
dri3_free_buffers(__DRIdrawable *driDrawable,
                  enum loader_dri3_buffer_type buffer_type,
                  struct loader_dri3_drawable *draw)
{
   struct loader_dri3_buffer *buffer;
   int first_id;
   int n_id;
   int buf_id;

   switch (buffer_type) {
   case loader_dri3_buffer_back:
      first_id = LOADER_DRI3_BACK_ID(0);
      n_id = LOADER_DRI3_MAX_BACK;
      break;
   case loader_dri3_buffer_front:
      first_id = LOADER_DRI3_FRONT_ID;
      n_id = 1;
   }

   for (buf_id = first_id; buf_id < first_id + n_id; buf_id++) {
      buffer = draw->buffers[buf_id];
      if (buffer) {
         dri3_free_render_buffer(draw, buffer);
         draw->buffers[buf_id] = NULL;
      }
   }
}
Esempio n. 2
0
void
loader_dri3_drawable_fini(struct loader_dri3_drawable *draw)
{
   int i;

   (draw->ext->core->destroyDrawable)(draw->dri_drawable);

   for (i = 0; i < LOADER_DRI3_NUM_BUFFERS; i++) {
      if (draw->buffers[i])
         dri3_free_render_buffer(draw, draw->buffers[i]);
   }

   if (draw->special_event)
      xcb_unregister_for_special_event(draw->conn, draw->special_event);
}
Esempio n. 3
0
void
loader_dri3_drawable_fini(struct loader_dri3_drawable *draw)
{
    int i;

    (draw->ext->core->destroyDrawable)(draw->dri_drawable);

    for (i = 0; i < LOADER_DRI3_NUM_BUFFERS; i++) {
        if (draw->buffers[i])
            dri3_free_render_buffer(draw, draw->buffers[i]);
    }

    if (draw->special_event) {
        xcb_void_cookie_t cookie =
            xcb_present_select_input_checked(draw->conn, draw->eid, draw->drawable,
                                             XCB_PRESENT_EVENT_MASK_NO_EVENT);

        xcb_discard_reply(draw->conn, cookie.sequence);
        xcb_unregister_for_special_event(draw->conn, draw->special_event);
    }
}
Esempio n. 4
0
/*
 * Process one Present event
 */
static void
dri3_handle_present_event(struct loader_dri3_drawable *draw,
                          xcb_present_generic_event_t *ge)
{
   switch (ge->evtype) {
   case XCB_PRESENT_CONFIGURE_NOTIFY: {
      xcb_present_configure_notify_event_t *ce = (void *) ge;

      draw->width = ce->width;
      draw->height = ce->height;
      draw->vtable->set_drawable_size(draw, draw->width, draw->height);
      break;
   }
   case XCB_PRESENT_COMPLETE_NOTIFY: {
      xcb_present_complete_notify_event_t *ce = (void *) ge;

      /* Compute the processed SBC number from the received 32-bit serial number
       * merged with the upper 32-bits of the sent 64-bit serial number while
       * checking for wrap.
       */
      if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) {
         draw->recv_sbc = (draw->send_sbc & 0xffffffff00000000LL) | ce->serial;
         if (draw->recv_sbc > draw->send_sbc)
            draw->recv_sbc -= 0x100000000;
         switch (ce->mode) {
         case XCB_PRESENT_COMPLETE_MODE_FLIP:
            draw->flipping = true;
            break;
         case XCB_PRESENT_COMPLETE_MODE_COPY:
            draw->flipping = false;
            break;
         }
         dri3_update_num_back(draw);

         if (draw->vtable->show_fps)
            draw->vtable->show_fps(draw, ce->ust);

         draw->ust = ce->ust;
         draw->msc = ce->msc;
      } else {
         draw->recv_msc_serial = ce->serial;
         draw->notify_ust = ce->ust;
         draw->notify_msc = ce->msc;
      }
      break;
   }
   case XCB_PRESENT_EVENT_IDLE_NOTIFY: {
      xcb_present_idle_notify_event_t *ie = (void *) ge;
      int b;

      for (b = 0; b < sizeof(draw->buffers) / sizeof(draw->buffers[0]); b++) {
         struct loader_dri3_buffer *buf = draw->buffers[b];

         if (buf && buf->pixmap == ie->pixmap) {
            buf->busy = 0;
            if (draw->num_back <= b && b < LOADER_DRI3_MAX_BACK) {
               dri3_free_render_buffer(draw, buf);
               draw->buffers[b] = NULL;
            }
            break;
         }
      }
      break;
   }
   }
   free(ge);
}
Esempio n. 5
0
/** dri3_get_buffer
 *
 * Find a front or back buffer, allocating new ones as necessary
 */
static struct loader_dri3_buffer *
dri3_get_buffer(__DRIdrawable *driDrawable,
                unsigned int format,
                enum loader_dri3_buffer_type buffer_type,
                struct loader_dri3_drawable *draw)
{
   struct loader_dri3_buffer *buffer;
   int buf_id;
   __DRIcontext *dri_context;

   dri_context = draw->vtable->get_dri_context(draw);

   if (buffer_type == loader_dri3_buffer_back) {
      buf_id = dri3_find_back(draw);

      if (buf_id < 0)
         return NULL;
   } else {
      buf_id = LOADER_DRI3_FRONT_ID;
   }

   buffer = draw->buffers[buf_id];

   /* Allocate a new buffer if there isn't an old one, or if that
    * old one is the wrong size
    */
   if (!buffer || buffer->width != draw->width ||
       buffer->height != draw->height) {
      struct loader_dri3_buffer *new_buffer;

      /* Allocate the new buffers
       */
      new_buffer = dri3_alloc_render_buffer(draw,
                                                   format,
                                                   draw->width,
                                                   draw->height,
                                                   draw->depth);
      if (!new_buffer)
         return NULL;

      /* When resizing, copy the contents of the old buffer, waiting for that
       * copy to complete using our fences before proceeding
       */
      switch (buffer_type) {
      case loader_dri3_buffer_back:
         if (buffer) {
            if (!buffer->linear_buffer) {
               dri3_fence_reset(draw->conn, new_buffer);
               dri3_fence_await(draw->conn, buffer);
               dri3_copy_area(draw->conn,
                              buffer->pixmap,
                              new_buffer->pixmap,
                              dri3_drawable_gc(draw),
                              0, 0, 0, 0,
                              draw->width, draw->height);
               dri3_fence_trigger(draw->conn, new_buffer);
            } else if (draw->vtable->in_current_context(draw)) {
               draw->ext->image->blitImage(dri_context,
                                           new_buffer->image,
                                           buffer->image,
                                           0, 0, draw->width, draw->height,
                                           0, 0, draw->width, draw->height, 0);
            }
            dri3_free_render_buffer(draw, buffer);
         }
         break;
      case loader_dri3_buffer_front:
         dri3_fence_reset(draw->conn, new_buffer);
         dri3_copy_area(draw->conn,
                        draw->drawable,
                        new_buffer->pixmap,
                        dri3_drawable_gc(draw),
                        0, 0, 0, 0,
                        draw->width, draw->height);
         dri3_fence_trigger(draw->conn, new_buffer);

         if (new_buffer->linear_buffer &&
             draw->vtable->in_current_context(draw)) {
            dri3_fence_await(draw->conn, new_buffer);
            draw->ext->image->blitImage(dri_context,
                                        new_buffer->image,
                                        new_buffer->linear_buffer,
                                        0, 0, draw->width, draw->height,
                                        0, 0, draw->width, draw->height, 0);
         }
         break;
      }
      buffer = new_buffer;
      buffer->buffer_type = buffer_type;
      draw->buffers[buf_id] = buffer;
   }
   dri3_fence_await(draw->conn, buffer);

   /* Return the requested buffer */
   return buffer;
}