diff options
author | Uday Kiran Pichika <pichika.uday.kiran@intel.com> | 2020-06-18 16:07:33 +0530 |
---|---|---|
committer | Martin Peres <martin.peres@free.fr> | 2020-09-08 08:00:20 +0000 |
commit | ede2c32ce116138ddf081932ea2c33bd6f4b6990 (patch) | |
tree | ab0bde76a493f4a40a1323a5dc324879e57813c7 | |
parent | 9823ea4ed24db76b1e61d69a8da8f7599857d02a (diff) |
modesetting: Detect changes to the _VARIABLE_REFRESH window properties
Window wrappers gets the notification when the window
properties changes. These wrappers are mainly used to
keep track of per-window _VARIABLE_REFRESH property values.
These changes have been ported from AMDGPU
Signed-off-by: Uday Kiran Pichika <pichika.uday.kiran@intel.com>
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 513816c70..63ec0ba92 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -80,6 +80,14 @@ static Bool ms_pci_probe(DriverPtr driver, intptr_t match_data); static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data); +/* window wrapper functions used to get the notification when + * the window property changes */ +static Atom vrr_atom; +static Bool property_vectors_wrapped; +static Bool restore_property_vector; +static int (*saved_change_property) (ClientPtr client); +static int (*saved_delete_property) (ClientPtr client); + #ifdef XSERVER_LIBPCIACCESS static const struct pci_id_match ms_device_match[] = { { @@ -712,6 +720,126 @@ ms_window_has_variable_refresh(modesettingPtr ms, WindowPtr win) { return priv->variable_refresh; } + +static void +ms_vrr_property_update(WindowPtr window, Bool variable_refresh) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen); + modesettingPtr ms = modesettingPTR(scrn); + + struct ms_vrr_priv *priv = dixLookupPrivate(&window->devPrivates, + &ms->drmmode.vrrPrivateKeyRec); + priv->variable_refresh = variable_refresh; + + if (ms->flip_window == window && ms->drmmode.present_flipping) + ms_present_set_screen_vrr(scrn, variable_refresh); +} + +/* Wrapper for xserver/dix/property.c:ProcChangeProperty */ +static int +ms_change_property(ClientPtr client) +{ + WindowPtr window = NULL; + int ret = 0; + + REQUEST(xChangePropertyReq); + + client->requestVector[X_ChangeProperty] = saved_change_property; + ret = saved_change_property(client); + if (ret != Success) + return ret; + + if (restore_property_vector) + return ret; + + client->requestVector[X_ChangeProperty] = ms_change_property; + + ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess); + if (ret != Success) + return ret; + + // Checking for the VRR property change on the window + if (stuff->property == vrr_atom && + xf86ScreenToScrn(window->drawable.pScreen)->PreInit == PreInit && + stuff->format == 32 && stuff->nUnits == 1) { + uint32_t *value = (uint32_t *)(stuff + 1); + ms_vrr_property_update(window, *value != 0); + } + + return ret; +} + +/* Wrapper for xserver/dix/property.c:ProcDeleteProperty */ +static int +ms_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) + return ret; + + client->requestVector[X_DeleteProperty] = ms_delete_property; + + if (ret != Success) + return ret; + + ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess); + if (ret != Success) + return ret; + + if (stuff->property == vrr_atom && + xf86ScreenToScrn(window->drawable.pScreen)->PreInit == PreInit) + ms_vrr_property_update(window, FALSE); + + return ret; +} + +static void +ms_unwrap_property_requests(ScrnInfoPtr scrn) +{ + int i; + + if (!property_vectors_wrapped) + return; + + if (ProcVector[X_ChangeProperty] == ms_change_property) + ProcVector[X_ChangeProperty] = saved_change_property; + else + restore_property_vector = TRUE; + + if (ProcVector[X_DeleteProperty] == ms_delete_property) + ProcVector[X_DeleteProperty] = saved_delete_property; + else + restore_property_vector = TRUE; + + for (i = 0; i < currentMaxClients; i++) { + if (clients[i]->requestVector[X_ChangeProperty] == ms_change_property) { + clients[i]->requestVector[X_ChangeProperty] = saved_change_property; + } else { + restore_property_vector = TRUE; + } + + if (clients[i]->requestVector[X_DeleteProperty] == ms_delete_property) { + clients[i]->requestVector[X_DeleteProperty] = saved_delete_property; + } else { + restore_property_vector = TRUE; + } + } + + if (restore_property_vector) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Couldn't unwrap some window property request vectors\n"); + } + + property_vectors_wrapped = FALSE; +} + static void FreeRec(ScrnInfoPtr pScrn) { @@ -731,6 +859,7 @@ FreeRec(ScrnInfoPtr pScrn) ms_ent = ms_ent_priv(pScrn); ms_ent->fd_ref--; if (!ms_ent->fd_ref) { + ms_unwrap_property_requests(pScrn); if (ms->pEnt->location.type == BUS_PCI) ret = drmClose(ms->fd); else @@ -1817,6 +1946,18 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) pScrn->vtSema = TRUE; + if (ms->vrr_support) { + if (!property_vectors_wrapped) { + saved_change_property = ProcVector[X_ChangeProperty]; + ProcVector[X_ChangeProperty] = ms_change_property; + saved_delete_property = ProcVector[X_DeleteProperty]; + ProcVector[X_DeleteProperty] = ms_delete_property; + property_vectors_wrapped = TRUE; + } + vrr_atom = MakeAtom("_VARIABLE_REFRESH", + strlen("_VARIABLE_REFRESH"), TRUE); + } + return TRUE; } |