diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2016-09-07 18:28:23 +0900 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2016-09-09 19:02:11 +0900 |
commit | c7d27c94cb656899746898c2e55407c3e3d7cdc8 (patch) | |
tree | 047afa799841e7054d74d297cb3336614cf1ce29 /src | |
parent | 58773d1945cfa8155d8a6c5eb3f95097535604ef (diff) |
Keep track of damage event related flushes per-client
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.
(Ported from radeon commit 121a6de72da5fcf9a32408eff36b2235f3dfbcfe)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/amdgpu_drv.h | 5 | ||||
-rw-r--r-- | src/amdgpu_kms.c | 41 |
2 files changed, 37 insertions, 9 deletions
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h index d2b3a6b..fc6a79d 100644 --- a/src/amdgpu_drv.h +++ b/src/amdgpu_drv.h @@ -185,6 +185,10 @@ struct amdgpu_buffer { uint32_t flags; }; +struct amdgpu_client_priv { + uint_fast32_t needs_flush; +}; + typedef struct { EntityInfoPtr pEnt; pciVideoPtr PciInfo; @@ -210,7 +214,6 @@ typedef struct { /* accel */ PixmapPtr fbcon_pixmap; int callback_event_type; - uint_fast32_t callback_needs_flush; uint_fast32_t gpu_flushed; uint_fast32_t gpu_synced; Bool use_glamor; diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index b1f6bd7..d557313 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -39,6 +39,7 @@ #include "amdgpu_version.h" #include "shadow.h" +#include <xf86Priv.h> #include "amdpciids.h" @@ -58,6 +59,8 @@ #include <gbm.h> +static DevScreenPrivateKeyRec amdgpu_client_private_key; + extern SymTabRec AMDGPUChipsets[]; static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen); @@ -166,9 +169,9 @@ amdgpuUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) } static Bool -callback_needs_flush(AMDGPUInfoPtr info) +callback_needs_flush(AMDGPUInfoPtr info, struct amdgpu_client_priv *client_priv) { - return (int)(info->callback_needs_flush - info->gpu_flushed) > 0; + return (int)(client_priv->needs_flush - info->gpu_flushed) > 0; } static void @@ -177,20 +180,30 @@ amdgpu_event_callback(CallbackListPtr *list, { EventInfoRec *eventinfo = call_data; ScrnInfoPtr pScrn = user_data; + ScreenPtr pScreen = pScrn->pScreen; + struct amdgpu_client_priv *client_priv = + dixLookupScreenPrivate(&eventinfo->client->devPrivates, + &amdgpu_client_private_key, pScreen); + struct amdgpu_client_priv *server_priv = + dixLookupScreenPrivate(&serverClient->devPrivates, + &amdgpu_client_private_key, pScreen); AMDGPUInfoPtr info = AMDGPUPTR(pScrn); int i; - if (callback_needs_flush(info)) + if (callback_needs_flush(info, client_priv) || + callback_needs_flush(info, server_priv)) return; - /* Don't let gpu_flushed get too far ahead of callback_needs_flush, - * in order to prevent false positives in callback_needs_flush() + /* Don't let gpu_flushed get too far ahead of needs_flush, in order + * to prevent false positives in callback_needs_flush() */ - info->callback_needs_flush = info->gpu_flushed; + client_priv->needs_flush = info->gpu_flushed; + server_priv->needs_flush = 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++; + server_priv->needs_flush++; return; } } @@ -201,9 +214,14 @@ amdgpu_flush_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { ScrnInfoPtr pScrn = user_data; + ScreenPtr pScreen = pScrn->pScreen; + ClientPtr client = call_data ? call_data : serverClient; + struct amdgpu_client_priv *client_priv = + dixLookupScreenPrivate(&client->devPrivates, + &amdgpu_client_private_key, pScreen); AMDGPUInfoPtr info = AMDGPUPTR(pScrn); - if (pScrn->vtSema && callback_needs_flush(info)) + if (pScrn->vtSema && callback_needs_flush(info, client_priv)) amdgpu_glamor_flush(pScrn); } @@ -273,6 +291,13 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen) DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); return FALSE; } + + if (!dixRegisterScreenPrivateKey(&amdgpu_client_private_key, pScreen, + PRIVATE_CLIENT, sizeof(struct amdgpu_client_priv))) { + DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); + DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn); + return FALSE; + } } return TRUE; |