summaryrefslogtreecommitdiff
path: root/hw/xfree86/drivers/modesetting
diff options
context:
space:
mode:
authorUday Kiran Pichika <pichika.uday.kiran@intel.com>2020-06-18 16:07:33 +0530
committerMartin Peres <martin.peres@free.fr>2020-09-08 08:00:20 +0000
commitede2c32ce116138ddf081932ea2c33bd6f4b6990 (patch)
treeab0bde76a493f4a40a1323a5dc324879e57813c7 /hw/xfree86/drivers/modesetting
parent9823ea4ed24db76b1e61d69a8da8f7599857d02a (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>
Diffstat (limited to 'hw/xfree86/drivers/modesetting')
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c141
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;
}