[PATCH 1/2] Xv: Only stop the adaptors when the Pixmap is finally destroyed

Chris Wilson chris at chris-wilson.co.uk
Sun Apr 5 02:32:03 PDT 2015


Pixmaps are reference counted and DestroyPixmap is called for the
removal of every reference. However, we only want to stop the adaptors
writing into the Pixmap just before the Pixmap is finally destroyed,
similar to how Windows are handled.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 Xext/xvmain.c | 82 +++++++++++++++++------------------------------------------
 1 file changed, 24 insertions(+), 58 deletions(-)

diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index 0abf190..ad1b39d 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -327,36 +327,24 @@ XvGetRTPort(void)
     return XvRTPort;
 }
 
-static Bool
-XvDestroyPixmap(PixmapPtr pPix)
+static void
+XvStopAdaptors(DrawablePtr pDrawable)
 {
-    Bool status;
-    ScreenPtr pScreen;
-    XvScreenPtr pxvs;
-    XvAdaptorPtr pa;
-    int na;
-    XvPortPtr pp;
-    int np;
-
-    pScreen = pPix->drawable.pScreen;
-
-    SCREEN_PROLOGUE(pScreen, DestroyPixmap);
-
-    pxvs = (XvScreenPtr) dixLookupPrivate(&pScreen->devPrivates, XvScreenKey);
+    ScreenPtr pScreen = pDrawable->pScreen;
+    XvScreenPtr pxvs = dixLookupPrivate(&pScreen->devPrivates, XvScreenKey);
+    XvAdaptorPtr pa = pxvs->pAdaptors;
+    int na = pxvs->nAdaptors;
 
     /* CHECK TO SEE IF THIS PORT IS IN USE */
-
-    pa = pxvs->pAdaptors;
-    na = pxvs->nAdaptors;
     while (na--) {
-        np = pa->nPorts;
-        pp = pa->pPorts;
+        XvPortPtr pp = pa->pPorts;
+        int np = pa->nPorts;
 
         while (np--) {
-            if (pp->pDraw == (DrawablePtr) pPix) {
-                XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
+            if (pp->pDraw == pDrawable) {
+                XvdiSendVideoNotify(pp, pDrawable, XvPreempted);
 
-                (void) (*pp->pAdaptor->ddStopVideo) (pp, pp->pDraw);
+                (void) (*pp->pAdaptor->ddStopVideo) (pp, pDrawable);
 
                 pp->pDraw = NULL;
                 pp->client = NULL;
@@ -366,9 +354,19 @@ XvDestroyPixmap(PixmapPtr pPix)
         }
         pa++;
     }
+}
 
-    status = (*pScreen->DestroyPixmap) (pPix);
+static Bool
+XvDestroyPixmap(PixmapPtr pPix)
+{
+    ScreenPtr pScreen = pPix->drawable.pScreen;
+    Bool status;
+
+    if (pPix->refcnt == 1)
+        XvStopAdaptors(&pPix->drawable);
 
+    SCREEN_PROLOGUE(pScreen, DestroyPixmap);
+    status = (*pScreen->DestroyPixmap) (pPix);
     SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap);
 
     return status;
@@ -378,45 +376,13 @@ XvDestroyPixmap(PixmapPtr pPix)
 static Bool
 XvDestroyWindow(WindowPtr pWin)
 {
+    ScreenPtr pScreen = pWin->drawable.pScreen;
     Bool status;
-    ScreenPtr pScreen;
-    XvScreenPtr pxvs;
-    XvAdaptorPtr pa;
-    int na;
-    XvPortPtr pp;
-    int np;
 
-    pScreen = pWin->drawable.pScreen;
+    XvStopAdaptors(&pWin->drawable);
 
     SCREEN_PROLOGUE(pScreen, DestroyWindow);
-
-    pxvs = (XvScreenPtr) dixLookupPrivate(&pScreen->devPrivates, XvScreenKey);
-
-    /* CHECK TO SEE IF THIS PORT IS IN USE */
-
-    pa = pxvs->pAdaptors;
-    na = pxvs->nAdaptors;
-    while (na--) {
-        np = pa->nPorts;
-        pp = pa->pPorts;
-
-        while (np--) {
-            if (pp->pDraw == (DrawablePtr) pWin) {
-                XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
-
-                (void) (*pp->pAdaptor->ddStopVideo) (pp, pp->pDraw);
-
-                pp->pDraw = NULL;
-                pp->client = NULL;
-                pp->time = currentTime;
-            }
-            pp++;
-        }
-        pa++;
-    }
-
     status = (*pScreen->DestroyWindow) (pWin);
-
     SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow);
 
     return status;
-- 
2.1.4



More information about the xorg-devel mailing list