static void
dri3_update_num_back(struct loader_dri3_drawable *draw)
{
- draw->num_back = 1;
- if (draw->flipping) {
- if (!draw->is_pixmap &&
- !(draw->present_capabilities & XCB_PRESENT_CAPABILITY_ASYNC))
- draw->num_back++;
- draw->num_back++;
- }
- if (draw->vtable->get_swap_interval(draw) == 0)
- draw->num_back++;
+ if (draw->flipping)
+ draw->num_back = 3;
+ else
+ draw->num_back = 2;
}
void
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);
}
{
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])
dri3_free_render_buffer(draw, draw->buffers[i]);
}
- if (draw->special_event)
+ 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);
+ }
}
int
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;
/* 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;
++(*draw->stamp);
}
- (draw->ext->flush->invalidate)(draw->dri_drawable);
+ draw->ext->flush->invalidate(draw->dri_drawable);
return ret;
}
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)
/* 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,
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:
* 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;
}
xcb_sync_fence_t sync_fence;
struct xshmfence *shm_fence;
int fence_fd;
+ __DRIscreen *cur_screen;
if (buffer)
return buffer;
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;
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);
+ }
+}