[Mesa-dev] [PATCH 9/9] loader_dri3: Make sure we have an updated back v2
Thomas Hellstrom
thellstrom at vmware.com
Wed Aug 16 06:32:28 UTC 2017
On 08/15/2017 08:32 PM, Thomas Hellstrom wrote:
> With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations
> when glXSwapBuffers() is immediately followed by for example another
> glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we
> haven't yet allocated and initialized a new back buffer because there was
> no GL rendering in between.
>
> Make sure that we have a back buffer in those situations.
>
> v2: Eliminate the drawable have_back_format member.
>
> Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
> ---
> src/loader/loader_dri3_helper.c | 62 ++++++++++++++++++++++++++++++++++-------
> src/loader/loader_dri3_helper.h | 1 +
> 2 files changed, 53 insertions(+), 10 deletions(-)
>
> diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
> index 55e1471..a2885ac 100644
> --- a/src/loader/loader_dri3_helper.c
> +++ b/src/loader/loader_dri3_helper.c
> @@ -59,6 +59,9 @@ static struct loader_dri3_blit_context blit_context = {
> static void
> dri3_flush_present_events(struct loader_dri3_drawable *draw);
>
> +static struct loader_dri3_buffer *
> +dri3_find_back_alloc(struct loader_dri3_drawable *draw);
> +
> /**
> * Do we have blit functionality in the image blit extension?
> *
> @@ -269,6 +272,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
> draw->first_init = true;
>
> draw->cur_blit_source = -1;
> + draw->back_format = __DRI_IMAGE_FORMAT_NONE;
>
> if (draw->ext->config)
> draw->ext->config->configQueryi(draw->dri_screen,
> @@ -616,7 +620,10 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
> flags |= __DRI2_FLUSH_CONTEXT;
> loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
>
> - back = dri3_back_buffer(draw);
> + back = dri3_find_back_alloc(draw);
> + if (!back)
> + return;
> +
> y = draw->height - y - height;
>
> if (draw->is_different_gpu) {
> @@ -641,7 +648,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
> loader_dri3_swapbuffer_barrier(draw);
> dri3_fence_reset(draw->conn, back);
> dri3_copy_area(draw->conn,
> - dri3_back_buffer(draw)->pixmap,
> + back->pixmap,
> draw->drawable,
> dri3_drawable_gc(draw),
> x, y, x, y, width, height);
> @@ -652,7 +659,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
> if (draw->have_fake_front && !draw->is_different_gpu) {
> dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
> dri3_copy_area(draw->conn,
> - dri3_back_buffer(draw)->pixmap,
> + back->pixmap,
> dri3_fake_front_buffer(draw)->pixmap,
> dri3_drawable_gc(draw),
> x, y, x, y, width, height);
> @@ -763,7 +770,8 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
>
> draw->vtable->flush_drawable(draw, flush_flags);
>
> - back = draw->buffers[dri3_find_back(draw)];
> + back = dri3_find_back_alloc(draw);
> +
> if (draw->is_different_gpu && back) {
> /* Update the linear buffer before presenting the pixmap */
> (void) loader_dri3_blit_image(draw,
> @@ -892,15 +900,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
> int
> loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
> {
> - int back_id = LOADER_DRI3_BACK_ID(dri3_find_back(draw));
> + struct loader_dri3_buffer *back = dri3_find_back_alloc(draw);
>
> - if (back_id < 0 || !draw->buffers[back_id])
> + if (!back || back->last_swap == 0)
> return 0;
>
> - if (draw->buffers[back_id]->last_swap != 0)
> - return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
> - else
> - return 0;
> + return draw->send_sbc - back->last_swap + 1;
> }
>
> /** loader_dri3_open
> @@ -1334,6 +1339,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
> int buf_id;
>
> if (buffer_type == loader_dri3_buffer_back) {
> + draw->back_format = format;
> +
> buf_id = dri3_find_back(draw);
>
> if (buf_id < 0)
> @@ -1620,3 +1627,38 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
> }
> mtx_unlock(&blit_context.mtx);
> }
> +
> +/**
> + * Find a backbuffer slot - potentially allocating a back buffer
> + *
> + * \param draw[in,out] Pointer to the drawable for which to find back.
> + * \return Pointer to a new back buffer or NULL if allocation failed or was
> + * not mandated.
> + *
> + * Find a potentially new back buffer, and if it's not been allocated yet and
> + * in addition needs initializing, then try to allocate and initialize it.
> + */
> +static struct loader_dri3_buffer *
> +dri3_find_back_alloc(struct loader_dri3_drawable *draw)
> +{
> + struct loader_dri3_buffer *back;
> + int id;
> +
> + id = dri3_find_back(draw);
> + back = (id >= 0) ? draw->buffers[id] : NULL;
> +
> + if (!back && draw->back_format != __DRI_IMAGE_FORMAT_NONE) {
> + (void) dri3_get_buffer(draw->dri_drawable,
> + draw->back_format,
> + loader_dri3_buffer_back,
> + draw);
> + } else if (back) {
Actually, if we end up here on a glXSwapBuffer immediately followed by a
glXSwapBuffer, a local back-preserving copy will not take place. We need
to call dri3_get_buffer() here as well. Will send out a v3 for reference.
/Thomas
More information about the mesa-dev
mailing list