Commit 30b4ca27 authored by Siarhei Siamashka's avatar Siarhei Siamashka
Browse files

DRI2: Ensure correct ordering of frames after window resize



In double buffer mode, explicitly mark the buffers as designated
for odd or even frame position when putting them into queue. And
when swapping the buffers, use these flags to re-synchronize if
it is necessary. This prevents problems after window resize (when
gles-rgb-cycle-demo could expose a mismatch between the color
name in the window title and the actual window color).
Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
parent 84ee17d9
......@@ -394,10 +394,14 @@ static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw,
buffer->name = private->ump_fb_secure_id;
if (window_state->buf_request_cnt & 1)
if (window_state->buf_request_cnt & 1) {
buffer->flags = disp->gfx_layer_size;
else
privates->extra_flags |= UMPBUF_MUST_BE_ODD_FRAME;
}
else {
buffer->flags = disp->gfx_layer_size + privates->size;
privates->extra_flags |= UMPBUF_MUST_BE_EVEN_FRAME;
}
umpbuf_add_to_queue(window_state, privates);
privates->refcount++;
......@@ -631,16 +635,35 @@ static void MaliDRI2CopyRegion(DrawablePtr pDraw,
}
/* Try to fetch a new UMP buffer from the queue */
if (umpbuf = umpbuf_fetch_from_queue(window_state)) {
if (window_state->ump_back_buffer_ptr)
unref_ump_buffer_info(window_state->ump_back_buffer_ptr);
window_state->ump_back_buffer_ptr = umpbuf;
}
umpbuf = umpbuf_fetch_from_queue(window_state);
/* Swap back and front buffers */
umpbuf = window_state->ump_back_buffer_ptr;
/*
* Swap back and front buffers. But also ensure that the buffer
* flags UMPBUF_MUST_BE_ODD_FRAME and UMPBUF_MUST_BE_EVEN_FRAME
* are respected. In the case if swapping the buffers would result
* in fetching the UMP buffer from the queue in the wrong order,
* just skip the swap. This is a hack, which causes some temporary
* glitch when resizing windows, but prevents a bigger problem.
*/
if (!umpbuf || (!((umpbuf->extra_flags & UMPBUF_MUST_BE_ODD_FRAME) &&
(window_state->buf_swap_cnt & 1)) &&
!((umpbuf->extra_flags & UMPBUF_MUST_BE_EVEN_FRAME) &&
!(window_state->buf_swap_cnt & 1)))) {
UMPBufferInfoPtr tmp = window_state->ump_back_buffer_ptr;
window_state->ump_back_buffer_ptr = window_state->ump_front_buffer_ptr;
window_state->ump_front_buffer_ptr = tmp;
window_state->buf_swap_cnt++;
}
/* Try to replace the front buffer with a new UMP buffer from the queue */
if (umpbuf) {
if (window_state->ump_front_buffer_ptr)
unref_ump_buffer_info(window_state->ump_front_buffer_ptr);
window_state->ump_front_buffer_ptr = umpbuf;
}
else {
umpbuf = window_state->ump_front_buffer_ptr;
}
if (!umpbuf)
umpbuf = window_state->ump_mem_buffer_ptr;
......
......@@ -29,6 +29,9 @@
#include "uthash.h"
#define UMPBUF_MUST_BE_ODD_FRAME 1
#define UMPBUF_MUST_BE_EVEN_FRAME 2
/* Data structure with the information about an UMP buffer */
typedef struct
{
......@@ -45,6 +48,7 @@ typedef struct
int depth;
size_t width;
size_t height;
int extra_flags;
ump_secure_id secure_id;
unsigned int pitch;
......@@ -81,7 +85,9 @@ typedef struct
/* width and height must be the same for back and front buffers */
int width, height;
/* the number of back buffer requests */
int buf_request_cnt;
unsigned int buf_request_cnt;
/* the number of back/front buffer swaps */
unsigned int buf_swap_cnt;
/* allocated UMP buffer (shared between back and front DRI2 buffers) */
UMPBufferInfoPtr ump_mem_buffer_ptr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment