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 <[EMAIL PROTECTED]> --- 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 _______________________________________________ xorg mailing list xorg@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/xorg