X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Floader%2Floader_dri3_helper.c;h=493a7f5218cd1c76bca8edd93dd3710cdb4b1794;hb=884f65e1856733697a894c86f94803343cfa9a21;hp=67d0c2c2f3a1521112cb160067805ae331a5dd15;hpb=fd32868590c7cbc5c6c2b3d59ff66694de3864b8;p=mesa.git diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 67d0c2c2f3a..493a7f5218c 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -68,15 +68,10 @@ dri3_fence_await(xcb_connection_t *c, struct loader_dri3_buffer *buffer) 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 @@ -100,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); } @@ -111,15 +106,21 @@ 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]) 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 @@ -129,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; @@ -170,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; @@ -739,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; } @@ -855,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) @@ -891,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, @@ -929,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: @@ -1081,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; } @@ -1116,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; @@ -1146,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; @@ -1397,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); + } +}