[PATCH] Notify DRI when crtc regions change

Keith Packard keithp at keithp.com
Fri Nov 14 12:50:12 PST 2008


Drivers that care about crtc positions on the screen to ensure that vblank
works correctly need to be notified when crtcs are changed.

Provide a hook in the mode setting code that is invoked whenever any
configuration is done to the screen.

Use this new hook in the DRI code so that DRI clients are notified and
receive updated information.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 hw/xfree86/dri/Makefile.am  |    5 +++++
 hw/xfree86/dri/dri.c        |   19 +++++++++++++++++++
 hw/xfree86/dri/dristruct.h  |    2 ++
 hw/xfree86/loader/xf86sym.c |    3 +++
 hw/xfree86/modes/xf86Crtc.c |   33 +++++++++++++++++++++++++++++++++
 hw/xfree86/modes/xf86Crtc.h |   14 ++++++++++++++
 6 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/dri/Makefile.am b/hw/xfree86/dri/Makefile.am
index e17cea7..3ec30be 100644
--- a/hw/xfree86/dri/Makefile.am
+++ b/hw/xfree86/dri/Makefile.am
@@ -1,6 +1,11 @@
 libdri_la_LTLIBRARIES = libdri.la
 libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \
                    -I$(top_srcdir)/hw/xfree86/os-support \
+                   -I$(top_srcdir)/hw/xfree86/modes \
+                   -I$(top_srcdir)/hw/xfree86/ddc \
+                   -I$(top_srcdir)/hw/xfree86/i2c \
+                   -I$(top_srcdir)/hw/xfree86/parser \
+                   -I$(top_srcdir)/hw/xfree86/ramdac \
                    -I$(top_srcdir)/hw/xfree86/os-support/bus \
                    -I$(top_srcdir)/glx \
                    -I$(top_srcdir)/GL/include \
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 3713659..1a3e091 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -302,6 +302,18 @@ DRIOpenDRMMaster(ScrnInfoPtr pScrn,
     return FALSE;
 }
 
+static void
+DRIClipNotifyAllDrawables(ScreenPtr pScreen);
+
+static void
+dri_crtc_notify(ScreenPtr pScreen)
+{
+    DRIScreenPrivPtr  pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+    DRIClipNotifyAllDrawables(pScreen);
+    xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+    xf86_crtc_notify(pScreen);
+    pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen, dri_crtc_notify);
+}
 
 Bool
 DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
@@ -605,6 +617,9 @@ DRIFinishScreenInit(ScreenPtr pScreen)
     pDRIPriv->DestroyWindow             = pScreen->DestroyWindow;
     pScreen->DestroyWindow              = DRIDestroyWindow;
 
+    pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen,
+						       dri_crtc_notify);
+						       
     if (pDRIInfo->wrap.CopyWindow) {
 	pDRIPriv->wrap.CopyWindow       = pScreen->CopyWindow;
 	pScreen->CopyWindow             = pDRIInfo->wrap.CopyWindow;
@@ -658,6 +673,9 @@ DRICloseScreen(ScreenPtr pScreen)
 		pScreen->DestroyWindow          = pDRIPriv->DestroyWindow;
 		pDRIPriv->DestroyWindow         = NULL;
 	    }
+
+	    xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+
 	    if (pDRIInfo->wrap.CopyWindow) {
 		pScreen->CopyWindow             = pDRIPriv->wrap.CopyWindow;
 		pDRIPriv->wrap.CopyWindow       = NULL;
@@ -671,6 +689,7 @@ DRICloseScreen(ScreenPtr pScreen)
 		pScrn->AdjustFrame              = pDRIPriv->wrap.AdjustFrame;
 		pDRIPriv->wrap.AdjustFrame      = NULL;
 	    }
+	    
 	    pDRIPriv->wrapped = FALSE;
 	}
 
diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h
index ae970d8..fc929c2 100644
--- a/hw/xfree86/dri/dristruct.h
+++ b/hw/xfree86/dri/dristruct.h
@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DRI_STRUCT_H
 
 #include "xf86drm.h"
+#include "xf86Crtc.h"
 
 
 #define DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin) ((DRIDrawablePrivPtr) \
@@ -106,6 +107,7 @@ typedef struct _DRIScreenPrivRec
     XF86DRILSAREAPtr    pLSAREA;      /* Mapped pointer to SAREA containing lock */
     int*                pLockRefCount;
     int*                pLockingContext;
+    xf86_crtc_notify_proc_ptr	xf86_crtc_notify;
 } DRIScreenPrivRec, *DRIScreenPrivPtr;
 
 
diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index 4891be2..373a651 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -914,6 +914,9 @@ _X_HIDDEN void *xfree86LookupTab[] = {
     SYMFUNC(xf86_hide_cursors)
     SYMFUNC(xf86_cursors_fini)
     SYMFUNC(xf86_crtc_clip_video_helper)
+    SYMFUNC(xf86_wrap_crtc_notify)
+    SYMFUNC(xf86_unwrap_crtc_notify)
+    SYMFUNC(xf86_crtc_notify)
 
     SYMFUNC(xf86DoEDID_DDC1)
     SYMFUNC(xf86DoEDID_DDC2)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index df47598..774e1fe 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2571,6 +2571,8 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
 	    memset(&crtc->mode, 0, sizeof(crtc->mode));
 	}
     }
+    if (pScrn->pScreen)
+	xf86_crtc_notify(pScrn->pScreen);
 }
 
 #ifdef RANDR_12_INTERFACE
@@ -2825,3 +2827,34 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
 
     return ret;
 }
+
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86_crtc_notify_proc_ptr	old;
+    
+    old = config->xf86_crtc_notify;
+    config->xf86_crtc_notify = new;
+    return old;
+}
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+
+    config->xf86_crtc_notify = old;
+}
+
+void
+xf86_crtc_notify(ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+    if (config->xf86_crtc_notify)
+	config->xf86_crtc_notify(screen);
+}
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 83b1f13..ef8589e 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -569,6 +569,8 @@ typedef struct _xf86CrtcConfigFuncs {
 	      int		height);
 } xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
 
+typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
+
 typedef struct _xf86CrtcConfig {
     int			num_output;
     xf86OutputPtr	*output;
@@ -621,6 +623,9 @@ typedef struct _xf86CrtcConfig {
     /* wrap screen BlockHandler for rotation */
     ScreenBlockHandlerProcPtr	BlockHandler;
 
+    /* callback when crtc configuration changes */
+    xf86_crtc_notify_proc_ptr  xf86_crtc_notify;
+
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
@@ -838,4 +843,13 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
 			    INT32	width,
 			    INT32	height);
     
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new);
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old);
+
+void
+xf86_crtc_notify(ScreenPtr pScreen);
+
 #endif /* _XF86CRTC_H_ */
-- 
1.5.6.5




More information about the xorg mailing list