[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