From: Michel Dänzer <michel.daenzer@xxxxxxx> This further reduces the compositing slowdown due to flushing overhead, by only flushing when the X server actually sends XDamageNotify events to a client, and there hasn't been a flush yet in the meantime. Signed-off-by: Michel Dänzer <michel.daenzer at amd.com> --- This patch can't have an effect without a corresponding xserver patch which passes the ClientPtr to the FlushCallback, so I'll only push this one once the xserver patch has landed. src/radeon.h | 5 ++++- src/radeon_kms.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 25ff61c..b119241 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -448,6 +448,10 @@ struct radeon_accel_state { Bool force; }; +struct radeon_client_priv { + uint_fast32_t needs_flush[0]; +}; + typedef struct { EntityInfoPtr pEnt; pciVideoPtr PciInfo; @@ -474,7 +478,6 @@ typedef struct { Bool allowColorTiling; Bool allowColorTiling2D; int callback_event_type; - uint_fast32_t callback_needs_flush; uint_fast32_t gpu_flushed; uint_fast32_t gpu_synced; struct radeon_accel_state *accel_state; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index da11358..7ede3a1 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -40,6 +40,7 @@ #include "radeon_version.h" #include "shadow.h" +#include <xf86Priv.h> #include "atipciids.h" @@ -59,6 +60,8 @@ #include "radeon_cs_gem.h" #include "radeon_vbo.h" +static DevPrivateKeyRec radeon_client_private_key; + extern SymTabRec RADEONChipsets[]; static Bool radeon_setup_kernel_mem(ScreenPtr pScreen); @@ -241,9 +244,9 @@ radeonUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) } static Bool -callback_needs_flush(RADEONInfoPtr info) +callback_needs_flush(RADEONInfoPtr info, uint_fast32_t needs_flush) { - return (int)(info->callback_needs_flush - info->gpu_flushed) > 0; + return (int)(needs_flush - info->gpu_flushed) > 0; } static void @@ -251,21 +254,28 @@ radeon_event_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { EventInfoRec *eventinfo = call_data; + struct radeon_client_priv *client_priv = + dixLookupPrivate(&eventinfo->client->devPrivates, &radeon_client_private_key); + struct radeon_client_priv *server_priv = + dixLookupPrivate(&serverClient->devPrivates, &radeon_client_private_key); ScrnInfoPtr pScrn = user_data; RADEONInfoPtr info = RADEONPTR(pScrn); int i; - if (callback_needs_flush(info)) + if (callback_needs_flush(info, client_priv->needs_flush[pScrn->scrnIndex]) || + callback_needs_flush(info, server_priv->needs_flush[pScrn->scrnIndex])) return; /* Don't let gpu_flushed get too far ahead of callback_needs_flush, * in order to prevent false positives in callback_needs_flush() */ - info->callback_needs_flush = info->gpu_flushed; + client_priv->needs_flush[pScrn->scrnIndex] = info->gpu_flushed; + server_priv->needs_flush[pScrn->scrnIndex] = info->gpu_flushed; for (i = 0; i < eventinfo->count; i++) { if (eventinfo->events[i].u.u.type == info->callback_event_type) { - info->callback_needs_flush++; + client_priv->needs_flush[pScrn->scrnIndex]++; + server_priv->needs_flush[pScrn->scrnIndex]++; return; } } @@ -276,9 +286,13 @@ radeon_flush_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { ScrnInfoPtr pScrn = user_data; + ClientPtr client = call_data ? call_data : serverClient; + struct radeon_client_priv *client_priv = + dixLookupPrivate(&client->devPrivates, &radeon_client_private_key); RADEONInfoPtr info = RADEONPTR(pScrn); - if (pScrn->vtSema && callback_needs_flush(info)) + if (pScrn->vtSema && + callback_needs_flush(info, client_priv->needs_flush[pScrn->scrnIndex])) radeon_cs_flush_indirect(pScrn); } @@ -351,6 +365,14 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn); return FALSE; } + + if (!dixPrivateKeyRegistered(&radeon_client_private_key) && + !dixRegisterPrivateKey(&radeon_client_private_key, PRIVATE_CLIENT, + xf86NumScreens * sizeof(uint_fast32_t))) { + DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn); + DeleteCallback(&EventCallback, radeon_event_callback, pScrn); + return FALSE; + } } return TRUE; -- 2.8.1