egl/dri3: implement query surface hook
[mesa.git] / src / loader / loader_dri3_helper.c
index 3ce03524dac23846bde18dcea12f9413d69d0d6d..493a7f5218cd1c76bca8edd93dd3710cdb4b1794 100644 (file)
@@ -95,9 +95,9 @@ dri3_free_render_buffer(struct loader_dri3_drawable *draw,
       xcb_free_pixmap(draw->conn, buffer->pixmap);
    xcb_sync_destroy_fence(draw->conn, buffer->sync_fence);
    xshmfence_unmap_shm(buffer->shm_fence);
-   (draw->ext->image->destroyImage)(buffer->image);
+   draw->ext->image->destroyImage(buffer->image);
    if (buffer->linear_buffer)
-      (draw->ext->image->destroyImage)(buffer->linear_buffer);
+      draw->ext->image->destroyImage(buffer->linear_buffer);
    free(buffer);
 }
 
@@ -106,7 +106,7 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw)
 {
    int i;
 
-   (draw->ext->core->destroyDrawable)(draw->dri_drawable);
+   draw->ext->core->destroyDrawable(draw->dri_drawable);
 
    for (i = 0; i < LOADER_DRI3_NUM_BUFFERS; i++) {
       if (draw->buffers[i])
@@ -130,7 +130,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
                           bool is_different_gpu,
                           const __DRIconfig *dri_config,
                           struct loader_dri3_extensions *ext,
-                          struct loader_dri3_vtable *vtable,
+                          const struct loader_dri3_vtable *vtable,
                           struct loader_dri3_drawable *draw)
 {
    xcb_get_geometry_cookie_t cookie;
@@ -171,9 +171,9 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
 
    /* Create a new drawable */
    draw->dri_drawable =
-      (draw->ext->image_driver->createNewDrawable)(dri_screen,
-                                                   dri_config,
-                                                   draw);
+      draw->ext->image_driver->createNewDrawable(dri_screen,
+                                                 dri_config,
+                                                 draw);
 
    if (!draw->dri_drawable)
       return 1;
@@ -740,7 +740,7 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
          ++(*draw->stamp);
    }
 
-   (draw->ext->flush->invalidate)(draw->dri_drawable);
+   draw->ext->flush->invalidate(draw->dri_drawable);
 
    return ret;
 }
@@ -856,34 +856,34 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
       goto no_image;
 
    if (!draw->is_different_gpu) {
-      buffer->image = (draw->ext->image->createImage)(draw->dri_screen,
-                                                      width, height,
-                                                      format,
-                                                      __DRI_IMAGE_USE_SHARE |
-                                                      __DRI_IMAGE_USE_SCANOUT |
-                                                      __DRI_IMAGE_USE_BACKBUFFER,
-                                                      buffer);
+      buffer->image = draw->ext->image->createImage(draw->dri_screen,
+                                                    width, height,
+                                                    format,
+                                                    __DRI_IMAGE_USE_SHARE |
+                                                    __DRI_IMAGE_USE_SCANOUT |
+                                                    __DRI_IMAGE_USE_BACKBUFFER,
+                                                    buffer);
       pixmap_buffer = buffer->image;
 
       if (!buffer->image)
          goto no_image;
    } else {
-      buffer->image = (draw->ext->image->createImage)(draw->dri_screen,
-                                                      width, height,
-                                                      format,
-                                                      0,
-                                                      buffer);
+      buffer->image = draw->ext->image->createImage(draw->dri_screen,
+                                                    width, height,
+                                                    format,
+                                                    0,
+                                                    buffer);
 
       if (!buffer->image)
          goto no_image;
 
       buffer->linear_buffer =
-        (draw->ext->image->createImage)(draw->dri_screen,
-                                        width, height, format,
-                                        __DRI_IMAGE_USE_SHARE |
-                                        __DRI_IMAGE_USE_LINEAR |
-                                        __DRI_IMAGE_USE_BACKBUFFER,
-                                        buffer);
+        draw->ext->image->createImage(draw->dri_screen,
+                                      width, height, format,
+                                      __DRI_IMAGE_USE_SHARE |
+                                      __DRI_IMAGE_USE_LINEAR |
+                                      __DRI_IMAGE_USE_BACKBUFFER,
+                                      buffer);
       pixmap_buffer = buffer->linear_buffer;
 
       if (!buffer->linear_buffer)
@@ -892,14 +892,14 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
 
    /* X wants the stride, so ask the image for it
     */
-   if (!(draw->ext->image->queryImage)(pixmap_buffer, __DRI_IMAGE_ATTRIB_STRIDE,
-                                       &stride))
+   if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_STRIDE,
+                                     &stride))
       goto no_buffer_attrib;
 
    buffer->pitch = stride;
 
-   if (!(draw->ext->image->queryImage)(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD,
-                                       &buffer_fd))
+   if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD,
+                                     &buffer_fd))
       goto no_buffer_attrib;
 
    xcb_dri3_pixmap_from_buffer(draw->conn,
@@ -930,10 +930,10 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
    return buffer;
 
 no_buffer_attrib:
-   (draw->ext->image->destroyImage)(pixmap_buffer);
+   draw->ext->image->destroyImage(pixmap_buffer);
 no_linear_buffer:
    if (draw->is_different_gpu)
-      (draw->ext->image->destroyImage)(buffer->image);
+      draw->ext->image->destroyImage(buffer->image);
 no_image:
    free(buffer);
 no_buffer:
@@ -1082,19 +1082,19 @@ loader_dri3_create_image(xcb_connection_t *c,
     * we've gotten the planar wrapper, pull the single plane out of it and
     * discard the wrapper.
     */
-   image_planar = (image->createImageFromFds)(dri_screen,
-                                              bp_reply->width,
-                                              bp_reply->height,
-                                              image_format_to_fourcc(format),
-                                              fds, 1,
-                                              &stride, &offset, loaderPrivate);
+   image_planar = image->createImageFromFds(dri_screen,
+                                            bp_reply->width,
+                                            bp_reply->height,
+                                            image_format_to_fourcc(format),
+                                            fds, 1,
+                                            &stride, &offset, loaderPrivate);
    close(fds[0]);
    if (!image_planar)
       return NULL;
 
-   ret = (image->fromPlanar)(image_planar, 0, loaderPrivate);
+   ret = image->fromPlanar(image_planar, 0, loaderPrivate);
 
-   (image->destroyImage)(image_planar);
+   image->destroyImage(image_planar);
 
    return ret;
 }
@@ -1117,6 +1117,7 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
    xcb_sync_fence_t                     sync_fence;
    struct xshmfence                     *shm_fence;
    int                                  fence_fd;
+   __DRIscreen                          *cur_screen;
 
    if (buffer)
       return buffer;
@@ -1147,8 +1148,17 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
    if (!bp_reply)
       goto no_image;
 
+   /* Get the currently-bound screen or revert to using the drawable's screen if
+    * no contexts are currently bound. The latter case is at least necessary for
+    * obs-studio, when using Window Capture (Xcomposite) as a Source.
+    */
+   cur_screen = draw->vtable->get_dri_screen(draw);
+   if (!cur_screen) {
+       cur_screen = draw->dri_screen;
+   }
+
    buffer->image = loader_dri3_create_image(draw->conn, bp_reply, format,
-                                            draw->dri_screen, draw->ext->image,
+                                            cur_screen, draw->ext->image,
                                             buffer);
    if (!buffer->image)
       goto no_image;
@@ -1398,3 +1408,26 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable,
 
    return true;
 }
+
+/** loader_dri3_update_drawable_geometry
+ *
+ * Get the current drawable geometry.
+ */
+void
+loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw)
+{
+   xcb_get_geometry_cookie_t geom_cookie;
+   xcb_get_geometry_reply_t *geom_reply;
+
+   geom_cookie = xcb_get_geometry(draw->conn, draw->drawable);
+
+   geom_reply = xcb_get_geometry_reply(draw->conn, geom_cookie, NULL);
+
+   if (geom_reply) {
+      draw->width = geom_reply->width;
+      draw->height = geom_reply->height;
+      draw->vtable->set_drawable_size(draw, draw->width, draw->height);
+
+      free(geom_reply);
+   }
+}