From 3c7a27dc77595ad018bb7c4f7cef6bc178268cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2007 16:17:18 +0100 Subject: [PATCH] DRI: New ClipNotify driver hook. The hook is called whenever the clipList of any DRI window changes, be it via DRIClipNotify, DRICreateDrawable or DRIDrawablePrivDelete. This allows the driver to keep track of which DRI windows are visible where. --- hw/xfree86/dri/dri.c | 55 ++++++++++++++++++++++++++++++++++++++ hw/xfree86/dri/dri.h | 5 +++- hw/xfree86/dri/dristruct.h | 1 + 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index ebfe28b5f..bdef75ad9 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -1007,6 +1007,55 @@ DRITransitionTo2d(ScreenPtr pScreen) } +static int +DRIDCNTreeTraversal(WindowPtr pWin, pointer data) +{ + DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); + + if (pDRIDrawablePriv) { + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (REGION_NUM_RECTS(&pWin->clipList) > 0) { + WindowPtr *pDRIWindows = (WindowPtr*)data; + int i = 0; + + while (pDRIWindows[i]) + i++; + + pDRIWindows[i] = pWin; + + pDRIPriv->nrWalked++; + } + + if (pDRIPriv->nrWindows == pDRIPriv->nrWalked) + return WT_STOPWALKING; + } + + return WT_WALKCHILDREN; +} + +static void +DRIDriverClipNotify(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv->pDriverInfo->ClipNotify) { + WindowPtr *pDRIWindows = xcalloc(sizeof(WindowPtr), pDRIPriv->nrWindows); + DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; + + if (pDRIPriv->nrWindows > 0) { + pDRIPriv->nrWalked = 0; + TraverseTree(WindowTable[pScreen->myNum], DRIDCNTreeTraversal, + (pointer)pDRIWindows); + } + + pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows); + + xfree(pDRIWindows); + } +} + static void DRIIncreaseNumberVisible(ScreenPtr pScreen) { @@ -1022,6 +1071,8 @@ DRIIncreaseNumberVisible(ScreenPtr pScreen) default: break; } + + DRIDriverClipNotify(pScreen); } static void @@ -1039,6 +1090,8 @@ DRIDecreaseNumberVisible(ScreenPtr pScreen) default: break; } + + DRIDriverClipNotify(pScreen); } Bool @@ -1880,6 +1933,8 @@ DRIClipNotify(WindowPtr pWin, int dx, int dy) DRIIncreaseNumberVisible(pScreen); else if (!nrects && pDRIDrawablePriv->nrects) DRIDecreaseNumberVisible(pScreen); + else + DRIDriverClipNotify(pScreen); pDRIDrawablePriv->nrects = nrects; diff --git a/hw/xfree86/dri/dri.h b/hw/xfree86/dri/dri.h index dca0edde8..f65c57160 100644 --- a/hw/xfree86/dri/dri.h +++ b/hw/xfree86/dri/dri.h @@ -107,7 +107,7 @@ typedef struct { */ #define DRIINFO_MAJOR_VERSION 5 -#define DRIINFO_MINOR_VERSION 0 +#define DRIINFO_MINOR_VERSION 1 #define DRIINFO_PATCH_VERSION 0 typedef struct { @@ -173,6 +173,9 @@ typedef struct { /* New with DRI version 4.1.0 */ void (*TransitionSingleToMulti3D)(ScreenPtr pScreen); void (*TransitionMultiToSingle3D)(ScreenPtr pScreen); + + /* New with DRI version 5.1.0 */ + void (*ClipNotify)(ScreenPtr pScreen, WindowPtr *ppWin, int num); } DRIInfoRec, *DRIInfoPtr; diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h index 757980671..9c42ff9cc 100644 --- a/hw/xfree86/dri/dristruct.h +++ b/hw/xfree86/dri/dristruct.h @@ -89,6 +89,7 @@ typedef struct _DRIScreenPrivRec DRIInfoPtr pDriverInfo; int nrWindows; int nrWindowsVisible; + int nrWalked; drm_clip_rect_t private_buffer_rect; /* management of private buffers */ DrawablePtr fullscreen; /* pointer to fullscreen drawable */ drm_clip_rect_t fullscreen_rect; /* fake rect for fullscreen mode */