<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>