diff options
author | faith <faith> | 2000-10-25 20:33:00 +0000 |
---|---|---|
committer | faith <faith> | 2000-10-25 20:33:00 +0000 |
commit | 7aaab2720edd097ae034dca9f253ba48b84a9298 (patch) | |
tree | b432c1584d7c756098220ceda7acf5f04d38d46b | |
parent | 3d9a87637b9885b76f54df681bef7bfe6a529fee (diff) |
Added server-side protocol for the automatic fullscreen mode:
ProcXF86DRIOpenFullScreen and ProcXF86DRICloseFullScreen
Added SAREA-mediated optimization of this mode: DRIAdjustFrame
-rw-r--r-- | xc/programs/Xserver/GL/dri/XFree86-DRI.txt | 61 | ||||
-rw-r--r-- | xc/programs/Xserver/GL/dri/dri.c | 156 | ||||
-rw-r--r-- | xc/programs/Xserver/GL/dri/dri.h | 9 | ||||
-rw-r--r-- | xc/programs/Xserver/GL/dri/dristruct.h | 2 | ||||
-rw-r--r-- | xc/programs/Xserver/GL/dri/sarea.h | 10 | ||||
-rw-r--r-- | xc/programs/Xserver/GL/dri/xf86dri.c | 63 |
6 files changed, 249 insertions, 52 deletions
diff --git a/xc/programs/Xserver/GL/dri/XFree86-DRI.txt b/xc/programs/Xserver/GL/dri/XFree86-DRI.txt index 6be36884c..82c57263d 100644 --- a/xc/programs/Xserver/GL/dri/XFree86-DRI.txt +++ b/xc/programs/Xserver/GL/dri/XFree86-DRI.txt @@ -3,11 +3,11 @@ DRI Extension for supporting Direct Rendering Protocol Specification - $Date: 2000/10/25 03:59:27 $, $Revision: 1.1.4.1 $ + $Date: 2000/10/25 20:33:00 $, $Revision: 1.1.4.2 $ - Jens Owen (jens@precisioninsight.com) - Kevin Martin (kevin@precisioninsight.com) - Rickard E. Faith (faith@valinux.com) + Jens Owen (jens@valinux.com) + Kevin Martin (martin@valinux.com + Rickard E. Faith (faith@valinux.com) Copyright 1999 by Precision Insight, Inc., Cedar Park, Texas. @@ -483,47 +483,10 @@ Requests for DRI Specific Commands 4 CARD32 authenticated 24 unused -12. Update Frame Information - Name: XF86DRIUpdateFrameInfo +12. Open Full Screen - Request: - screen: CARD32 - - Reply: - [empty] - - Errors: - BadValue - - Description: - This request is used by the client to request that the X - server update the information about the frame that is - contained in the SAREA. This information is updated - automatically by the X server whenever the viewport onto the - virtual desktop changes, but if the desktop has not yet been - changed, this information may not have been provided. In that - case, the client can request an update. (A reply is provided - so that the client can be certain that that SAREA has been - updated before continuing. A client will use this request - zero or one times, so this is not a performance consideration.) - - Encoding: - XF86DRIUpdateFrameInfo - 1 CARD8 opcode (X assigned) - 1 2 DRI opcode - 2 4 request length - 4 CARD32 screen - => - 1 1 Reply - 1 unused - 2 CARD16 sequence number - 4 0 reply length - 24 unused - -13. Open Full Screen Mode - - Name: XF86DRIOpenFullScreenMode + Name: XF86DRIOpenFullScreen Request: screen: CARD32 @@ -533,27 +496,29 @@ Requests for DRI Specific Commands Errors: BadValue + BadAlloc (if full screen mode not possile) Description: Encoding: - XF86DRIOpenFullScreenMode + XF86DRIOpenFullScreen 1 CARD8 opcode (X assigned) 1 1 DRI opcode 2 2 request length 4 CARD32 screen + 4 CARD32 drawable => 1 1 Reply 1 unused 2 CARD16 sequence number 4 0 reply length - 4 CARD32 is_fullscreen + 4 CARD32 isFullScreen 20 unused -14. Close Full Screen Mode +13. Close Full Screen - Name: XF86DRICloseFullScreenMode + Name: XF86DRICloseFullScreen Request: screen: CARD32 @@ -567,7 +532,7 @@ Requests for DRI Specific Commands Description: Encoding: - XF86DRIOpenFullScreenMode + XF86DRIOpenFullScreen 1 CARD8 opcode (X assigned) 1 1 DRI opcode 2 2 request length diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c index fce294b2e..c3bea9a01 100644 --- a/xc/programs/Xserver/GL/dri/dri.c +++ b/xc/programs/Xserver/GL/dri/dri.c @@ -2,6 +2,7 @@ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -28,7 +29,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Jens Owen <jens@precisioninsight.com> + * Jens Owen <jens@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> * */ @@ -136,6 +138,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) pDRIPriv->directRenderingSupport = TRUE; pDRIPriv->pDriverInfo = pDRIInfo; pDRIPriv->nrWindows = 0; + pDRIPriv->fullscreen = NULL; if (drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString) < 0) { pDRIPriv->directRenderingSupport = FALSE; @@ -183,6 +186,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) "[drm] drmMap failed\n"); return FALSE; } + memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize); DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA 0x%08lx to %p\n", pDRIPriv->hSAREA, pDRIPriv->pSAREA); @@ -357,6 +361,12 @@ DRIFinishScreenInit(ScreenPtr pScreen) } if (pDRIInfo->wrap.ClipNotify) miClipNotify(pDRIInfo->wrap.ClipNotify); + + if (pDRIInfo->wrap.AdjustFrame) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame; + pScrn->AdjustFrame = pDRIInfo->wrap.AdjustFrame; + } DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n"); @@ -372,6 +382,12 @@ DRICloseScreen(ScreenPtr pScreen) if (pDRIPriv && pDRIPriv->directRenderingSupport) { + if (pDRIPriv->wrap.AdjustFrame) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame; + pDRIPriv->wrap.AdjustFrame = NULL; + } + if (pDRIPriv->pDriverInfo->driverSwapMethod != DRI_KERNEL_SWAP) { if (!drmRemoveSIGIOHandler(pDRIPriv->drmFD)) { DRIDrvMsg(pScreen->myNum, X_ERROR, @@ -893,7 +909,7 @@ DRIGetDrawableInfo(ScreenPtr pScreen, int* numBackClipRects, XF86DRIClipRectPtr* pBackClipRects) { - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv; WindowPtr pWin, pOldWin; int i; @@ -988,6 +1004,25 @@ DRIGetDrawableInfo(ScreenPtr pScreen, *H = (int)(pWin->drawable.height); *numClipRects = REGION_NUM_RECTS(&pWin->clipList); *pClipRects = (XF86DRIClipRectPtr)REGION_RECTS(&pWin->clipList); + + if (!*numClipRects && pDRIPriv->fullscreen) { + /* use fake full-screen clip rect */ + pDRIPriv->fullscreen_rect.x1 = *X; + pDRIPriv->fullscreen_rect.y1 = *Y; + pDRIPriv->fullscreen_rect.x2 = *X + *W; + pDRIPriv->fullscreen_rect.y2 = *Y + *H; + + *numClipRects = 1; + *pClipRects = &pDRIPriv->fullscreen_rect; + /* FIXME, remove this after debugging */ + DRIDrvMsg(pScreen->myNum, X_INFO, + "[DRI] fullscreen=%p fakecliprect=(%d,%d) (%d,%d)\n", + pDRIPriv->fullscreen, + pDRIPriv->fullscreen_rect.x1, + pDRIPriv->fullscreen_rect.y1, + pDRIPriv->fullscreen_rect.x2, + pDRIPriv->fullscreen_rect.y2); + } *backX = *X; *backY = *Y; @@ -1070,6 +1105,7 @@ DRICreateInfoRec(void) inforec->wrap.ValidateTree = DRIValidateTree; inforec->wrap.PostValidateTree = DRIPostValidateTree; inforec->wrap.ClipNotify = DRIClipNotify; + inforec->wrap.AdjustFrame = DRIAdjustFrame; inforec->TransitionTo2d = 0; inforec->TransitionTo3d = 0; @@ -1665,3 +1701,119 @@ DRIQueryVersion(int *majorVersion, *minorVersion = XF86DRI_MINOR_VERSION; *patchVersion = XF86DRI_PATCH_VERSION; } + +static void +_DRIAdjustFrame(ScrnInfoPtr pScrn, DRIScreenPrivPtr pDRIPriv, int x, int y) +{ + pDRIPriv->pSAREA->frame.x = x; + pDRIPriv->pSAREA->frame.y = y; + pDRIPriv->pSAREA->frame.width = pScrn->frameX1 - x + 1; + pDRIPriv->pSAREA->frame.height = pScrn->frameY1 - y + 1; +} + +void +DRIAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[scrnIndex]; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (!pDRIPriv || !pDRIPriv->pSAREA) { + DRIDrvMsg(scrnIndex, X_ERROR, "[DRI] No SAREA (%p %p)\n", + pDRIPriv, pDRIPriv ? pDRIPriv->pSAREA : NULL); + return; + } + + if (pDRIPriv->wrap.AdjustFrame) { + /* unwrap */ + pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame; + /* call lower layers */ + (*pScrn->AdjustFrame)(scrnIndex, x, y, flags); + /* rewrap */ + pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame; + pScrn->AdjustFrame = DRIAdjustFrame; + } + + _DRIAdjustFrame(pScrn, pDRIPriv, x, y); + + /* FIXME, remove this after debugging */ + DRIDrvMsg(scrnIndex, X_INFO, + "[DRI] Frame now at (%d,%d) (%d,%d) *************************\n", + pDRIPriv->pSAREA->frame.x, + pDRIPriv->pSAREA->frame.y, + pDRIPriv->pSAREA->frame.width, + pDRIPriv->pSAREA->frame.height); +} + +Bool +DRIOpenFullScreen(int scrnIndex, Drawable id, DrawablePtr pDrawable) +{ + ScreenPtr pScreen = screenInfo.screens[scrnIndex]; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + WindowPtr pWin = (WindowPtr)pDrawable; + XF86DRIClipRectPtr pClipRects = (void *)REGION_RECTS(&pWin->clipList); + + DRIDrvMsg(scrnIndex, X_INFO, + "[DRI] OpenFullScreen vtSema=%d (%d,%d) (%d,%d) rects=%d\n", + pScrn->vtSema, + pDrawable->x, pDrawable->y, + pDrawable->width, pDrawable->height, + REGION_NUM_RECTS(&pWin->clipList)); + + _DRIAdjustFrame(pScrn, pDRIPriv, pScrn->frameX0, pScrn->frameY0); + + if (!pScrn->vtSema) return FALSE; /* switched away */ + + if (pDrawable->x != pScrn->frameX0 + || pDrawable->y != pScrn->frameY0 + || pDrawable->width != pScrn->frameX1 - pScrn->frameX0 + 1 + || pDrawable->height != pScrn->frameY1 - pScrn->frameY0 + 1) { + return FALSE; + } + + if (REGION_NUM_RECTS(&pWin->clipList) != 1) return FALSE; + if (pDrawable->x != pClipRects[0].x1 + || pDrawable->y != pClipRects[0].y1 + || pDrawable->width != pClipRects[0].x2 - pClipRects[0].x1 + || pDrawable->height != pClipRects[0].y2 - pClipRects[0].y1) { + return FALSE; + } + + pScrn->EnableDisableFBAccess(scrnIndex, FALSE); + pScrn->vtSema = FALSE; + pDRIPriv->fullscreen = pDrawable; + DRIClipNotify(pWin, 0, 0); + + if (pScrn->FullScreenMode) pScrn->FullScreenMode(scrnIndex, TRUE); + + DRIDrvMsg(scrnIndex, X_INFO, "[DRI] OpenFullScreen returning TRUE\n"); + return TRUE; +} + +Bool +DRICloseFullScreen(int scrnIndex, Drawable id, DrawablePtr pDrawable) +{ + ScreenPtr pScreen = screenInfo.screens[scrnIndex]; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + WindowPtr pWin = (WindowPtr)pDrawable; + WindowOptPtr optional = pWin->optional; + Mask mask = pWin->eventMask; + + DRIDrvMsg(scrnIndex, X_INFO, "[DRI] CloseFullScreen\n"); + + if (pScrn->FullScreenMode) pScrn->FullScreenMode(scrnIndex, FALSE); + + pDRIPriv->fullscreen = NULL; + pScrn->vtSema = TRUE; + + /* Turn off expose events for the top window */ + pWin->eventMask &= ~ExposureMask; + pWin->optional = NULL; + pScrn->EnableDisableFBAccess(scrnIndex, TRUE); + pWin->eventMask = mask; + pWin->optional = optional; + + return TRUE; +} diff --git a/xc/programs/Xserver/GL/dri/dri.h b/xc/programs/Xserver/GL/dri/dri.h index e50b6119f..aad0da9df 100644 --- a/xc/programs/Xserver/GL/dri/dri.h +++ b/xc/programs/Xserver/GL/dri/dri.h @@ -71,6 +71,7 @@ typedef int DRIWindowRequests; typedef void (*ClipNotifyPtr)( WindowPtr, int, int ); +typedef void (*AdjustFramePtr)(int scrnIndex, int x, int y, int flags); /* @@ -87,6 +88,7 @@ typedef struct { ValidateTreeProcPtr ValidateTree; PostValidateTreeProcPtr PostValidateTree; ClipNotifyPtr ClipNotify; + AdjustFramePtr AdjustFrame; } DRIWrappedFuncsRec, *DRIWrappedFuncsPtr; @@ -295,6 +297,13 @@ extern void DRIQueryVersion(int *majorVersion, int *minorVersion, int *patchVersion); +extern void DRIAdjustFrame(int scrnIndex, int x, int y, int flags); + +extern int DRIOpenFullScreen(int scrnIndex, Drawable id, + DrawablePtr pDrawable); +extern int DRICloseFullScreen(int scrnIndex, Drawable id, + DrawablePtr pDrawable); + #define _DRI_H_ #endif diff --git a/xc/programs/Xserver/GL/dri/dristruct.h b/xc/programs/Xserver/GL/dri/dristruct.h index 02d62ae49..c08dff2c8 100644 --- a/xc/programs/Xserver/GL/dri/dristruct.h +++ b/xc/programs/Xserver/GL/dri/dristruct.h @@ -89,6 +89,8 @@ typedef struct _DRIScreenPrivRec DRIInfoPtr pDriverInfo; int nrWindows; XF86DRIClipRectRec private_buffer_rect; /* management of private buffers */ + DrawablePtr fullscreen; /* pointer to fullscreen drawable */ + XF86DRIClipRectRec fullscreen_rect; /* fake rect for fullscreen mode */ DRIWrappedFuncsRec wrap; DrawablePtr DRIDrawables[SAREA_MAX_DRAWABLES]; } DRIScreenPrivRec, *DRIScreenPrivPtr; diff --git a/xc/programs/Xserver/GL/dri/sarea.h b/xc/programs/Xserver/GL/dri/sarea.h index 24ce045e0..86199ba25 100644 --- a/xc/programs/Xserver/GL/dri/sarea.h +++ b/xc/programs/Xserver/GL/dri/sarea.h @@ -2,6 +2,7 @@ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -30,6 +31,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <kevin@precisioninsight.com> * Jens Owen <jens@precisioninsight.com> + * Rickard E. (Rik) Faith <faith@valinux.com> * */ @@ -52,12 +54,20 @@ typedef struct _XF86DRISAREADrawable { unsigned int flags; } XF86DRISAREADrawableRec, *XF86DRISAREADrawablePtr; +typedef struct _XF86DRISAREAFrame { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; +} XF86DRISAREAFrameRec, *XF86DRISAREAFramePtr; + typedef struct _XF86DRISAREA { /* first thing is always the drm locking structure */ drmLock lock; /* NOT_DONE: Use readers/writer lock for drawable_lock */ drmLock drawable_lock; XF86DRISAREADrawableRec drawableTable[SAREA_MAX_DRAWABLES]; + XF86DRISAREAFrameRec frame; } XF86DRISAREARec, *XF86DRISAREAPtr; #endif diff --git a/xc/programs/Xserver/GL/dri/xf86dri.c b/xc/programs/Xserver/GL/dri/xf86dri.c index b35e5680b..67731e4c9 100644 --- a/xc/programs/Xserver/GL/dri/xf86dri.c +++ b/xc/programs/Xserver/GL/dri/xf86dri.c @@ -2,6 +2,7 @@ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -28,8 +29,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Jens Owen <jens@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> * */ @@ -73,6 +75,8 @@ static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo); static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo); static DISPATCH_PROC(ProcXF86DRIDispatch); static DISPATCH_PROC(ProcXF86DRIAuthConnection); +static DISPATCH_PROC(ProcXF86DRIOpenFullScreen); +static DISPATCH_PROC(ProcXF86DRICloseFullScreen); static DISPATCH_PROC(SProcXF86DRIQueryVersion); static DISPATCH_PROC(SProcXF86DRIDispatch); @@ -515,6 +519,57 @@ ProcXF86DRIGetDeviceInfo( } static int +ProcXF86DRIOpenFullScreen ( + register ClientPtr client +) +{ + REQUEST(xXF86DRIOpenFullScreenReq); + xXF86DRIOpenFullScreenReply rep; + DrawablePtr pDrawable; + + REQUEST_SIZE_MATCH(xXF86DRIOpenFullScreenReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!(pDrawable = SecurityLookupDrawable(stuff->drawable, + client, + SecurityReadAccess))) + return BadValue; + + rep.isFullScreen = DRIOpenFullScreen(stuff->screen, stuff->drawable, + pDrawable); + + WriteToClient(client, sizeof(xXF86DRIOpenFullScreenReply), (char *)&rep); + return client->noClientException; +} + +static int +ProcXF86DRICloseFullScreen ( + register ClientPtr client +) +{ + REQUEST(xXF86DRICloseFullScreenReq); + xXF86DRICloseFullScreenReply rep; + DrawablePtr pDrawable; + + REQUEST_SIZE_MATCH(xXF86DRICloseFullScreenReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!(pDrawable = SecurityLookupDrawable(stuff->drawable, + client, + SecurityReadAccess))) + return BadValue; + + DRICloseFullScreen(stuff->screen, stuff->drawable, pDrawable); + + WriteToClient(client, sizeof(xXF86DRICloseFullScreenReply), (char *)&rep); + return (client->noClientException); +} + +static int ProcXF86DRIDispatch ( register ClientPtr client ) @@ -554,6 +609,10 @@ ProcXF86DRIDispatch ( return ProcXF86DRIGetDeviceInfo(client); case X_XF86DRIAuthConnection: return ProcXF86DRIAuthConnection(client); + case X_XF86DRIOpenFullScreen: + return ProcXF86DRIOpenFullScreen(client); + case X_XF86DRICloseFullScreen: + return ProcXF86DRICloseFullScreen(client); default: return BadRequest; } |