Commit 0fd7d5de authored by Siarhei Siamashka's avatar Siarhei Siamashka
Browse files

DRI2: CPU copy fallback path does not drop half of the frames anymore

The recent commit 9e0a8731

 (its part
that suppressed buffers reuse in the Xorg DRI2 framework) introduced
a regression. Half of the frames stoppped reaching the screen on
the CPU copy fallback path because the Mali blob now ended up
rendering them to the "wrong" buffer.

It just confirms that we need to completely move from the standard
DRI2 framework in the Xorg server to our own buffers bookkeeping
logic. This patch fixes the regression by introducing a single UMP
buffer per window, which is shared between back and front DRI2
buffers. We can do this because double buffering does not make much
sense on the fallback path at the moment (we can't set scanout from
this buffer and anyway have to copy this data elsewhere immediately
after we get it from Mali).
Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
parent 7994a0f3
...@@ -190,6 +190,23 @@ static void UpdateOverlay(ScreenPtr pScreen); ...@@ -190,6 +190,23 @@ static void UpdateOverlay(ScreenPtr pScreen);
typedef UMPBufferInfoRec MaliDRI2BufferPrivateRec; typedef UMPBufferInfoRec MaliDRI2BufferPrivateRec;
typedef UMPBufferInfoPtr MaliDRI2BufferPrivatePtr; typedef UMPBufferInfoPtr MaliDRI2BufferPrivatePtr;
static void unref_ump_buffer_info(UMPBufferInfoPtr umpbuf)
{
if (--umpbuf->refcount <= 0) {
DebugMsg("unref_ump_buffer_info(%p) [refcount=%d, handle=%p]\n",
umpbuf, umpbuf->refcount, umpbuf->handle);
if (umpbuf->handle != UMP_INVALID_MEMORY_HANDLE) {
ump_mapped_pointer_release(umpbuf->handle);
ump_reference_release(umpbuf->handle);
}
free(umpbuf);
}
else {
DebugMsg("Reduced ump_buffer_info %p refcount to %d\n",
umpbuf, umpbuf->refcount);
}
}
static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw,
unsigned int attachment, unsigned int attachment,
unsigned int format) unsigned int format)
...@@ -336,6 +353,25 @@ static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, ...@@ -336,6 +353,25 @@ static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw,
} }
} }
else { else {
/* Reuse the existing UMP buffer if we can */
if (window_state->ump_mem_buffer_ptr &&
window_state->ump_mem_buffer_ptr->size == privates->size &&
window_state->ump_mem_buffer_ptr->depth == privates->depth &&
window_state->ump_mem_buffer_ptr->width == privates->width &&
window_state->ump_mem_buffer_ptr->height == privates->height) {
free(privates);
privates = window_state->ump_mem_buffer_ptr;
privates->refcount++;
buffer->driverPrivate = privates;
buffer->name = ump_secure_id_get(privates->handle);
DebugMsg("Reuse the already allocated UMP buffer %p, ump=%d\n",
privates, buffer->name);
return buffer;
}
/* Allocate UMP memory buffer */ /* Allocate UMP memory buffer */
#ifdef HAVE_LIBUMP_CACHE_CONTROL #ifdef HAVE_LIBUMP_CACHE_CONTROL
privates->handle = ump_ref_drv_allocate(privates->size, privates->handle = ump_ref_drv_allocate(privates->size,
...@@ -356,6 +392,13 @@ static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, ...@@ -356,6 +392,13 @@ static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw,
privates->addr = ump_mapped_pointer_get(privates->handle); privates->addr = ump_mapped_pointer_get(privates->handle);
buffer->name = ump_secure_id_get(privates->handle); buffer->name = ump_secure_id_get(privates->handle);
buffer->flags = 0; buffer->flags = 0;
/* Replace the old UMP buffer with the newly allocated one */
if (window_state->ump_mem_buffer_ptr)
unref_ump_buffer_info(window_state->ump_mem_buffer_ptr);
window_state->ump_mem_buffer_ptr = privates;
privates->refcount++;
} }
DebugMsg("DRI2CreateBuffer win=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d\n", DebugMsg("DRI2CreateBuffer win=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d\n",
...@@ -381,17 +424,7 @@ static void MaliDRI2DestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) ...@@ -381,17 +424,7 @@ static void MaliDRI2DestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
if (buffer != NULL) { if (buffer != NULL) {
privates = (MaliDRI2BufferPrivatePtr)buffer->driverPrivate; privates = (MaliDRI2BufferPrivatePtr)buffer->driverPrivate;
if (!privates->pPixmap) { unref_ump_buffer_info(privates);
/* If pPixmap != 0, then these are freed in DestroyPixmap */
if (privates->handle != UMP_INVALID_MEMORY_HANDLE) {
ump_mapped_pointer_release(privates->handle);
ump_reference_release(privates->handle);
}
}
if (--privates->refcount <= 0) {
DebugMsg("free(privates)\n");
free(privates);
}
free(buffer); free(buffer);
} }
} }
...@@ -575,6 +608,8 @@ DestroyWindow(WindowPtr pWin) ...@@ -575,6 +608,8 @@ DestroyWindow(WindowPtr pWin)
if (window_state) { if (window_state) {
DebugMsg("Free DRI2 bookkeeping for window %p\n", pWin); DebugMsg("Free DRI2 bookkeeping for window %p\n", pWin);
HASH_DEL(private->HashWindowState, window_state); HASH_DEL(private->HashWindowState, window_state);
if (window_state->ump_mem_buffer_ptr)
unref_ump_buffer_info(window_state->ump_mem_buffer_ptr);
free(window_state); free(window_state);
} }
...@@ -650,15 +685,9 @@ DestroyPixmap(PixmapPtr pPixmap) ...@@ -650,15 +685,9 @@ DestroyPixmap(PixmapPtr pPixmap)
pPixmap->devKind = umpbuf->BackupDevKind; pPixmap->devKind = umpbuf->BackupDevKind;
pPixmap->devPrivate.ptr = umpbuf->BackupDevPrivatePtr; pPixmap->devPrivate.ptr = umpbuf->BackupDevPrivatePtr;
ump_mapped_pointer_release(umpbuf->handle);
ump_reference_release(umpbuf->handle);
HASH_DEL(self->HashPixmapToUMP, umpbuf); HASH_DEL(self->HashPixmapToUMP, umpbuf);
DebugMsg("umpbuf->refcount=%d\n", umpbuf->refcount); umpbuf->pPixmap = NULL;
if (--umpbuf->refcount <= 0) { unref_ump_buffer_info(umpbuf);
DebugMsg("free(umpbuf)\n");
free(umpbuf);
}
} }
pScreen->DestroyPixmap = self->DestroyPixmap; pScreen->DestroyPixmap = self->DestroyPixmap;
......
...@@ -77,6 +77,9 @@ typedef struct ...@@ -77,6 +77,9 @@ typedef struct
int width, height; int width, height;
/* the number of back buffer requests */ /* the number of back buffer requests */
int buf_request_cnt; int buf_request_cnt;
/* allocated UMP buffer (shared between back and front DRI2 buffers) */
UMPBufferInfoPtr ump_mem_buffer_ptr;
} DRI2WindowStateRec, *DRI2WindowStatePtr; } DRI2WindowStateRec, *DRI2WindowStatePtr;
typedef struct { typedef struct {
......
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