<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">Reviewed-by: Alex Deucher <alexander.deucher@amd.com><br>
</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Michel Dänzer <michel@daenzer.net><br>
<b>Sent:</b> Friday, December 22, 2017 12:39:44 PM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org<br>
<b>Subject:</b> [PATCH xf86-video-amdgpu 2/2] Keep track of how many SW cursors are visible on each screen</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">From: Michel Dänzer <michel.daenzer@amd.com><br>
<br>
And use this to determine when we cannot use page flipping for DRI<br>
clients. We previously did this based on whether the HW cursor cannot<br>
be used on at least one CRTC, which had at least two issues:<br>
<br>
* Even while the HW cursor cannot be used, no SW cursor may actually be<br>
visible (e.g. because all cursors are disabled), in which case we can<br>
use page flipping for DRI clients anyway<br>
* Even while the HW cursor can be used, there may be SW cursors visible<br>
from non-core pointer devices, in which case we cannot use page<br>
flipping for DRI clients anyway<br>
<br>
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com><br>
---<br>
src/amdgpu_dri2.c | 2 +-<br>
src/amdgpu_drv.h | 13 +++++++++++++<br>
src/amdgpu_kms.c | 28 +++++++++++++++++++++++++++<br>
src/amdgpu_present.c | 2 +-<br>
src/drmmode_display.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++<br>
src/drmmode_display.h | 4 ++++<br>
6 files changed, 99 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c<br>
index a8ccd22ba..4ffa34676 100644<br>
--- a/src/amdgpu_dri2.c<br>
+++ b/src/amdgpu_dri2.c<br>
@@ -603,7 +603,7 @@ can_flip(xf86CrtcPtr crtc, DrawablePtr draw,<br>
<br>
if (draw->type != DRAWABLE_WINDOW ||<br>
!info->allowPageFlip ||<br>
- info->hwcursor_disabled ||<br>
+ info->sprites_visible > 0 ||<br>
info->drmmode.present_flipping ||<br>
!pScrn->vtSema ||<br>
!DRI2CanFlip(draw))<br>
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h<br>
index 055c3c3e9..72975d597 100644<br>
--- a/src/amdgpu_drv.h<br>
+++ b/src/amdgpu_drv.h<br>
@@ -234,6 +234,13 @@ struct amdgpu_client_priv {<br>
uint_fast32_t needs_flush;<br>
};<br>
<br>
+struct amdgpu_device_priv {<br>
+ CursorPtr cursor;<br>
+ Bool sprite_visible;<br>
+};<br>
+<br>
+extern DevScreenPrivateKeyRec amdgpu_device_private_key;<br>
+<br>
typedef struct {<br>
EntityInfoPtr pEnt;<br>
struct pci_device *PciInfo;<br>
@@ -274,6 +281,12 @@ typedef struct {<br>
CreateScreenResourcesProcPtr CreateScreenResources;<br>
CreateWindowProcPtr CreateWindow;<br>
WindowExposuresProcPtr WindowExposures;<br>
+ void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen,<br>
+ CursorPtr pCursor, int x, int y);<br>
+ void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);<br>
+<br>
+ /* Number of SW cursor currently visible on this screen */<br>
+ int sprites_visible;<br>
<br>
Bool IsSecondary;<br>
<br>
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c<br>
index 58531bf33..49044f514 100644<br>
--- a/src/amdgpu_kms.c<br>
+++ b/src/amdgpu_kms.c<br>
@@ -37,6 +37,7 @@<br>
#include "amdgpu_glamor.h"<br>
#include "amdgpu_probe.h"<br>
#include "micmap.h"<br>
+#include "mipointrst.h"<br>
<br>
#include "amdgpu_version.h"<br>
#include "shadow.h"<br>
@@ -62,6 +63,7 @@<br>
#include <gbm.h><br>
<br>
static DevScreenPrivateKeyRec amdgpu_client_private_key;<br>
+DevScreenPrivateKeyRec amdgpu_device_private_key;<br>
<br>
static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen);<br>
<br>
@@ -1532,6 +1534,23 @@ static Bool AMDGPUCursorInit_KMS(ScreenPtr pScreen)<br>
/* Cursor setup */<br>
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());<br>
<br>
+ if (info->allowPageFlip) {<br>
+ miPointerScreenPtr PointPriv =<br>
+ dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);<br>
+<br>
+ if (!dixRegisterScreenPrivateKey(&amdgpu_device_private_key, pScreen,<br>
+ PRIVATE_DEVICE,<br>
+ sizeof(struct amdgpu_device_priv))) {<br>
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "dixRegisterScreenPrivateKey failed\n");<br>
+ return FALSE;<br>
+ }<br>
+<br>
+ info->SetCursor = PointPriv->spriteFuncs->SetCursor;<br>
+ info->MoveCursor = PointPriv->spriteFuncs->MoveCursor;<br>
+ PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor;<br>
+ PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor;<br>
+ }<br>
+<br>
if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))<br>
return TRUE;<br>
<br>
@@ -1701,6 +1720,15 @@ static Bool AMDGPUCloseScreen_KMS(ScreenPtr pScreen)<br>
amdgpu_glamor_fini(pScreen);<br>
pScrn->vtSema = FALSE;<br>
xf86ClearPrimInitDone(info->pEnt->index);<br>
+<br>
+ if (info->allowPageFlip) {<br>
+ miPointerScreenPtr PointPriv =<br>
+ dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);<br>
+<br>
+ PointPriv->spriteFuncs->SetCursor = info->SetCursor;<br>
+ PointPriv->spriteFuncs->MoveCursor = info->MoveCursor;<br>
+ }<br>
+<br>
pScreen->BlockHandler = info->BlockHandler;<br>
pScreen->CloseScreen = info->CloseScreen;<br>
return pScreen->CloseScreen(pScreen);<br>
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c<br>
index cef93c068..4e74bfac9 100644<br>
--- a/src/amdgpu_present.c<br>
+++ b/src/amdgpu_present.c<br>
@@ -273,7 +273,7 @@ amdgpu_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,<br>
if (!info->allowPageFlip)<br>
return FALSE;<br>
<br>
- if (info->hwcursor_disabled)<br>
+ if (info->sprites_visible > 0)<br>
return FALSE;<br>
<br>
if (info->drmmode.dri2_flipping)<br>
diff --git a/src/drmmode_display.c b/src/drmmode_display.c<br>
index 55551eea7..047179449 100644<br>
--- a/src/drmmode_display.c<br>
+++ b/src/drmmode_display.c<br>
@@ -34,6 +34,7 @@<br>
#include <time.h><br>
#include "cursorstr.h"<br>
#include "damagestr.h"<br>
+#include "inputstr.h"<br>
#include "list.h"<br>
#include "micmap.h"<br>
#include "xf86cmap.h"<br>
@@ -2431,6 +2432,57 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)<br>
drmmode_crtc_scanout_free(config->crtc[c]->driver_private);<br>
}<br>
<br>
+static void drmmode_sprite_do_set_cursor(struct amdgpu_device_priv *device_priv,<br>
+ ScrnInfoPtr scrn, int x, int y)<br>
+{<br>
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);<br>
+ CursorPtr cursor = device_priv->cursor;<br>
+ Bool sprite_visible = device_priv->sprite_visible;<br>
+<br>
+ if (cursor) {<br>
+ x -= cursor->bits->xhot;<br>
+ y -= cursor->bits->yhot;<br>
+<br>
+ device_priv->sprite_visible =<br>
+ x < scrn->virtualX && y < scrn->virtualY &&<br>
+ (x + cursor->bits->width > 0) &&<br>
+ (y + cursor->bits->height > 0);<br>
+ } else {<br>
+ device_priv->sprite_visible = FALSE;<br>
+ }<br>
+<br>
+ info->sprites_visible += device_priv->sprite_visible - sprite_visible;<br>
+}<br>
+<br>
+void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,<br>
+ CursorPtr pCursor, int x, int y)<br>
+{<br>
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);<br>
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);<br>
+ struct amdgpu_device_priv *device_priv =<br>
+ dixLookupScreenPrivate(&pDev->devPrivates,<br>
+ &amdgpu_device_private_key, pScreen);<br>
+<br>
+ device_priv->cursor = pCursor;<br>
+ drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);<br>
+<br>
+ info->SetCursor(pDev, pScreen, pCursor, x, y);<br>
+}<br>
+<br>
+void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,<br>
+ int y)<br>
+{<br>
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);<br>
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);<br>
+ struct amdgpu_device_priv *device_priv =<br>
+ dixLookupScreenPrivate(&pDev->devPrivates,<br>
+ &amdgpu_device_private_key, pScreen);<br>
+<br>
+ drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);<br>
+<br>
+ info->MoveCursor(pDev, pScreen, x, y);<br>
+}<br>
+<br>
void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id,<br>
struct amdgpu_buffer *bo)<br>
{<br>
diff --git a/src/drmmode_display.h b/src/drmmode_display.h<br>
index 03134f0c9..4e6f70776 100644<br>
--- a/src/drmmode_display.h<br>
+++ b/src/drmmode_display.h<br>
@@ -198,6 +198,10 @@ extern int drmmode_page_flip_target_relative(AMDGPUEntPtr pAMDGPUEnt,<br>
extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);<br>
extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);<br>
extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);<br>
+extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,<br>
+ CursorPtr pCursor, int x, int y);<br>
+extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,<br>
+ int y);<br>
extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id,<br>
struct amdgpu_buffer *bo);<br>
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);<br>
-- <br>
2.15.1<br>
<br>
_______________________________________________<br>
amd-gfx mailing list<br>
amd-gfx@lists.freedesktop.org<br>
<a href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a><br>
</div>
</span></font></div>
</body>
</html>