diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2019-02-12 12:26:25 +0100 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2019-02-22 17:44:30 +0100 |
commit | d9be5d712d469595e1e610f7294bc670ca3b1985 (patch) | |
tree | 766b979374be71b82a45b7e5d58af27f5f26a253 | |
parent | ef8fbe33b7d97f7fb5518db9c0e4d2dcbf2fab6f (diff) |
Make use of property request wrappers for VRR property
Instead of scanning for PropertyNotify events. Reasons:
* Works even if no client listens to PropertyNotify events for the
window.
* No overhead on delivery of unrelated events, and no overhead at all
if Option "VariableRefresh" is disabled.
v2:
* Use shorter variable name amdgpu_vrr_atom.
* Call MakeAtom regardless of info->instance_id, for robustness vs VRR
being enabled in some but not all AMDGPU screens.
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
-rw-r--r-- | src/amdgpu_kms.c | 115 |
1 files changed, 55 insertions, 60 deletions
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index a870027..e50c6d1 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -66,6 +66,7 @@ static DevPrivateKeyRec amdgpu_window_private_key; static DevScreenPrivateKeyRec amdgpu_client_private_key; DevScreenPrivateKeyRec amdgpu_device_private_key; +static Atom amdgpu_vrr_atom; static Bool amdgpu_property_vectors_wrapped; static Bool restore_property_vector; static int (*saved_change_property) (ClientPtr client); @@ -94,17 +95,47 @@ const OptionInfoRec *AMDGPUOptionsWeak(void) return AMDGPUOptions_KMS; } +static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) { + return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key); +} + +static void +amdgpu_vrr_property_update(WindowPtr window, Bool variable_refresh) +{ + get_window_priv(window)->variable_refresh = variable_refresh; +} + /* Wrapper for xserver/dix/property.c:ProcChangeProperty */ static int amdgpu_change_property(ClientPtr client) { + WindowPtr window; int ret; + REQUEST(xChangePropertyReq); + client->requestVector[X_ChangeProperty] = saved_change_property; ret = saved_change_property(client); - if (!restore_property_vector) - client->requestVector[X_ChangeProperty] = amdgpu_change_property; + if (restore_property_vector) + return ret; + + client->requestVector[X_ChangeProperty] = amdgpu_change_property; + + if (ret != Success) + return ret; + + ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess); + if (ret != Success) + return ret; + + if (stuff->property == amdgpu_vrr_atom && + xf86ScreenToScrn(window->drawable.pScreen)->PreInit == + AMDGPUPreInit_KMS && stuff->format == 32 && stuff->nUnits == 1) { + uint32_t *value = (uint32_t*)(stuff + 1); + + amdgpu_vrr_property_update(window, *value != 0); + } return ret; } @@ -113,13 +144,30 @@ amdgpu_change_property(ClientPtr client) static int amdgpu_delete_property(ClientPtr client) { + WindowPtr window; int ret; + REQUEST(xDeletePropertyReq); + client->requestVector[X_DeleteProperty] = saved_delete_property; ret = saved_delete_property(client); - if (!restore_property_vector) - client->requestVector[X_DeleteProperty] = amdgpu_delete_property; + if (restore_property_vector) + return ret; + + client->requestVector[X_DeleteProperty] = amdgpu_delete_property; + + if (ret != Success) + return ret; + + ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess); + if (ret != Success) + return ret; + + if (stuff->property == amdgpu_vrr_atom && + xf86ScreenToScrn(window->drawable.pScreen)->PreInit == + AMDGPUPreInit_KMS) + amdgpu_vrr_property_update(window, FALSE); return ret; } @@ -236,51 +284,6 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn) free(pEnt); } -static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) { - return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key); -} - -static void -amdgpu_property_notify(ClientPtr client, - XID id, - int state, - ATOM property_name) -{ - WindowPtr win; - PropertyPtr prop; - struct amdgpu_window_priv *priv; - const char* str; - int res; - - res = dixLookupWindow(&win, id, client, DixReadAccess); - if (res != Success) - return; - - str = NameForAtom(property_name); - if (str == NULL) - return; - - if (strcmp(str, "_VARIABLE_REFRESH") != 0) - return; - - priv = get_window_priv(win); - if (!priv) - return; - - priv->variable_refresh = 0; - - res = dixLookupProperty(&prop, - win, - property_name, - client, - DixReadAccess); - - if (res == Success && prop->format == 32 && prop->size == 1) { - uint32_t value = *(uint32_t*)prop->data; - priv->variable_refresh = (value != 0); - } -} - Bool amdgpu_window_has_variable_refresh(WindowPtr win) { struct amdgpu_window_priv *priv = get_window_priv(win); @@ -328,17 +331,6 @@ amdgpu_event_callback(CallbackListPtr *list, AMDGPUInfoPtr info = AMDGPUPTR(pScrn); int i; - if (info->vrr_support) { - for (i = 0; i < eventinfo->count; i++) { - xEventPtr ev = &eventinfo->events[i]; - if (ev->u.u.type == PropertyNotify) - amdgpu_property_notify(eventinfo->client, - ev->u.property.window, - ev->u.property.state, - ev->u.property.atom); - } - } - if (callback_needs_flush(info, client_priv) || callback_needs_flush(info, server_priv)) return; @@ -2182,6 +2174,9 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) ProcVector[X_DeleteProperty] = amdgpu_delete_property; amdgpu_property_vectors_wrapped = TRUE; } + + amdgpu_vrr_atom = MakeAtom("_VARIABLE_REFRESH", + strlen("_VARIABLE_REFRESH"), TRUE); } drmmode_init(pScrn, &info->drmmode); |