[PATCH xf86-video-amdgpu 4/6] Handle Alt+Tab case when freesync enabled in steam client v2

Nicholas Kazlauskas nicholas.kazlauskas at amd.com
Tue Sep 11 16:18:40 UTC 2018


From: Hawking Zhang <Hawking.Zhang at amd.com>

v2:
fix ddx build warning unused var

The change supports the following scenario when freesync enabled for steam game
1). use Alt+Tab to run-time switch between windowed mode and fullscreen mode
2). use option setting to switch between windowed mode and fullscreen mode
Also verified on unigine heaven via setting check/un-check fullscreen

Signed-off-by: Hawking Zhang <Hawking.Zhang at amd.com>
Reviewed-by: Flora Cui <Flora.Cui at amd.com>
---
 src/amdgpu_dri2.c      |  9 ++++++---
 src/amdgpu_drv.h       |  8 ++++++--
 src/amdgpu_extension.c | 25 +++++++++++++++----------
 src/amdgpu_kms.c       | 41 +++++++++++++++++++++++++++++++++++++++++
 src/amdgpu_present.c   |  3 ++-
 5 files changed, 70 insertions(+), 16 deletions(-)

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 8c601c8..c14ffb1 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -528,7 +528,8 @@ amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client,
 	xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info);
 
-	if (info->freesync_capable_client &&
+	if (info->allow_freesync &&
+	    info->freesync_client &&
 	    info->freesync_enabled == FALSE) {
 		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
 		if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE))
@@ -720,7 +721,8 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq,
 		}
 		/* else fall through to exchange/blit */
 	case DRI2_SWAP:
-		if (info->freesync_capable_client &&
+		if (info->allow_freesync &&
+		    info->freesync_client &&
 		    info->freesync_enabled == TRUE) {
 			if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
 				info->freesync_enabled = FALSE;
@@ -1266,7 +1268,8 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	return TRUE;
 
 blit_fallback:
-	if (info->freesync_capable_client &&
+	if (info->allow_freesync &&
+	    info->freesync_client &&
 	    info->freesync_enabled == TRUE) {
 		if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
 			info->freesync_enabled = FALSE;
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 91bb829..71274d1 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -248,6 +248,8 @@ typedef struct {
 	uint32_t family;
 	struct gbm_device *gbm;
 
+	ClipNotifyProcPtr ClipNotify;
+
 	Bool(*CloseScreen) (ScreenPtr pScreen);
 
 	void (*BlockHandler) (BLOCKHANDLER_ARGS_DECL);
@@ -304,9 +306,11 @@ typedef struct {
 	Bool allowPageFlip;
 
 	/* freesync */
-	ClientPtr freesync_capable_client;
-	uint32_t client_resource_id;
+	ClientPtr freesync_client;
+	DrawablePtr freesync_drawable;
+	XID freesync_client_id;
 	Bool freesync_enabled;
+	Bool allow_freesync;
 
 	/* cursor size */
 	int cursor_w;
diff --git a/src/amdgpu_extension.c b/src/amdgpu_extension.c
index ab7d6e3..33c8987 100644
--- a/src/amdgpu_extension.c
+++ b/src/amdgpu_extension.c
@@ -62,15 +62,17 @@ static int ProcAMDGPUFreesyncCapability(ClientPtr client)
 				client, 0, DixReadAccess);
 
 	if (!ret &&
-	    info->freesync_capable_client == NULL &&
 	    pDrawable->x == pDrawable->pScreen->x &&
 	    pDrawable->y == pDrawable->pScreen->y &&
 	    pDrawable->width == pDrawable->pScreen->width &&
 	    pDrawable->height == pDrawable->pScreen->height) {
-		info->freesync_capable_client = client;
-		cliResId = FakeClientID(client->index);
-		if (AddResource(cliResId, RT_AMDGPUCLIENT, (void *)pScrn))
-			info->client_resource_id = cliResId;
+		if (!info->freesync_client) {
+			info->freesync_client = client;
+			cliResId = FakeClientID(client->index);
+			if (AddResource(cliResId, RT_AMDGPUCLIENT, (void *)pScrn))
+				info->freesync_client_id = cliResId;
+		}
+		info->freesync_drawable = pDrawable;
 	}
 
 	return client->noClientException;
@@ -162,8 +164,8 @@ void AMDGPUFreeResourceByType(ScreenPtr pScreen)
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 
-	if (info->client_resource_id)
-		FreeResourceByType(info->client_resource_id,
+	if (info->freesync_client_id)
+		FreeResourceByType(info->freesync_client_id,
 				   RT_AMDGPUCLIENT, FALSE);
 	return;
 }
@@ -174,9 +176,10 @@ int AMDGPUClientGone(void *data, XID id)
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
 
-	if (id == (XID)info->client_resource_id) {
-		info->client_resource_id = None;
-		info->freesync_capable_client = NULL;
+	if (id == info->freesync_client_id) {
+		info->freesync_client_id = None;
+		info->freesync_client = NULL;
+		info->freesync_drawable = NULL;
 	}
 
 	if (info->freesync_enabled == TRUE) {
@@ -184,5 +187,7 @@ int AMDGPUClientGone(void *data, XID id)
 			info->freesync_enabled = FALSE;
 	}
 
+	info->allow_freesync = FALSE;
+
         return 1;
 }
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index dc98473..88af2fa 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -1722,6 +1722,42 @@ static Bool AMDGPUCloseScreen_KMS(ScreenPtr pScreen)
 	return pScreen->CloseScreen(pScreen);
 }
 
+static void AMDGPUClipNotify(WindowPtr win, int dx, int dy)
+{
+	ScreenPtr pScreen = win->drawable.pScreen;
+	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
+	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+	ClientPtr client = wClient(win);
+
+	if (info->ClipNotify) {
+		pScreen->ClipNotify = info->ClipNotify;
+		pScreen->ClipNotify(win, dx, dy);
+		info->ClipNotify = pScreen->ClipNotify;
+		pScreen->ClipNotify = AMDGPUClipNotify;
+	}
+
+	if (!info->freesync_client)
+		return;
+
+	if (client == info->freesync_client &&
+	    win->drawable.id == info->freesync_drawable->id) {
+		if (win->drawable.x == pScreen->x &&
+		    win->drawable.y == pScreen->y &&
+		    win->drawable.width == pScreen->width &&
+		    win->drawable.height == pScreen->height) {
+			info->allow_freesync = TRUE;
+		} else {
+			info->allow_freesync = FALSE;
+			if (info->freesync_enabled == TRUE &&
+			    !AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE))
+				info->freesync_enabled = FALSE;
+		}
+	}
+
+	return;
+}
+
 void AMDGPUFreeScreen_KMS(ScrnInfoPtr pScrn)
 {
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
@@ -1946,6 +1982,11 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv)
 	pScreen->SyncSharedPixmap = amdgpu_sync_shared_pixmap;
 #endif
 
+	if (!info->shadow_fb) {
+		info->ClipNotify = pScreen->ClipNotify;
+		pScreen->ClipNotify = AMDGPUClipNotify;
+	}
+
 	if (!xf86CrtcScreenInit(pScreen))
 		return FALSE;
 
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
index 8b70b38..66d264c 100644
--- a/src/amdgpu_present.c
+++ b/src/amdgpu_present.c
@@ -322,7 +322,8 @@ amdgpu_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
 	if (!amdgpu_present_check_flip(crtc, screen->root, pixmap, sync_flip))
 		return ret;
 
-	if (info->freesync_capable_client &&
+	if (info->allow_freesync &&
+	    info->freesync_client &&
 	    info->freesync_enabled == FALSE) {
 		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
 		if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE))
-- 
2.18.0



More information about the amd-gfx mailing list