示例#1
0
static bool
dri3_set_drawable(struct vl_dri3_screen *scrn, Drawable drawable)
{
   xcb_get_geometry_cookie_t geom_cookie;
   xcb_get_geometry_reply_t *geom_reply;
   xcb_void_cookie_t cookie;
   xcb_generic_error_t *error;
   xcb_present_event_t peid;
   bool ret = true;

   assert(drawable);

   if (scrn->drawable == drawable)
      return true;

   scrn->drawable = drawable;

   geom_cookie = xcb_get_geometry(scrn->conn, scrn->drawable);
   geom_reply = xcb_get_geometry_reply(scrn->conn, geom_cookie, NULL);
   if (!geom_reply)
      return false;

   scrn->width = geom_reply->width;
   scrn->height = geom_reply->height;
   scrn->depth = geom_reply->depth;
   free(geom_reply);

   if (scrn->special_event) {
      xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
      scrn->special_event = NULL;
   }

   scrn->is_pixmap = false;
   peid = xcb_generate_id(scrn->conn);
   cookie =
      xcb_present_select_input_checked(scrn->conn, peid, scrn->drawable,
                      XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
                      XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
                      XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);

   error = xcb_request_check(scrn->conn, cookie);
   if (error) {
      if (error->error_code != BadWindow)
         ret = false;
      else {
         scrn->is_pixmap = true;
         if (scrn->front_buffer) {
            dri3_free_front_buffer(scrn, scrn->front_buffer);
            scrn->front_buffer = NULL;
         }
      }
      free(error);
   } else
      scrn->special_event =
         xcb_register_for_special_xge(scrn->conn, &xcb_present_id, peid, 0);

   dri3_flush_present_events(scrn);

   return ret;
}
示例#2
0
static VkResult
x11_swapchain_destroy(struct wsi_swapchain *anv_chain,
                      const VkAllocationCallbacks *pAllocator)
{
   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
   xcb_void_cookie_t cookie;

   for (uint32_t i = 0; i < chain->image_count; i++)
      x11_image_finish(chain, pAllocator, &chain->images[i]);

   if (chain->threaded) {
      chain->status = VK_ERROR_OUT_OF_DATE_KHR;
      /* Push a UINT32_MAX to wake up the manager */
      wsi_queue_push(&chain->present_queue, UINT32_MAX);
      pthread_join(chain->queue_manager, NULL);
      wsi_queue_destroy(&chain->acquire_queue);
      wsi_queue_destroy(&chain->present_queue);
   }

   xcb_unregister_for_special_event(chain->conn, chain->special_event);
   cookie = xcb_present_select_input_checked(chain->conn, chain->event_id,
                                             chain->window,
                                             XCB_PRESENT_EVENT_MASK_NO_EVENT);
   xcb_discard_reply(chain->conn, cookie.sequence);

   vk_free(pAllocator, chain);

   return VK_SUCCESS;
}
示例#3
0
文件: dri3.c 项目: sarnex/wine
static BOOL PRESENTPrivChangeWindow(PRESENTpriv *present_priv, XID window)
{
    xcb_void_cookie_t cookie;
    xcb_generic_error_t *error;
    xcb_present_event_t eid;

    PRESENTForceReleases(present_priv);
    PRESENTFreeXcbQueue(present_priv);
    present_priv->window = window;

    if (window) {
        cookie = xcb_present_select_input_checked(present_priv->xcb_connection,
                                                  (eid = xcb_generate_id(present_priv->xcb_connection)),
                                                  window,
                                                  XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY|
                                                  XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);
        present_priv->special_event = xcb_register_for_special_xge(present_priv->xcb_connection,
                                                                   &xcb_present_id,
                                                                   eid, NULL);
        error = xcb_request_check(present_priv->xcb_connection, cookie); /* performs a flush */
        if (error || !present_priv->special_event) {
            ERR("FAILED to use the X PRESENT extension. Was the destination a window ?\n");
            if (present_priv->special_event)
                xcb_unregister_for_special_event(present_priv->xcb_connection, present_priv->special_event);
            present_priv->special_event = NULL;
            present_priv->window = 0;
        }
    }
    return (present_priv->window != 0);
}
示例#4
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);
    }
}
示例#5
0
static void
vl_dri3_screen_destroy(struct vl_screen *vscreen)
{
   struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
   int i;

   assert(vscreen);

   dri3_flush_present_events(scrn);

   if (scrn->front_buffer) {
      dri3_free_front_buffer(scrn, scrn->front_buffer);
      scrn->front_buffer = NULL;
   }

   for (i = 0; i < BACK_BUFFER_NUM; ++i) {
      if (scrn->back_buffers[i]) {
         dri3_free_back_buffer(scrn, scrn->back_buffers[i]);
         scrn->back_buffers[i] = NULL;
      }
   }

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

      xcb_discard_reply(scrn->conn, cookie.sequence);
      xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
   }
   scrn->pipe->destroy(scrn->pipe);
   scrn->base.pscreen->destroy(scrn->base.pscreen);
   pipe_loader_release(&scrn->base.dev, 1);
   FREE(scrn);

   return;
}
示例#6
0
/** loader_dri3_update_drawable
 *
 * Called the first time we use the drawable and then
 * after we receive present configure notify events to
 * track the geometry of the drawable
 */
static int
dri3_update_drawable(__DRIdrawable *driDrawable,
                     struct loader_dri3_drawable *draw)
{
   if (draw->first_init) {
      xcb_get_geometry_cookie_t                 geom_cookie;
      xcb_get_geometry_reply_t                  *geom_reply;
      xcb_void_cookie_t                         cookie;
      xcb_generic_error_t                       *error;
      xcb_present_query_capabilities_cookie_t   present_capabilities_cookie;
      xcb_present_query_capabilities_reply_t    *present_capabilities_reply;

      draw->first_init = false;

      /* Try to select for input on the window.
       *
       * If the drawable is a window, this will get our events
       * delivered.
       *
       * Otherwise, we'll get a BadWindow error back from this request which
       * will let us know that the drawable is a pixmap instead.
       */

      draw->eid = xcb_generate_id(draw->conn);
      cookie =
         xcb_present_select_input_checked(draw->conn, draw->eid, draw->drawable,
                                          XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
                                          XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
                                          XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);

      present_capabilities_cookie =
         xcb_present_query_capabilities(draw->conn, draw->drawable);

      /* Create an XCB event queue to hold present events outside of the usual
       * application event queue
       */
      draw->special_event = xcb_register_for_special_xge(draw->conn,
                                                         &xcb_present_id,
                                                         draw->eid,
                                                         draw->stamp);
      geom_cookie = xcb_get_geometry(draw->conn, draw->drawable);

      geom_reply = xcb_get_geometry_reply(draw->conn, geom_cookie, NULL);

      if (!geom_reply)
         return false;

      draw->width = geom_reply->width;
      draw->height = geom_reply->height;
      draw->depth = geom_reply->depth;
      draw->vtable->set_drawable_size(draw, draw->width, draw->height);

      free(geom_reply);

      draw->is_pixmap = false;

      /* Check to see if our select input call failed. If it failed with a
       * BadWindow error, then assume the drawable is a pixmap. Destroy the
       * special event queue created above and mark the drawable as a pixmap
       */

      error = xcb_request_check(draw->conn, cookie);

      present_capabilities_reply =
          xcb_present_query_capabilities_reply(draw->conn,
                                               present_capabilities_cookie,
                                               NULL);

      if (present_capabilities_reply) {
         draw->present_capabilities = present_capabilities_reply->capabilities;
         free(present_capabilities_reply);
      } else
         draw->present_capabilities = 0;

      if (error) {
         if (error->error_code != BadWindow) {
            free(error);
            return false;
         }
         draw->is_pixmap = true;
         xcb_unregister_for_special_event(draw->conn, draw->special_event);
         draw->special_event = NULL;
      }
   }
   dri3_flush_present_events(draw);
   return true;
}