diff options
author | Jon Turney <jon.turney@dronecode.org.uk> | 2016-03-23 16:39:10 +0000 |
---|---|---|
committer | Jon Turney <jon.turney@dronecode.org.uk> | 2016-03-23 16:39:10 +0000 |
commit | 660d7581a66b19392205a266e4475caf3343759a (patch) | |
tree | 7db7b37b4288cb2016caf5b402b2c819d6e777e1 | |
parent | b462a92d05cdc8a63c13e85859e90cd1f41afe39 (diff) | |
parent | 93d4224ccf3dee5a51815a66f76c905450419b50 (diff) |
Merge tag 'xorg-server-1.18.2' into cygwin-release-1.18
xorg-server-1.18.2
98 files changed, 3058 insertions, 1808 deletions
diff --git a/Xext/Makefile.am b/Xext/Makefile.am index a9a446820..1ceb9803d 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -1,4 +1,4 @@ -noinst_LTLIBRARIES = libXext.la libXextdpmsstubs.la +noinst_LTLIBRARIES = libXext.la libXextdpmsstubs.la libXvidmode.la AM_CFLAGS = $(DIX_CFLAGS) @@ -6,7 +6,7 @@ if XORG sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h endif -# Sources always included in libXextbuiltin.la & libXext.la +# Sources always included in libXextbuiltin.la, libXext.la BUILTIN_SRCS = \ bigreq.c \ geext.c \ @@ -98,6 +98,9 @@ libXext_la_LIBADD = $(BUILTIN_LIBS) libXextdpmsstubs_la_SOURCES = dpmsstubs.c +# XVidMode extension +libXvidmode_la_SOURCES = vidmode.c + EXTRA_DIST = \ $(MITSHM_SRCS) \ $(XV_SRCS) \ diff --git a/hw/xfree86/common/xf86vmode.c b/Xext/vidmode.c index d133687b6..7c838f449 100644 --- a/hw/xfree86/common/xf86vmode.c +++ b/Xext/vidmode.c @@ -1,4 +1,3 @@ - /* Copyright 1995 Kaleb S. KEITHLEY @@ -30,32 +29,34 @@ from Kaleb S. KEITHLEY */ /* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> #endif +#ifdef XF86VIDMODE + #include <X11/X.h> #include <X11/Xproto.h> +#include <X11/extensions/xf86vmproto.h> #include "misc.h" #include "dixstruct.h" #include "extnsionst.h" -#include "xf86Extensions.h" #include "scrnintstr.h" #include "servermd.h" -#include <X11/extensions/xf86vmproto.h> #include "swaprep.h" -#include "xf86.h" -#include "vidmodeproc.h" +#include "vidmodestr.h" #include "globals.h" #include "protocol-versions.h" -#define DEFAULT_XF86VIDMODE_VERBOSITY 3 - static int VidModeErrorBase; -static DevPrivateKeyRec VidModeClientPrivateKeyRec; +static int VidModeAllowNonLocal; +static DevPrivateKeyRec VidModeClientPrivateKeyRec; #define VidModeClientPrivateKey (&VidModeClientPrivateKeyRec) +static DevPrivateKeyRec VidModePrivateKeyRec; +#define VidModePrivateKey (&VidModePrivateKeyRec) + /* This holds the client's version information */ typedef struct { int major; @@ -67,16 +68,119 @@ typedef struct { #define VM_SETPRIV(c,p) \ dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p) -#if 0 -static unsigned char XF86VidModeReqCode = 0; -#endif - #ifdef DEBUG -#define DEBUG_P(x) ErrorF(x"\n"); +#define DEBUG_P(x) LogMessage(X_INFO, x"\n"); #else #define DEBUG_P(x) /**/ #endif - static int + +static DisplayModePtr +VidModeCreateMode(void) +{ + DisplayModePtr mode; + + mode = malloc(sizeof(DisplayModeRec)); + if (mode != NULL) { + mode->name = ""; + mode->VScan = 1; /* divides refresh rate. default = 1 */ + mode->Private = NULL; + mode->next = mode; + mode->prev = mode; + } + return mode; +} + +static void +VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto) +{ + memcpy(modeto, modefrom, sizeof(DisplayModeRec)); +} + +static int +VidModeGetModeValue(DisplayModePtr mode, int valtyp) +{ + int ret = 0; + + switch (valtyp) { + case VIDMODE_H_DISPLAY: + ret = mode->HDisplay; + break; + case VIDMODE_H_SYNCSTART: + ret = mode->HSyncStart; + break; + case VIDMODE_H_SYNCEND: + ret = mode->HSyncEnd; + break; + case VIDMODE_H_TOTAL: + ret = mode->HTotal; + break; + case VIDMODE_H_SKEW: + ret = mode->HSkew; + break; + case VIDMODE_V_DISPLAY: + ret = mode->VDisplay; + break; + case VIDMODE_V_SYNCSTART: + ret = mode->VSyncStart; + break; + case VIDMODE_V_SYNCEND: + ret = mode->VSyncEnd; + break; + case VIDMODE_V_TOTAL: + ret = mode->VTotal; + break; + case VIDMODE_FLAGS: + ret = mode->Flags; + break; + case VIDMODE_CLOCK: + ret = mode->Clock; + break; + } + return ret; +} + +static void +VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val) +{ + switch (valtyp) { + case VIDMODE_H_DISPLAY: + mode->HDisplay = val; + break; + case VIDMODE_H_SYNCSTART: + mode->HSyncStart = val; + break; + case VIDMODE_H_SYNCEND: + mode->HSyncEnd = val; + break; + case VIDMODE_H_TOTAL: + mode->HTotal = val; + break; + case VIDMODE_H_SKEW: + mode->HSkew = val; + break; + case VIDMODE_V_DISPLAY: + mode->VDisplay = val; + break; + case VIDMODE_V_SYNCSTART: + mode->VSyncStart = val; + break; + case VIDMODE_V_SYNCEND: + mode->VSyncEnd = val; + break; + case VIDMODE_V_TOTAL: + mode->VTotal = val; + break; + case VIDMODE_FLAGS: + mode->Flags = val; + break; + case VIDMODE_CLOCK: + mode->Clock = val; + break; + } + return; +} + +static int ClientMajorVersion(ClientPtr client) { VidModePrivPtr pPriv; @@ -89,7 +193,7 @@ ClientMajorVersion(ClientPtr client) } static int -ProcXF86VidModeQueryVersion(ClientPtr client) +ProcVidModeQueryVersion(ClientPtr client) { xXF86VidModeQueryVersionReply rep = { .type = X_Reply, @@ -114,14 +218,16 @@ ProcXF86VidModeQueryVersion(ClientPtr client) } static int -ProcXF86VidModeGetModeLine(ClientPtr client) +ProcVidModeGetModeLine(ClientPtr client) { REQUEST(xXF86VidModeGetModeLineReq); xXF86VidModeGetModeLineReply rep = { .type = X_Reply, .sequenceNumber = client->sequence }; - void *mode; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode; int dotClock; int ver; @@ -141,8 +247,12 @@ ProcXF86VidModeGetModeLine(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock)) + if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock)) return BadValue; rep.dotclock = dotClock; @@ -157,15 +267,13 @@ ProcXF86VidModeGetModeLine(ClientPtr client) rep.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL); rep.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS); - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("GetModeLine - scrn: %d clock: %ld\n", + LogMessage(X_INFO, "GetModeLine - scrn: %d clock: %ld\n", stuff->screen, (unsigned long) rep.dotclock); - ErrorF("GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, "GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n", rep.hdisplay, rep.hsyncstart, rep.hsyncend, rep.htotal); - ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", rep.vdisplay, rep.vsyncstart, rep.vsyncend, rep.vtotal, (unsigned long) rep.flags); - } /* * Older servers sometimes had server privates that the VidMode @@ -216,11 +324,13 @@ ProcXF86VidModeGetModeLine(ClientPtr client) } static int -ProcXF86VidModeGetAllModeLines(ClientPtr client) +ProcVidModeGetAllModeLines(ClientPtr client) { REQUEST(xXF86VidModeGetAllModeLinesReq); xXF86VidModeGetAllModeLinesReply rep; - void *mode; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode; int modecount, dotClock; int ver; @@ -230,14 +340,17 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; - + pScreen = screenInfo.screens[stuff->screen]; ver = ClientMajorVersion(client); + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - modecount = VidModeGetNumOfModes(stuff->screen); + modecount = pVidMode->GetNumOfModes(pScreen); if (modecount < 1) return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) + if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) return BadValue; rep = (xXF86VidModeGetAllModeLinesReply) { @@ -308,7 +421,7 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client) WriteToClient(client, sizeof(xXF86VidModeModeInfo), &mdinf); } - } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock)); + } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock)); return Success; } @@ -325,13 +438,15 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client) && VidModeGetModeValue(mode, VIDMODE_FLAGS) == stuff->flags ) static int -ProcXF86VidModeAddModeLine(ClientPtr client) +ProcVidModeAddModeLine(ClientPtr client) { REQUEST(xXF86VidModeAddModeLineReq); xXF86OldVidModeAddModeLineReq *oldstuff = (xXF86OldVidModeAddModeLineReq *) client->requestBuffer; xXF86VidModeAddModeLineReq newstuff; - void *mode; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode; int len; int dotClock; int ver; @@ -368,25 +483,23 @@ ProcXF86VidModeAddModeLine(ClientPtr client) stuff->after_vtotal = oldstuff->after_vtotal; stuff->after_flags = oldstuff->after_flags; } - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("AddModeLine - scrn: %d clock: %ld\n", + LogMessage(X_INFO, "AddModeLine - scrn: %d clock: %ld\n", (int) stuff->screen, (unsigned long) stuff->dotclock); - ErrorF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, "AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n", stuff->hdisplay, stuff->hsyncstart, stuff->hsyncend, stuff->htotal); - ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal, (unsigned long) stuff->flags); - ErrorF(" after - scrn: %d clock: %ld\n", + LogMessage(X_INFO, " after - scrn: %d clock: %ld\n", (int) stuff->screen, (unsigned long) stuff->after_dotclock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", stuff->after_hdisplay, stuff->after_hsyncstart, stuff->after_hsyncend, stuff->after_htotal); - ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", stuff->after_vdisplay, stuff->after_vsyncstart, stuff->after_vsyncend, stuff->after_vtotal, (unsigned long) stuff->after_flags); - } if (ver < 2) { REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq); @@ -405,6 +518,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; if (stuff->hsyncstart < stuff->hdisplay || stuff->hsyncend < stuff->hsyncstart || @@ -421,17 +535,21 @@ ProcXF86VidModeAddModeLine(ClientPtr client) stuff->after_vtotal < stuff->after_vsyncend) return BadValue; + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; + if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) { Bool found = FALSE; - if (VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) { + if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) { do { - if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) + if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) && MODEMATCH(mode, stuff)) { found = TRUE; break; } - } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock)); + } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock)); } if (!found) return BadValue; @@ -454,10 +572,10 @@ ProcXF86VidModeAddModeLine(ClientPtr client) VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags); if (stuff->privsize) - ErrorF("AddModeLine - Privates in request have been ignored\n"); + LogMessage(X_INFO, "AddModeLine - Privates in request have been ignored\n"); /* Check that the mode is consistent with the monitor specs */ - switch (VidModeCheckModeForMonitor(stuff->screen, mode)) { + switch (pVidMode->CheckModeForMonitor(pScreen, mode)) { case MODE_OK: break; case MODE_HSYNC: @@ -474,28 +592,30 @@ ProcXF86VidModeAddModeLine(ClientPtr client) } /* Check that the driver is happy with the mode */ - if (VidModeCheckModeForDriver(stuff->screen, mode) != MODE_OK) { + if (pVidMode->CheckModeForDriver(pScreen, mode) != MODE_OK) { free(mode); return VidModeErrorBase + XF86VidModeModeUnsuitable; } - VidModeSetCrtcForMode(stuff->screen, mode); + pVidMode->SetCrtcForMode(pScreen, mode); - VidModeAddModeline(stuff->screen, mode); + pVidMode->AddModeline(pScreen, mode); + + LogMessage(X_INFO, "AddModeLine - Succeeded\n"); - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) - ErrorF("AddModeLine - Succeeded\n"); return Success; } static int -ProcXF86VidModeDeleteModeLine(ClientPtr client) +ProcVidModeDeleteModeLine(ClientPtr client) { REQUEST(xXF86VidModeDeleteModeLineReq); xXF86OldVidModeDeleteModeLineReq *oldstuff = (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer; xXF86VidModeDeleteModeLineReq newstuff; - void *mode; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode; int len, dotClock; int ver; @@ -520,17 +640,14 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client) stuff->flags = oldstuff->flags; stuff->privsize = oldstuff->privsize; } - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("DeleteModeLine - scrn: %d clock: %ld\n", + LogMessage(X_INFO, "DeleteModeLine - scrn: %d clock: %ld\n", (int) stuff->screen, (unsigned long) stuff->dotclock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", stuff->hdisplay, stuff->hsyncstart, stuff->hsyncend, stuff->htotal); - ErrorF - (" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal, (unsigned long) stuff->flags); - } if (ver < 2) { REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq); @@ -545,82 +662,82 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client) bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq)); } if (len != stuff->privsize) { - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, " + LogMessage(X_INFO, "req_len = %ld, sizeof(Req) = %d, privsize = %ld, " "len = %d, length = %d\n", (unsigned long) client->req_len, (int) sizeof(xXF86VidModeDeleteModeLineReq) >> 2, (unsigned long) stuff->privsize, len, stuff->length); - } return BadLength; } if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock)) + if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock)) return BadValue; - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("Checking against clock: %d (%d)\n", + LogMessage(X_INFO, "Checking against clock: %d (%d)\n", VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", VidModeGetModeValue(mode, VIDMODE_H_DISPLAY), VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART), VidModeGetModeValue(mode, VIDMODE_H_SYNCEND), VidModeGetModeValue(mode, VIDMODE_H_TOTAL)); - ErrorF - (" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n", - VidModeGetModeValue(mode, VIDMODE_V_DISPLAY), - VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART), - VidModeGetModeValue(mode, VIDMODE_V_SYNCEND), - VidModeGetModeValue(mode, VIDMODE_V_TOTAL), - VidModeGetModeValue(mode, VIDMODE_FLAGS)); - } - if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) && + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n", + VidModeGetModeValue(mode, VIDMODE_V_DISPLAY), + VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART), + VidModeGetModeValue(mode, VIDMODE_V_SYNCEND), + VidModeGetModeValue(mode, VIDMODE_V_TOTAL), + VidModeGetModeValue(mode, VIDMODE_FLAGS)); + + if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) && MODEMATCH(mode, stuff)) return BadValue; - if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) + if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) return BadValue; do { - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("Checking against clock: %d (%d)\n", + LogMessage(X_INFO, "Checking against clock: %d (%d)\n", VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", VidModeGetModeValue(mode, VIDMODE_H_DISPLAY), VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART), VidModeGetModeValue(mode, VIDMODE_H_SYNCEND), VidModeGetModeValue(mode, VIDMODE_H_TOTAL)); - ErrorF - (" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n", - VidModeGetModeValue(mode, VIDMODE_V_DISPLAY), - VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART), - VidModeGetModeValue(mode, VIDMODE_V_SYNCEND), - VidModeGetModeValue(mode, VIDMODE_V_TOTAL), - VidModeGetModeValue(mode, VIDMODE_FLAGS)); - } - if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) && + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n", + VidModeGetModeValue(mode, VIDMODE_V_DISPLAY), + VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART), + VidModeGetModeValue(mode, VIDMODE_V_SYNCEND), + VidModeGetModeValue(mode, VIDMODE_V_TOTAL), + VidModeGetModeValue(mode, VIDMODE_FLAGS)); + + if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) && MODEMATCH(mode, stuff)) { - VidModeDeleteModeline(stuff->screen, mode); - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) - ErrorF("DeleteModeLine - Succeeded\n"); + pVidMode->DeleteModeline(pScreen, mode); + LogMessage(X_INFO, "DeleteModeLine - Succeeded\n"); return Success; } - } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock)); + } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock)); return BadValue; } static int -ProcXF86VidModeModModeLine(ClientPtr client) +ProcVidModeModModeLine(ClientPtr client) { REQUEST(xXF86VidModeModModeLineReq); xXF86OldVidModeModModeLineReq *oldstuff = (xXF86OldVidModeModModeLineReq *) client->requestBuffer; xXF86VidModeModModeLineReq newstuff; - void *mode, *modetmp; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode, modetmp; int len, dotClock; int ver; @@ -644,14 +761,12 @@ ProcXF86VidModeModModeLine(ClientPtr client) stuff->flags = oldstuff->flags; stuff->privsize = oldstuff->privsize; } - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, "ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n", (int) stuff->screen, stuff->hdisplay, stuff->hsyncstart, stuff->hsyncend, stuff->htotal); - ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal, (unsigned long) stuff->flags); - } if (ver < 2) { REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq); @@ -677,8 +792,13 @@ ProcXF86VidModeModModeLine(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock)) + if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock)) return BadValue; modetmp = VidModeCreateMode(); @@ -696,10 +816,10 @@ ProcXF86VidModeModModeLine(ClientPtr client) VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags); if (stuff->privsize) - ErrorF("ModModeLine - Privates in request have been ignored\n"); + LogMessage(X_INFO, "ModModeLine - Privates in request have been ignored\n"); /* Check that the mode is consistent with the monitor specs */ - switch (VidModeCheckModeForMonitor(stuff->screen, modetmp)) { + switch (pVidMode->CheckModeForMonitor(pScreen, modetmp)) { case MODE_OK: break; case MODE_HSYNC: @@ -716,7 +836,7 @@ ProcXF86VidModeModModeLine(ClientPtr client) } /* Check that the driver is happy with the mode */ - if (VidModeCheckModeForDriver(stuff->screen, modetmp) != MODE_OK) { + if (pVidMode->CheckModeForDriver(pScreen, modetmp) != MODE_OK) { free(modetmp); return VidModeErrorBase + XF86VidModeModeUnsuitable; } @@ -733,23 +853,24 @@ ProcXF86VidModeModModeLine(ClientPtr client) VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal); VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags); - VidModeSetCrtcForMode(stuff->screen, mode); - VidModeSwitchMode(stuff->screen, mode); + pVidMode->SetCrtcForMode(pScreen, mode); + pVidMode->SwitchMode(pScreen, mode); - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) - ErrorF("ModModeLine - Succeeded\n"); + LogMessage(X_INFO, "ModModeLine - Succeeded\n"); return Success; } static int -ProcXF86VidModeValidateModeLine(ClientPtr client) +ProcVidModeValidateModeLine(ClientPtr client) { REQUEST(xXF86VidModeValidateModeLineReq); xXF86OldVidModeValidateModeLineReq *oldstuff = (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer; xXF86VidModeValidateModeLineReq newstuff; xXF86VidModeValidateModeLineReply rep; - void *mode, *modetmp = NULL; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode, modetmp = NULL; int len, status, dotClock; int ver; @@ -774,17 +895,15 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) stuff->flags = oldstuff->flags; stuff->privsize = oldstuff->privsize; } - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("ValidateModeLine - scrn: %d clock: %ld\n", + + LogMessage(X_INFO, "ValidateModeLine - scrn: %d clock: %ld\n", (int) stuff->screen, (unsigned long) stuff->dotclock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", stuff->hdisplay, stuff->hsyncstart, stuff->hsyncend, stuff->htotal); - ErrorF - (" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal, (unsigned long) stuff->flags); - } if (ver < 2) { REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq); @@ -802,6 +921,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; status = MODE_OK; @@ -815,7 +935,11 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) goto status_reply; } - if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock)) + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; + + if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock)) return BadValue; modetmp = VidModeCreateMode(); @@ -832,15 +956,15 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal); VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags); if (stuff->privsize) - ErrorF("ValidateModeLine - Privates in request have been ignored\n"); + LogMessage(X_INFO, "ValidateModeLine - Privates in request have been ignored\n"); /* Check that the mode is consistent with the monitor specs */ if ((status = - VidModeCheckModeForMonitor(stuff->screen, modetmp)) != MODE_OK) + pVidMode->CheckModeForMonitor(pScreen, modetmp)) != MODE_OK) goto status_reply; /* Check that the driver is happy with the mode */ - status = VidModeCheckModeForDriver(stuff->screen, modetmp); + status = pVidMode->CheckModeForDriver(pScreen, modetmp); status_reply: free(modetmp); @@ -858,15 +982,17 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) swapl(&rep.status); } WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), &rep); - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) - ErrorF("ValidateModeLine - Succeeded (status = %d)\n", status); + LogMessage(X_INFO, "ValidateModeLine - Succeeded (status = %d)\n", status); + return Success; } static int -ProcXF86VidModeSwitchMode(ClientPtr client) +ProcVidModeSwitchMode(ClientPtr client) { REQUEST(xXF86VidModeSwitchModeReq); + ScreenPtr pScreen; + VidModePtr pVidMode; DEBUG_P("XF86VidModeSwitchMode"); @@ -874,20 +1000,27 @@ ProcXF86VidModeSwitchMode(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; - VidModeZoomViewport(stuff->screen, (short) stuff->zoom); + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; + + pVidMode->ZoomViewport(pScreen, (short) stuff->zoom); return Success; } static int -ProcXF86VidModeSwitchToMode(ClientPtr client) +ProcVidModeSwitchToMode(ClientPtr client) { REQUEST(xXF86VidModeSwitchToModeReq); xXF86OldVidModeSwitchToModeReq *oldstuff = (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer; xXF86VidModeSwitchToModeReq newstuff; - void *mode; + ScreenPtr pScreen; + VidModePtr pVidMode; + DisplayModePtr mode; int len, dotClock; int ver; @@ -912,17 +1045,15 @@ ProcXF86VidModeSwitchToMode(ClientPtr client) stuff->flags = oldstuff->flags; stuff->privsize = oldstuff->privsize; } - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("SwitchToMode - scrn: %d clock: %ld\n", + + LogMessage(X_INFO, "SwitchToMode - scrn: %d clock: %ld\n", (int) stuff->screen, (unsigned long) stuff->dotclock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", stuff->hdisplay, stuff->hsyncstart, stuff->hsyncend, stuff->htotal); - ErrorF - (" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", - stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal, - (unsigned long) stuff->flags); - } + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n", + stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal, + (unsigned long) stuff->flags); if (ver < 2) { REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq); @@ -941,53 +1072,57 @@ ProcXF86VidModeSwitchToMode(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; - if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock)) + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; + + if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock)) return BadValue; - if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) + if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) && MODEMATCH(mode, stuff)) return Success; - if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) + if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) return BadValue; do { - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { - ErrorF("Checking against clock: %d (%d)\n", + LogMessage(X_INFO, "Checking against clock: %d (%d)\n", VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock); - ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n", + LogMessage(X_INFO, " hdsp: %d hbeg: %d hend: %d httl: %d\n", VidModeGetModeValue(mode, VIDMODE_H_DISPLAY), VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART), VidModeGetModeValue(mode, VIDMODE_H_SYNCEND), VidModeGetModeValue(mode, VIDMODE_H_TOTAL)); - ErrorF - (" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n", + LogMessage(X_INFO, " vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n", VidModeGetModeValue(mode, VIDMODE_V_DISPLAY), VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART), VidModeGetModeValue(mode, VIDMODE_V_SYNCEND), VidModeGetModeValue(mode, VIDMODE_V_TOTAL), VidModeGetModeValue(mode, VIDMODE_FLAGS)); - } - if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) && + + if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) && MODEMATCH(mode, stuff)) { - if (!VidModeSwitchMode(stuff->screen, mode)) + if (!pVidMode->SwitchMode(pScreen, mode)) return BadValue; - if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) - ErrorF("SwitchToMode - Succeeded\n"); + LogMessage(X_INFO, "SwitchToMode - Succeeded\n"); return Success; } - } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock)); + } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock)); return BadValue; } static int -ProcXF86VidModeLockModeSwitch(ClientPtr client) +ProcVidModeLockModeSwitch(ClientPtr client) { REQUEST(xXF86VidModeLockModeSwitchReq); + ScreenPtr pScreen; + VidModePtr pVidMode; REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq); @@ -995,15 +1130,20 @@ ProcXF86VidModeLockModeSwitch(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; - if (!VidModeLockZoom(stuff->screen, (short) stuff->lock)) + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; + + if (!pVidMode->LockZoom(pScreen, (short) stuff->lock)) return VidModeErrorBase + XF86VidModeZoomLocked; return Success; } static int -ProcXF86VidModeGetMonitor(ClientPtr client) +ProcVidModeGetMonitor(ClientPtr client) { REQUEST(xXF86VidModeGetMonitorReq); xXF86VidModeGetMonitorReply rep = { @@ -1011,8 +1151,9 @@ ProcXF86VidModeGetMonitor(ClientPtr client) .sequenceNumber = client->sequence }; CARD32 *hsyncdata, *vsyncdata; + ScreenPtr pScreen; + VidModePtr pVidMode; int i, nHsync, nVrefresh; - void *monitor; DEBUG_P("XF86VidModeGetMonitor"); @@ -1020,23 +1161,25 @@ ProcXF86VidModeGetMonitor(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; - if (!VidModeGetMonitor(stuff->screen, &monitor)) - return BadValue; + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - nHsync = VidModeGetMonitorValue(monitor, VIDMODE_MON_NHSYNC, 0).i; - nVrefresh = VidModeGetMonitorValue(monitor, VIDMODE_MON_NVREFRESH, 0).i; + nHsync = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i; + nVrefresh = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i; - if ((char *) (VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr) - rep.vendorLength = strlen((char *) (VidModeGetMonitorValue(monitor, - VIDMODE_MON_VENDOR, - 0)).ptr); + if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr) + rep.vendorLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen, + VIDMODE_MON_VENDOR, + 0)).ptr); else rep.vendorLength = 0; - if ((char *) (VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr) - rep.modelLength = strlen((char *) (VidModeGetMonitorValue(monitor, - VIDMODE_MON_MODEL, - 0)).ptr); + if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr) + rep.modelLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen, + VIDMODE_MON_MODEL, + 0)).ptr); else rep.modelLength = 0; rep.length = @@ -1059,20 +1202,20 @@ ProcXF86VidModeGetMonitor(ClientPtr client) } for (i = 0; i < nHsync; i++) { - hsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(monitor, - VIDMODE_MON_HSYNC_LO, - i)).f | + hsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen, + VIDMODE_MON_HSYNC_LO, + i)).f | (unsigned - short) (VidModeGetMonitorValue(monitor, VIDMODE_MON_HSYNC_HI, - i)).f << 16; + short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI, + i)).f << 16; } for (i = 0; i < nVrefresh; i++) { - vsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(monitor, - VIDMODE_MON_VREFRESH_LO, - i)).f | + vsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen, + VIDMODE_MON_VREFRESH_LO, + i)).f | (unsigned - short) (VidModeGetMonitorValue(monitor, VIDMODE_MON_VREFRESH_HI, - i)).f << 16; + short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI, + i)).f << 16; } if (client->swapped) { @@ -1085,10 +1228,10 @@ ProcXF86VidModeGetMonitor(ClientPtr client) WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata); if (rep.vendorLength) WriteToClient(client, rep.vendorLength, - (VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr); + (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr); if (rep.modelLength) WriteToClient(client, rep.modelLength, - (VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr); + (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr); free(hsyncdata); free(vsyncdata); @@ -1097,10 +1240,12 @@ ProcXF86VidModeGetMonitor(ClientPtr client) } static int -ProcXF86VidModeGetViewPort(ClientPtr client) +ProcVidModeGetViewPort(ClientPtr client) { REQUEST(xXF86VidModeGetViewPortReq); xXF86VidModeGetViewPortReply rep; + ScreenPtr pScreen; + VidModePtr pVidMode; int x, y; DEBUG_P("XF86VidModeGetViewPort"); @@ -1109,8 +1254,13 @@ ProcXF86VidModeGetViewPort(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - VidModeGetViewPort(stuff->screen, &x, &y); + pVidMode->GetViewPort(pScreen, &x, &y); rep = (xXF86VidModeGetViewPortReply) { .type = X_Reply, @@ -1131,9 +1281,11 @@ ProcXF86VidModeGetViewPort(ClientPtr client) } static int -ProcXF86VidModeSetViewPort(ClientPtr client) +ProcVidModeSetViewPort(ClientPtr client) { REQUEST(xXF86VidModeSetViewPortReq); + ScreenPtr pScreen; + VidModePtr pVidMode; DEBUG_P("XF86VidModeSetViewPort"); @@ -1141,18 +1293,25 @@ ProcXF86VidModeSetViewPort(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (!VidModeSetViewPort(stuff->screen, stuff->x, stuff->y)) + if (!pVidMode->SetViewPort(pScreen, stuff->x, stuff->y)) return BadValue; return Success; } static int -ProcXF86VidModeGetDotClocks(ClientPtr client) +ProcVidModeGetDotClocks(ClientPtr client) { REQUEST(xXF86VidModeGetDotClocksReq); xXF86VidModeGetDotClocksReply rep; + ScreenPtr pScreen; + VidModePtr pVidMode; int n; int numClocks; CARD32 dotclock; @@ -1165,8 +1324,13 @@ ProcXF86VidModeGetDotClocks(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - numClocks = VidModeGetNumOfClocks(stuff->screen, &ClockProg); + numClocks = pVidMode->GetNumOfClocks(pScreen, &ClockProg); rep = (xXF86VidModeGetDotClocksReply) { .type = X_Reply, @@ -1182,7 +1346,7 @@ ProcXF86VidModeGetDotClocks(ClientPtr client) Clocks = calloc(numClocks, sizeof(int)); if (!Clocks) return BadValue; - if (!VidModeGetClocks(stuff->screen, Clocks)) { + if (!pVidMode->GetClocks(pScreen, Clocks)) { free(Clocks); return BadValue; } @@ -1215,9 +1379,11 @@ ProcXF86VidModeGetDotClocks(ClientPtr client) } static int -ProcXF86VidModeSetGamma(ClientPtr client) +ProcVidModeSetGamma(ClientPtr client) { REQUEST(xXF86VidModeSetGammaReq); + ScreenPtr pScreen; + VidModePtr pVidMode; DEBUG_P("XF86VidModeSetGamma"); @@ -1225,8 +1391,13 @@ ProcXF86VidModeSetGamma(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (!VidModeSetGamma(stuff->screen, ((float) stuff->red) / 10000., + if (!pVidMode->SetGamma(pScreen, ((float) stuff->red) / 10000., ((float) stuff->green) / 10000., ((float) stuff->blue) / 10000.)) return BadValue; @@ -1235,10 +1406,12 @@ ProcXF86VidModeSetGamma(ClientPtr client) } static int -ProcXF86VidModeGetGamma(ClientPtr client) +ProcVidModeGetGamma(ClientPtr client) { REQUEST(xXF86VidModeGetGammaReq); xXF86VidModeGetGammaReply rep; + ScreenPtr pScreen; + VidModePtr pVidMode; float red, green, blue; DEBUG_P("XF86VidModeGetGamma"); @@ -1247,8 +1420,13 @@ ProcXF86VidModeGetGamma(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (!VidModeGetGamma(stuff->screen, &red, &green, &blue)) + if (!pVidMode->GetGamma(pScreen, &red, &green, &blue)) return BadValue; rep = (xXF86VidModeGetGammaReply) { .type = X_Reply, @@ -1271,17 +1449,24 @@ ProcXF86VidModeGetGamma(ClientPtr client) } static int -ProcXF86VidModeSetGammaRamp(ClientPtr client) +ProcVidModeSetGammaRamp(ClientPtr client) { CARD16 *r, *g, *b; int length; + ScreenPtr pScreen; + VidModePtr pVidMode; REQUEST(xXF86VidModeSetGammaRampReq); if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (stuff->size != VidModeGetGammaRampSize(stuff->screen)) + if (stuff->size != pVidMode->GetGammaRampSize(pScreen)) return BadValue; length = (stuff->size + 1) & ~1; @@ -1292,19 +1477,21 @@ ProcXF86VidModeSetGammaRamp(ClientPtr client) g = r + length; b = g + length; - if (!VidModeSetGammaRamp(stuff->screen, stuff->size, r, g, b)) + if (!pVidMode->SetGammaRamp(pScreen, stuff->size, r, g, b)) return BadValue; return Success; } static int -ProcXF86VidModeGetGammaRamp(ClientPtr client) +ProcVidModeGetGammaRamp(ClientPtr client) { CARD16 *ramp = NULL; int length; size_t ramplen = 0; xXF86VidModeGetGammaRampReply rep; + ScreenPtr pScreen; + VidModePtr pVidMode; REQUEST(xXF86VidModeGetGammaRampReq); @@ -1312,8 +1499,13 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; - if (stuff->size != VidModeGetGammaRampSize(stuff->screen)) + if (stuff->size != pVidMode->GetGammaRampSize(pScreen)) return BadValue; length = (stuff->size + 1) & ~1; @@ -1323,7 +1515,7 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client) return BadAlloc; ramplen = length * 3 * sizeof(CARD16); - if (!VidModeGetGammaRamp(stuff->screen, stuff->size, + if (!pVidMode->GetGammaRamp(pScreen, stuff->size, ramp, ramp + length, ramp + (length * 2))) { free(ramp); return BadValue; @@ -1351,10 +1543,13 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client) return Success; } + static int -ProcXF86VidModeGetGammaRampSize(ClientPtr client) +ProcVidModeGetGammaRampSize(ClientPtr client) { xXF86VidModeGetGammaRampSizeReply rep; + ScreenPtr pScreen; + VidModePtr pVidMode; REQUEST(xXF86VidModeGetGammaRampSizeReq); @@ -1362,12 +1557,17 @@ ProcXF86VidModeGetGammaRampSize(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; + pScreen = screenInfo.screens[stuff->screen]; + + pVidMode = VidModeGetPtr(pScreen); + if (pVidMode == NULL) + return BadImplementation; rep = (xXF86VidModeGetGammaRampSizeReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, - .size = VidModeGetGammaRampSize(stuff->screen) + .size = pVidMode->GetGammaRampSize(pScreen) }; if (client->swapped) { swaps(&rep.sequenceNumber); @@ -1380,7 +1580,7 @@ ProcXF86VidModeGetGammaRampSize(ClientPtr client) } static int -ProcXF86VidModeGetPermissions(ClientPtr client) +ProcVidModeGetPermissions(ClientPtr client) { xXF86VidModeGetPermissionsReply rep = { .type = X_Reply, @@ -1396,8 +1596,7 @@ ProcXF86VidModeGetPermissions(ClientPtr client) if (stuff->screen >= screenInfo.numScreens) return BadValue; - if (xf86GetVidModeEnabled() && - (xf86GetVidModeAllowNonLocal() || client->local)) { + if (VidModeAllowNonLocal || client->local) { rep.permissions |= XF86VM_WRITE_PERMISSION; } if (client->swapped) { @@ -1411,7 +1610,7 @@ ProcXF86VidModeGetPermissions(ClientPtr client) } static int -ProcXF86VidModeSetClientVersion(ClientPtr client) +ProcVidModeSetClientVersion(ClientPtr client) { REQUEST(xXF86VidModeSetClientVersionReq); @@ -1435,57 +1634,55 @@ ProcXF86VidModeSetClientVersion(ClientPtr client) } static int -ProcXF86VidModeDispatch(ClientPtr client) +ProcVidModeDispatch(ClientPtr client) { REQUEST(xReq); switch (stuff->data) { case X_XF86VidModeQueryVersion: - return ProcXF86VidModeQueryVersion(client); + return ProcVidModeQueryVersion(client); case X_XF86VidModeGetModeLine: - return ProcXF86VidModeGetModeLine(client); + return ProcVidModeGetModeLine(client); case X_XF86VidModeGetMonitor: - return ProcXF86VidModeGetMonitor(client); + return ProcVidModeGetMonitor(client); case X_XF86VidModeGetAllModeLines: - return ProcXF86VidModeGetAllModeLines(client); + return ProcVidModeGetAllModeLines(client); case X_XF86VidModeValidateModeLine: - return ProcXF86VidModeValidateModeLine(client); + return ProcVidModeValidateModeLine(client); case X_XF86VidModeGetViewPort: - return ProcXF86VidModeGetViewPort(client); + return ProcVidModeGetViewPort(client); case X_XF86VidModeGetDotClocks: - return ProcXF86VidModeGetDotClocks(client); + return ProcVidModeGetDotClocks(client); case X_XF86VidModeSetClientVersion: - return ProcXF86VidModeSetClientVersion(client); + return ProcVidModeSetClientVersion(client); case X_XF86VidModeGetGamma: - return ProcXF86VidModeGetGamma(client); + return ProcVidModeGetGamma(client); case X_XF86VidModeGetGammaRamp: - return ProcXF86VidModeGetGammaRamp(client); + return ProcVidModeGetGammaRamp(client); case X_XF86VidModeGetGammaRampSize: - return ProcXF86VidModeGetGammaRampSize(client); + return ProcVidModeGetGammaRampSize(client); case X_XF86VidModeGetPermissions: - return ProcXF86VidModeGetPermissions(client); + return ProcVidModeGetPermissions(client); default: - if (!xf86GetVidModeEnabled()) - return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (xf86GetVidModeAllowNonLocal() || client->local) { + if (VidModeAllowNonLocal || client->local) { switch (stuff->data) { case X_XF86VidModeAddModeLine: - return ProcXF86VidModeAddModeLine(client); + return ProcVidModeAddModeLine(client); case X_XF86VidModeDeleteModeLine: - return ProcXF86VidModeDeleteModeLine(client); + return ProcVidModeDeleteModeLine(client); case X_XF86VidModeModModeLine: - return ProcXF86VidModeModModeLine(client); + return ProcVidModeModModeLine(client); case X_XF86VidModeSwitchMode: - return ProcXF86VidModeSwitchMode(client); + return ProcVidModeSwitchMode(client); case X_XF86VidModeSwitchToMode: - return ProcXF86VidModeSwitchToMode(client); + return ProcVidModeSwitchToMode(client); case X_XF86VidModeLockModeSwitch: - return ProcXF86VidModeLockModeSwitch(client); + return ProcVidModeLockModeSwitch(client); case X_XF86VidModeSetViewPort: - return ProcXF86VidModeSetViewPort(client); + return ProcVidModeSetViewPort(client); case X_XF86VidModeSetGamma: - return ProcXF86VidModeSetGamma(client); + return ProcVidModeSetGamma(client); case X_XF86VidModeSetGammaRamp: - return ProcXF86VidModeSetGammaRamp(client); + return ProcVidModeSetGammaRamp(client); default: return BadRequest; } @@ -1496,35 +1693,35 @@ ProcXF86VidModeDispatch(ClientPtr client) } static int -SProcXF86VidModeQueryVersion(ClientPtr client) +SProcVidModeQueryVersion(ClientPtr client) { REQUEST(xXF86VidModeQueryVersionReq); swaps(&stuff->length); - return ProcXF86VidModeQueryVersion(client); + return ProcVidModeQueryVersion(client); } static int -SProcXF86VidModeGetModeLine(ClientPtr client) +SProcVidModeGetModeLine(ClientPtr client) { REQUEST(xXF86VidModeGetModeLineReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq); swaps(&stuff->screen); - return ProcXF86VidModeGetModeLine(client); + return ProcVidModeGetModeLine(client); } static int -SProcXF86VidModeGetAllModeLines(ClientPtr client) +SProcVidModeGetAllModeLines(ClientPtr client) { REQUEST(xXF86VidModeGetAllModeLinesReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq); swaps(&stuff->screen); - return ProcXF86VidModeGetAllModeLines(client); + return ProcVidModeGetAllModeLines(client); } static int -SProcXF86VidModeAddModeLine(ClientPtr client) +SProcVidModeAddModeLine(ClientPtr client) { xXF86OldVidModeAddModeLineReq *oldstuff = (xXF86OldVidModeAddModeLineReq *) client->requestBuffer; @@ -1565,11 +1762,11 @@ SProcXF86VidModeAddModeLine(ClientPtr client) swapl(&stuff->privsize); SwapRestL(stuff); } - return ProcXF86VidModeAddModeLine(client); + return ProcVidModeAddModeLine(client); } static int -SProcXF86VidModeDeleteModeLine(ClientPtr client) +SProcVidModeDeleteModeLine(ClientPtr client) { xXF86OldVidModeDeleteModeLineReq *oldstuff = (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer; @@ -1610,11 +1807,11 @@ SProcXF86VidModeDeleteModeLine(ClientPtr client) swapl(&stuff->privsize); SwapRestL(stuff); } - return ProcXF86VidModeDeleteModeLine(client); + return ProcVidModeDeleteModeLine(client); } static int -SProcXF86VidModeModModeLine(ClientPtr client) +SProcVidModeModModeLine(ClientPtr client) { xXF86OldVidModeModModeLineReq *oldstuff = (xXF86OldVidModeModModeLineReq *) client->requestBuffer; @@ -1655,11 +1852,11 @@ SProcXF86VidModeModModeLine(ClientPtr client) swapl(&stuff->privsize); SwapRestL(stuff); } - return ProcXF86VidModeModModeLine(client); + return ProcVidModeModModeLine(client); } static int -SProcXF86VidModeValidateModeLine(ClientPtr client) +SProcVidModeValidateModeLine(ClientPtr client) { xXF86OldVidModeValidateModeLineReq *oldstuff = (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer; @@ -1700,63 +1897,63 @@ SProcXF86VidModeValidateModeLine(ClientPtr client) swapl(&stuff->privsize); SwapRestL(stuff); } - return ProcXF86VidModeValidateModeLine(client); + return ProcVidModeValidateModeLine(client); } static int -SProcXF86VidModeSwitchMode(ClientPtr client) +SProcVidModeSwitchMode(ClientPtr client) { REQUEST(xXF86VidModeSwitchModeReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq); swaps(&stuff->screen); swaps(&stuff->zoom); - return ProcXF86VidModeSwitchMode(client); + return ProcVidModeSwitchMode(client); } static int -SProcXF86VidModeSwitchToMode(ClientPtr client) +SProcVidModeSwitchToMode(ClientPtr client) { REQUEST(xXF86VidModeSwitchToModeReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq); swapl(&stuff->screen); - return ProcXF86VidModeSwitchToMode(client); + return ProcVidModeSwitchToMode(client); } static int -SProcXF86VidModeLockModeSwitch(ClientPtr client) +SProcVidModeLockModeSwitch(ClientPtr client) { REQUEST(xXF86VidModeLockModeSwitchReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq); swaps(&stuff->screen); swaps(&stuff->lock); - return ProcXF86VidModeLockModeSwitch(client); + return ProcVidModeLockModeSwitch(client); } static int -SProcXF86VidModeGetMonitor(ClientPtr client) +SProcVidModeGetMonitor(ClientPtr client) { REQUEST(xXF86VidModeGetMonitorReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq); swaps(&stuff->screen); - return ProcXF86VidModeGetMonitor(client); + return ProcVidModeGetMonitor(client); } static int -SProcXF86VidModeGetViewPort(ClientPtr client) +SProcVidModeGetViewPort(ClientPtr client) { REQUEST(xXF86VidModeGetViewPortReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq); swaps(&stuff->screen); - return ProcXF86VidModeGetViewPort(client); + return ProcVidModeGetViewPort(client); } static int -SProcXF86VidModeSetViewPort(ClientPtr client) +SProcVidModeSetViewPort(ClientPtr client) { REQUEST(xXF86VidModeSetViewPortReq); swaps(&stuff->length); @@ -1764,32 +1961,32 @@ SProcXF86VidModeSetViewPort(ClientPtr client) swaps(&stuff->screen); swapl(&stuff->x); swapl(&stuff->y); - return ProcXF86VidModeSetViewPort(client); + return ProcVidModeSetViewPort(client); } static int -SProcXF86VidModeGetDotClocks(ClientPtr client) +SProcVidModeGetDotClocks(ClientPtr client) { REQUEST(xXF86VidModeGetDotClocksReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq); swaps(&stuff->screen); - return ProcXF86VidModeGetDotClocks(client); + return ProcVidModeGetDotClocks(client); } static int -SProcXF86VidModeSetClientVersion(ClientPtr client) +SProcVidModeSetClientVersion(ClientPtr client) { REQUEST(xXF86VidModeSetClientVersionReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq); swaps(&stuff->major); swaps(&stuff->minor); - return ProcXF86VidModeSetClientVersion(client); + return ProcVidModeSetClientVersion(client); } static int -SProcXF86VidModeSetGamma(ClientPtr client) +SProcVidModeSetGamma(ClientPtr client) { REQUEST(xXF86VidModeSetGammaReq); swaps(&stuff->length); @@ -1798,21 +1995,21 @@ SProcXF86VidModeSetGamma(ClientPtr client) swapl(&stuff->red); swapl(&stuff->green); swapl(&stuff->blue); - return ProcXF86VidModeSetGamma(client); + return ProcVidModeSetGamma(client); } static int -SProcXF86VidModeGetGamma(ClientPtr client) +SProcVidModeGetGamma(ClientPtr client) { REQUEST(xXF86VidModeGetGammaReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq); swaps(&stuff->screen); - return ProcXF86VidModeGetGamma(client); + return ProcVidModeGetGamma(client); } static int -SProcXF86VidModeSetGammaRamp(ClientPtr client) +SProcVidModeSetGammaRamp(ClientPtr client) { int length; @@ -1824,92 +2021,90 @@ SProcXF86VidModeSetGammaRamp(ClientPtr client) length = ((stuff->size + 1) & ~1) * 6; REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length); SwapRestS(stuff); - return ProcXF86VidModeSetGammaRamp(client); + return ProcVidModeSetGammaRamp(client); } static int -SProcXF86VidModeGetGammaRamp(ClientPtr client) +SProcVidModeGetGammaRamp(ClientPtr client) { REQUEST(xXF86VidModeGetGammaRampReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq); swaps(&stuff->size); swaps(&stuff->screen); - return ProcXF86VidModeGetGammaRamp(client); + return ProcVidModeGetGammaRamp(client); } static int -SProcXF86VidModeGetGammaRampSize(ClientPtr client) +SProcVidModeGetGammaRampSize(ClientPtr client) { REQUEST(xXF86VidModeGetGammaRampSizeReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq); swaps(&stuff->screen); - return ProcXF86VidModeGetGammaRampSize(client); + return ProcVidModeGetGammaRampSize(client); } static int -SProcXF86VidModeGetPermissions(ClientPtr client) +SProcVidModeGetPermissions(ClientPtr client) { REQUEST(xXF86VidModeGetPermissionsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq); swaps(&stuff->screen); - return ProcXF86VidModeGetPermissions(client); + return ProcVidModeGetPermissions(client); } static int -SProcXF86VidModeDispatch(ClientPtr client) +SProcVidModeDispatch(ClientPtr client) { REQUEST(xReq); switch (stuff->data) { case X_XF86VidModeQueryVersion: - return SProcXF86VidModeQueryVersion(client); + return SProcVidModeQueryVersion(client); case X_XF86VidModeGetModeLine: - return SProcXF86VidModeGetModeLine(client); + return SProcVidModeGetModeLine(client); case X_XF86VidModeGetMonitor: - return SProcXF86VidModeGetMonitor(client); + return SProcVidModeGetMonitor(client); case X_XF86VidModeGetAllModeLines: - return SProcXF86VidModeGetAllModeLines(client); + return SProcVidModeGetAllModeLines(client); case X_XF86VidModeGetViewPort: - return SProcXF86VidModeGetViewPort(client); + return SProcVidModeGetViewPort(client); case X_XF86VidModeValidateModeLine: - return SProcXF86VidModeValidateModeLine(client); + return SProcVidModeValidateModeLine(client); case X_XF86VidModeGetDotClocks: - return SProcXF86VidModeGetDotClocks(client); + return SProcVidModeGetDotClocks(client); case X_XF86VidModeSetClientVersion: - return SProcXF86VidModeSetClientVersion(client); + return SProcVidModeSetClientVersion(client); case X_XF86VidModeGetGamma: - return SProcXF86VidModeGetGamma(client); + return SProcVidModeGetGamma(client); case X_XF86VidModeGetGammaRamp: - return SProcXF86VidModeGetGammaRamp(client); + return SProcVidModeGetGammaRamp(client); case X_XF86VidModeGetGammaRampSize: - return SProcXF86VidModeGetGammaRampSize(client); + return SProcVidModeGetGammaRampSize(client); case X_XF86VidModeGetPermissions: - return SProcXF86VidModeGetPermissions(client); + return SProcVidModeGetPermissions(client); default: - if (!xf86GetVidModeEnabled()) - return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (xf86GetVidModeAllowNonLocal() || client->local) { + if (VidModeAllowNonLocal || client->local) { switch (stuff->data) { case X_XF86VidModeAddModeLine: - return SProcXF86VidModeAddModeLine(client); + return SProcVidModeAddModeLine(client); case X_XF86VidModeDeleteModeLine: - return SProcXF86VidModeDeleteModeLine(client); + return SProcVidModeDeleteModeLine(client); case X_XF86VidModeModModeLine: - return SProcXF86VidModeModModeLine(client); + return SProcVidModeModModeLine(client); case X_XF86VidModeSwitchMode: - return SProcXF86VidModeSwitchMode(client); + return SProcVidModeSwitchMode(client); case X_XF86VidModeSwitchToMode: - return SProcXF86VidModeSwitchToMode(client); + return SProcVidModeSwitchToMode(client); case X_XF86VidModeLockModeSwitch: - return SProcXF86VidModeLockModeSwitch(client); + return SProcVidModeLockModeSwitch(client); case X_XF86VidModeSetViewPort: - return SProcXF86VidModeSetViewPort(client); + return SProcVidModeSetViewPort(client); case X_XF86VidModeSetGamma: - return SProcXF86VidModeSetGamma(client); + return SProcVidModeSetGamma(client); case X_XF86VidModeSetGammaRamp: - return SProcXF86VidModeSetGammaRamp(client); + return SProcVidModeSetGammaRamp(client); default: return BadRequest; } @@ -1920,36 +2115,37 @@ SProcXF86VidModeDispatch(ClientPtr client) } void -XFree86VidModeExtensionInit(void) +VidModeAddExtension(Bool allow_non_local) { ExtensionEntry *extEntry; - ScreenPtr pScreen; - int i; - Bool enabled = FALSE; - - DEBUG_P("XFree86VidModeExtensionInit"); - if (!dixRegisterPrivateKey(&VidModeClientPrivateKeyRec, PRIVATE_CLIENT, 0)) - return; + DEBUG_P("VidModeAddExtension"); - for (i = 0; i < screenInfo.numScreens; i++) { - pScreen = screenInfo.screens[i]; - if (VidModeExtensionInit(pScreen)) - enabled = TRUE; - } - /* This means that the DDX doesn't want the vidmode extension enabled */ - if (!enabled) + if (!dixRegisterPrivateKey(VidModeClientPrivateKey, PRIVATE_CLIENT, 0)) return; if ((extEntry = AddExtension(XF86VIDMODENAME, XF86VidModeNumberEvents, XF86VidModeNumberErrors, - ProcXF86VidModeDispatch, - SProcXF86VidModeDispatch, + ProcVidModeDispatch, + SProcVidModeDispatch, NULL, StandardMinorOpcode))) { -#if 0 - XF86VidModeReqCode = (unsigned char) extEntry->base; -#endif VidModeErrorBase = extEntry->errorBase; + VidModeAllowNonLocal = allow_non_local; } } + +VidModePtr VidModeGetPtr(ScreenPtr pScreen) +{ + return (VidModePtr) (dixLookupPrivate(&pScreen->devPrivates, VidModePrivateKey)); +} + +VidModePtr VidModeInit(ScreenPtr pScreen) +{ + if (!dixRegisterPrivateKey(VidModePrivateKey, PRIVATE_SCREEN, sizeof(VidModeRec))) + return NULL; + + return VidModeGetPtr(pScreen); +} + +#endif /* XF86VIDMODE */ diff --git a/Xext/xvmain.c b/Xext/xvmain.c index 0c6f25b5a..c9b11d4bb 100644 --- a/Xext/xvmain.c +++ b/Xext/xvmain.c @@ -800,10 +800,9 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff) if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) return BadAlloc; tpn->next = NULL; - if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) { - free(tpn); + tpn->client = NULL; + if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) return BadAlloc; - } } else { /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ @@ -844,7 +843,8 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff) tpn->client = NULL; tpn->id = FakeClientID(client->index); - AddResource(tpn->id, XvRTVideoNotify, tpn); + if (!AddResource(tpn->id, XvRTVideoNotify, tpn)) + return BadAlloc; tpn->client = client; return Success; @@ -893,7 +893,8 @@ XvdiSelectPortNotify(ClientPtr client, XvPortPtr pPort, BOOL onoff) tpn->client = client; tpn->id = FakeClientID(client->index); - AddResource(tpn->id, XvRTPortNotify, tpn); + if (!AddResource(tpn->id, XvRTPortNotify, tpn)) + return BadAlloc; return Success; diff --git a/Xext/xvmc.c b/Xext/xvmc.c index 64eda922b..7565c173d 100644 --- a/Xext/xvmc.c +++ b/Xext/xvmc.c @@ -253,6 +253,10 @@ ProcXvMCCreateContext(ClientPtr client) free(pContext); return result; } + if (!AddResource(pContext->context_id, XvMCRTContext, pContext)) { + free(data); + return BadAlloc; + } rep = (xvmcCreateContextReply) { .type = X_Reply, @@ -266,7 +270,6 @@ ProcXvMCCreateContext(ClientPtr client) WriteToClient(client, sizeof(xvmcCreateContextReply), &rep); if (dwords) WriteToClient(client, dwords << 2, data); - AddResource(pContext->context_id, XvMCRTContext, pContext); free(data); @@ -329,6 +332,11 @@ ProcXvMCCreateSurface(ClientPtr client) free(pSurface); return result; } + if (!AddResource(pSurface->surface_id, XvMCRTSurface, pSurface)) { + free(data); + return BadAlloc; + } + rep = (xvmcCreateSurfaceReply) { .type = X_Reply, .sequenceNumber = client->sequence, @@ -338,7 +346,6 @@ ProcXvMCCreateSurface(ClientPtr client) WriteToClient(client, sizeof(xvmcCreateSurfaceReply), &rep); if (dwords) WriteToClient(client, dwords << 2, data); - AddResource(pSurface->surface_id, XvMCRTSurface, pSurface); free(data); @@ -445,6 +452,11 @@ ProcXvMCCreateSubpicture(ClientPtr client) free(pSubpicture); return result; } + if (!AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture)) { + free(data); + return BadAlloc; + } + rep = (xvmcCreateSubpictureReply) { .type = X_Reply, .sequenceNumber = client->sequence, @@ -462,7 +474,6 @@ ProcXvMCCreateSubpicture(ClientPtr client) WriteToClient(client, sizeof(xvmcCreateSubpictureReply), &rep); if (dwords) WriteToClient(client, dwords << 2, data); - AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture); free(data); diff --git a/autogen.sh b/autogen.sh index aee4beba2..4de97bf8e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -9,6 +9,9 @@ cd "$srcdir" autoreconf --force -v --install || exit 1 cd "$ORIGDIR" || exit $? +git config --local --get format.subjectPrefix || + git config --local format.subjectPrefix "PATCH xserver" + if test -z "$NOCONFIGURE"; then exec "$srcdir"/configure "$@" fi diff --git a/configure.ac b/configure.ac index 8d039de2e..03687db51 100644 --- a/configure.ac +++ b/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.18.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2016-02-08" -RELEASE_NAME="Spanakopita" +AC_INIT([xorg-server], 1.18.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2016-03-11" +RELEASE_NAME="Saganaki" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -228,7 +228,8 @@ AC_SUBST(DLOPEN_LIBS) dnl Checks for library functions. AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \ getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \ - mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext]) + mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \ + walkcontext]) AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup]) AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]]) @@ -1520,6 +1521,14 @@ if test "x$XDMAUTH" = xyes; then fi fi +if test "x$XF86VIDMODE" = xauto; then + PKG_CHECK_EXISTS($VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no]) +fi +if test "x$XF86VIDMODE" = xyes; then + AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension]) +fi +AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) + AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path]) AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path]) @@ -2029,13 +2038,8 @@ if test "x$XORG" = xyes; then AC_DEFINE(XFreeXDGA, 1, [Build XDGA support]) fi - if test "x$XF86VIDMODE" = xauto; then - PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no]) - fi if test "x$XF86VIDMODE" = xyes; then XORG_MODULES="$XORG_MODULES $VIDMODEPROTO" - PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO) - AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension]) fi if test -n "$XORG_MODULES"; then @@ -2117,7 +2121,6 @@ AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes]) AM_CONDITIONAL([LNXAPM], [test "x$linux_apm" = xyes]) AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) AM_CONDITIONAL([DGA], [test "x$DGA" = xyes]) -AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) AM_CONDITIONAL([XORG_BUS_PLATFORM], [test "x$CONFIG_UDEV_KMS" = xyes]) AM_CONDITIONAL([XORG_DRIVER_MODESETTING], [test "x$XORG_DRIVER_MODESETTING" = xyes]) @@ -2468,7 +2471,11 @@ AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes]) dnl Xwayland DDX -PKG_CHECK_MODULES(XWAYLANDMODULES, [wayland-client >= 1.3.0 libdrm epoxy], [have_xwayland=yes], [have_xwayland=no]) +XWAYLANDMODULES="wayland-client >= 1.3.0 libdrm epoxy" +if test "x$XF86VIDMODE" = xyes; then + XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO" +fi +PKG_CHECK_MODULES(XWAYLANDMODULES, [$XWAYLANDMODULES], [have_xwayland=yes], [have_xwayland=no]) AC_MSG_CHECKING([whether to build Xwayland DDX]) if test "x$XWAYLAND" = xauto; then XWAYLAND="$have_xwayland" diff --git a/dix/dixutils.c b/dix/dixutils.c index 205550eb4..b6b002385 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -620,6 +620,28 @@ ClientSignal(ClientPtr client) return FALSE; } +int +ClientSignalAll(ClientPtr client, ClientSleepProcPtr function, void *closure) +{ + SleepQueuePtr q; + int count = 0; + + for (q = sleepQueue; q; q = q->next) { + if (!(client == CLIENT_SIGNAL_ANY || q->client == client)) + continue; + + if (!(function == CLIENT_SIGNAL_ANY || q->function == function)) + continue; + + if (!(closure == CLIENT_SIGNAL_ANY || q->closure == closure)) + continue; + + count += QueueWorkProc(q->function, q->client, q->closure); + } + + return count; +} + void ClientWakeup(ClientPtr client) { diff --git a/dix/window.c b/dix/window.c index 25d29ecd4..ead4dc27f 100644 --- a/dix/window.c +++ b/dix/window.c @@ -3647,7 +3647,7 @@ WindowParentHasDeviceCursor(WindowPtr pWin, * all of the windows */ void -SetRootClip(ScreenPtr pScreen, Bool enable) +SetRootClip(ScreenPtr pScreen, int enable) { WindowPtr pWin = pScreen->root; WindowPtr pChild; @@ -3655,6 +3655,7 @@ SetRootClip(ScreenPtr pScreen, Bool enable) Bool anyMarked = FALSE; WindowPtr pLayerWin; BoxRec box; + enum RootClipMode mode = enable; if (!pWin) return; @@ -3679,23 +3680,32 @@ SetRootClip(ScreenPtr pScreen, Bool enable) } } - /* - * Use REGION_BREAK to avoid optimizations in ValidateTree - * that assume the root borderClip can't change well, normally - * it doesn't...) - */ - if (enable) { + if (mode != ROOT_CLIP_NONE) { + pWin->drawable.width = pScreen->width; + pWin->drawable.height = pScreen->height; + box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; + RegionInit(&pWin->winSize, &box, 1); RegionInit(&pWin->borderSize, &box, 1); - if (WasViewable) - RegionReset(&pWin->borderClip, &box); - pWin->drawable.width = pScreen->width; - pWin->drawable.height = pScreen->height; + + /* + * Use REGION_BREAK to avoid optimizations in ValidateTree + * that assume the root borderClip can't change well, normally + * it doesn't...) + */ RegionBreak(&pWin->clipList); + + /* For INPUT_ONLY, empty the borderClip so no rendering will ever + * be attempted to the screen pixmap (only redirected windows), + * but we keep borderSize as full regardless. */ + if (WasViewable && mode == ROOT_CLIP_FULL) + RegionReset(&pWin->borderClip, &box); + else + RegionEmpty(&pWin->borderClip); } else { RegionEmpty(&pWin->borderClip); diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c index 2d7558863..2b3622148 100644 --- a/dri3/dri3_request.c +++ b/dri3/dri3_request.c @@ -312,6 +312,8 @@ int proc_dri3_dispatch(ClientPtr client) { REQUEST(xReq); + if (!client->local) + return BadMatch; if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data]) return BadRequest; return (*proc_dri3_vector[stuff->data]) (client); @@ -405,6 +407,8 @@ int sproc_dri3_dispatch(ClientPtr client) { REQUEST(xReq); + if (!client->local) + return BadMatch; if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data]) return BadRequest; return (*sproc_dri3_vector[stuff->data]) (client); diff --git a/glamor/Makefile.am b/glamor/Makefile.am index c48802999..c631c530b 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -46,10 +46,14 @@ libglamor_la_SOURCES = \ glamor_compositerects.c\ glamor_utils.c\ glamor_utils.h\ - glamor_xv.c \ glamor_sync.c \ glamor.h +if XV +libglamor_la_SOURCES += \ + glamor_xv.c +endif + libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c sdk_HEADERS = glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index f2aec4607..9c6a0d1cc 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -579,10 +579,20 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP || epoxy_gl_version() >= 30 || epoxy_has_gl_extension("GL_NV_pack_subimage"); + glamor_priv->has_vertex_array_object = + epoxy_has_gl_extension("GL_ARB_vertex_array_object"); + glamor_priv->has_dual_blend = + epoxy_has_gl_extension("GL_ARB_blend_func_extended"); + + /* assume a core profile if we are GL 3.1 and don't have ARB_compatibility */ + glamor_priv->is_core_profile = + gl_version >= 31 && !epoxy_has_gl_extension("GL_ARB_compatibility"); glamor_setup_debug_output(screen); - glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); + glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) && + !glamor_priv->is_core_profile; + /* Driver-specific hack: Avoid using GL_QUADS on VC4, where * they'll be emulated more expensively than we can with our * cached IB. @@ -600,6 +610,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->max_fbo_size = MAX_FBO_SIZE; #endif + glamor_priv->one_channel_format = GL_ALPHA; + if (epoxy_has_gl_extension("GL_ARB_texture_rg") && epoxy_has_gl_extension("GL_ARB_texture_swizzle")) + glamor_priv->one_channel_format = GL_RED; + glamor_set_debug_level(&glamor_debug_level); glamor_priv->saved_procs.create_screen_resources = diff --git a/glamor/glamor.h b/glamor/glamor.h index 4be880058..0aa6d5604 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -64,6 +64,10 @@ typedef enum glamor_pixmap_type { #define GLAMOR_VALID_FLAGS (GLAMOR_USE_EGL_SCREEN \ | GLAMOR_NO_DRI3) +/* until we need geometry shaders GL3.1 should suffice. */ +#define GLAMOR_GL_CORE_VER_MAJOR 3 +#define GLAMOR_GL_CORE_VER_MINOR 1 + /* @glamor_init: Initialize glamor internal data structure. * * @screen: Current screen pointer. diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c index 8692904eb..f51ff6dad 100644 --- a/glamor/glamor_composite_glyphs.c +++ b/glamor/glamor_composite_glyphs.c @@ -186,7 +186,9 @@ static const glamor_facet glamor_facet_composite_glyphs_130 = { .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" GLAMOR_POS(gl_Position, (primitive.xy + pos)) " glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"), - .fs_vars = ("varying vec2 glyph_pos;\n"), + .fs_vars = ("varying vec2 glyph_pos;\n" + "out vec4 color0;\n" + "out vec4 color1;\n"), .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"), .source_name = "source", .locations = glamor_program_location_atlas, @@ -235,10 +237,10 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst, glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); PixmapPtr atlas_pixmap = atlas->atlas; glamor_pixmap_private *atlas_priv = glamor_get_pixmap_private(atlas_pixmap); - glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0, 0); + glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - int box_x, box_y; + int box_index; int off_x, off_y; glamor_put_vbo_space(drawable->pScreen); @@ -253,11 +255,13 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst, glUniform1i(prog->atlas_uniform, 1); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { BoxPtr box = RegionRects(dst->pCompositeClip); int nbox = RegionNumRects(dst->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE, + prog->matrix_uniform, + &off_x, &off_y); /* Run over the clip list, drawing the glyphs * in each box diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c index 1adfba0e6..5fed89f0c 100644 --- a/glamor/glamor_copy.c +++ b/glamor/glamor_copy.c @@ -307,7 +307,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src, PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); - int src_box_x, src_box_y, dst_box_x, dst_box_y; + int src_box_index, dst_box_index; int dst_off_x, dst_off_y; int src_off_x, src_off_y; GLshort *v; @@ -368,19 +368,20 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src, glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(src_priv, src_box_x, src_box_y) { - BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y); + glamor_pixmap_loop(src_priv, src_box_index) { + BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_index); args.dx = dx + src_off_x - src_box->x1; args.dy = dy + src_off_y - src_box->y1; - args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y); + args.src = glamor_pixmap_fbo_at(src_priv, src_box_index); if (!glamor_use_program(dst_pixmap, gc, prog, &args)) goto bail_ctx; - glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) { - glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE, - prog->matrix_uniform, &dst_off_x, &dst_off_y); + glamor_pixmap_loop(dst_priv, dst_box_index) { + glamor_set_destination_drawable(dst, dst_box_index, FALSE, FALSE, + prog->matrix_uniform, + &dst_off_x, &dst_off_y); glScissor(dst_off_x - args.dx, dst_off_y - args.dy, diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 0104b8885..b9948b569 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -87,6 +87,17 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) GLint ok; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + if (glamor_priv->has_khr_debug) { + char *label; + va_list va; + + va_start(va, format); + XNFvasprintf(&label, format, va); + glObjectLabel(GL_PROGRAM, prog, -1, label); + free(label); + va_end(va); + } + glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &ok); if (!ok) { @@ -100,17 +111,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) ErrorF("Failed to link: %s\n", info); FatalError("GLSL link failure\n"); } - - if (glamor_priv->has_khr_debug) { - char *label; - va_list va; - - va_start(va, format); - XNFvasprintf(&label, format, va); - glObjectLabel(GL_PROGRAM, prog, -1, label); - free(label); - va_end(va); - } } /* diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c index 101228e40..a6a11c1a2 100644 --- a/glamor/glamor_dash.c +++ b/glamor/glamor_dash.c @@ -205,16 +205,16 @@ glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog, { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - int box_x, box_y; + int box_index; int off_x, off_y; glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, + glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y); while (nbox--) { diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index cc16b0a75..80a97f7a1 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -395,79 +395,92 @@ glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name) } #endif -#ifdef GLAMOR_HAS_GBM -static void * -_get_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, unsigned int tex) +static Bool +glamor_make_pixmap_exportable(PixmapPtr pixmap) { +#ifdef GLAMOR_HAS_GBM + ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - struct glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - struct glamor_egl_screen_private *glamor_egl; - EGLImageKHR image; + unsigned width = pixmap->drawable.width; + unsigned height = pixmap->drawable.height; struct gbm_bo *bo; + PixmapPtr exported; + GCPtr scratch_gc; - EGLint attribs[] = { - EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, - EGL_GL_TEXTURE_LEVEL_KHR, 0, - EGL_NONE - }; + if (pixmap_priv->image) + return TRUE; - glamor_egl = glamor_egl_get_screen_private(scrn); + if (pixmap->drawable.bitsPerPixel != 32) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make %dbpp pixmap exportable\n", + pixmap->drawable.bitsPerPixel); + return FALSE; + } - glamor_make_current(glamor_priv); + bo = gbm_bo_create(glamor_egl->gbm, width, height, + GBM_FORMAT_ARGB8888, +#ifdef GLAMOR_HAS_GBM_LINEAR + (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ? + GBM_BO_USE_LINEAR : 0) | +#endif + GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT); + if (!bo) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make %dx%dx%dbpp GBM bo\n", + width, height, pixmap->drawable.bitsPerPixel); + return FALSE; + } - image = pixmap_priv->image; - if (!image) { - image = eglCreateImageKHR(glamor_egl->display, - glamor_egl->context, - EGL_GL_TEXTURE_2D_KHR, - (EGLClientBuffer) (uintptr_t) - tex, attribs); - if (image == EGL_NO_IMAGE_KHR) - return NULL; - - glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); - glamor_egl_set_pixmap_image(pixmap, image); + exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0); + screen->ModifyPixmapHeader(exported, width, height, 0, 0, + gbm_bo_get_stride(bo), NULL); + if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make %dx%dx%dbpp pixmap from GBM bo\n", + width, height, pixmap->drawable.bitsPerPixel); + screen->DestroyPixmap(exported); + gbm_bo_destroy(bo); + return FALSE; } + gbm_bo_destroy(bo); - bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); - if (!bo) - return NULL; + scratch_gc = GetScratchGC(pixmap->drawable.depth, screen); + ValidateGC(&pixmap->drawable, scratch_gc); + scratch_gc->ops->CopyArea(&pixmap->drawable, &exported->drawable, + scratch_gc, + 0, 0, width, height, 0, 0); + FreeScratchGC(scratch_gc); - pixmap->devKind = gbm_bo_get_stride(bo); + /* Now, swap the tex/gbm/EGLImage/etc. of the exported pixmap into + * the original pixmap struct. + */ + glamor_egl_exchange_buffers(pixmap, exported); - return bo; -} + screen->DestroyPixmap(exported); + + return TRUE; +#else + return FALSE; #endif +} void * glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) { -#ifdef GLAMOR_HAS_GBM - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - glamor_pixmap_private *pixmap_priv = + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); + struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!glamor_priv->dri3_enabled) + if (!glamor_make_pixmap_exportable(pixmap)) return NULL; - switch (pixmap_priv->type) { - case GLAMOR_TEXTURE_DRM: - case GLAMOR_TEXTURE_ONLY: - if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0)) - return NULL; - return _get_gbm_bo_from_pixmap(screen, pixmap, - pixmap_priv->fbo->tex); - default: - break; - } - return NULL; -#else - return NULL; -#endif + + return gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, + pixmap_priv->image, 0); } int @@ -483,7 +496,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); - bo = _get_gbm_bo_from_pixmap(screen, pixmap, tex); + bo = glamor_gbm_bo_from_pixmap(screen, pixmap); if (!bo) goto failure; @@ -520,18 +533,8 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl; struct gbm_bo *bo; - EGLImageKHR image; - Bool ret = FALSE; - - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, - EGL_DMA_BUF_PLANE0_FD_EXT, 0, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, - EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, - EGL_NONE - }; + struct gbm_import_fd_data import_data = { 0 }; + Bool ret; glamor_egl = glamor_egl_get_screen_private(scrn); @@ -541,23 +544,12 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap, if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0) return FALSE; - attribs[1] = width; - attribs[3] = height; - attribs[7] = fd; - attribs[11] = stride; - image = eglCreateImageKHR(glamor_egl->display, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - NULL, attribs); - - if (image == EGL_NO_IMAGE_KHR) - return FALSE; - - /* EGL_EXT_image_dma_buf_import can impose restrictions on the - * usage of the image. Use gbm_bo to bypass the limitations. */ - bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); - eglDestroyImageKHR(glamor_egl->display, image); - + import_data.fd = fd; + import_data.width = width; + import_data.height = height; + import_data.stride = stride; + import_data.format = GBM_FORMAT_ARGB8888; + bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0); if (!bo) return FALSE; @@ -565,10 +557,7 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap, ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); gbm_bo_destroy(bo); - - if (ret) - return TRUE; - return FALSE; + return ret; #else return FALSE; #endif @@ -802,6 +791,15 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) #endif EGL_NONE }; + static const EGLint config_attribs_core[] = { + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_CONTEXT_MAJOR_VERSION_KHR, + GLAMOR_GL_CORE_VER_MAJOR, + EGL_CONTEXT_MINOR_VERSION_KHR, + GLAMOR_GL_CORE_VER_MINOR, + EGL_NONE + }; glamor_identify(0); glamor_egl = calloc(sizeof(*glamor_egl), 1); @@ -862,12 +860,21 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) KHR_surfaceless_opengl); #endif +#ifndef GLAMOR_GLES2 glamor_egl->context = eglCreateContext(glamor_egl->display, NULL, EGL_NO_CONTEXT, - config_attribs); - if (glamor_egl->context == EGL_NO_CONTEXT) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n"); - goto error; + config_attribs_core); +#else + glamor_egl->context = NULL; +#endif + if (!glamor_egl->context) { + glamor_egl->context = eglCreateContext(glamor_egl->display, + NULL, EGL_NO_CONTEXT, + config_attribs); + if (glamor_egl->context == EGL_NO_CONTEXT) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n"); + goto error; + } } if (!eglMakeCurrent(glamor_egl->display, @@ -879,8 +886,6 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) #ifdef GLAMOR_HAS_GBM if (epoxy_has_egl_extension(glamor_egl->display, "EGL_KHR_gl_texture_2D_image") && - epoxy_has_egl_extension(glamor_egl->display, - "EGL_EXT_image_dma_buf_import") && epoxy_has_gl_extension("GL_OES_EGL_image")) glamor_egl->dri3_capable = TRUE; #endif diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c index c11e6d51b..5dbbfe4b2 100644 --- a/glamor/glamor_egl_stubs.c +++ b/glamor/glamor_egl_stubs.c @@ -48,9 +48,3 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, { return 0; } - -unsigned int -glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear) -{ - return 0; -} diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index 545f89fcd..5bfffe501 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -75,6 +75,8 @@ cache_format(GLenum format) { switch (format) { case GL_ALPHA: + case GL_LUMINANCE: + case GL_RED: return 2; case GL_RGB: return 1; @@ -329,30 +331,21 @@ glamor_destroy_fbo(glamor_screen_private *glamor_priv, static int _glamor_create_tex(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, Bool linear) + int w, int h, GLenum format) { - unsigned int tex = 0; - - /* With dri3, we want to allocate ARGB8888 pixmaps only. - * Depending on the implementation, GL_RGBA might not - * give us ARGB8888. We ask glamor_egl to use get - * an ARGB8888 based texture for us. */ - if (glamor_priv->dri3_enabled && format == GL_RGBA) { - tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen, - w, h, linear); - } - if (!tex) { - glamor_make_current(glamor_priv); - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glamor_priv->suppress_gl_out_of_memory_logging = true; - glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, - format, GL_UNSIGNED_BYTE, NULL); - glamor_priv->suppress_gl_out_of_memory_logging = false; - } + unsigned int tex; + + glamor_make_current(glamor_priv); + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + if (format == glamor_priv->one_channel_format && format == GL_RED) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + glamor_priv->suppress_gl_out_of_memory_logging = true; + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, + format, GL_UNSIGNED_BYTE, NULL); + glamor_priv->suppress_gl_out_of_memory_logging = false; if (glGetError() == GL_OUT_OF_MEMORY) { if (!glamor_priv->logged_any_fbo_allocation_failure) { @@ -383,7 +376,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv, if (fbo) return fbo; new_fbo: - tex = _glamor_create_tex(glamor_priv, w, h, format, flag == CREATE_PIXMAP_USAGE_SHARED); + tex = _glamor_create_tex(glamor_priv, w, h, format); if (!tex) return NULL; fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag); @@ -548,7 +541,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag) if (!pixmap_priv->fbo->tex) pixmap_priv->fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width, - pixmap->drawable.height, format, FALSE); + pixmap->drawable.height, format); if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0) if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0) diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index 1791f6dca..b21aa068e 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -48,7 +48,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, glamor_pixmap_private *pixmap_priv; glamor_program *prog; RegionPtr clip = gc->pCompositeClip; - int box_x, box_y; + int box_index; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) @@ -67,7 +67,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, start_x += drawable->x; y += drawable->y; - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int x; int n; int num_points, max_points; @@ -75,7 +75,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, int off_x, off_y; char *vbo_offset; - glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, + glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y); max_points = 500; @@ -169,7 +169,7 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap, int bitmap_stride = bitmap->devKind; glamor_program *prog; RegionPtr clip = gc->pCompositeClip; - int box_x, box_y; + int box_index; int yy, xx; int num_points; INT16 *points = NULL; @@ -220,8 +220,8 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap, glamor_put_vbo_space(screen); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { - glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, + glamor_pixmap_loop(pixmap_priv, box_index) { + glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE, prog->matrix_uniform, NULL, NULL); glDrawArrays(GL_POINTS, 0, num_points); diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index 30c29f610..c50542a32 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -647,12 +647,12 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, PicturePtr dst_picture, GLfloat *xscale, GLfloat *yscale, int x_source, int y_source, - float vertices[8], - float tex_vertices[8], int tex_normalize) { glamor_pixmap_private *pixmap_priv; PixmapPtr pixmap = NULL; + GLfloat *v; + char *vbo_offset; pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable); pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -670,13 +670,15 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, *xscale, *yscale, x_source, y_source, dst_picture->pDrawable->width, dst_picture->pDrawable->height); + v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset); + glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale, 0, 0, (INT16) (dst_picture->pDrawable-> width), (INT16) (dst_picture->pDrawable-> height), - vertices); + v); if (tex_normalize) { glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale, @@ -687,7 +689,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, (INT16) (dst_picture-> pDrawable->height + y_source), - tex_vertices); + &v[8]); } else { glamor_set_tcoords_tri_strip(x_source, y_source, @@ -695,28 +697,29 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, x_source, (INT16) (dst_picture->pDrawable->height) + y_source, - tex_vertices); + &v[8]); } DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", - vertices[0], vertices[1], vertices[2], vertices[3], - vertices[4], vertices[5], vertices[6], vertices[7]); + v[0], v[1], v[2], v[3], + v[4], v[5], v[6], v[7]); DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", - tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3], - tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]); + v[8], v[9], v[10], v[11], + v[12], v[13], v[14], v[15]); glamor_make_current(glamor_priv); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 0, vertices); + GL_FALSE, 0, vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, 0, tex_vertices); + GL_FALSE, 0, vbo_offset + 8 * sizeof(GLfloat)); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glamor_put_vbo_space(screen); return 1; } @@ -812,13 +815,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, PixmapPtr pixmap = NULL; GLint gradient_prog = 0; int error; - float tex_vertices[8]; int stops_count = 0; int count = 0; GLfloat *stop_colors = NULL; GLfloat *n_stops = NULL; GLfloat xscale, yscale; - float vertices[8]; float transform_mat[3][3]; static const float identity_mat[3][3] = { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, @@ -969,7 +970,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, if (!_glamor_gradient_set_pixmap_destination (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source, - vertices, tex_vertices, 0)) + 0)) goto GRADIENT_FAIL; glamor_set_alu(screen, GXcopy); @@ -1123,7 +1124,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, float pt_distance; float p1_distance; GLfloat cos_val; - float tex_vertices[8]; int stops_count = 0; GLfloat *stop_colors = NULL; GLfloat *n_stops = NULL; @@ -1131,7 +1131,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, float slope; GLfloat xscale, yscale; GLfloat pt1[2], pt2[2]; - float vertices[8]; float transform_mat[3][3]; static const float identity_mat[3][3] = { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, @@ -1287,7 +1286,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, if (!_glamor_gradient_set_pixmap_destination (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source, - vertices, tex_vertices, 1)) + 1)) goto GRADIENT_FAIL; glamor_set_alu(screen, GXcopy); diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c index 2dd9c07db..a2c9b1fcc 100644 --- a/glamor/glamor_lines.c +++ b/glamor/glamor_lines.c @@ -44,7 +44,7 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc, int off_x, off_y; DDXPointPtr v; char *vbo_offset; - int box_x, box_y; + int box_index; int add_last; pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -99,11 +99,11 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc, glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, + glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y); while (nbox--) { diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c index d6f37cf92..b069ce56b 100644 --- a/glamor/glamor_picture.c +++ b/glamor/glamor_picture.c @@ -41,19 +41,21 @@ * Return 0 if find a matched texture type. Otherwise return -1. **/ static int -glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format, +glamor_get_tex_format_type_from_pictformat_gl(ScreenPtr pScreen, + PictFormatShort format, GLenum *tex_format, GLenum *tex_type, int *no_alpha, int *revert, int *swap_rb, int is_upload) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); *no_alpha = 0; *revert = REVERT_NONE; *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; switch (format) { case PICT_a1: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; break; @@ -111,7 +113,7 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format, *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case PICT_a8: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; break; case PICT_x4r4g4b4: @@ -137,13 +139,15 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format, #define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst) static int -glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format, +glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen, + PictFormatShort format, GLenum *tex_format, GLenum *tex_type, int *no_alpha, int *revert, int *swap_rb, int is_upload) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); int need_swap_rb = 0; *no_alpha = 0; @@ -264,13 +268,13 @@ glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format, break; case PICT_a1: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; break; case PICT_a8: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *revert = REVERT_NONE; break; @@ -317,14 +321,16 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, glamor_get_screen_private(pixmap->drawable.pScreen); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - return glamor_get_tex_format_type_from_pictformat_gl(pict_format, + return glamor_get_tex_format_type_from_pictformat_gl(pixmap->drawable.pScreen, + pict_format, format, type, no_alpha, revert, swap_rb, is_upload); } else { - return glamor_get_tex_format_type_from_pictformat_gles2(pict_format, + return glamor_get_tex_format_type_from_pictformat_gles2(pixmap->drawable.pScreen, + pict_format, format, type, no_alpha, revert, @@ -597,14 +603,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - static float vertices[8]; - - static float texcoords_inv[8] = { 0, 0, - 1, 0, - 1, 1, - 0, 1 - }; - float *ptexcoords; float dst_xscale, dst_yscale; GLuint tex = 0; int need_free_bits = 0; @@ -666,14 +664,22 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, return FALSE; } } else { - ptexcoords = texcoords_inv; + static const float texcoords_inv[8] = { 0, 0, + 1, 0, + 1, 1, + 0, 1 + }; + GLfloat *v; + char *vbo_offset; + + v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset); pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale); glamor_set_normalize_vcoords(pixmap_priv, dst_xscale, dst_yscale, x, y, x + w, y + h, - vertices); + v); /* Slow path, we need to flip y or wire alpha to 1. */ glamor_make_current(glamor_priv); @@ -685,13 +691,16 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, return FALSE; } + memcpy(&v[8], texcoords_inv, 8 * sizeof(GLfloat)); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), vertices); + GL_FALSE, 2 * sizeof(float), vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), ptexcoords); + GL_FALSE, 2 * sizeof(float), vbo_offset + 8 * sizeof(GLfloat)); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glamor_put_vbo_space(screen); glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv); glamor_set_alu(screen, GXcopy); glActiveTexture(GL_TEXTURE0); diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c index 3ba4a6927..facfe8240 100644 --- a/glamor/glamor_points.c +++ b/glamor/glamor_points.c @@ -46,7 +46,7 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint int off_x, off_y; GLshort *vbo_ppt; char *vbo_offset; - int box_x, box_y; + int box_index; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) @@ -86,11 +86,12 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, + prog->matrix_uniform, &off_x, &off_y); while (nbox--) { glScissor(box->x1 + off_x, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index a190e67b1..a70f10eb4 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -86,6 +86,12 @@ typedef struct glamor_composite_shader { }; } glamor_composite_shader; +enum ca_state { + CA_NONE, + CA_TWO_PASS, + CA_DUAL_BLEND, +}; + enum shader_source { SHADER_SOURCE_SOLID, SHADER_SOURCE_TEXTURE, @@ -101,18 +107,17 @@ enum shader_mask { SHADER_MASK_COUNT, }; -enum shader_in { - SHADER_IN_SOURCE_ONLY, - SHADER_IN_NORMAL, - SHADER_IN_CA_SOURCE, - SHADER_IN_CA_ALPHA, - SHADER_IN_COUNT, +enum shader_dest_swizzle { + SHADER_DEST_SWIZZLE_DEFAULT, + SHADER_DEST_SWIZZLE_ALPHA_TO_RED, + SHADER_DEST_SWIZZLE_COUNT, }; struct shader_key { enum shader_source source; enum shader_mask mask; - enum shader_in in; + glamor_program_alpha in; + enum shader_dest_swizzle dest_swizzle; }; struct blendinfo { @@ -201,8 +206,13 @@ typedef struct glamor_screen_private { Bool has_unpack_subimage; Bool has_rw_pbo; Bool use_quads; + Bool has_vertex_array_object; + Bool has_dual_blend; + Bool is_core_profile; int max_fbo_size; + GLuint one_channel_format; + struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; unsigned long fbo_cache_watermark; @@ -247,6 +257,7 @@ typedef struct glamor_screen_private { char *glyph_defines; /** Vertex buffer for all GPU rendering. */ + GLuint vao; GLuint vbo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ int vbo_offset; @@ -272,7 +283,8 @@ typedef struct glamor_screen_private { int render_nr_quads; glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] [SHADER_MASK_COUNT] - [SHADER_IN_COUNT]; + [glamor_program_alpha_count] + [SHADER_DEST_SWIZZLE_COUNT]; /* shaders to restore a texture to another texture. */ GLint finish_access_prog[2]; @@ -297,7 +309,7 @@ typedef struct glamor_screen_private { Bool logged_any_fbo_allocation_failure; /* xv */ - GLint xv_prog; + glamor_program xv_prog; struct glamor_context ctx; } glamor_screen_private; @@ -473,19 +485,17 @@ glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx) } static inline glamor_pixmap_fbo * -glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y) +glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int box) { - assert(x < priv->block_wcnt); - assert(y < priv->block_hcnt); - return priv->fbo_array[y * priv->block_wcnt + x]; + assert(box < priv->block_wcnt * priv->block_hcnt); + return priv->fbo_array[box]; } static inline BoxPtr -glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y) +glamor_pixmap_box_at(glamor_pixmap_private *priv, int box) { - assert(x < priv->block_wcnt); - assert(y < priv->block_hcnt); - return &priv->box_array[y * priv->block_wcnt + x]; + assert(box < priv->block_wcnt * priv->block_hcnt); + return &priv->box_array[box]; } static inline int @@ -500,9 +510,9 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv) return priv->block_hcnt; } -#define glamor_pixmap_loop(priv, x, y) \ - for (y = 0; y < glamor_pixmap_hcnt(priv); y++) \ - for (x = 0; x < glamor_pixmap_wcnt(priv); x++) +#define glamor_pixmap_loop(priv, box_index) \ + for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) * \ + glamor_pixmap_wcnt(priv); box_index++) \ /** * Pixmap upload status, used by glamor_render.c's support for diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index 416c54a71..0a94de62f 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -344,6 +344,10 @@ glamor_build_program(ScreenPtr screen, #endif glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE, prim->source_name); } + if (prog->alpha == glamor_program_alpha_dual_blend) { + glBindFragDataLocationIndexed(prog->prog, 0, 0, "color0"); + glBindFragDataLocationIndexed(prog->prog, 0, 1, "color1"); + } glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name); @@ -474,11 +478,24 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) } /* Set up the source alpha value for blending in component alpha mode. */ - if (alpha != glamor_program_alpha_normal && op_info->source_alpha) { - if (dst_blend == GL_SRC_ALPHA) + if (alpha == glamor_program_alpha_dual_blend) { + switch (dst_blend) { + case GL_SRC_ALPHA: + dst_blend = GL_SRC1_COLOR; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dst_blend = GL_ONE_MINUS_SRC1_COLOR; + break; + } + } else if (alpha != glamor_program_alpha_normal) { + switch (dst_blend) { + case GL_SRC_ALPHA: dst_blend = GL_SRC_COLOR; - else if (dst_blend == GL_ONE_MINUS_SRC_ALPHA) + break; + case GL_ONE_MINUS_SRC_ALPHA: dst_blend = GL_ONE_MINUS_SRC_COLOR; + break; + } } glEnable(GL_BLEND); @@ -491,9 +508,9 @@ use_source_solid(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) glamor_set_blend(op, prog->alpha, dst); - glamor_set_color(glamor_get_drawable_pixmap(dst->pDrawable), - src->pSourcePict->solidFill.color, - prog->fg_uniform); + glamor_set_color_depth(dst->pDrawable->pScreen, 32, + src->pSourcePict->solidFill.color, + prog->fg_uniform); return TRUE; } @@ -547,7 +564,9 @@ static const glamor_facet *glamor_facet_source[glamor_program_source_count] = { static const char *glamor_combine[] = { [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n", [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n", - [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n" + [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n", + [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n" + " color1 = source.a * mask;\n" }; static Bool @@ -567,9 +586,9 @@ glamor_setup_one_program_render(ScreenPtr screen, if (!fill) return FALSE; + prog->alpha = alpha; if (!glamor_build_program(screen, prog, prim, fill, glamor_combine[alpha], defines)) return FALSE; - prog->alpha = alpha; } return TRUE; @@ -585,6 +604,7 @@ glamor_setup_program_render(CARD8 op, const char *defines) { ScreenPtr screen = dst->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_program_alpha alpha; glamor_program_source source_type; glamor_program *prog; @@ -593,10 +613,15 @@ glamor_setup_program_render(CARD8 op, return NULL; if (glamor_is_component_alpha(mask)) { - /* This only works for PictOpOver */ - if (op != PictOpOver) - return NULL; - alpha = glamor_program_alpha_ca_first; + if (glamor_priv->has_dual_blend) { + alpha = glamor_program_alpha_dual_blend; + } else { + /* This only works for PictOpOver */ + if (op != PictOpOver) + return NULL; + + alpha = glamor_program_alpha_ca_first; + } } else alpha = glamor_program_alpha_normal; diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h index 9e561cd92..ab6e46f7b 100644 --- a/glamor/glamor_program.h +++ b/glamor/glamor_program.h @@ -43,6 +43,7 @@ typedef enum { glamor_program_alpha_normal, glamor_program_alpha_ca_first, glamor_program_alpha_ca_second, + glamor_program_alpha_dual_blend, glamor_program_alpha_count } glamor_program_alpha; diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c index c378e4a30..e4473209d 100644 --- a/glamor/glamor_rects.c +++ b/glamor/glamor_rects.c @@ -51,7 +51,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable, int off_x, off_y; GLshort *v; char *vbo_offset; - int box_x, box_y; + int box_index; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) @@ -111,11 +111,12 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable, glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE, + prog->matrix_uniform, &off_x, &off_y); while (nbox--) { glScissor(box->x1 + off_x, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 92b6b0cd0..73ac831ee 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -72,146 +72,153 @@ glamor_create_composite_fs(struct shader_key *key) "uniform int source_repeat_mode;\n" "uniform int mask_repeat_mode;\n"; const char *relocate_texture = - GLAMOR_DEFAULT_PRECISION "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n" "{\n" - " vec2 rel_tex; \n" - " rel_tex = texture * wh.xy; \n" - " if (repeat == RepeatNone)\n" + " vec2 rel_tex; \n" + " rel_tex = texture * wh.xy; \n" + " if (repeat == RepeatFix + RepeatNone)\n" " return rel_tex; \n" - " else if (repeat == RepeatNormal) \n" - " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n" - " else if(repeat == RepeatPad) { \n" - " if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n" - " else if(rel_tex.x < 0.0) rel_tex.x = 0.0; \n" - " if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n" - " else if(rel_tex.y < 0.0) rel_tex.y = 0.0; \n" - " rel_tex = rel_tex / wh.xy; \n" - " } \n" - " else if(repeat == RepeatReflect) {\n" + " else if (repeat == RepeatFix + RepeatNormal) \n" + " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n" + " else if (repeat == RepeatFix + RepeatPad) { \n" + " if (rel_tex.x >= 1.0) \n" + " rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n" + " else if (rel_tex.x < 0.0) \n" + " rel_tex.x = 0.0; \n" + " if (rel_tex.y >= 1.0) \n" + " rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n" + " else if (rel_tex.y < 0.0) \n" + " rel_tex.y = 0.0; \n" + " rel_tex = rel_tex / wh.xy; \n" + " } else if (repeat == RepeatFix + RepeatReflect) {\n" " if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n" - " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n" + " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x)) / wh.x;\n" " else \n" - " rel_tex.x = fract(rel_tex.x)/wh.x;\n" + " rel_tex.x = fract(rel_tex.x) / wh.x;\n" " if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n" - " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n" + " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y)) / wh.y;\n" " else \n" - " rel_tex.y = fract(rel_tex.y)/wh.y;\n" - " } \n" - " return rel_tex; \n" + " rel_tex.y = fract(rel_tex.y) / wh.y;\n" + " } \n" + " return rel_tex; \n" "}\n"; /* The texture and the pixmap size is not match eaxctly, so can't sample it directly. * rel_sampler will recalculate the texture coords.*/ const char *rel_sampler = - " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n" + " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n" "{\n" - " tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n" - " if (repeat == RepeatFix) {\n" - " if (!(tex.x >= 0.0 && tex.x < 1.0 \n" - " && tex.y >= 0.0 && tex.y < 1.0))\n" - " return vec4(0.0, 0.0, 0.0, set_alpha);\n" - " tex = (fract(tex) / wh.xy);\n" + " if (repeat >= RepeatFix) {\n" + " tex = rel_tex_coord(tex, wh, repeat);\n" + " if (repeat == RepeatFix + RepeatNone) {\n" + " if (tex.x < 0.0 || tex.x >= 1.0 || \n" + " tex.y < 0.0 || tex.y >= 1.0)\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " tex = (fract(tex) / wh.xy);\n" + " }\n" " }\n" - " if (set_alpha != 1)\n" - " return texture2D(tex_image, tex);\n" - " else\n" - " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n" + " return texture2D(tex_image, tex);\n" "}\n"; const char *source_solid_fetch = - GLAMOR_DEFAULT_PRECISION "uniform vec4 source;\n" "vec4 get_source()\n" "{\n" " return source;\n" "}\n"; const char *source_alpha_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "uniform vec4 source_wh;" "vec4 get_source()\n" "{\n" - " if (source_repeat_mode < RepeatFix)\n" - " return texture2D(source_sampler, source_texture);\n" - " else \n" - " return rel_sampler(source_sampler, source_texture,\n" - " source_wh, source_repeat_mode, 0);\n" + " return rel_sampler(source_sampler, source_texture,\n" + " source_wh, source_repeat_mode);\n" "}\n"; const char *source_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "uniform vec4 source_wh;\n" "vec4 get_source()\n" "{\n" - " if (source_repeat_mode < RepeatFix) \n" - " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" - " else \n" - " return rel_sampler(source_sampler, source_texture,\n" - " source_wh, source_repeat_mode, 1);\n" + " return vec4(rel_sampler(source_sampler, source_texture,\n" + " source_wh, source_repeat_mode).rgb,\n" + " 1.0);\n" + "}\n"; + const char *mask_none = + "vec4 get_mask()\n" + "{\n" + " return vec4(0.0, 0.0, 0.0, 1.0);\n" "}\n"; const char *mask_solid_fetch = - GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n" "vec4 get_mask()\n" "{\n" " return mask;\n" "}\n"; const char *mask_alpha_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "uniform vec4 mask_wh;\n" "vec4 get_mask()\n" "{\n" - " if (mask_repeat_mode < RepeatFix) \n" - " return texture2D(mask_sampler, mask_texture);\n" - " else \n" - " return rel_sampler(mask_sampler, mask_texture,\n" - " mask_wh, mask_repeat_mode, 0);\n" + " return rel_sampler(mask_sampler, mask_texture,\n" + " mask_wh, mask_repeat_mode);\n" "}\n"; const char *mask_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "uniform vec4 mask_wh;\n" "vec4 get_mask()\n" "{\n" - " if (mask_repeat_mode < RepeatFix) \n" - " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" - " else \n" - " return rel_sampler(mask_sampler, mask_texture,\n" - " mask_wh, mask_repeat_mode, 1);\n" - "}\n"; - const char *in_source_only = - GLAMOR_DEFAULT_PRECISION - "void main()\n" - "{\n" - " gl_FragColor = get_source();\n" + " return vec4(rel_sampler(mask_sampler, mask_texture,\n" + " mask_wh, mask_repeat_mode).rgb, 1.0);\n" "}\n"; + + const char *dest_swizzle_default = + "vec4 dest_swizzle(vec4 color)\n" + "{" + " return color;" + "}"; + const char *dest_swizzle_alpha_to_red = + "vec4 dest_swizzle(vec4 color)\n" + "{" + " float undef;\n" + " return vec4(color.a, undef, undef, undef);" + "}"; + const char *in_normal = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source() * get_mask().a;\n" + " gl_FragColor = dest_swizzle(get_source() * get_mask().a);\n" "}\n"; const char *in_ca_source = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source() * get_mask();\n" + " gl_FragColor = dest_swizzle(get_source() * get_mask());\n" "}\n"; const char *in_ca_alpha = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source().a * get_mask();\n" + " gl_FragColor = dest_swizzle(get_source().a * get_mask());\n" + "}\n"; + const char *in_ca_dual_blend = + "out vec4 color0;\n" + "out vec4 color1;\n" + "void main()\n" + "{\n" + " color0 = dest_swizzle(get_source() * get_mask());\n" + " color1 = dest_swizzle(get_source().a * get_mask());\n" "}\n"; + const char *header_ca_dual_blend = + "#version 130\n"; + char *source; const char *source_fetch; const char *mask_fetch = ""; const char *in; + const char *header; + const char *header_norm = ""; + const char *dest_swizzle; GLuint prog; switch (key->source) { @@ -230,6 +237,7 @@ glamor_create_composite_fs(struct shader_key *key) switch (key->mask) { case SHADER_MASK_NONE: + mask_fetch = mask_none; break; case SHADER_MASK_SOLID: mask_fetch = mask_solid_fetch; @@ -244,25 +252,45 @@ glamor_create_composite_fs(struct shader_key *key) FatalError("Bad composite shader mask"); } - switch (key->in) { - case SHADER_IN_SOURCE_ONLY: - in = in_source_only; + /* If we're storing to an a8 texture but our texture format is + * GL_RED because of a core context, then we need to make sure to + * put the alpha into the red channel. + */ + switch (key->dest_swizzle) { + case SHADER_DEST_SWIZZLE_DEFAULT: + dest_swizzle = dest_swizzle_default; + break; + case SHADER_DEST_SWIZZLE_ALPHA_TO_RED: + dest_swizzle = dest_swizzle_alpha_to_red; break; - case SHADER_IN_NORMAL: + default: + FatalError("Bad composite shader dest swizzle"); + } + + header = header_norm; + switch (key->in) { + case glamor_program_alpha_normal: in = in_normal; break; - case SHADER_IN_CA_SOURCE: + case glamor_program_alpha_ca_first: in = in_ca_source; break; - case SHADER_IN_CA_ALPHA: + case glamor_program_alpha_ca_second: in = in_ca_alpha; break; + case glamor_program_alpha_dual_blend: + in = in_ca_dual_blend; + header = header_ca_dual_blend; + break; default: FatalError("Bad composite IN type"); } - XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture, - rel_sampler, source_fetch, mask_fetch, in); + XNFasprintf(&source, + "%s" + GLAMOR_DEFAULT_PRECISION + "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture, + rel_sampler, source_fetch, mask_fetch, dest_swizzle, in); prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source); free(source); @@ -331,6 +359,10 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); + if (key->in == glamor_program_alpha_dual_blend) { + glBindFragDataLocationIndexed(prog, 0, 0, "color0"); + glBindFragDataLocationIndexed(prog, 0, 1, "color1"); + } glamor_link_glsl_prog(screen, prog, "composite"); shader->prog = prog; @@ -372,17 +404,36 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_composite_shader *shader; - shader = &glamor_priv->composite_shader[key->source][key->mask][key->in]; + shader = &glamor_priv->composite_shader[key->source][key->mask][key->in][key->dest_swizzle]; if (shader->prog == 0) glamor_create_composite_shader(screen, key, shader); return shader; } +static GLenum +glamor_translate_blend_alpha_to_red(GLenum blend) +{ + switch (blend) { + case GL_SRC_ALPHA: + return GL_SRC_COLOR; + case GL_DST_ALPHA: + return GL_DST_COLOR; + case GL_ONE_MINUS_SRC_ALPHA: + return GL_ONE_MINUS_SRC_COLOR; + case GL_ONE_MINUS_DST_ALPHA: + return GL_ONE_MINUS_DST_COLOR; + default: + return blend; + } +} + static Bool glamor_set_composite_op(ScreenPtr screen, CARD8 op, struct blendinfo *op_info_result, - PicturePtr dest, PicturePtr mask) + PicturePtr dest, PicturePtr mask, + enum ca_state ca_state, + struct shader_key *key) { GLenum source_blend, dest_blend; struct blendinfo *op_info; @@ -391,6 +442,7 @@ glamor_set_composite_op(ScreenPtr screen, glamor_fallback("unsupported render op %d \n", op); return GL_FALSE; } + op_info = &composite_op_info[op]; source_blend = op_info->source_blend; @@ -407,12 +459,33 @@ glamor_set_composite_op(ScreenPtr screen, } /* Set up the source alpha value for blending in component alpha mode. */ - if (mask && mask->componentAlpha - && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) { - if (dest_blend == GL_SRC_ALPHA) + if (ca_state == CA_DUAL_BLEND) { + switch (dest_blend) { + case GL_SRC_ALPHA: + dest_blend = GL_SRC1_COLOR; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dest_blend = GL_ONE_MINUS_SRC1_COLOR; + break; + } + } else if (mask && mask->componentAlpha + && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) { + switch (dest_blend) { + case GL_SRC_ALPHA: dest_blend = GL_SRC_COLOR; - else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA) + break; + case GL_ONE_MINUS_SRC_ALPHA: dest_blend = GL_ONE_MINUS_SRC_COLOR; + break; + } + } + + /* If we're outputting our alpha to the red channel, then any + * reads of alpha for blending need to come from the red channel. + */ + if (key->dest_swizzle == SHADER_DEST_SWIZZLE_ALPHA_TO_RED) { + source_blend = glamor_translate_blend_alpha_to_red(source_blend); + dest_blend = glamor_translate_blend_alpha_to_red(dest_blend); } op_info_result->source_blend = source_blend; @@ -483,22 +556,15 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit, * GLES2 doesn't support RepeatNone. We need to fix it anyway. * **/ - if (repeat_type != RepeatNone) - repeat_type += RepeatFix; - else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - || glamor_pixmap_priv_is_large(pixmap_priv)) { - if (picture->transform) - repeat_type += RepeatFix; - } - if (repeat_type >= RepeatFix) { + if (glamor_pixmap_priv_is_large(pixmap_priv) || + (glamor_priv->gl_flavor == GLAMOR_GL_ES2 && repeat_type == RepeatNone && + picture->transform)) { glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, pixmap_priv); - if ((wh[0] != 1.0 || wh[1] != 1.0) - || (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - && repeat_type == RepeatFix)) - glUniform4fv(wh_location, 1, wh); - else - repeat_type -= RepeatFix; + glUniform4fv(wh_location, 1, wh); + + repeat_type += RepeatFix; } + glUniform1i(repeat_location, repeat_type); } @@ -508,41 +574,6 @@ glamor_set_composite_solid(float *color, GLint uniform_location) glUniform4fv(uniform_location, 1, color); } -static int -compatible_formats(CARD8 op, PicturePtr dst, PicturePtr src) -{ - if (op == PictOpSrc) { - /* We can't do direct copies between different depths at 16bpp - * because r,g,b are allocated to different bits. - */ - if (dst->pDrawable->bitsPerPixel == 16 && - dst->pDrawable->depth != src->pDrawable->depth) { - return 0; - } - - if (src->format == dst->format) - return 1; - - if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8) - return 1; - - if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8) - return 1; - } - else if (op == PictOpOver) { - if (src->alphaMap || dst->alphaMap) - return 0; - - if (src->format != dst->format) - return 0; - - if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8) - return 1; - } - - return 0; -} - static char glamor_get_picture_location(PicturePtr picture) { @@ -564,54 +595,6 @@ glamor_get_picture_location(PicturePtr picture) return glamor_get_drawable_location(picture->pDrawable); } -static Bool -glamor_composite_with_copy(CARD8 op, - PicturePtr source, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_dest, INT16 y_dest, RegionPtr region) -{ - int ret = FALSE; - - if (!source->pDrawable) - return FALSE; - - if (!compatible_formats(op, dest, source)) - return FALSE; - - if (source->repeat || source->transform) { - return FALSE; - } - - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - x_source += source->pDrawable->x; - y_source += source->pDrawable->y; - if (PICT_FORMAT_A(source->format) == 0) { - /* Fallback if we sample outside the source so that we - * swizzle the correct clear color for out-of-bounds texels. - */ - if (region->extents.x1 + x_source - x_dest < 0) - goto cleanup_region; - if (region->extents.x2 + x_source - x_dest > source->pDrawable->width) - goto cleanup_region; - - if (region->extents.y1 + y_source - y_dest < 0) - goto cleanup_region; - if (region->extents.y2 + y_source - y_dest > source->pDrawable->height) - goto cleanup_region; - } - glamor_copy(source->pDrawable, - dest->pDrawable, NULL, - RegionRects(region), RegionNumRects(region), - x_source - x_dest, y_source - y_dest, - FALSE, FALSE, 0, NULL); - ret = TRUE; - cleanup_region: - return ret; -} - static void * glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) { @@ -675,7 +658,7 @@ static const int pict_format_combine_tab[][3] = { static Bool combine_pict_format(PictFormatShort * des, const PictFormatShort src, - const PictFormatShort mask, enum shader_in in_ca) + const PictFormatShort mask, glamor_program_alpha in_ca) { PictFormatShort new_vis; int src_type, mask_type, src_bpp; @@ -692,20 +675,22 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src, new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask); switch (in_ca) { - case SHADER_IN_SOURCE_ONLY: - return TRUE; - case SHADER_IN_NORMAL: + case glamor_program_alpha_normal: src_type = PICT_FORMAT_TYPE(src); mask_type = PICT_TYPE_A; break; - case SHADER_IN_CA_SOURCE: + case glamor_program_alpha_ca_first: src_type = PICT_FORMAT_TYPE(src); mask_type = PICT_FORMAT_TYPE(mask); break; - case SHADER_IN_CA_ALPHA: + case glamor_program_alpha_ca_second: src_type = PICT_TYPE_A; mask_type = PICT_FORMAT_TYPE(mask); break; + case glamor_program_alpha_dual_blend: + src_type = PICT_FORMAT_TYPE(src); + mask_type = PICT_FORMAT_TYPE(mask); + break; default: return FALSE; } @@ -798,9 +783,11 @@ glamor_composite_choose_shader(CARD8 op, struct shader_key *s_key, glamor_composite_shader ** shader, struct blendinfo *op_info, - PictFormatShort *psaved_source_format) + PictFormatShort *psaved_source_format, + enum ca_state ca_state) { ScreenPtr screen = dest->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); enum glamor_pixmap_status source_status = GLAMOR_NONE; enum glamor_pixmap_status mask_status = GLAMOR_NONE; PictFormatShort saved_source_format = 0; @@ -864,17 +851,19 @@ glamor_composite_choose_shader(CARD8 op, } if (!mask->componentAlpha) { - key.in = SHADER_IN_NORMAL; + key.in = glamor_program_alpha_normal; } else { if (op == PictOpClear) key.mask = SHADER_MASK_NONE; + else if (glamor_priv->has_dual_blend) + key.in = glamor_program_alpha_dual_blend; else if (op == PictOpSrc || op == PictOpAdd || op == PictOpIn || op == PictOpOut || op == PictOpOverReverse) - key.in = SHADER_IN_CA_SOURCE; + key.in = glamor_program_alpha_ca_second; else if (op == PictOpOutReverse || op == PictOpInReverse) { - key.in = SHADER_IN_CA_ALPHA; + key.in = glamor_program_alpha_ca_first; } else { glamor_fallback("Unsupported component alpha op: %d\n", op); @@ -884,7 +873,13 @@ glamor_composite_choose_shader(CARD8 op, } else { key.mask = SHADER_MASK_NONE; - key.in = SHADER_IN_SOURCE_ONLY; + } + + if (dest_pixmap->drawable.bitsPerPixel <= 8 && + glamor_priv->one_channel_format == GL_RED) { + key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED; + } else { + key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT; } if (source && source->alphaMap) { @@ -1016,8 +1011,10 @@ glamor_composite_choose_shader(CARD8 op, goto fail; } - if (!glamor_set_composite_op(screen, op, op_info, dest, mask)) + if (!glamor_set_composite_op(screen, op, op_info, dest, mask, ca_state, + &key)) { goto fail; + } *shader = glamor_lookup_composite_shader(screen, &key); if ((*shader)->prog == 0) { @@ -1108,7 +1105,7 @@ glamor_composite_with_shader(CARD8 op, glamor_pixmap_private *mask_pixmap_priv, glamor_pixmap_private *dest_pixmap_priv, int nrect, glamor_composite_rect_t *rects, - Bool two_pass_ca) + enum ca_state ca_state) { ScreenPtr screen = dest->pDrawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -1131,17 +1128,17 @@ glamor_composite_with_shader(CARD8 op, source_pixmap_priv, mask_pixmap_priv, dest_pixmap_priv, &key, &shader, &op_info, - &saved_source_format)) { + &saved_source_format, ca_state)) { glamor_fallback("glamor_composite_choose_shader failed\n"); return ret; } - if (two_pass_ca) { + if (ca_state == CA_TWO_PASS) { if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest, source_pixmap, mask_pixmap, dest_pixmap, source_pixmap_priv, mask_pixmap_priv, dest_pixmap_priv, &key_ca, &shader_ca, &op_info_ca, - &saved_source_format)) { + &saved_source_format, ca_state)) { glamor_fallback("glamor_composite_choose_shader failed\n"); return ret; } @@ -1256,7 +1253,7 @@ glamor_composite_with_shader(CARD8 op, glamor_put_vbo_space(screen); glamor_flush_composite_rects(screen); nrect -= rect_processed; - if (two_pass_ca) { + if (ca_state == CA_TWO_PASS) { glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key_ca, shader_ca, &op_info_ca); glamor_flush_composite_rects(screen); @@ -1361,6 +1358,7 @@ glamor_composite_clipped_region(CARD8 op, glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); + glamor_screen_private *glamor_priv = glamor_get_screen_private(dest_pixmap->drawable.pScreen); ScreenPtr screen = dest->pDrawable->pScreen; PicturePtr temp_src = source, temp_mask = mask; PixmapPtr temp_src_pixmap = source_pixmap; @@ -1378,7 +1376,7 @@ glamor_composite_clipped_region(CARD8 op, int height; BoxPtr box; int nbox; - Bool two_pass_ca = FALSE; + enum ca_state ca_state = CA_NONE; extent = RegionExtents(region); box = RegionRects(region); @@ -1440,23 +1438,15 @@ glamor_composite_clipped_region(CARD8 op, x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x; y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y; } - /* Do two-pass PictOpOver componentAlpha, until we enable - * dual source color blending. - */ if (mask && mask->componentAlpha) { - if (op == PictOpOver) { - two_pass_ca = TRUE; - op = PictOpOutReverse; - } - } - - if (!mask && temp_src) { - if (glamor_composite_with_copy(op, temp_src, dest, - x_temp_src, y_temp_src, - x_dest, y_dest, region)) { - ok = TRUE; - goto out; + if (glamor_priv->has_dual_blend) { + ca_state = CA_DUAL_BLEND; + } else { + if (op == PictOpOver) { + ca_state = CA_TWO_PASS; + op = PictOpOutReverse; + } } } @@ -1508,7 +1498,7 @@ glamor_composite_clipped_region(CARD8 op, temp_src_pixmap, temp_mask_pixmap, dest_pixmap, temp_src_priv, temp_mask_priv, dest_pixmap_priv, - box_cnt, prect, two_pass_ca); + box_cnt, prect, ca_state); if (!ok) break; nbox -= box_cnt; @@ -1566,10 +1556,12 @@ glamor_composite(CARD8 op, if (!glamor_pixmap_has_fbo(dest_pixmap)) goto fail; - if (op >= ARRAY_SIZE(composite_op_info)) + if (op >= ARRAY_SIZE(composite_op_info)) { + glamor_fallback("Unsupported composite op %x\n", op); goto fail; + } - if (mask && mask->componentAlpha) { + if (mask && mask->componentAlpha && !glamor_priv->has_dual_blend) { if (op == PictOpAtop || op == PictOpAtopReverse || op == PictOpXor || op >= PictOpSaturate) { diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c index e16732565..5fffa3b0f 100644 --- a/glamor/glamor_segs.c +++ b/glamor/glamor_segs.c @@ -44,7 +44,7 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc, int off_x, off_y; xSegment *v; char *vbo_offset; - int box_x, box_y; + int box_index; int add_last; pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -91,11 +91,11 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc, glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, + glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y); while (nbox--) { diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c index 58da3edf7..89a9c5102 100644 --- a/glamor/glamor_spans.c +++ b/glamor/glamor_spans.c @@ -55,7 +55,7 @@ glamor_fill_spans_gl(DrawablePtr drawable, GLshort *v; char *vbo_offset; int c; - int box_x, box_y; + int box_index; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) @@ -119,11 +119,12 @@ glamor_fill_spans_gl(DrawablePtr drawable, glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, FALSE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_index, FALSE, FALSE, + prog->matrix_uniform, &off_x, &off_y); while (nbox--) { glScissor(box->x1 + off_x, @@ -180,7 +181,7 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax, glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; - int box_x, box_y; + int box_index; int n; char *d; GLenum type; @@ -197,9 +198,9 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax, glamor_make_current(glamor_priv); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { - BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y); - glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y); + glamor_pixmap_loop(pixmap_priv, box_index) { + BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); + glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index); glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); glPixelStorei(GL_PACK_ALIGNMENT, 4); @@ -265,7 +266,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src, glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; - int box_x, box_y; + int box_index; int n; char *s; GLenum type; @@ -289,9 +290,9 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src, glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { - BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y); - glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y); + glamor_pixmap_loop(pixmap_priv, box_index) { + BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); + glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, fbo->tex); diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c index 429f53b8a..c305305f4 100644 --- a/glamor/glamor_text.c +++ b/glamor/glamor_text.c @@ -107,7 +107,7 @@ glamor_text(DrawablePtr drawable, GCPtr gc, int firstCol = font->info.firstCol; int glyph_spacing_x = glamor_font->glyph_width_bytes * 8; int glyph_spacing_y = glamor_font->glyph_height; - int box_x, box_y; + int box_index; PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -188,11 +188,13 @@ glamor_text(DrawablePtr drawable, GCPtr gc, glEnable(GL_SCISSOR_TEST); - glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_pixmap_loop(pixmap_priv, box_index) { BoxPtr box = RegionRects(gc->pCompositeClip); int nbox = RegionNumRects(gc->pCompositeClip); - glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE, + prog->matrix_uniform, + &off_x, &off_y); /* Run over the clip list, drawing the glyphs * in each box diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c index 155d7e0fa..ed81195b6 100644 --- a/glamor/glamor_transfer.c +++ b/glamor/glamor_transfer.c @@ -42,7 +42,7 @@ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type) *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case 8: - *format = GL_ALPHA; + *format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format; *type = GL_UNSIGNED_BYTE; break; default: @@ -63,7 +63,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); - int box_x, box_y; + int box_index; int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3; GLenum type; GLenum format; @@ -77,9 +77,9 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, if (glamor_priv->has_unpack_subimage) glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel); - glamor_pixmap_loop(priv, box_x, box_y) { - BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y); - glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y); + glamor_pixmap_loop(priv, box_index) { + BoxPtr box = glamor_pixmap_box_at(priv, box_index); + glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_index); BoxPtr boxes = in_boxes; int nbox = in_nbox; @@ -167,7 +167,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); - int box_x, box_y; + int box_index; int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3; GLenum type; GLenum format; @@ -180,9 +180,9 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, if (glamor_priv->has_pack_subimage) glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel); - glamor_pixmap_loop(priv, box_x, box_y) { - BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y); - glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y); + glamor_pixmap_loop(priv, box_index) { + BoxPtr box = glamor_pixmap_box_at(priv, box_index); + glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_index); BoxPtr boxes = in_boxes; int nbox = in_nbox; diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c index f476a99b7..fc96fd670 100644 --- a/glamor/glamor_transform.c +++ b/glamor/glamor_transform.c @@ -35,8 +35,7 @@ void glamor_set_destination_drawable(DrawablePtr drawable, - int box_x, - int box_y, + int box_index, Bool do_drawable_translate, Bool center_offset, GLint matrix_uniform_location, @@ -48,7 +47,7 @@ glamor_set_destination_drawable(DrawablePtr drawable, PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int off_x, off_y; - BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y); + BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); int w = box->x2 - box->x1; int h = box->y2 - box->y1; float scale_x = 2.0f / (float) w; @@ -77,8 +76,6 @@ glamor_set_destination_drawable(DrawablePtr drawable, * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1 * * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1 - * - * I'll think about yInverted later, when I have some way to test */ if (do_drawable_translate) { @@ -97,7 +94,7 @@ glamor_set_destination_drawable(DrawablePtr drawable, scale_x, (off_x + center_adjust) * scale_x - 1.0f, scale_y, (off_y + center_adjust) * scale_y - 1.0f); - glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y), + glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_index), 0, 0, w, h); } @@ -107,15 +104,21 @@ glamor_set_destination_drawable(DrawablePtr drawable, */ void -glamor_set_color(PixmapPtr pixmap, - CARD32 pixel, - GLint uniform) +glamor_set_color_depth(ScreenPtr pScreen, + int depth, + CARD32 pixel, + GLint uniform) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); float color[4]; glamor_get_rgba_from_pixel(pixel, &color[0], &color[1], &color[2], &color[3], - format_for_pixmap(pixmap)); + format_for_depth(depth)); + + if ((depth == 1 || depth == 8) && + glamor_priv->one_channel_format == GL_RED) + color[0] = color[3]; glUniform4fv(uniform, 1, color); } diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h index dca6a26ab..5a520ebb0 100644 --- a/glamor/glamor_transform.h +++ b/glamor/glamor_transform.h @@ -25,8 +25,7 @@ void glamor_set_destination_drawable(DrawablePtr drawable, - int box_x, - int box_y, + int box_index, Bool do_drawable_translate, Bool center_offset, GLint matrix_uniform_location, @@ -34,9 +33,19 @@ glamor_set_destination_drawable(DrawablePtr drawable, int *p_off_y); void +glamor_set_color_depth(ScreenPtr pScreen, + int depth, + CARD32 pixel, + GLint uniform); + +static inline void glamor_set_color(PixmapPtr pixmap, CARD32 pixel, - GLint uniform); + GLint uniform) +{ + glamor_set_color_depth(pixmap->drawable.pScreen, + pixmap->drawable.depth, pixel, uniform); +} Bool glamor_set_texture_pixmap(PixmapPtr texture); diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index e648af2de..5128a33d8 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -36,11 +36,9 @@ #include "mipict.h" #define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0) -#define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0) -#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) +#define v_from_x_coord_y(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) #define t_from_x_coord_x(_xscale_, _x_) ((_x_) * (_xscale_)) -#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_)) -#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_)) +#define t_from_x_coord_y(_yscale_, _y_) ((_y_) * (_yscale_)) #define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \ do { \ @@ -313,7 +311,7 @@ texcoord) \ do { \ (texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \ - (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \ + (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \ DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \ (texcoord)[1]); \ } while(0) @@ -332,7 +330,7 @@ tx += fbo_x_off; \ ty += fbo_y_off; \ (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ - (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ + (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \ } while(0) @@ -484,8 +482,8 @@ (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ - (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \ - (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \ + (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \ + (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) @@ -564,8 +562,8 @@ (vertices)[2] = t_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ - (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \ + (vertices)[1] = t_from_x_coord_y(yscale, y1); \ + (vertices)[7] = t_from_x_coord_y(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) @@ -598,7 +596,7 @@ vertices) \ do { \ (vertices)[0] = v_from_x_coord_x(xscale, x); \ - (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \ + (vertices)[1] = v_from_x_coord_y(yscale, y); \ } while(0) #define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \ @@ -641,11 +639,9 @@ x2 + fbo_x_off); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ - (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \ - y1 + fbo_y_off); \ + (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \ (vertices)[2 * stride + 1] = _t5_ = \ - v_from_x_coord_y_inverted(yscale, \ - y2 + fbo_y_off); \ + v_from_x_coord_y(yscale, y2 + fbo_y_off); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) @@ -677,8 +673,8 @@ (vertices)[2] = v_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ - (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \ + (vertices)[1] = v_from_x_coord_y(yscale, y1); \ + (vertices)[7] = v_from_x_coord_y(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) @@ -687,7 +683,7 @@ pt) \ do { \ (pt)[0] = t_from_x_coord_x(xscale, x); \ - (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \ + (pt)[1] = t_from_x_coord_y(yscale, y); \ } while(0) #define glamor_set_circle_centre(width, height, x, y, \ @@ -757,7 +753,7 @@ gl_iformat_for_pixmap(PixmapPtr pixmap) if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) { - return GL_ALPHA; + return glamor_priv->one_channel_format; } else { return GL_RGBA; } @@ -856,24 +852,6 @@ glamor_get_rgba_from_pixel(CARD32 pixel, } inline static Bool -glamor_pict_format_is_compatible(PicturePtr picture) -{ - GLenum iformat; - PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable); - - iformat = gl_iformat_for_pixmap(pixmap); - switch (iformat) { - case GL_RGBA: - return (picture->format == PICT_a8r8g8b8 || - picture->format == PICT_x8r8g8b8); - case GL_ALPHA: - return (picture->format == PICT_a8); - default: - return FALSE; - } -} - -inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *priv; diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c index ba60ce660..b8db0092b 100644 --- a/glamor/glamor_vbo.c +++ b/glamor/glamor_vbo.c @@ -174,6 +174,11 @@ glamor_init_vbo(ScreenPtr screen) glamor_make_current(glamor_priv); glGenBuffers(1, &glamor_priv->vbo); + if (glamor_priv->has_vertex_array_object) { + glGenVertexArrays(1, &glamor_priv->vao); + glBindVertexArray(glamor_priv->vao); + } else + glamor_priv->vao = 0; } void @@ -183,6 +188,10 @@ glamor_fini_vbo(ScreenPtr screen) glamor_make_current(glamor_priv); + if (glamor_priv->vao != 0) { + glDeleteVertexArrays(1, &glamor_priv->vao); + glamor_priv->vao = 0; + } if (!glamor_priv->has_map_buffer_range) free(glamor_priv->vb); } diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index 85e652832..3bcf909b0 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -37,6 +37,7 @@ #endif #include "glamor_priv.h" +#include "glamor_transform.h" #include "glamor_transfer.h" #include <X11/extensions/Xv.h> @@ -58,36 +59,36 @@ typedef struct tagREF_TRANSFORM { #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) #define RTFHue(a) (((a)*3.1416)/1000.0) -static const char *xv_vs = "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord0;\n" - "varying vec2 tcs;\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - "tcs = v_texcoord0.xy;\n" - "}\n"; - -static const char *xv_ps = GLAMOR_DEFAULT_PRECISION - "uniform sampler2D y_sampler;\n" - "uniform sampler2D u_sampler;\n" - "uniform sampler2D v_sampler;\n" - "uniform vec4 offsetyco;\n" - "uniform vec4 ucogamma;\n" - "uniform vec4 vco;\n" - "varying vec2 tcs;\n" - "float sample;\n" - "vec4 temp1;\n" - "void main()\n" - "{\n" - "sample = texture2D(y_sampler, tcs).w;\n" - "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n" - "sample = texture2D(u_sampler, tcs).w;\n" - "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n" - "sample = texture2D(v_sampler, tcs).w;\n" - "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n" - "temp1.w = 1.0;\n" - "gl_FragColor = temp1;\n" - "}\n"; +static const glamor_facet glamor_facet_xv_planar = { + .name = "xv_planar", + + .source_name = "v_texcoord0", + .vs_vars = ("attribute vec2 position;\n" + "attribute vec2 v_texcoord0;\n" + "varying vec2 tcs;\n"), + .vs_exec = (GLAMOR_POS(gl_Position, position) + " tcs = v_texcoord0;\n"), + + .fs_vars = ("uniform sampler2D y_sampler;\n" + "uniform sampler2D u_sampler;\n" + "uniform sampler2D v_sampler;\n" + "uniform vec4 offsetyco;\n" + "uniform vec4 ucogamma;\n" + "uniform vec4 vco;\n" + "varying vec2 tcs;\n"), + .fs_exec = ( + " float sample;\n" + " vec4 temp1;\n" + " sample = texture2D(y_sampler, tcs).w;\n" + " temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n" + " sample = texture2D(u_sampler, tcs).w;\n" + " temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n" + " sample = texture2D(v_sampler, tcs).w;\n" + " temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n" + " temp1.w = 1.0;\n" + " gl_FragColor = temp1;\n" + ), +}; #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) @@ -113,23 +114,21 @@ int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images); static void glamor_init_xv_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - GLint fs_prog, vs_prog; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + GLint sampler_loc; + + glamor_build_program(screen, + &glamor_priv->xv_prog, + &glamor_facet_xv_planar, NULL, NULL, NULL); + + glUseProgram(glamor_priv->xv_prog.prog); + sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler"); + glUniform1i(sampler_loc, 0); + sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler"); + glUniform1i(sampler_loc, 1); + sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler"); + glUniform1i(sampler_loc, 2); - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glamor_priv->xv_prog = glCreateProgram(); - - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xv_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xv_ps); - glAttachShader(glamor_priv->xv_prog, vs_prog); - glAttachShader(glamor_priv->xv_prog, fs_prog); - - glBindAttribLocation(glamor_priv->xv_prog, - GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->xv_prog, - GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv"); } #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) @@ -245,11 +244,8 @@ glamor_xv_render(glamor_port_private *port_priv) PixmapPtr pixmap = port_priv->pPixmap; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *src_pixmap_priv[3]; - float vertices[32], texcoords[8]; BoxPtr box = REGION_RECTS(&port_priv->clip); int nBox = REGION_NUM_RECTS(&port_priv->clip); - int dst_x_off, dst_y_off; - GLfloat dst_xscale, dst_yscale; GLfloat src_xscale[3], src_yscale[3]; int i; const float Loff = -0.0627; @@ -259,9 +255,12 @@ glamor_xv_render(glamor_port_private *port_priv) float uco[3], vco[3], off[3]; float bright, cont, gamma; int ref = port_priv->transform_index; - GLint uloc, sampler_loc; + GLint uloc; + GLfloat *v; + char *vbo_offset; + int dst_box_index; - if (!glamor_priv->xv_prog) + if (!glamor_priv->xv_prog.prog) glamor_init_xv_shader(screen); cont = RTFContrast(port_priv->contrast); @@ -283,10 +282,6 @@ glamor_xv_render(glamor_port_private *port_priv) off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; gamma = 1.0; - pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale); - glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off, - &dst_y_off); - glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv); glamor_set_alu(screen, GXcopy); for (i = 0; i < 3; i++) { @@ -298,13 +293,13 @@ glamor_xv_render(glamor_port_private *port_priv) } } glamor_make_current(glamor_priv); - glUseProgram(glamor_priv->xv_prog); + glUseProgram(glamor_priv->xv_prog.prog); - uloc = glGetUniformLocation(glamor_priv->xv_prog, "offsetyco"); + uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "offsetyco"); glUniform4f(uloc, off[0], off[1], off[2], yco); - uloc = glGetUniformLocation(glamor_priv->xv_prog, "ucogamma"); + uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "ucogamma"); glUniform4f(uloc, uco[0], uco[1], uco[2], gamma); - uloc = glGetUniformLocation(glamor_priv->xv_prog, "vco"); + uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "vco"); glUniform4f(uloc, vco[0], vco[1], vco[2], 0); glActiveTexture(GL_TEXTURE0); @@ -328,60 +323,71 @@ glamor_xv_render(glamor_port_private *port_priv) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler"); - glUniform1i(sampler_loc, 0); - sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler"); - glUniform1i(sampler_loc, 1); - sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler"); - glUniform1i(sampler_loc, 2); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + glEnable(GL_SCISSOR_TEST); + + v = glamor_get_vbo_space(screen, 3 * 4 * sizeof(GLfloat), &vbo_offset); + + /* Set up a single primitive covering the area being drawn. We'll + * clip it to port_priv->clip using GL scissors instead of just + * emitting a GL_QUAD per box, because this way we hopefully avoid + * diagonal tearing between the two trangles used to rasterize a + * GL_QUAD. + */ + i = 0; + v[i++] = port_priv->drw_x; + v[i++] = port_priv->drw_y; + + v[i++] = port_priv->drw_x + port_priv->dst_w * 2; + v[i++] = port_priv->drw_y; + + v[i++] = port_priv->drw_x; + v[i++] = port_priv->drw_y + port_priv->dst_h * 2; + + v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x); + v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y); + + v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x + + port_priv->src_w * 2); + v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y); + + v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x); + v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y + + port_priv->src_h * 2); + + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, + GL_FLOAT, GL_FALSE, + 2 * sizeof(float), vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, - 2 * sizeof(float), texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + 2 * sizeof(float), vbo_offset + 6 * sizeof(GLfloat)); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), vertices); + glamor_put_vbo_space(screen); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glEnable(GL_SCISSOR_TEST); - for (i = 0; i < nBox; i++) { - float off_x = box[i].x1 - port_priv->drw_x; - float off_y = box[i].y1 - port_priv->drw_y; - float diff_x = (float) port_priv->src_w / (float) port_priv->dst_w; - float diff_y = (float) port_priv->src_h / (float) port_priv->dst_h; - float srcx, srcy, srcw, srch; - int dstx, dsty, dstw, dsth; - - dstx = box[i].x1 + dst_x_off; - dsty = box[i].y1 + dst_y_off; - dstw = box[i].x2 - box[i].x1; - dsth = box[i].y2 - box[i].y1; - - srcx = port_priv->src_x + off_x * diff_x; - srcy = port_priv->src_y + off_y * diff_y; - srcw = (port_priv->src_w * dstw) / (float) port_priv->dst_w; - srch = (port_priv->src_h * dsth) / (float) port_priv->dst_h; - - glamor_set_normalize_vcoords(pixmap_priv, - dst_xscale, dst_yscale, - dstx - dstw, - dsty, - dstx + dstw, - dsty + dsth * 2, - vertices); - - glamor_set_normalize_tcoords(src_pixmap_priv[0], - src_xscale[0], - src_yscale[0], - srcx - srcw, - srcy, - srcx + srcw, - srcy + srch * 2, - texcoords); - - glScissor(dstx, dsty, dstw, dsth); - glDrawArrays(GL_TRIANGLE_FAN, 0, 3); + /* Now draw our big triangle, clipped to each of the clip boxes. */ + glamor_pixmap_loop(pixmap_priv, dst_box_index) { + int dst_off_x, dst_off_y; + + glamor_set_destination_drawable(port_priv->pDraw, + dst_box_index, + FALSE, FALSE, + glamor_priv->xv_prog.matrix_uniform, + &dst_off_x, &dst_off_y); + + for (i = 0; i < nBox; i++) { + int dstx, dsty, dstw, dsth; + + dstx = box[i].x1 + dst_off_x; + dsty = box[i].y1 + dst_off_y; + dstw = box[i].x2 - box[i].x1; + dsth = box[i].y2 - box[i].y1; + + glScissor(dstx, dsty, dstw, dsth); + glDrawArrays(GL_TRIANGLE_FAN, 0, 3); + } } glDisable(GL_SCISSOR_TEST); @@ -489,7 +495,7 @@ glamor_xv_put_image(glamor_port_private *port_priv, RegionCopy(&port_priv->clip, clipBoxes); port_priv->src_x = src_x; - port_priv->src_y = src_y; + port_priv->src_y = src_y - top; port_priv->src_w = src_w; port_priv->src_h = src_h; port_priv->dst_w = drw_w; diff --git a/glx/extension_string.c b/glx/extension_string.c index cf9014609..616c7932e 100644 --- a/glx/extension_string.c +++ b/glx/extension_string.c @@ -82,8 +82,10 @@ static const struct extension_info known_glx_extensions[] = { { GLX(EXT_create_context_es_profile), VER(0,0), N, }, { GLX(EXT_create_context_es2_profile), VER(0,0), N, }, + { GLX(EXT_fbconfig_packed_float), VER(0,0), N, }, { GLX(EXT_framebuffer_sRGB), VER(0,0), N, }, { GLX(EXT_import_context), VER(0,0), Y, }, + { GLX(EXT_stereo_tree), VER(0,0), N, }, { GLX(EXT_texture_from_pixmap), VER(0,0), Y, }, { GLX(EXT_visual_info), VER(0,0), Y, }, { GLX(EXT_visual_rating), VER(0,0), Y, }, diff --git a/glx/extension_string.h b/glx/extension_string.h index ffaab073a..425a8058b 100644 --- a/glx/extension_string.h +++ b/glx/extension_string.h @@ -45,7 +45,9 @@ enum { ARB_multisample_bit, EXT_create_context_es_profile_bit, EXT_create_context_es2_profile_bit, + EXT_fbconfig_packed_float_bit, EXT_import_context_bit, + EXT_stereo_tree_bit, EXT_texture_from_pixmap_bit, EXT_visual_info_bit, EXT_visual_rating_bit, diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 1247cf0f5..7b42ef0d1 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -544,7 +544,6 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client, /* since we are creating the drawablePrivate, drawId should be new */ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { - pGlxDraw->destroy(pGlxDraw); *error = BadAlloc; return NULL; } @@ -1239,20 +1238,16 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen, if (pGlxDraw == NULL) return BadAlloc; - if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) { - pGlxDraw->destroy(pGlxDraw); + if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) return BadAlloc; - } /* * Windows aren't refcounted, so track both the X and the GLX window * so we get called regardless of destruction order. */ if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW && - !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { - pGlxDraw->destroy(pGlxDraw); + !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) return BadAlloc; - } return Success; } @@ -1926,6 +1921,11 @@ __glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc) return Success; } +/* hack for old glxext.h */ +#ifndef GLX_STEREO_TREE_EXT +#define GLX_STEREO_TREE_EXT 0x20F5 +#endif + /* ** Get drawable attributes */ @@ -1936,7 +1936,7 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId) xGLXGetDrawableAttributesReply reply; __GLXdrawable *pGlxDraw = NULL; DrawablePtr pDraw; - CARD32 attributes[14]; + CARD32 attributes[18]; int num = 0, error; if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, @@ -1950,33 +1950,30 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId) if (pGlxDraw) pDraw = pGlxDraw->pDraw; - attributes[2*num] = GLX_Y_INVERTED_EXT; - attributes[2*num+1] = GL_FALSE; - num++; - attributes[2*num] = GLX_WIDTH; - attributes[2*num+1] = pDraw->width; - num++; - attributes[2*num] = GLX_HEIGHT; - attributes[2*num+1] = pDraw->height; - num++; +#define ATTRIB(a, v) do { \ + attributes[2*num] = (a); \ + attributes[2*num+1] = (v); \ + num++; \ + } while (0) + + ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE); + ATTRIB(GLX_WIDTH, pDraw->width); + ATTRIB(GLX_HEIGHT, pDraw->height); + ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum); if (pGlxDraw) { - attributes[2*num] = GLX_TEXTURE_TARGET_EXT; - attributes[2*num+1] = pGlxDraw->target == GL_TEXTURE_2D ? - GLX_TEXTURE_2D_EXT : - GLX_TEXTURE_RECTANGLE_EXT; - num++; - attributes[2*num] = GLX_EVENT_MASK; - attributes[2*num+1] = pGlxDraw->eventMask; - num++; - attributes[2*num] = GLX_FBCONFIG_ID; - attributes[2*num+1] = pGlxDraw->config->fbconfigID; - num++; + ATTRIB(GLX_TEXTURE_TARGET_EXT, + pGlxDraw->target == GL_TEXTURE_2D ? + GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT); + ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask); + ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID); if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) { - attributes[2*num] = GLX_PRESERVED_CONTENTS; - attributes[2*num+1] = GL_TRUE; - num++; + ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE); + } + if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) { + ATTRIB(GLX_STEREO_TREE_EXT, 0); } } +#undef ATTRIB reply = (xGLXGetDrawableAttributesReply) { .type = X_Reply, diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 89ad808c9..58e60b976 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -895,6 +895,12 @@ initializeExtensions(__GLXDRIscreen * screen) LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_fbconfig_float\n"); } + /* enable EXT_fbconfig_packed_float (even if there are no packed float fbconfigs) */ + { + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float"); + LogMessage(X_INFO, "AIGLX: enabled GLX_EXT_fbconfig_packed_float\n"); + } + for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { __glXEnableExtension(screen->glx_enable_bits, diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index be00f5f06..924067c79 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -413,6 +413,7 @@ initializeExtensions(__GLXDRIscreen * screen) /* these are harmless to enable unconditionally */ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_framebuffer_sRGB"); __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float"); + __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float"); __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read"); extensions = screen->core->getExtensions(screen->driScreen); diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c index ddcb98135..a77d556db 100644 --- a/hw/dmx/glxProxy/glxcmds.c +++ b/hw/dmx/glxProxy/glxcmds.c @@ -2010,11 +2010,8 @@ CreateGLXPixmap(__GLXclientState * cl, XFlush(dpy); } - if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { - free(pGlxPixmap->be_xids); - free(pGlxPixmap); + if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) return BadAlloc; - } return Success; } diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c index 582e3af96..2f219141e 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -41,6 +41,10 @@ #include "os.h" #include <X11/Xproto.h> +/* until we need geometry shaders GL3.1 should suffice. */ +/* Xephyr has it's own copy of this for build reasons */ +#define GLAMOR_GL_CORE_VER_MAJOR 3 +#define GLAMOR_GL_CORE_VER_MINOR 1 /** @{ * * global state for Xephyr with glamor. @@ -71,6 +75,8 @@ struct ephyr_glamor { /* Size of the window that we're rendering to. */ unsigned width, height; + + GLuint vao, vbo; }; static GLint @@ -189,47 +195,55 @@ ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex) glamor->tex = tex; } +static void +ephyr_glamor_set_vertices(struct ephyr_glamor *glamor) +{ + glVertexAttribPointer(glamor->texture_shader_position_loc, + 2, GL_FLOAT, FALSE, 0, (void *) 0); + glVertexAttribPointer(glamor->texture_shader_texcoord_loc, + 2, GL_FLOAT, FALSE, 0, (void *) (sizeof (float) * 8)); + + glEnableVertexAttribArray(glamor->texture_shader_position_loc); + glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc); +} + +static void +ephyr_glamor_clear_vertices(struct ephyr_glamor *glamor) +{ + glDisableVertexAttribArray(glamor->texture_shader_position_loc); + glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc); +} + void ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, struct pixman_region16 *damage) { - /* Redraw the whole screen, since glXSwapBuffers leaves the back - * buffer undefined. - */ - static const float position[] = { - -1, -1, - 1, -1, - 1, 1, - -1, 1, - }; - static const float texcoords[] = { - 0, 1, - 1, 1, - 1, 0, - 0, 0, - }; + GLint old_vao; glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx); + if (glamor->vao) { + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao); + glBindVertexArray(glamor->vao); + } else { + glBindBuffer(GL_ARRAY_BUFFER, glamor->vbo); + ephyr_glamor_set_vertices(glamor); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(glamor->texture_shader); glViewport(0, 0, glamor->width, glamor->height); if (!ephyr_glamor_gles2) glDisable(GL_COLOR_LOGIC_OP); - glVertexAttribPointer(glamor->texture_shader_position_loc, - 2, GL_FLOAT, FALSE, 0, position); - glVertexAttribPointer(glamor->texture_shader_texcoord_loc, - 2, GL_FLOAT, FALSE, 0, texcoords); - glEnableVertexAttribArray(glamor->texture_shader_position_loc); - glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glamor->tex); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(glamor->texture_shader_position_loc); - glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc); + if (glamor->vao) + glBindVertexArray(old_vao); + else + ephyr_glamor_clear_vertices(glamor); glXSwapBuffers(dpy, glamor->glx_win); } @@ -268,9 +282,28 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev) XUnlockDisplay(dpy); } +static int +ephyr_glx_error_handler(Display * _dpy, XErrorEvent * ev) +{ + return 0; +} + struct ephyr_glamor * ephyr_glamor_glx_screen_init(xcb_window_t win) { + int (*oldErrorHandler) (Display *, XErrorEvent *); + static const float position[] = { + -1, -1, + 1, -1, + 1, 1, + -1, 1, + 0, 1, + 1, 1, + 1, 0, + 0, 0, + }; + GLint old_vao; + GLXContext ctx; struct ephyr_glamor *glamor; GLXWindow glx_win; @@ -299,7 +332,28 @@ ephyr_glamor_glx_screen_init(xcb_window_t win) "GLX_EXT_create_context_es2_profile\n"); } } else { - ctx = glXCreateContext(dpy, visual_info, NULL, True); + if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy), + "GLX_ARB_create_context")) { + static const int context_attribs[] = { + GLX_CONTEXT_PROFILE_MASK_ARB, + GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_MAJOR_VERSION_ARB, + GLAMOR_GL_CORE_VER_MAJOR, + GLX_CONTEXT_MINOR_VERSION_ARB, + GLAMOR_GL_CORE_VER_MINOR, + 0, + }; + oldErrorHandler = XSetErrorHandler(ephyr_glx_error_handler); + ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True, + context_attribs); + XSync(dpy, False); + XSetErrorHandler(oldErrorHandler); + } else { + ctx = NULL; + } + + if (!ctx) + ctx = glXCreateContext(dpy, visual_info, NULL, True); } if (ctx == NULL) FatalError("glXCreateContext failed\n"); @@ -312,6 +366,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win) glamor->glx_win = glx_win; ephyr_glamor_setup_texturing_shader(glamor); + if (epoxy_has_gl_extension("GL_ARB_vertex_array_object")) { + glGenVertexArrays(1, &glamor->vao); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao); + glBindVertexArray(glamor->vao); + } else + glamor->vao = 0; + + glGenBuffers(1, &glamor->vbo); + + glBindBuffer(GL_ARRAY_BUFFER, glamor->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW); + + if (glamor->vao) { + ephyr_glamor_set_vertices(glamor); + glBindVertexArray(old_vao); + } else + glBindBuffer(GL_ARRAY_BUFFER, 0); + return glamor; } diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c index 63e840996..752489489 100644 --- a/hw/kdrive/linux/evdev.c +++ b/hw/kdrive/linux/evdev.c @@ -440,10 +440,16 @@ EvdevKbdEnable(KdKeyboardInfo * ki) static void EvdevKbdLeds(KdKeyboardInfo * ki, int leds) { -/* struct input_event event; + struct input_event event; Kevdev *ke; - ki->driverPrivate = ke; + if (!ki) + return; + + ke = ki->driverPrivate; + + if (!ke) + return; memset(&event, 0, sizeof(event)); @@ -466,7 +472,6 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds) event.code = LED_COMPOSE; event.value = leds & (1 << 3) ? 1 : 0; write(ke->fd, (char *) &event, sizeof(event)); -*/ } static void diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index dddbe6e96..582ff66d2 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -99,7 +99,7 @@ KdDisableScreen(ScreenPtr pScreen) if (!pScreenPriv->enabled) return; if (!pScreenPriv->closed) - SetRootClip(pScreen, FALSE); + SetRootClip(pScreen, ROOT_CLIP_NONE); KdDisableColormap(pScreen); if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel) (*pScreenPriv->card->cfuncs->disableAccel) (pScreen); @@ -182,7 +182,7 @@ KdEnableScreen(ScreenPtr pScreen) if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel) (*pScreenPriv->card->cfuncs->enableAccel) (pScreen); KdEnableColormap(pScreen); - SetRootClip(pScreen, TRUE); + SetRootClip(pScreen, ROOT_CLIP_FULL); if (pScreenPriv->card->cfuncs->dpms) (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState); return TRUE; diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c index 9e8dd7a3b..01bb63128 100644 --- a/hw/vfb/InitOutput.c +++ b/hw/vfb/InitOutput.c @@ -763,7 +763,7 @@ vfbRRScreenSetSize(ScreenPtr pScreen, CARD32 mmHeight) { // Prevent screen updates while we change things around - SetRootClip(pScreen, FALSE); + SetRootClip(pScreen, ROOT_CLIP_NONE); pScreen->width = width; pScreen->height = height; @@ -771,7 +771,7 @@ vfbRRScreenSetSize(ScreenPtr pScreen, pScreen->mmHeight = mmHeight; // Restore the ability to update screen, now with new dimensions - SetRootClip(pScreen, TRUE); + SetRootClip(pScreen, ROOT_CLIP_FULL); RRScreenSizeNotify (pScreen); RRTellChanged(pScreen); diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 64c4f7456..85bd0bed0 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -72,7 +72,9 @@ LOCAL_LIBS = \ $(DRI3_LIB) \ $(top_builddir)/miext/sync/libsync.la \ $(top_builddir)/mi/libmi.la \ - $(top_builddir)/os/libos.la + $(top_builddir)/os/libos.la \ + $(top_builddir)/Xext/libXvidmode.la + Xorg_LDADD = \ $(LOCAL_LIBS) \ $(XORG_SYS_LIBS) \ diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 3bc0046aa..caae7fd97 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -14,10 +14,6 @@ XVSOURCES = xf86xv.c xf86xvmc.c XVSDKINCS = xf86xv.h xf86xvmc.h xf86xvpriv.h endif -if XF86VIDMODE -XF86VMODESOURCES = xf86vmode.c -endif - if DGA DGASOURCES = xf86DGA.c DGA_SDK = dgaproc.h @@ -71,7 +67,6 @@ CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = \ compiler.h \ fourcc.h \ - vidmodeproc.h \ xf86.h \ xf86Bus.h \ xf86Config.h \ diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h deleted file mode 100644 index 59d714c77..000000000 --- a/hw/xfree86/common/vidmodeproc.h +++ /dev/null @@ -1,83 +0,0 @@ - -/* Prototypes for DGA functions that the DDX must provide */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#ifndef _VIDMODEPROC_H_ -#define _VIDMODEPROC_H_ - -typedef enum { - VIDMODE_H_DISPLAY, - VIDMODE_H_SYNCSTART, - VIDMODE_H_SYNCEND, - VIDMODE_H_TOTAL, - VIDMODE_H_SKEW, - VIDMODE_V_DISPLAY, - VIDMODE_V_SYNCSTART, - VIDMODE_V_SYNCEND, - VIDMODE_V_TOTAL, - VIDMODE_FLAGS, - VIDMODE_CLOCK -} VidModeSelectMode; - -typedef enum { - VIDMODE_MON_VENDOR, - VIDMODE_MON_MODEL, - VIDMODE_MON_NHSYNC, - VIDMODE_MON_NVREFRESH, - VIDMODE_MON_HSYNC_LO, - VIDMODE_MON_HSYNC_HI, - VIDMODE_MON_VREFRESH_LO, - VIDMODE_MON_VREFRESH_HI -} VidModeSelectMonitor; - -typedef union { - const void *ptr; - int i; - float f; -} vidMonitorValue; - -extern Bool VidModeExtensionInit(ScreenPtr pScreen); - -extern Bool VidModeGetCurrentModeline(int scrnIndex, void **mode, - int *dotClock); -extern Bool VidModeGetFirstModeline(int scrnIndex, void **mode, - int *dotClock); -extern Bool VidModeGetNextModeline(int scrnIndex, void **mode, - int *dotClock); -extern Bool VidModeDeleteModeline(int scrnIndex, void *mode); -extern Bool VidModeZoomViewport(int scrnIndex, int zoom); -extern Bool VidModeGetViewPort(int scrnIndex, int *x, int *y); -extern Bool VidModeSetViewPort(int scrnIndex, int x, int y); -extern Bool VidModeSwitchMode(int scrnIndex, void *mode); -extern Bool VidModeLockZoom(int scrnIndex, Bool lock); -extern Bool VidModeGetMonitor(int scrnIndex, void **monitor); -extern int VidModeGetNumOfClocks(int scrnIndex, Bool *progClock); -extern Bool VidModeGetClocks(int scrnIndex, int *Clocks); -extern ModeStatus VidModeCheckModeForMonitor(int scrnIndex, - void *mode); -extern ModeStatus VidModeCheckModeForDriver(int scrnIndex, - void *mode); -extern void VidModeSetCrtcForMode(int scrnIndex, void *mode); -extern Bool VidModeAddModeline(int scrnIndex, void *mode); -extern int VidModeGetDotClock(int scrnIndex, int Clock); -extern int VidModeGetNumOfModes(int scrnIndex); -extern Bool VidModeSetGamma(int scrnIndex, float red, float green, - float blue); -extern Bool VidModeGetGamma(int scrnIndex, float *red, float *green, - float *blue); -extern void *VidModeCreateMode(void); -extern void VidModeCopyMode(void *modefrom, void *modeto); -extern int VidModeGetModeValue(void *mode, int valtyp); -extern void VidModeSetModeValue(void *mode, int valtyp, int val); -extern vidMonitorValue VidModeGetMonitorValue(void *monitor, - int valtyp, int indx); -extern Bool VidModeSetGammaRamp(int, int, CARD16 *, CARD16 *, - CARD16 *); -extern Bool VidModeGetGammaRamp(int, int, CARD16 *, CARD16 *, - CARD16 *); -extern int VidModeGetGammaRampSize(int scrnIndex); - -#endif diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index d2c32258e..0c067c0c9 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -46,10 +46,8 @@ #include <xorg-config.h> #endif -#ifdef XF86DRI #include <sys/types.h> #include <grp.h> -#endif #include "xf86.h" #include "xf86Modes.h" @@ -132,9 +130,7 @@ static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input, static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display); static Bool addDefaultModes(MonPtr monitorp); -#ifdef XF86DRI static void configDRI(XF86ConfDRIPtr drip); -#endif static void configExtensions(XF86ConfExtensionsPtr conf_ext); /* @@ -2218,7 +2214,6 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool g return TRUE; } -#ifdef XF86DRI static void configDRI(XF86ConfDRIPtr drip) { @@ -2239,7 +2234,6 @@ configDRI(XF86ConfDRIPtr drip) xf86ConfigDRI.mode = drip->dri_mode; } } -#endif static void configExtensions(XF86ConfExtensionsPtr conf_ext) @@ -2532,9 +2526,7 @@ xf86HandleConfigFile(Bool autoconfig) configServerFlags(xf86configptr->conf_flags, xf86ConfigLayout.options); configFiles(xf86configptr->conf_files); configExtensions(xf86configptr->conf_extensions); -#ifdef XF86DRI configDRI(xf86configptr->conf_dri); -#endif checkInput(&xf86ConfigLayout, implicit_layout); diff --git a/hw/xfree86/common/xf86Extensions.c b/hw/xfree86/common/xf86Extensions.c index 25b2bc3d0..1b8b78505 100644 --- a/hw/xfree86/common/xf86Extensions.c +++ b/hw/xfree86/common/xf86Extensions.c @@ -28,6 +28,7 @@ #endif #include "extension.h" +#include "extinit.h" #include "globals.h" #include "xf86.h" @@ -47,7 +48,7 @@ #ifdef XF86VIDMODE #include <X11/extensions/xf86vmproto.h> -#include "vidmodeproc.h" +#include "vidmodestr.h" #endif /* diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c index c42e93ed8..3b01a49b5 100644 --- a/hw/xfree86/common/xf86Helper.c +++ b/hw/xfree86/common/xf86Helper.c @@ -1076,14 +1076,14 @@ xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable) * Restore all of the clip lists on the screen */ if (!xf86Resetting) - SetRootClip(pScreen, TRUE); + SetRootClip(pScreen, ROOT_CLIP_FULL); } else { /* * Empty all of the clip lists on the screen */ - SetRootClip(pScreen, FALSE); + SetRootClip(pScreen, ROOT_CLIP_NONE); } } diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 017dcb6bb..de51497b5 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -72,6 +72,7 @@ #include "mipointer.h" #include <X11/extensions/XI.h> #include <X11/extensions/XIproto.h> +#include "xf86Extensions.h" #include "xf86DDC.h" #include "xf86Xinput.h" #include "xf86InPriv.h" diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h index cffa14d01..58d5a0f13 100644 --- a/hw/xfree86/common/xf86Privstr.h +++ b/hw/xfree86/common/xf86Privstr.h @@ -115,16 +115,6 @@ typedef struct { } DPMSRec, *DPMSPtr; #endif -#ifdef XF86VIDMODE -/* Private info for Video Mode Extentsion */ -typedef struct { - DisplayModePtr First; - DisplayModePtr Next; - int Flags; - CloseScreenProcPtr CloseScreen; -} VidModeRec, *VidModePtr; -#endif - /* Information for root window properties. */ typedef struct _RootWinProp { struct _RootWinProp *next; diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c index 10c7b4b40..7e12ea2cc 100644 --- a/hw/xfree86/common/xf86VidMode.c +++ b/hw/xfree86/common/xf86VidMode.c @@ -42,113 +42,62 @@ #include "os.h" #include "xf86.h" #include "xf86Priv.h" +#include "extinit.h" #ifdef XF86VIDMODE -#include "vidmodeproc.h" +#include "vidmodestr.h" +#include "xf86Privstr.h" +#include "xf86Extensions.h" #include "xf86cmap.h" -static DevPrivateKeyRec VidModeKeyRec; -static DevPrivateKey VidModeKey; -static int VidModeCount = 0; -static Bool VidModeClose(ScreenPtr pScreen); - -#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey)) - -#endif - -Bool -VidModeExtensionInit(ScreenPtr pScreen) -{ -#ifdef XF86VIDMODE - VidModePtr pVidMode; - - if (!xf86GetVidModeEnabled()) { - DebugF("!xf86GetVidModeEnabled()\n"); - return FALSE; - } - - VidModeKey = &VidModeKeyRec; - - if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - pVidMode = calloc(sizeof(VidModeRec), 1); - if (!pVidMode) - return FALSE; - - dixSetPrivate(&pScreen->devPrivates, VidModeKey, pVidMode); - - pVidMode->Flags = 0; - pVidMode->Next = NULL; - pVidMode->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = VidModeClose; - VidModeCount++; - return TRUE; -#else - DebugF("no vidmode extension\n"); - return FALSE; -#endif -} - -#ifdef XF86VIDMODE - -static Bool -VidModeClose(ScreenPtr pScreen) -{ - VidModePtr pVidMode = VMPTR(pScreen); - - /* This shouldn't happen */ - if (!pVidMode) - return FALSE; - - pScreen->CloseScreen = pVidMode->CloseScreen; - - if (--VidModeCount == 0) { - free(dixLookupPrivate(&pScreen->devPrivates, VidModeKey)); - dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL); - VidModeKey = NULL; - } - return pScreen->CloseScreen(pScreen); -} - -static Bool -VidModeAvailable(int scrnIndex) +static vidMonitorValue +xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx) { + vidMonitorValue ret = { NULL, }; + MonPtr monitor; ScrnInfoPtr pScrn; - VidModePtr pVidMode; - if (VidModeKey == NULL) { - DebugF("VidModeKey == NULL\n"); - return FALSE; - } + pScrn = xf86ScreenToScrn(pScreen); + monitor = pScrn->monitor; - pScrn = xf86Screens[scrnIndex]; - if (pScrn == NULL) { - DebugF("pScrn == NULL\n"); - return FALSE; - } - - pVidMode = VMPTR(pScrn->pScreen); - if (pVidMode) - return TRUE; - else { - DebugF("pVidMode == NULL\n"); - return FALSE; + switch (valtyp) { + case VIDMODE_MON_VENDOR: + ret.ptr = monitor->vendor; + break; + case VIDMODE_MON_MODEL: + ret.ptr = monitor->model; + break; + case VIDMODE_MON_NHSYNC: + ret.i = monitor->nHsync; + break; + case VIDMODE_MON_NVREFRESH: + ret.i = monitor->nVrefresh; + break; + case VIDMODE_MON_HSYNC_LO: + ret.f = (100.0 * monitor->hsync[indx].lo); + break; + case VIDMODE_MON_HSYNC_HI: + ret.f = (100.0 * monitor->hsync[indx].hi); + break; + case VIDMODE_MON_VREFRESH_LO: + ret.f = (100.0 * monitor->vrefresh[indx].lo); + break; + case VIDMODE_MON_VREFRESH_HI: + ret.f = (100.0 * monitor->vrefresh[indx].hi); + break; } + return ret; } -Bool -VidModeGetCurrentModeline(int scrnIndex, void **mode, int *dotClock) +static Bool +xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); if (pScrn->currentMode) { - *mode = (void *) (pScrn->currentMode); + *mode = pScrn->currentMode; *dotClock = pScrn->currentMode->Clock; return TRUE; @@ -156,30 +105,24 @@ VidModeGetCurrentModeline(int scrnIndex, void **mode, int *dotClock) return FALSE; } -int -VidModeGetDotClock(int scrnIndex, int Clock) +static int +xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return 0; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); if ((pScrn->progClock) || (Clock >= MAXCLOCKS)) return Clock; else return pScrn->clock[Clock]; } -int -VidModeGetNumOfClocks(int scrnIndex, Bool *progClock) +static int +xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return 0; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); if (pScrn->progClock) { *progClock = TRUE; return 0; @@ -190,16 +133,13 @@ VidModeGetNumOfClocks(int scrnIndex, Bool *progClock) } } -Bool -VidModeGetClocks(int scrnIndex, int *Clocks) +static Bool +xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks) { ScrnInfoPtr pScrn; int i; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); if (pScrn->progClock) return FALSE; @@ -210,92 +150,75 @@ VidModeGetClocks(int scrnIndex, int *Clocks) return TRUE; } -Bool -VidModeGetFirstModeline(int scrnIndex, void **mode, int *dotClock) +static Bool +xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) { - ScrnInfoPtr pScrn; VidModePtr pVidMode; + DisplayModePtr p; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; - if (pScrn->modes == NULL) - return FALSE; - - pVidMode = VMPTR(pScrn->pScreen); - pVidMode->First = pScrn->modes; - pVidMode->Next = pVidMode->First->next; + pVidMode = VidModeGetPtr(pScreen); - if (pVidMode->First->status == MODE_OK) { - *mode = (void *) (pVidMode->First); - *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock); - return TRUE; + for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) { + if (p->status == MODE_OK) { + pVidMode->Next = p->next; + *mode = p; + *dotClock = xf86VidModeGetDotClock(pScreen, p->Clock); + return TRUE; + } } - return VidModeGetNextModeline(scrnIndex, mode, dotClock); + return FALSE; } -Bool -VidModeGetNextModeline(int scrnIndex, void **mode, int *dotClock) +static Bool +xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) { ScrnInfoPtr pScrn; VidModePtr pVidMode; - DisplayModePtr p; - if (!VidModeAvailable(scrnIndex)) + pScrn = xf86ScreenToScrn(pScreen); + if (pScrn->modes == NULL) return FALSE; - pScrn = xf86Screens[scrnIndex]; - pVidMode = VMPTR(pScrn->pScreen); + pVidMode = VidModeGetPtr(pScreen); + pVidMode->First = pScrn->modes; + pVidMode->Next = pVidMode->First->next; - for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) { - if (p->status == MODE_OK) { - pVidMode->Next = p->next; - *mode = (void *) p; - *dotClock = VidModeGetDotClock(scrnIndex, p->Clock); - return TRUE; - } + if (pVidMode->First->status == MODE_OK) { + *mode = pVidMode->First; + *dotClock = xf86VidModeGetDotClock(pScreen, pVidMode->First->Clock); + return TRUE; } - return FALSE; + return xf86VidModeGetNextModeline(pScreen, mode, dotClock); } -Bool -VidModeDeleteModeline(int scrnIndex, void *mode) +static Bool +xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode) { ScrnInfoPtr pScrn; - if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) + if (mode == NULL) return FALSE; - pScrn = xf86Screens[scrnIndex]; - xf86DeleteMode(&(pScrn->modes), (DisplayModePtr) mode); + pScrn = xf86ScreenToScrn(pScreen); + xf86DeleteMode(&(pScrn->modes), mode); return TRUE; } -Bool -VidModeZoomViewport(int scrnIndex, int zoom) +static Bool +xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom) { - ScrnInfoPtr pScrn; - - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; - xf86ZoomViewport(pScrn->pScreen, zoom); + xf86ZoomViewport(pScreen, zoom); return TRUE; } -Bool -VidModeSetViewPort(int scrnIndex, int x, int y) +static Bool +xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); pScrn->frameX0 = min(max(x, 0), pScrn->virtualX - pScrn->currentMode->HDisplay); pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1; @@ -308,31 +231,25 @@ VidModeSetViewPort(int scrnIndex, int x, int y) return TRUE; } -Bool -VidModeGetViewPort(int scrnIndex, int *x, int *y) +static Bool +xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); *x = pScrn->frameX0; *y = pScrn->frameY0; return TRUE; } -Bool -VidModeSwitchMode(int scrnIndex, void *mode) +static Bool +xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode) { ScrnInfoPtr pScrn; DisplayModePtr pTmpMode; Bool retval; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); /* save in case we fail */ pTmpMode = pScrn->currentMode; /* Force a mode switch */ @@ -344,326 +261,203 @@ VidModeSwitchMode(int scrnIndex, void *mode) return retval; } -Bool -VidModeLockZoom(int scrnIndex, Bool lock) +static Bool +xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock) { - ScrnInfoPtr pScrn; - - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; - if (xf86Info.dontZoom) return FALSE; - xf86LockZoom(pScrn->pScreen, lock); + xf86LockZoom(pScreen, lock); return TRUE; } -Bool -VidModeGetMonitor(int scrnIndex, void **monitor) +static ModeStatus +xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; - *monitor = (void *) (pScrn->monitor); - - return TRUE; -} - -ModeStatus -VidModeCheckModeForMonitor(int scrnIndex, void *mode) -{ - ScrnInfoPtr pScrn; - - if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) + if (mode == NULL) return MODE_ERROR; - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); - return xf86CheckModeForMonitor((DisplayModePtr) mode, pScrn->monitor); + return xf86CheckModeForMonitor(mode, pScrn->monitor); } -ModeStatus -VidModeCheckModeForDriver(int scrnIndex, void *mode) +static ModeStatus +xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode) { ScrnInfoPtr pScrn; - if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) + if (mode == NULL) return MODE_ERROR; - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); - return xf86CheckModeForDriver(pScrn, (DisplayModePtr) mode, 0); + return xf86CheckModeForDriver(pScrn, mode, 0); } -void -VidModeSetCrtcForMode(int scrnIndex, void *mode) +static void +xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode) { ScrnInfoPtr pScrn; DisplayModePtr ScreenModes; - if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) + if (mode == NULL) return; /* Ugly hack so that the xf86Mode.c function can be used without change */ - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); ScreenModes = pScrn->modes; - pScrn->modes = (DisplayModePtr) mode; + pScrn->modes = mode; xf86SetCrtcForModes(pScrn, pScrn->adjustFlags); pScrn->modes = ScreenModes; return; } -Bool -VidModeAddModeline(int scrnIndex, void *mode) +static Bool +xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode) { ScrnInfoPtr pScrn; - if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) + if (mode == NULL) return FALSE; - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); - ((DisplayModePtr) mode)->name = strdup(""); /* freed by deletemode */ - ((DisplayModePtr) mode)->status = MODE_OK; - ((DisplayModePtr) mode)->next = pScrn->modes->next; - ((DisplayModePtr) mode)->prev = pScrn->modes; - pScrn->modes->next = (DisplayModePtr) mode; - if (((DisplayModePtr) mode)->next != NULL) - ((DisplayModePtr) mode)->next->prev = (DisplayModePtr) mode; + mode->name = strdup(""); /* freed by deletemode */ + mode->status = MODE_OK; + mode->next = pScrn->modes->next; + mode->prev = pScrn->modes; + pScrn->modes->next = mode; + if (mode->next != NULL) + mode->next->prev = mode; return TRUE; } -int -VidModeGetNumOfModes(int scrnIndex) +static int +xf86VidModeGetNumOfModes(ScreenPtr pScreen) { - void *mode = NULL; + DisplayModePtr mode = NULL; int dotClock = 0, nummodes = 0; - if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock)) + if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock)) return nummodes; do { nummodes++; - if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock)) + if (!xf86VidModeGetNextModeline(pScreen, &mode, &dotClock)) return nummodes; } while (TRUE); } -Bool -VidModeSetGamma(int scrnIndex, float red, float green, float blue) +static Bool +xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue) { - ScrnInfoPtr pScrn; Gamma gamma; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; gamma.red = red; gamma.green = green; gamma.blue = blue; - if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success) + if (xf86ChangeGamma(pScreen, gamma) != Success) return FALSE; else return TRUE; } -Bool -VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue) +static Bool +xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue) { ScrnInfoPtr pScrn; - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86ScreenToScrn(pScreen); *red = pScrn->gamma.red; *green = pScrn->gamma.green; *blue = pScrn->gamma.blue; return TRUE; } -Bool -VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b) +static Bool +xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b) { - ScrnInfoPtr pScrn; - - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; - xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b); + xf86ChangeGammaRamp(pScreen, size, r, g, b); return TRUE; } -Bool -VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b) +static Bool +xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b) { - ScrnInfoPtr pScrn; - - if (!VidModeAvailable(scrnIndex)) - return FALSE; - - pScrn = xf86Screens[scrnIndex]; - xf86GetGammaRamp(pScrn->pScreen, size, r, g, b); + xf86GetGammaRamp(pScreen, size, r, g, b); return TRUE; } -int -VidModeGetGammaRampSize(int scrnIndex) +static Bool +xf86VidModeInit(ScreenPtr pScreen) { - if (!VidModeAvailable(scrnIndex)) - return 0; - - return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen); -} + VidModePtr pVidMode; -void * -VidModeCreateMode(void) -{ - DisplayModePtr mode; - - mode = malloc(sizeof(DisplayModeRec)); - if (mode != NULL) { - mode->name = ""; - mode->VScan = 1; /* divides refresh rate. default = 1 */ - mode->Private = NULL; - mode->next = mode; - mode->prev = mode; + if (!xf86GetVidModeEnabled()) { + DebugF("!xf86GetVidModeEnabled()\n"); + return FALSE; } - return mode; -} -void -VidModeCopyMode(void *modefrom, void *modeto) -{ - memcpy(modeto, modefrom, sizeof(DisplayModeRec)); -} + pVidMode = VidModeInit(pScreen); + if (!pVidMode) + return FALSE; -int -VidModeGetModeValue(void *mode, int valtyp) -{ - int ret = 0; + pVidMode->Flags = 0; + pVidMode->Next = NULL; - switch (valtyp) { - case VIDMODE_H_DISPLAY: - ret = ((DisplayModePtr) mode)->HDisplay; - break; - case VIDMODE_H_SYNCSTART: - ret = ((DisplayModePtr) mode)->HSyncStart; - break; - case VIDMODE_H_SYNCEND: - ret = ((DisplayModePtr) mode)->HSyncEnd; - break; - case VIDMODE_H_TOTAL: - ret = ((DisplayModePtr) mode)->HTotal; - break; - case VIDMODE_H_SKEW: - ret = ((DisplayModePtr) mode)->HSkew; - break; - case VIDMODE_V_DISPLAY: - ret = ((DisplayModePtr) mode)->VDisplay; - break; - case VIDMODE_V_SYNCSTART: - ret = ((DisplayModePtr) mode)->VSyncStart; - break; - case VIDMODE_V_SYNCEND: - ret = ((DisplayModePtr) mode)->VSyncEnd; - break; - case VIDMODE_V_TOTAL: - ret = ((DisplayModePtr) mode)->VTotal; - break; - case VIDMODE_FLAGS: - ret = ((DisplayModePtr) mode)->Flags; - break; - case VIDMODE_CLOCK: - ret = ((DisplayModePtr) mode)->Clock; - break; - } - return ret; + pVidMode->GetMonitorValue = xf86VidModeGetMonitorValue; + pVidMode->GetCurrentModeline = xf86VidModeGetCurrentModeline; + pVidMode->GetFirstModeline = xf86VidModeGetFirstModeline; + pVidMode->GetNextModeline = xf86VidModeGetNextModeline; + pVidMode->DeleteModeline = xf86VidModeDeleteModeline; + pVidMode->ZoomViewport = xf86VidModeZoomViewport; + pVidMode->GetViewPort = xf86VidModeGetViewPort; + pVidMode->SetViewPort = xf86VidModeSetViewPort; + pVidMode->SwitchMode = xf86VidModeSwitchMode; + pVidMode->LockZoom = xf86VidModeLockZoom; + pVidMode->GetNumOfClocks = xf86VidModeGetNumOfClocks; + pVidMode->GetClocks = xf86VidModeGetClocks; + pVidMode->CheckModeForMonitor = xf86VidModeCheckModeForMonitor; + pVidMode->CheckModeForDriver = xf86VidModeCheckModeForDriver; + pVidMode->SetCrtcForMode = xf86VidModeSetCrtcForMode; + pVidMode->AddModeline = xf86VidModeAddModeline; + pVidMode->GetDotClock = xf86VidModeGetDotClock; + pVidMode->GetNumOfModes = xf86VidModeGetNumOfModes; + pVidMode->SetGamma = xf86VidModeSetGamma; + pVidMode->GetGamma = xf86VidModeGetGamma; + pVidMode->SetGammaRamp = xf86VidModeSetGammaRamp; + pVidMode->GetGammaRamp = xf86VidModeGetGammaRamp; + pVidMode->GetGammaRampSize = xf86GetGammaRampSize; /* use xf86cmap API directly */ + + return TRUE; } void -VidModeSetModeValue(void *mode, int valtyp, int val) +XFree86VidModeExtensionInit(void) { - switch (valtyp) { - case VIDMODE_H_DISPLAY: - ((DisplayModePtr) mode)->HDisplay = val; - break; - case VIDMODE_H_SYNCSTART: - ((DisplayModePtr) mode)->HSyncStart = val; - break; - case VIDMODE_H_SYNCEND: - ((DisplayModePtr) mode)->HSyncEnd = val; - break; - case VIDMODE_H_TOTAL: - ((DisplayModePtr) mode)->HTotal = val; - break; - case VIDMODE_H_SKEW: - ((DisplayModePtr) mode)->HSkew = val; - break; - case VIDMODE_V_DISPLAY: - ((DisplayModePtr) mode)->VDisplay = val; - break; - case VIDMODE_V_SYNCSTART: - ((DisplayModePtr) mode)->VSyncStart = val; - break; - case VIDMODE_V_SYNCEND: - ((DisplayModePtr) mode)->VSyncEnd = val; - break; - case VIDMODE_V_TOTAL: - ((DisplayModePtr) mode)->VTotal = val; - break; - case VIDMODE_FLAGS: - ((DisplayModePtr) mode)->Flags = val; - break; - case VIDMODE_CLOCK: - ((DisplayModePtr) mode)->Clock = val; - break; - } - return; -} + int i; + Bool enabled = FALSE; -vidMonitorValue -VidModeGetMonitorValue(void *monitor, int valtyp, int indx) -{ - vidMonitorValue ret = { NULL, }; + DebugF("XFree86VidModeExtensionInit"); - switch (valtyp) { - case VIDMODE_MON_VENDOR: - ret.ptr = (((MonPtr) monitor)->vendor); - break; - case VIDMODE_MON_MODEL: - ret.ptr = (((MonPtr) monitor)->model); - break; - case VIDMODE_MON_NHSYNC: - ret.i = ((MonPtr) monitor)->nHsync; - break; - case VIDMODE_MON_NVREFRESH: - ret.i = ((MonPtr) monitor)->nVrefresh; - break; - case VIDMODE_MON_HSYNC_LO: - ret.f = (100.0 * ((MonPtr) monitor)->hsync[indx].lo); - break; - case VIDMODE_MON_HSYNC_HI: - ret.f = (100.0 * ((MonPtr) monitor)->hsync[indx].hi); - break; - case VIDMODE_MON_VREFRESH_LO: - ret.f = (100.0 * ((MonPtr) monitor)->vrefresh[indx].lo); - break; - case VIDMODE_MON_VREFRESH_HI: - ret.f = (100.0 * ((MonPtr) monitor)->vrefresh[indx].hi); - break; + /* This means that the DDX doesn't want the vidmode extension enabled */ + if (!xf86GetVidModeEnabled()) + return; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (xf86VidModeInit (screenInfo.screens[i])) + enabled = TRUE; } - return ret; + /* This means that the DDX doesn't want the vidmode extension enabled */ + if (!enabled) + return; + + VidModeAddExtension(xf86GetVidModeAllowNonLocal()); } #endif /* XF86VIDMODE */ diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index a58fafebd..5e6e97778 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -41,6 +41,7 @@ #include "colormapst.h" #include "xf86Module.h" #include "xf86Opt.h" +#include "displaymode.h" /** * Integer type that is of the size of the addressable memory (machine size). @@ -84,48 +85,6 @@ typedef enum { MODECHECK_FINAL = 1 } ModeCheckFlags; -/* These are possible return values for xf86CheckMode() and ValidMode() */ -typedef enum { - MODE_OK = 0, /* Mode OK */ - MODE_HSYNC, /* hsync out of range */ - MODE_VSYNC, /* vsync out of range */ - MODE_H_ILLEGAL, /* mode has illegal horizontal timings */ - MODE_V_ILLEGAL, /* mode has illegal horizontal timings */ - MODE_BAD_WIDTH, /* requires an unsupported linepitch */ - MODE_NOMODE, /* no mode with a maching name */ - MODE_NO_INTERLACE, /* interlaced mode not supported */ - MODE_NO_DBLESCAN, /* doublescan mode not supported */ - MODE_NO_VSCAN, /* multiscan mode not supported */ - MODE_MEM, /* insufficient video memory */ - MODE_VIRTUAL_X, /* mode width too large for specified virtual size */ - MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */ - MODE_MEM_VIRT, /* insufficient video memory given virtual size */ - MODE_NOCLOCK, /* no fixed clock available */ - MODE_CLOCK_HIGH, /* clock required is too high */ - MODE_CLOCK_LOW, /* clock required is too low */ - MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */ - MODE_BAD_HVALUE, /* horizontal timing was out of range */ - MODE_BAD_VVALUE, /* vertical timing was out of range */ - MODE_BAD_VSCAN, /* VScan value out of range */ - MODE_HSYNC_NARROW, /* horizontal sync too narrow */ - MODE_HSYNC_WIDE, /* horizontal sync too wide */ - MODE_HBLANK_NARROW, /* horizontal blanking too narrow */ - MODE_HBLANK_WIDE, /* horizontal blanking too wide */ - MODE_VSYNC_NARROW, /* vertical sync too narrow */ - MODE_VSYNC_WIDE, /* vertical sync too wide */ - MODE_VBLANK_NARROW, /* vertical blanking too narrow */ - MODE_VBLANK_WIDE, /* vertical blanking too wide */ - MODE_PANEL, /* exceeds panel dimensions */ - MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */ - MODE_ONE_WIDTH, /* only one width is supported */ - MODE_ONE_HEIGHT, /* only one height is supported */ - MODE_ONE_SIZE, /* only one resolution is supported */ - MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */ - MODE_BANDWIDTH, /* mode requires too much memory bandwidth */ - MODE_BAD = -2, /* unspecified reason */ - MODE_ERROR = -1 /* error condition */ -} ModeStatus; - /* * The mode sets are, from best to worst: USERDEF, DRIVER, and DEFAULT/BUILTIN. * Preferred will bubble a mode to the top within a set. @@ -141,54 +100,6 @@ typedef enum { #define M_T_DRIVER 0x40 /* Supplied by the driver (EDID, etc) */ #define M_T_USERPREF 0x80 /* mode preferred by the user config */ -/* Video mode */ -typedef struct _DisplayModeRec { - struct _DisplayModeRec *prev; - struct _DisplayModeRec *next; - const char *name; /* identifier for the mode */ - ModeStatus status; - int type; - - /* These are the values that the user sees/provides */ - int Clock; /* pixel clock freq (kHz) */ - int HDisplay; /* horizontal timing */ - int HSyncStart; - int HSyncEnd; - int HTotal; - int HSkew; - int VDisplay; /* vertical timing */ - int VSyncStart; - int VSyncEnd; - int VTotal; - int VScan; - int Flags; - - /* These are the values the hardware uses */ - int ClockIndex; - int SynthClock; /* Actual clock freq to - * be programmed (kHz) */ - int CrtcHDisplay; - int CrtcHBlankStart; - int CrtcHSyncStart; - int CrtcHSyncEnd; - int CrtcHBlankEnd; - int CrtcHTotal; - int CrtcHSkew; - int CrtcVDisplay; - int CrtcVBlankStart; - int CrtcVSyncStart; - int CrtcVSyncEnd; - int CrtcVBlankEnd; - int CrtcVTotal; - Bool CrtcHAdjusted; - Bool CrtcVAdjusted; - int PrivSize; - INT32 *Private; - int PrivFlags; - - float HSync, VRefresh; -} DisplayModeRec, *DisplayModePtr; - /* The monitor description */ #define MAX_HSYNC 8 @@ -377,7 +288,6 @@ typedef struct _bus { } id; } BusRec, *BusPtr; -#define MAXCLOCKS 128 typedef enum { DAC_BPP8 = 0, DAC_BPP16, diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index 875c9cc6c..0046e52b0 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -1032,7 +1032,8 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, } /* track this in case the client dies before cleanup */ - AddResource(context, DRIContextPrivResType, (void *) pDRIContextPriv); + if (!AddResource(context, DRIContextPrivResType, (void *) pDRIContextPriv)) + return FALSE; return TRUE; } @@ -1263,8 +1264,9 @@ DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable, } /* track this in case the client dies */ - AddResource(FakeClientID(client->index), DRIDrawablePrivResType, - (void *) (intptr_t) pDrawable->id); + if (!AddResource(FakeClientID(client->index), DRIDrawablePrivResType, + (void *) (intptr_t) pDrawable->id)) + return FALSE; if (pDRIDrawablePriv->hwDrawable) { drmUpdateDrawableInfo(pDRIPriv->drmFD, diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 60ea6dd93..d55be1913 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -90,8 +90,6 @@ typedef struct _DRI2Drawable { DRI2BufferPtr *buffers; int bufferCount; unsigned int swapsPending; - ClientPtr blockedClient; - Bool blockedOnMsc; int swap_interval; CARD64 swap_count; int64_t target_sbc; /* -1 means no SBC wait outstanding */ @@ -99,6 +97,7 @@ typedef struct _DRI2Drawable { CARD64 last_swap_msc; /* msc at completion of most recent swap */ CARD64 last_swap_ust; /* ust at completion of most recent swap */ int swap_limit; /* for N-buffering */ + unsigned blocked[3]; Bool needInvalidate; int prime_id; PixmapPtr prime_slave_pixmap; @@ -139,6 +138,44 @@ typedef struct _DRI2Screen { static void destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, int prime_id); +enum DRI2WakeType { + WAKE_SBC, + WAKE_MSC, + WAKE_SWAP, +}; + +#define Wake(c, t) (void *)((uintptr_t)(c) | (t)) + +static Bool +dri2WakeClient(ClientPtr client, void *closure) +{ + ClientWakeup(client); + return TRUE; +} + +static Bool +dri2WakeAll(ClientPtr client, DRI2DrawablePtr pPriv, enum DRI2WakeType t) +{ + int count; + + if (!pPriv->blocked[t]) + return FALSE; + + count = ClientSignalAll(client, dri2WakeClient, Wake(pPriv, t)); + pPriv->blocked[t] -= count; + return count; +} + +static Bool +dri2Sleep(ClientPtr client, DRI2DrawablePtr pPriv, enum DRI2WakeType t) +{ + if (ClientSleep(client, dri2WakeClient, Wake(pPriv, t))) { + pPriv->blocked[t]++; + return TRUE; + } + return FALSE; +} + static DRI2ScreenPtr DRI2GetScreen(ScreenPtr pScreen) { @@ -210,8 +247,6 @@ DRI2AllocateDrawable(DrawablePtr pDraw) pPriv->buffers = NULL; pPriv->bufferCount = 0; pPriv->swapsPending = 0; - pPriv->blockedClient = NULL; - pPriv->blockedOnMsc = FALSE; pPriv->swap_count = 0; pPriv->target_sbc = -1; pPriv->swap_interval = 1; @@ -219,6 +254,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw) if (!ds->GetMSC || !(*ds->GetMSC) (pDraw, &ust, &pPriv->last_swap_target)) pPriv->last_swap_target = 0; + memset(pPriv->blocked, 0, sizeof(pPriv->blocked)); pPriv->swap_limit = 1; /* default to double buffering */ pPriv->last_swap_msc = 0; pPriv->last_swap_ust = 0; @@ -258,13 +294,7 @@ DRI2SwapLimit(DrawablePtr pDraw, int swap_limit) if (pPriv->swapsPending >= pPriv->swap_limit) return TRUE; - if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) { - if (pPriv->blockedClient) { - AttendClient(pPriv->blockedClient); - pPriv->blockedClient = NULL; - } - } - + dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SWAP); return TRUE; } @@ -413,6 +443,10 @@ DRI2DrawableGone(void *p, XID id) (*pDraw->pScreen->DestroyPixmap)(pPriv->redirectpixmap); } + dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SWAP); + dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_MSC); + dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SBC); + free(pPriv); return Success; @@ -704,26 +738,17 @@ DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw) return FALSE; /* Throttle to swap limit */ - if ((pPriv->swapsPending >= pPriv->swap_limit) && !pPriv->blockedClient) { - ResetCurrentRequest(client); - client->sequence--; - IgnoreClient(client); - pPriv->blockedClient = client; - return TRUE; + if (pPriv->swapsPending >= pPriv->swap_limit) { + if (dri2Sleep(client, pPriv, WAKE_SWAP)) { + ResetCurrentRequest(client); + client->sequence--; + return TRUE; + } } return FALSE; } -static void -__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv) -{ - if (pPriv->blockedClient == NULL) { - IgnoreClient(client); - pPriv->blockedClient = client; - } -} - void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw) { @@ -733,8 +758,7 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw) if (pPriv == NULL) return; - __DRI2BlockClient(client, pPriv); - pPriv->blockedOnMsc = TRUE; + dri2Sleep(client, pPriv, WAKE_MSC); } static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable) @@ -967,11 +991,7 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame, ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec, frame, pPriv->swap_count); - if (pPriv->blockedClient) - AttendClient(pPriv->blockedClient); - - pPriv->blockedClient = NULL; - pPriv->blockedOnMsc = FALSE; + dri2WakeAll(client, pPriv, WAKE_MSC); } static void @@ -997,19 +1017,14 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame, * - is not blocked due to an MSC wait */ if (pPriv->target_sbc != -1 && pPriv->target_sbc <= pPriv->swap_count) { - ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec, - frame, pPriv->swap_count); - pPriv->target_sbc = -1; - - AttendClient(pPriv->blockedClient); - pPriv->blockedClient = NULL; - } - else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) { - if (pPriv->blockedClient) { - AttendClient(pPriv->blockedClient); - pPriv->blockedClient = NULL; + if (dri2WakeAll(client, pPriv, WAKE_SBC)) { + ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec, + frame, pPriv->swap_count); + pPriv->target_sbc = -1; } } + + dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SWAP); } void @@ -1057,13 +1072,13 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); /* If we're currently waiting for a swap on this drawable, reset - * the request and suspend the client. We only support one - * blocked client per drawable. */ - if (pPriv && pPriv->swapsPending && pPriv->blockedClient == NULL) { - ResetCurrentRequest(client); - client->sequence--; - __DRI2BlockClient(client, pPriv); - return TRUE; + * the request and suspend the client. */ + if (pPriv && pPriv->swapsPending) { + if (dri2Sleep(client, pPriv, WAKE_SWAP)) { + ResetCurrentRequest(client); + client->sequence--; + return TRUE; + } } return FALSE; @@ -1264,6 +1279,9 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc) if (pPriv == NULL) return BadDrawable; + if (pPriv->target_sbc != -1) /* already in use */ + return BadDrawable; + /* target_sbc == 0 means to block until all pending swaps are * finished. Recalculate target_sbc to get that behaviour. */ @@ -1280,9 +1298,10 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc) return Success; } - pPriv->target_sbc = target_sbc; - __DRI2BlockClient(client, pPriv); + if (!dri2Sleep(client, pPriv, WAKE_SBC)) + return BadAlloc; + pPriv->target_sbc = target_sbc; return Success; } @@ -1385,8 +1404,7 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw, static void DRI2SetWindowPixmap(WindowPtr pWin, PixmapPtr pPix) { - DrawablePtr pDraw = (DrawablePtr) pWin; - ScreenPtr pScreen = pDraw->pScreen; + ScreenPtr pScreen = pWin->drawable.pScreen; DRI2ScreenPtr ds = DRI2GetScreen(pScreen); pScreen->SetWindowPixmap = ds->SetWindowPixmap; @@ -1394,7 +1412,7 @@ DRI2SetWindowPixmap(WindowPtr pWin, PixmapPtr pPix) ds->SetWindowPixmap = pScreen->SetWindowPixmap; pScreen->SetWindowPixmap = DRI2SetWindowPixmap; - DRI2InvalidateDrawableAll(pDraw); + DRI2InvalidateDrawable(&pWin->drawable); } #define MAX_PRIME DRI2DriverPrimeMask diff --git a/hw/xfree86/dri2/pci_ids/Makefile.am b/hw/xfree86/dri2/pci_ids/Makefile.am index c5111082b..69fe8c40d 100644 --- a/hw/xfree86/dri2/pci_ids/Makefile.am +++ b/hw/xfree86/dri2/pci_ids/Makefile.am @@ -8,4 +8,5 @@ EXTRA_DIST = \ r600_pci_ids.h \ radeon_pci_ids.h \ radeonsi_pci_ids.h \ + virtio_gpu_pci_ids.h \ vmwgfx_pci_ids.h diff --git a/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h b/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h index 8a97c6f31..da7ea1c1e 100644 --- a/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h +++ b/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h @@ -51,6 +51,12 @@ static const int radeonsi_chip_ids[] = { #undef CHIPSET }; +static const int virtio_gpu_chip_ids[] = { +#define CHIPSET(chip, name, family) chip, +#include "pci_ids/virtio_gpu_pci_ids.h" +#undef CHIPSET +}; + static const int vmwgfx_chip_ids[] = { #define CHIPSET(chip, name, family) chip, #include "pci_ids/vmwgfx_pci_ids.h" @@ -73,6 +79,7 @@ static const struct { { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) }, { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) }, { 0x10de, "nouveau", NULL, -1 }, + { 0x1af4, "virtio_gpu", virtio_gpu_chip_ids, ARRAY_SIZE(virtio_gpu_chip_ids) }, { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) }, { 0x0000, NULL, NULL, 0 }, }; diff --git a/hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h b/hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h new file mode 100644 index 000000000..9232cd288 --- /dev/null +++ b/hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h @@ -0,0 +1,2 @@ +CHIPSET(0x0010, VIRTGL, VIRTGL) +CHIPSET(0x1050, VIRTGL, VIRTGL) diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c index 0fe420cbc..83cb3e0e7 100644 --- a/hw/xfree86/drivers/modesetting/dri2.c +++ b/hw/xfree86/drivers/modesetting/dri2.c @@ -97,10 +97,8 @@ ms_get_resource(XID id, RESTYPE type) if (resource == NULL) return NULL; - if (!AddResource(id, type, resource)) { - free(resource); + if (!AddResource(id, type, resource)) return NULL; - } resource->id = id; resource->type = type; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 442157855..bb5f56ed5 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -373,7 +373,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, crtc->x = x; crtc->y = y; crtc->rotation = rotation; - crtc->transformPresent = FALSE; } output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 38bc58cbc..2639a3085 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -3121,6 +3121,12 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) xf86_crtc_notify(pScrn->pScreen); if (pScrn->ModeSet) pScrn->ModeSet(pScrn); + if (pScrn->pScreen) { + if (pScrn->pScreen->isGPU) + xf86CursorResetCursor(pScrn->pScreen->current_master); + else + xf86CursorResetCursor(pScrn->pScreen); + } } #ifdef RANDR_12_INTERFACE diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 321cde775..5df1ab73a 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -515,6 +515,7 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + int c; cursor = RefCursor(cursor); if (xf86_config->cursor) @@ -525,6 +526,16 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor) cursor->bits->height > cursor_info->MaxHeight) return FALSE; + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (!crtc->enabled) + continue; + + if (crtc->transformPresent) + return FALSE; + } + return TRUE; } @@ -535,19 +546,13 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - cursor = RefCursor(cursor); - if (xf86_config->cursor) - FreeCursor(xf86_config->cursor, None); - xf86_config->cursor = cursor; + if (!xf86_use_hw_cursor(screen, cursor)) + return FALSE; /* Make sure ARGB support is available */ if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0) return FALSE; - if (cursor->bits->width > cursor_info->MaxWidth || - cursor->bits->height > cursor_info->MaxHeight) - return FALSE; - return TRUE; } diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index eae701624..60d22543e 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -1848,13 +1848,13 @@ xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen, if (provider->output_source == source_provider) return TRUE; - SetRootClip(source_provider->pScreen, FALSE); + SetRootClip(source_provider->pScreen, ROOT_CLIP_NONE); DetachUnboundGPU(pScreen); AttachOutputGPU(source_provider->pScreen, pScreen); provider->output_source = source_provider; - SetRootClip(source_provider->pScreen, TRUE); + SetRootClip(source_provider->pScreen, ROOT_CLIP_FULL); return TRUE; } diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c index 2a54571cb..c061b8028 100644 --- a/hw/xfree86/ramdac/xf86Cursor.c +++ b/hw/xfree86/ramdac/xf86Cursor.c @@ -385,6 +385,30 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCurs, x, y); } +/* Re-set the current cursor. This will switch between hardware and software + * cursor depending on whether hardware cursor is currently supported + * according to the driver. + */ +void +xf86CursorResetCursor(ScreenPtr pScreen) +{ + xf86CursorScreenPtr ScreenPriv; + + if (!inputInfo.pointer) + return; + + if (!dixPrivateKeyRegistered(xf86CursorScreenKey)) + return; + + ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, + xf86CursorScreenKey); + if (!ScreenPriv) + return; + + xf86CursorSetCursor(inputInfo.pointer, pScreen, ScreenPriv->CurrentCursor, + ScreenPriv->x, ScreenPriv->y); +} + static void xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { diff --git a/hw/xfree86/ramdac/xf86Cursor.h b/hw/xfree86/ramdac/xf86Cursor.h index 8c98bb151..6e88240d9 100644 --- a/hw/xfree86/ramdac/xf86Cursor.h +++ b/hw/xfree86/ramdac/xf86Cursor.h @@ -59,6 +59,7 @@ extern _X_EXPORT Bool xf86InitCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr); extern _X_EXPORT xf86CursorInfoPtr xf86CreateCursorInfoRec(void); extern _X_EXPORT void xf86DestroyCursorInfoRec(xf86CursorInfoPtr); +extern _X_EXPORT void xf86CursorResetCursor(ScreenPtr pScreen); extern _X_EXPORT void xf86ForceHWCursor(ScreenPtr pScreen, Bool on); #define HARDWARE_CURSOR_INVERT_MASK 0x00000001 diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 557729768..7f34e0c68 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -275,7 +275,7 @@ DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) break; case kXquartzSetRootClip: - QuartzSetRootClip((Bool)e->data[0]); + QuartzSetRootClip(e->data[0]); break; case kXquartzQuit: diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index d3ec133f6..c8b6f966d 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -485,7 +485,7 @@ QuartzHide(void) * Enable or disable rendering to the X screen. */ void -QuartzSetRootClip(BOOL enable) +QuartzSetRootClip(int mode) { int i; @@ -494,7 +494,7 @@ QuartzSetRootClip(BOOL enable) for (i = 0; i < screenInfo.numScreens; i++) { if (screenInfo.screens[i]) { - SetRootClip(screenInfo.screens[i], enable); + SetRootClip(screenInfo.screens[i], mode); } } } diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h index 47c44162f..ddbf2e780 100644 --- a/hw/xquartz/quartz.h +++ b/hw/xquartz/quartz.h @@ -149,7 +149,7 @@ QuartzShow(void); void QuartzHide(void); void -QuartzSetRootClip(BOOL enable); +QuartzSetRootClip(int mode); void QuartzSpaceChanged(uint32_t space_id); diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am index ab1bbb6a5..0e6a1eaa2 100644 --- a/hw/xwayland/Makefile.am +++ b/hw/xwayland/Makefile.am @@ -16,6 +16,7 @@ Xwayland_SOURCES = \ xwayland-shm.c \ xwayland-output.c \ xwayland-cvt.c \ + xwayland-vidmode.c \ xwayland.h \ $(top_srcdir)/Xext/dpmsstubs.c \ $(top_srcdir)/Xi/stubs.c \ @@ -25,12 +26,18 @@ Xwayland_LDADD = \ $(glamor_lib) \ $(XWAYLAND_LIBS) \ $(XWAYLAND_SYS_LIBS) \ + $(top_builddir)/Xext/libXvidmode.la \ $(XSERVER_SYS_LIBS) Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) if GLAMOR_EGL -Xwayland_SOURCES += xwayland-glamor.c +Xwayland_SOURCES += \ + xwayland-glamor.c +if XV +Xwayland_SOURCES += \ + xwayland-glamor-xv.c +endif nodist_Xwayland_SOURCES = \ drm-client-protocol.h \ diff --git a/hw/xwayland/xwayland-glamor-xv.c b/hw/xwayland/xwayland-glamor-xv.c new file mode 100644 index 000000000..c99418d43 --- /dev/null +++ b/hw/xwayland/xwayland-glamor-xv.c @@ -0,0 +1,412 @@ +/* + * Copyright (c) 1998-2003 by The XFree86 Project, Inc. + * Copyright © 2013 Red Hat + * Copyright © 2014 Intel Corporation + * Copyright © 2016 Red Hat + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Olivier Fourdan <ofourdan@redhat.com> + * + * Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv + * implementations + */ + +#include "xwayland.h" +#include "glamor_priv.h" + +#include <X11/extensions/Xv.h> + +#define NUM_FORMATS 3 +#define NUM_PORTS 16 +#define ADAPTOR_NAME "glamor textured video" +#define ENCODER_NAME "XV_IMAGE" + +static DevPrivateKeyRec xwlXvScreenPrivateKeyRec; +#define xwlXvScreenPrivateKey (&xwlXvScreenPrivateKeyRec) + +typedef struct { + XvAdaptorPtr glxv_adaptor; /* We have only one adaptor, glamor Xv */ + glamor_port_private *port_privates; + + CloseScreenProcPtr CloseScreen; +} xwlXvScreenRec, *xwlXvScreenPtr; + +typedef struct { + char depth; + short class; +} xwlVideoFormatRec, *xwlVideoFormatPtr; + +static xwlVideoFormatRec Formats[NUM_FORMATS] = { + {15, TrueColor}, + {16, TrueColor}, + {24, TrueColor} +}; + +static int +xwl_glamor_xv_stop_video(XvPortPtr pPort, + DrawablePtr pDraw) +{ + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); + + if (pDraw->type != DRAWABLE_WINDOW) + return BadAlloc; + + glamor_xv_stop_video(gpp); + + return Success; +} + +static int +xwl_glamor_xv_set_port_attribute(XvPortPtr pPort, + Atom attribute, + INT32 value) +{ + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); + + return glamor_xv_set_port_attribute(gpp, attribute, value); +} + +static int +xwl_glamor_xv_get_port_attribute(XvPortPtr pPort, + Atom attribute, + INT32 *pValue) +{ + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); + + return glamor_xv_get_port_attribute(gpp, attribute, pValue); +} + +static int +xwl_glamor_xv_query_best_size(XvPortPtr pPort, + CARD8 motion, + CARD16 vid_w, + CARD16 vid_h, + CARD16 drw_w, + CARD16 drw_h, + unsigned int *p_w, + unsigned int *p_h) +{ + *p_w = drw_w; + *p_h = drw_h; + + return Success; +} + +static int +xwl_glamor_xv_query_image_attributes(XvPortPtr pPort, + XvImagePtr format, + CARD16 *width, + CARD16 *height, + int *pitches, + int *offsets) +{ + return glamor_xv_query_image_attributes(format->id, + width, + height, + pitches, + offsets); +} + +static int +xwl_glamor_xv_put_image(DrawablePtr pDrawable, + XvPortPtr pPort, + GCPtr pGC, + INT16 src_x, + INT16 src_y, + CARD16 src_w, + CARD16 src_h, + INT16 drw_x, + INT16 drw_y, + CARD16 drw_w, + CARD16 drw_h, + XvImagePtr format, + unsigned char *data, + Bool sync, + CARD16 width, + CARD16 height) +{ + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); + + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + int ret = Success; + + if (pDrawable->type != DRAWABLE_WINDOW) + return BadWindow; + + WinBox.x1 = pDrawable->x + drw_x; + WinBox.y1 = pDrawable->y + drw_y; + WinBox.x2 = WinBox.x1 + drw_w; + WinBox.y2 = WinBox.y1 + drw_h; + + RegionInit(&WinRegion, &WinBox, 1); + RegionInit(&ClipRegion, NullBox, 1); + RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); + + if (RegionNotEmpty(&ClipRegion)) + ret = glamor_xv_put_image(gpp, + pDrawable, + src_x, + src_y, + pDrawable->x + drw_x, + pDrawable->y + drw_y, + src_w, + src_h, + drw_w, + drw_h, + format->id, + data, + width, + height, + sync, + &ClipRegion); + + RegionUninit(&WinRegion); + RegionUninit(&ClipRegion); + + return ret; + +} + +static Bool +xwl_glamor_xv_add_formats(XvAdaptorPtr pa) +{ + ScreenPtr pScreen; + XvFormatPtr pFormat, pf; + VisualPtr pVisual; + int numFormat; + int totFormat; + int numVisuals; + int i; + + totFormat = NUM_FORMATS; + pFormat = xnfcalloc(totFormat, sizeof(XvFormatRec)); + pScreen = pa->pScreen; + for (pf = pFormat, i = 0, numFormat = 0; i < NUM_FORMATS; i++) { + numVisuals = pScreen->numVisuals; + pVisual = pScreen->visuals; + + while (numVisuals--) { + if ((pVisual->class == Formats[i].class) && + (pVisual->nplanes == Formats[i].depth)) { + if (numFormat >= totFormat) { + void *moreSpace; + + totFormat *= 2; + moreSpace = XNFreallocarray(pFormat, totFormat, + sizeof(XvFormatRec)); + pFormat = moreSpace; + pf = pFormat + numFormat; + } + + pf->visual = pVisual->vid; + pf->depth = Formats[i].depth; + + pf++; + numFormat++; + } + pVisual++; + } + } + pa->nFormats = numFormat; + pa->pFormats = pFormat; + + return numFormat != 0; +} + +static Bool +xwl_glamor_xv_add_ports(XvAdaptorPtr pa) +{ + XvPortPtr pPorts, pp; + xwlXvScreenPtr xwlXvScreen; + unsigned long PortResource = 0; + int nPorts; + int i; + + pPorts = xnfcalloc(NUM_PORTS, sizeof(XvPortRec)); + xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates, + xwlXvScreenPrivateKey); + xwlXvScreen->port_privates = xnfcalloc(NUM_PORTS, + sizeof(glamor_port_private)); + + PortResource = XvGetRTPort(); + for (pp = pPorts, i = 0, nPorts = 0; i < NUM_PORTS; i++) { + if (!(pp->id = FakeClientID(0))) + continue; + + pp->pAdaptor = pa; + + glamor_xv_init_port(&xwlXvScreen->port_privates[i]); + pp->devPriv.ptr = &xwlXvScreen->port_privates[i]; + + if (AddResource(pp->id, PortResource, pp)) { + pp++; + nPorts++; + } + } + + pa->base_id = pPorts->id; + pa->nPorts = nPorts; + pa->pPorts = pPorts; + + return nPorts != 0; +} + +static void +xwl_glamor_xv_add_attributes(XvAdaptorPtr pa) +{ + int i; + + pa->pAttributes = xnfcalloc(glamor_xv_num_attributes, sizeof(XvAttributeRec)); + memcpy(pa->pAttributes, glamor_xv_attributes, + glamor_xv_num_attributes * sizeof(XvAttributeRec)); + + for (i = 0; i < glamor_xv_num_attributes; i++) + pa->pAttributes[i].name = strdup(glamor_xv_attributes[i].name); + + pa->nAttributes = glamor_xv_num_attributes; +} + +static void +xwl_glamor_xv_add_images(XvAdaptorPtr pa) +{ + pa->pImages = xnfcalloc(glamor_xv_num_images, sizeof(XvImageRec)); + memcpy(pa->pImages, glamor_xv_images, glamor_xv_num_images * sizeof(XvImageRec)); + + pa->nImages = glamor_xv_num_images; +} + +static void +xwl_glamor_xv_add_encodings(XvAdaptorPtr pa) +{ + XvEncodingPtr pe; + GLint texsize; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize); + + pe = xnfcalloc(1, sizeof(XvEncodingRec)); + pe->id = 0; + pe->pScreen = pa->pScreen; + pe->name = strdup(ENCODER_NAME); + pe->width = texsize; + pe->height = texsize; + pe->rate.numerator = 1; + pe->rate.denominator = 1; + + pa->pEncodings = pe; + pa->nEncodings = 1; +} + +static Bool +xwl_glamor_xv_add_adaptors(ScreenPtr pScreen) +{ + DevPrivateKey XvScreenKey; + XvScreenPtr XvScreen; + xwlXvScreenPtr xwlXvScreen; + XvAdaptorPtr pa; + + if (XvScreenInit(pScreen) != Success) + return FALSE; + + XvScreenKey = XvGetScreenKey(); + XvScreen = dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey); + + XvScreen->nAdaptors = 0; + XvScreen->pAdaptors = NULL; + + pa = xnfcalloc(1, sizeof(XvAdaptorRec)); + pa->pScreen = pScreen; + pa->type = (unsigned int) (XvWindowMask | XvInputMask | XvImageMask); + pa->ddStopVideo = xwl_glamor_xv_stop_video; + pa->ddPutImage = xwl_glamor_xv_put_image; + pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute; + pa->ddGetPortAttribute = xwl_glamor_xv_get_port_attribute; + pa->ddQueryBestSize = xwl_glamor_xv_query_best_size; + pa->ddQueryImageAttributes = xwl_glamor_xv_query_image_attributes; + pa->name = strdup(ADAPTOR_NAME); + + xwl_glamor_xv_add_encodings(pa); + xwl_glamor_xv_add_images(pa); + xwl_glamor_xv_add_attributes(pa); + if (!xwl_glamor_xv_add_formats(pa)) + goto failed; + if (!xwl_glamor_xv_add_ports(pa)) + goto failed; + + /* We're good now with out Xv adaptor */ + XvScreen->nAdaptors = 1; + XvScreen->pAdaptors = pa; + + xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates, + xwlXvScreenPrivateKey); + xwlXvScreen->glxv_adaptor = pa; + + return TRUE; + +failed: + XvFreeAdaptor(pa); + free(pa); + + return FALSE; +} + +static Bool +xwl_glamor_xv_close_screen(ScreenPtr pScreen) +{ + xwlXvScreenPtr xwlXvScreen; + + xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates, + xwlXvScreenPrivateKey); + + if (xwlXvScreen->glxv_adaptor) { + XvFreeAdaptor(xwlXvScreen->glxv_adaptor); + free(xwlXvScreen->glxv_adaptor); + } + free(xwlXvScreen->port_privates); + + pScreen->CloseScreen = xwlXvScreen->CloseScreen; + + return pScreen->CloseScreen(pScreen); +} + +Bool +xwl_glamor_xv_init(ScreenPtr pScreen) +{ + xwlXvScreenPtr xwlXvScreen; + + if (!dixRegisterPrivateKey(xwlXvScreenPrivateKey, PRIVATE_SCREEN, + sizeof(xwlXvScreenRec))) + return FALSE; + + xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates, + xwlXvScreenPrivateKey); + + xwlXvScreen->port_privates = NULL; + xwlXvScreen->glxv_adaptor = NULL; + xwlXvScreen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = xwl_glamor_xv_close_screen; + + glamor_xv_core_init(pScreen); + + return xwl_glamor_xv_add_adaptors(pScreen); +} diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index dd4157794..04aa8f223 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -236,7 +236,6 @@ xwl_glamor_create_screen_resources(ScreenPtr screen) if (xwl_screen->rootless) { screen->devPrivate = fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0); - SetRootClip(screen, FALSE); } else { screen->devPrivate = @@ -247,6 +246,8 @@ xwl_glamor_create_screen_resources(ScreenPtr screen) glamor_set_screen_pixmap(screen->devPrivate, NULL); } + SetRootClip(screen, xwl_screen->root_clip_mode); + return screen->devPrivate != NULL; } @@ -270,6 +271,15 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen) { EGLint major, minor; const char *version; + static const EGLint config_attribs_core[] = { + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_CONTEXT_MAJOR_VERSION_KHR, + GLAMOR_GL_CORE_VER_MAJOR, + EGL_CONTEXT_MINOR_VERSION_KHR, + GLAMOR_GL_CORE_VER_MINOR, + EGL_NONE + }; if (xwl_screen->egl_display) return; @@ -298,7 +308,11 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen) ErrorF("glamor: EGL version %s:\n", version); xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display, - NULL, EGL_NO_CONTEXT, NULL); + NULL, EGL_NO_CONTEXT, config_attribs_core); + if (!xwl_screen->egl_context) + xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display, + NULL, EGL_NO_CONTEXT, NULL); + if (xwl_screen->egl_context == EGL_NO_CONTEXT) { ErrorF("Failed to create EGL context\n"); return; @@ -416,12 +430,6 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, return 0; } -unsigned int -glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear) -{ - return 0; -} - struct xwl_auth_state { int fd; ClientPtr client; @@ -566,5 +574,10 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) screen->CreatePixmap = xwl_glamor_create_pixmap; screen->DestroyPixmap = xwl_glamor_destroy_pixmap; +#ifdef XV + if (!xwl_glamor_xv_init(screen)) + ErrorF("Failed to initialize glamor Xv extension\n"); +#endif + return TRUE; } diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 7494e6332..23e138d53 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -267,6 +267,16 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, for (i = 0; i < dev->button->numButtons; i++) if (BitIsOn(dev->button->down, i)) QueuePointerEvents(dev, ButtonRelease, i, 0, &mask); + + /* The last cursor frame we commited before the pointer left one + * of our surfaces might not have been shown. In that case we'll + * have a cursor surface frame callback pending which we need to + * clear so that we can continue submitting new cursor frames. */ + if (xwl_seat->cursor_frame_cb) { + wl_callback_destroy(xwl_seat->cursor_frame_cb); + xwl_seat->cursor_frame_cb = NULL; + xwl_seat_set_cursor(xwl_seat); + } } static void diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index e9ec190f0..4903062a1 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -164,8 +164,8 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height) struct xwl_screen *xwl_screen = xwl_output->xwl_screen; double mmpd; - if (!xwl_screen->rootless) - SetRootClip(xwl_screen->screen, FALSE); + if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL) + SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE); xwl_screen->width = width; xwl_screen->height = height; @@ -181,6 +181,8 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height) xwl_screen->screen->mmHeight = height * mmpd; } + SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode); + if (xwl_screen->screen->root) { xwl_screen->screen->root->drawable.width = width; xwl_screen->screen->root->drawable.height = height; @@ -188,9 +190,6 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height) } update_desktop_dimensions(); - - if (!xwl_screen->rootless) - SetRootClip(xwl_screen->screen, TRUE); } static void @@ -298,6 +297,7 @@ xwl_output_destroy(struct xwl_output *xwl_output) wl_output_destroy(xwl_output->output); xorg_list_del(&xwl_output->link); + RRCrtcDestroy(xwl_output->randr_crtc); RROutputDestroy(xwl_output->randr_output); xorg_list_for_each_entry(it, &xwl_screen->output_list, link) diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c index 7072be4bc..e8545b3be 100644 --- a/hw/xwayland/xwayland-shm.c +++ b/hw/xwayland/xwayland-shm.c @@ -24,6 +24,10 @@ * SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include <dix-config.h> +#endif + #include "xwayland.h" #include <sys/mman.h> @@ -109,7 +113,7 @@ create_tmpfile_cloexec(char *tmpname) static int os_create_anonymous_file(off_t size) { - static const char template[] = "/weston-shared-XXXXXX"; + static const char template[] = "/xwayland-shared-XXXXXX"; const char *path; char *name; int fd; @@ -279,16 +283,16 @@ xwl_shm_create_screen_resources(ScreenPtr screen) if (!ret) return ret; - if (xwl_screen->rootless) { + if (xwl_screen->rootless) screen->devPrivate = fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0); - SetRootClip(screen, FALSE); - } else screen->devPrivate = xwl_shm_create_pixmap(screen, screen->width, screen->height, screen->rootDepth, CREATE_PIXMAP_USAGE_BACKING_PIXMAP); + SetRootClip(screen, xwl_screen->root_clip_mode); + return screen->devPrivate != NULL; } diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c new file mode 100644 index 000000000..6d70e39e6 --- /dev/null +++ b/hw/xwayland/xwayland-vidmode.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 1999-2003 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include "misc.h" +#include "os.h" +#include "extinit.h" + +#ifdef XF86VIDMODE +#include "xwayland.h" +#include "randrstr.h" +#include "vidmodestr.h" + +static DevPrivateKeyRec xwlVidModePrivateKeyRec; +#define xwlVidModePrivateKey (&xwlVidModePrivateKeyRec) + +/* Taken from xrandr, h sync frequency in KHz */ +static double +mode_hsync(const xRRModeInfo *mode_info) +{ + double rate; + + if (mode_info->hTotal) + rate = (double) mode_info->dotClock / (double) mode_info->hTotal; + else + rate = 0.0; + + return rate / 1000.0; +} + +/* Taken from xrandr, v refresh frequency in Hz */ +static double +mode_refresh(const xRRModeInfo *mode_info) +{ + double rate; + double vTotal = mode_info->vTotal; + + if (mode_info->modeFlags & RR_DoubleScan) + vTotal *= 2.0; + + if (mode_info->modeFlags & RR_Interlace) + vTotal /= 2.0; + + if (mode_info->hTotal > 0.0 && vTotal > 0.0) + rate = ((double) mode_info->dotClock / + ((double) mode_info->hTotal * (double) vTotal)); + else + rate = 0.0; + + return rate; +} + +static Bool +xwlVidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) +{ + DisplayModePtr pMod; + RROutputPtr output; + RRCrtcPtr crtc; + xRRModeInfo rrmode; + + pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey); + if (pMod == NULL) + return FALSE; + + output = RRFirstOutput(pScreen); + if (output == NULL) + return FALSE; + + crtc = output->crtc; + if (crtc == NULL) + return FALSE; + + rrmode = crtc->mode->mode; + + pMod->next = pMod; + pMod->prev = pMod; + pMod->name = ""; + pMod->VScan = 1; + pMod->Private = NULL; + pMod->HDisplay = rrmode.width; + pMod->HSyncStart = rrmode.hSyncStart; + pMod->HSyncEnd = rrmode.hSyncEnd; + pMod->HTotal = rrmode.hTotal; + pMod->HSkew = rrmode.hSkew; + pMod->VDisplay = rrmode.height; + pMod->VSyncStart = rrmode.vSyncStart; + pMod->VSyncEnd = rrmode.vSyncEnd; + pMod->VTotal = rrmode.vTotal; + pMod->Flags = rrmode.modeFlags; + pMod->Clock = rrmode.dotClock / 1000.0; + pMod->VRefresh = mode_refresh(&rrmode); /* Or RRVerticalRefresh() */ + pMod->HSync = mode_hsync(&rrmode); + *mode = pMod; + + if (dotClock != NULL) + *dotClock = rrmode.dotClock / 1000.0; + + return TRUE; +} + +static vidMonitorValue +xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx) +{ + vidMonitorValue ret = { NULL, }; + DisplayModePtr pMod; + + if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL)) + return ret; + + switch (valtyp) { + case VIDMODE_MON_VENDOR: + ret.ptr = XVENDORNAME; + break; + case VIDMODE_MON_MODEL: + ret.ptr = "XWAYLAND"; + break; + case VIDMODE_MON_NHSYNC: + ret.i = 1; + break; + case VIDMODE_MON_NVREFRESH: + ret.i = 1; + break; + case VIDMODE_MON_HSYNC_LO: + case VIDMODE_MON_HSYNC_HI: + ret.f = 100.0 * pMod->HSync; + break; + case VIDMODE_MON_VREFRESH_LO: + case VIDMODE_MON_VREFRESH_HI: + ret.f = 100.0 * pMod->VRefresh; + break; + } + return ret; +} + +static int +xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock) +{ + DisplayModePtr pMod; + + if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL)) + return 0; + + return pMod->Clock; + +} + +static int +xwlVidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock) +{ + return 1; +} + +static Bool +xwlVidModeGetClocks(ScreenPtr pScreen, int *Clocks) +{ + *Clocks = xwlVidModeGetDotClock(pScreen, 0); + + return TRUE; +} + +static Bool +xwlVidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) +{ + return FALSE; +} + +static Bool +xwlVidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) +{ + return xwlVidModeGetCurrentModeline(pScreen, mode, dotClock); +} + +static Bool +xwlVidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode) +{ + /* Unsupported */ + return FALSE; +} + +static Bool +xwlVidModeZoomViewport(ScreenPtr pScreen, int zoom) +{ + /* Unsupported for now */ + return FALSE; +} + +static Bool +xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y) +{ + /* Unsupported for now */ + return FALSE; +} + +static Bool +xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y) +{ + RROutputPtr output; + RRCrtcPtr crtc; + + output = RRFirstOutput(pScreen); + if (output == NULL) + return FALSE; + + crtc = output->crtc; + if (crtc == NULL) + return FALSE; + + *x = crtc->x; + *y = crtc->y; + + return TRUE; +} + +static Bool +xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode) +{ + /* Unsupported for now */ + return FALSE; +} + +static Bool +xwlVidModeLockZoom(ScreenPtr pScreen, Bool lock) +{ + /* Unsupported for now, but pretend it works */ + return TRUE; +} + +static ModeStatus +xwlVidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode) +{ + DisplayModePtr pMod; + + /* This should not happen */ + if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL)) + return MODE_ERROR; + + /* Only support mode with the same HSync/VRefresh as we advertise */ + if (mode->HSync == pMod->HSync && mode->VRefresh == pMod->VRefresh) + return MODE_OK; + + /* All the rest is unsupported - If we want to succeed, return MODE_OK instead */ + return MODE_ONE_SIZE; +} + +static ModeStatus +xwlVidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode) +{ + DisplayModePtr pMod; + + /* This should not happen */ + if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL)) + return MODE_ERROR; + + if (mode->HTotal != pMod->HTotal) + return MODE_BAD_HVALUE; + + if (mode->VTotal != pMod->VTotal) + return MODE_BAD_VVALUE; + + /* Unsupported for now, but pretend it works */ + return MODE_OK; +} + +static void +xwlVidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode) +{ + /* Unsupported */ + return; +} + +static Bool +xwlVidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode) +{ + /* Unsupported */ + return FALSE; +} + +static int +xwlVidModeGetNumOfModes(ScreenPtr pScreen) +{ + /* We have only one mode */ + return 1; +} + +static Bool +xwlVidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue) +{ + /* Unsupported for now, but pretend it works */ + return TRUE; +} + +static Bool +xwlVidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue) +{ + /* Unsupported for now, but pretend it works */ + return TRUE; +} + +static Bool +xwlVidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b) +{ + /* Unsupported for now */ + return FALSE; +} + +static Bool +xwlVidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b) +{ + /* Unsupported for now */ + return FALSE; +} + +static int +xwlVidModeGetGammaRampSize(ScreenPtr pScreen) +{ + /* Unsupported for now */ + return 0; +} + +static Bool +xwlVidModeInit(ScreenPtr pScreen) +{ + VidModePtr pVidMode = NULL; + + pVidMode = VidModeInit(pScreen); + if (!pVidMode) + return FALSE; + + pVidMode->Flags = 0; + pVidMode->Next = NULL; + + pVidMode->GetMonitorValue = xwlVidModeGetMonitorValue; + pVidMode->GetCurrentModeline = xwlVidModeGetCurrentModeline; + pVidMode->GetFirstModeline = xwlVidModeGetFirstModeline; + pVidMode->GetNextModeline = xwlVidModeGetNextModeline; + pVidMode->DeleteModeline = xwlVidModeDeleteModeline; + pVidMode->ZoomViewport = xwlVidModeZoomViewport; + pVidMode->GetViewPort = xwlVidModeGetViewPort; + pVidMode->SetViewPort = xwlVidModeSetViewPort; + pVidMode->SwitchMode = xwlVidModeSwitchMode; + pVidMode->LockZoom = xwlVidModeLockZoom; + pVidMode->GetNumOfClocks = xwlVidModeGetNumOfClocks; + pVidMode->GetClocks = xwlVidModeGetClocks; + pVidMode->CheckModeForMonitor = xwlVidModeCheckModeForMonitor; + pVidMode->CheckModeForDriver = xwlVidModeCheckModeForDriver; + pVidMode->SetCrtcForMode = xwlVidModeSetCrtcForMode; + pVidMode->AddModeline = xwlVidModeAddModeline; + pVidMode->GetDotClock = xwlVidModeGetDotClock; + pVidMode->GetNumOfModes = xwlVidModeGetNumOfModes; + pVidMode->SetGamma = xwlVidModeSetGamma; + pVidMode->GetGamma = xwlVidModeGetGamma; + pVidMode->SetGammaRamp = xwlVidModeSetGammaRamp; + pVidMode->GetGammaRamp = xwlVidModeGetGammaRamp; + pVidMode->GetGammaRampSize = xwlVidModeGetGammaRampSize; + + return TRUE; +} + +void +xwlVidModeExtensionInit(void) +{ + int i; + Bool enabled = FALSE; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (xwlVidModeInit (screenInfo.screens[i])) + enabled = TRUE; + } + /* This means that the DDX doesn't want the vidmode extension enabled */ + if (!enabled) + return; + + if (!dixRegisterPrivateKey(xwlVidModePrivateKey, PRIVATE_SCREEN, + sizeof(DisplayModeRec))) + return; + + VidModeAddExtension(FALSE); +} + +#endif /* XF86VIDMODE */ diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 55bf6d069..2d44d0709 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -33,6 +33,11 @@ #include <compositeext.h> #include <glx_extinit.h> +#ifdef XF86VIDMODE +#include <X11/extensions/xf86vmproto.h> +_X_EXPORT Bool noXFree86VidModeExtension; +#endif + void ddxGiveUp(enum ExitCode error) { @@ -589,6 +594,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) } } + /* In rootless mode, we don't have any screen storage, and the only + * rendering should be to redirected mode. */ + if (xwl_screen->rootless) + xwl_screen->root_clip_mode = ROOT_CLIP_INPUT_ONLY; + else + xwl_screen->root_clip_mode = ROOT_CLIP_FULL; + if (xwl_screen->listen_fd_count > 0) { if (xwl_screen->wm_fd >= 0) AddCallback(&SelectionCallback, wm_selection_callback, xwl_screen); @@ -704,6 +716,9 @@ static const ExtensionModule xwayland_extensions[] = { #ifdef GLXEXT { GlxExtensionInit, "GLX", &noGlxExtension }, #endif +#ifdef XF86VIDMODE + { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension }, +#endif }; void diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index a7d71193d..67b30cb94 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -49,6 +49,7 @@ struct xwl_screen { ScreenPtr screen; WindowPtr pointer_limbo_window; int expecting_event; + enum RootClipMode root_clip_mode; int wm_fd; int listen_fds[5]; @@ -189,4 +190,13 @@ Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version); struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap); +#ifdef XV +/* glamor Xv Adaptor */ +Bool xwl_glamor_xv_init(ScreenPtr pScreen); +#endif + +#ifdef XF86VIDMODE +void xwlVidModeExtensionInit(void); +#endif + #endif diff --git a/hw/xwin/winauth.c b/hw/xwin/winauth.c index fcad49e9f..e86343952 100644 --- a/hw/xwin/winauth.c +++ b/hw/xwin/winauth.c @@ -125,7 +125,6 @@ GenerateAuthorization(unsigned name_length, Bool winGenerateAuthorization(void) { - Bool fFreeAuth = FALSE; SecurityAuthorizationPtr pAuth = NULL; /* Call OS layer to generate authorization key */ @@ -134,7 +133,7 @@ winGenerateAuthorization(void) 0, NULL, &g_uiAuthDataLen, &g_pAuthData); if ((XID) ~0L == g_authId) { ErrorF("winGenerateAuthorization - GenerateAuthorization failed\n"); - goto auth_bailout; + return FALSE; } else { @@ -155,7 +154,7 @@ winGenerateAuthorization(void) if (!(pAuth)) { ErrorF("winGenerateAuthorization - Failed allocating " "SecurityAuthorizationPtr.\n"); - goto auth_bailout; + return FALSE; } /* Fill in the auth fields */ @@ -171,21 +170,11 @@ winGenerateAuthorization(void) /* Add the authorization to the server's auth list */ if (!AddResource(g_authId, SecurityAuthorizationResType, pAuth)) { ErrorF("winGenerateAuthorization - AddResource failed for auth.\n"); - fFreeAuth = TRUE; - goto auth_bailout; + return FALSE; } - - /* Don't free the auth data, since it is still used internally */ - pAuth = NULL; #endif return TRUE; - - auth_bailout: - if (fFreeAuth) - free(pAuth); - - return FALSE; } /* Use our generated cookie for authentication */ diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index bab5e1cfb..5891735c6 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -136,6 +136,11 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener; ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no"); + g_fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener"); + g_fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener"); + g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener; + ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no"); + g_winClipboardProcThread = pthread_self(); /* Set error handler */ diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c index 0be1c9964..1560199c1 100644 --- a/hw/xwin/winrandr.c +++ b/hw/xwin/winrandr.c @@ -105,7 +105,7 @@ winDoRandRScreenSetSize(ScreenPtr pScreen, return; // Prevent screen updates while we change things around - SetRootClip(pScreen, FALSE); + SetRootClip(pScreen, ROOT_CLIP_NONE); /* Update the screen size as requested */ pScreenInfo->dwWidth = width; @@ -131,7 +131,7 @@ winDoRandRScreenSetSize(ScreenPtr pScreen, // does this emit a ConfigureNotify?? // Restore the ability to update screen, now with new dimensions - SetRootClip(pScreen, TRUE); + SetRootClip(pScreen, ROOT_CLIP_FULL); // and arrange for it to be repainted pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); diff --git a/include/Makefile.am b/include/Makefile.am index 70b83ffec..b9cf584cb 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -53,6 +53,7 @@ sdk_HEADERS = \ servermd.h \ site.h \ validate.h \ + displaymode.h \ window.h \ windowstr.h \ xkbfile.h \ @@ -75,4 +76,5 @@ EXTRA_DIST = \ swaprep.h \ swapreq.h \ systemd-logind.h \ + vidmodestr.h \ xsha1.h diff --git a/include/displaymode.h b/include/displaymode.h new file mode 100644 index 000000000..ad01b87ec --- /dev/null +++ b/include/displaymode.h @@ -0,0 +1,102 @@ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _DISMODEPROC_H_ +#define _DISMODEPROC_H_ + +#include "scrnintstr.h" + +#define MAXCLOCKS 128 + +/* These are possible return values for xf86CheckMode() and ValidMode() */ +typedef enum { + MODE_OK = 0, /* Mode OK */ + MODE_HSYNC, /* hsync out of range */ + MODE_VSYNC, /* vsync out of range */ + MODE_H_ILLEGAL, /* mode has illegal horizontal timings */ + MODE_V_ILLEGAL, /* mode has illegal horizontal timings */ + MODE_BAD_WIDTH, /* requires an unsupported linepitch */ + MODE_NOMODE, /* no mode with a matching name */ + MODE_NO_INTERLACE, /* interlaced mode not supported */ + MODE_NO_DBLESCAN, /* doublescan mode not supported */ + MODE_NO_VSCAN, /* multiscan mode not supported */ + MODE_MEM, /* insufficient video memory */ + MODE_VIRTUAL_X, /* mode width too large for specified virtual size */ + MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */ + MODE_MEM_VIRT, /* insufficient video memory given virtual size */ + MODE_NOCLOCK, /* no fixed clock available */ + MODE_CLOCK_HIGH, /* clock required is too high */ + MODE_CLOCK_LOW, /* clock required is too low */ + MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */ + MODE_BAD_HVALUE, /* horizontal timing was out of range */ + MODE_BAD_VVALUE, /* vertical timing was out of range */ + MODE_BAD_VSCAN, /* VScan value out of range */ + MODE_HSYNC_NARROW, /* horizontal sync too narrow */ + MODE_HSYNC_WIDE, /* horizontal sync too wide */ + MODE_HBLANK_NARROW, /* horizontal blanking too narrow */ + MODE_HBLANK_WIDE, /* horizontal blanking too wide */ + MODE_VSYNC_NARROW, /* vertical sync too narrow */ + MODE_VSYNC_WIDE, /* vertical sync too wide */ + MODE_VBLANK_NARROW, /* vertical blanking too narrow */ + MODE_VBLANK_WIDE, /* vertical blanking too wide */ + MODE_PANEL, /* exceeds panel dimensions */ + MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */ + MODE_ONE_WIDTH, /* only one width is supported */ + MODE_ONE_HEIGHT, /* only one height is supported */ + MODE_ONE_SIZE, /* only one resolution is supported */ + MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */ + MODE_BANDWIDTH, /* mode requires too much memory bandwidth */ + MODE_BAD = -2, /* unspecified reason */ + MODE_ERROR = -1 /* error condition */ +} ModeStatus; + +/* Video mode */ +typedef struct _DisplayModeRec { + struct _DisplayModeRec *prev; + struct _DisplayModeRec *next; + const char *name; /* identifier for the mode */ + ModeStatus status; + int type; + + /* These are the values that the user sees/provides */ + int Clock; /* pixel clock freq (kHz) */ + int HDisplay; /* horizontal timing */ + int HSyncStart; + int HSyncEnd; + int HTotal; + int HSkew; + int VDisplay; /* vertical timing */ + int VSyncStart; + int VSyncEnd; + int VTotal; + int VScan; + int Flags; + + /* These are the values the hardware uses */ + int ClockIndex; + int SynthClock; /* Actual clock freq to + * be programmed (kHz) */ + int CrtcHDisplay; + int CrtcHBlankStart; + int CrtcHSyncStart; + int CrtcHSyncEnd; + int CrtcHBlankEnd; + int CrtcHTotal; + int CrtcHSkew; + int CrtcVDisplay; + int CrtcVBlankStart; + int CrtcVSyncStart; + int CrtcVSyncEnd; + int CrtcVBlankEnd; + int CrtcVTotal; + Bool CrtcHAdjusted; + Bool CrtcVAdjusted; + int PrivSize; + INT32 *Private; + int PrivFlags; + + float HSync, VRefresh; +} DisplayModeRec, *DisplayModePtr; + +#endif diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 112ab952f..a2f7184bf 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -518,4 +518,7 @@ /* Define if no local socket credentials interface exists */ #undef NO_LOCAL_CLIENT_CRED +/* Have posix_fallocate() */ +#undef HAVE_POSIX_FALLOCATE + #endif /* _DIX_CONFIG_H_ */ diff --git a/include/dix.h b/include/dix.h index 921156b4c..d49d05569 100644 --- a/include/dix.h +++ b/include/dix.h @@ -255,6 +255,14 @@ extern _X_EXPORT Bool ClientSleep(ClientPtr client, extern _X_EXPORT Bool ClientSignal(ClientPtr /*client */ ); #endif /* ___CLIENTSIGNAL_DEFINED___ */ +#ifndef ___CLIENTSIGNALALL_DEFINED___ +#define ___CLIENTSIGNALALL_DEFINED___ +#define CLIENT_SIGNAL_ANY ((void *)-1) +extern _X_EXPORT int ClientSignalAll(ClientPtr /*client*/, + ClientSleepProcPtr /*function*/, + void * /*closure*/); +#endif /* ___CLIENTSIGNALALL_DEFINED___ */ + extern _X_EXPORT void ClientWakeup(ClientPtr /*client */ ); extern _X_EXPORT Bool ClientIsAsleep(ClientPtr /*client */ ); diff --git a/include/vidmodestr.h b/include/vidmodestr.h new file mode 100644 index 000000000..b47daa779 --- /dev/null +++ b/include/vidmodestr.h @@ -0,0 +1,142 @@ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _VIDMODEPROC_H_ +#define _VIDMODEPROC_H_ + +#include "displaymode.h" + +typedef enum { + VIDMODE_H_DISPLAY, + VIDMODE_H_SYNCSTART, + VIDMODE_H_SYNCEND, + VIDMODE_H_TOTAL, + VIDMODE_H_SKEW, + VIDMODE_V_DISPLAY, + VIDMODE_V_SYNCSTART, + VIDMODE_V_SYNCEND, + VIDMODE_V_TOTAL, + VIDMODE_FLAGS, + VIDMODE_CLOCK +} VidModeSelectMode; + +typedef enum { + VIDMODE_MON_VENDOR, + VIDMODE_MON_MODEL, + VIDMODE_MON_NHSYNC, + VIDMODE_MON_NVREFRESH, + VIDMODE_MON_HSYNC_LO, + VIDMODE_MON_HSYNC_HI, + VIDMODE_MON_VREFRESH_LO, + VIDMODE_MON_VREFRESH_HI +} VidModeSelectMonitor; + +typedef union { + const void *ptr; + int i; + float f; +} vidMonitorValue; + +typedef Bool (*VidModeExtensionInitProcPtr) (ScreenPtr pScreen); +typedef vidMonitorValue (*VidModeGetMonitorValueProcPtr) (ScreenPtr pScreen, + int valtyp, + int indx); +typedef Bool (*VidModeGetEnabledProcPtr) (void); +typedef Bool (*VidModeGetAllowNonLocalProcPtr) (void); +typedef Bool (*VidModeGetCurrentModelineProcPtr) (ScreenPtr pScreen, + DisplayModePtr *mode, + int *dotClock); +typedef Bool (*VidModeGetFirstModelineProcPtr) (ScreenPtr pScreen, + DisplayModePtr *mode, + int *dotClock); +typedef Bool (*VidModeGetNextModelineProcPtr) (ScreenPtr pScreen, + DisplayModePtr *mode, + int *dotClock); +typedef Bool (*VidModeDeleteModelineProcPtr) (ScreenPtr pScreen, + DisplayModePtr mode); +typedef Bool (*VidModeZoomViewportProcPtr) (ScreenPtr pScreen, + int zoom); +typedef Bool (*VidModeGetViewPortProcPtr) (ScreenPtr pScreen, + int *x, + int *y); +typedef Bool (*VidModeSetViewPortProcPtr) (ScreenPtr pScreen, + int x, + int y); +typedef Bool (*VidModeSwitchModeProcPtr) (ScreenPtr pScreen, + DisplayModePtr mode); +typedef Bool (*VidModeLockZoomProcPtr) (ScreenPtr pScreen, + Bool lock); +typedef int (*VidModeGetNumOfClocksProcPtr) (ScreenPtr pScreen, + Bool *progClock); +typedef Bool (*VidModeGetClocksProcPtr) (ScreenPtr pScreen, + int *Clocks); +typedef ModeStatus (*VidModeCheckModeForMonitorProcPtr) (ScreenPtr pScreen, + DisplayModePtr mode); +typedef ModeStatus (*VidModeCheckModeForDriverProcPtr) (ScreenPtr pScreen, + DisplayModePtr mode); +typedef void (*VidModeSetCrtcForModeProcPtr) (ScreenPtr pScreen, + DisplayModePtr mode); +typedef Bool (*VidModeAddModelineProcPtr) (ScreenPtr pScreen, + DisplayModePtr mode); +typedef int (*VidModeGetDotClockProcPtr) (ScreenPtr pScreen, + int Clock); +typedef int (*VidModeGetNumOfModesProcPtr) (ScreenPtr pScreen); +typedef Bool (*VidModeSetGammaProcPtr) (ScreenPtr pScreen, + float red, + float green, + float blue); +typedef Bool (*VidModeGetGammaProcPtr) (ScreenPtr pScreen, + float *red, + float *green, + float *blue); +typedef Bool (*VidModeSetGammaRampProcPtr) (ScreenPtr pScreen, + int size, + CARD16 *red, + CARD16 *green, + CARD16 *blue); +typedef Bool (*VidModeGetGammaRampProcPtr) (ScreenPtr pScreen, + int size, + CARD16 *red, + CARD16 *green, + CARD16 *blue); +typedef int (*VidModeGetGammaRampSizeProcPtr) (ScreenPtr pScreen); + +typedef struct { + DisplayModePtr First; + DisplayModePtr Next; + int Flags; + + VidModeExtensionInitProcPtr ExtensionInit; + VidModeGetMonitorValueProcPtr GetMonitorValue; + VidModeGetCurrentModelineProcPtr GetCurrentModeline; + VidModeGetFirstModelineProcPtr GetFirstModeline; + VidModeGetNextModelineProcPtr GetNextModeline; + VidModeDeleteModelineProcPtr DeleteModeline; + VidModeZoomViewportProcPtr ZoomViewport; + VidModeGetViewPortProcPtr GetViewPort; + VidModeSetViewPortProcPtr SetViewPort; + VidModeSwitchModeProcPtr SwitchMode; + VidModeLockZoomProcPtr LockZoom; + VidModeGetNumOfClocksProcPtr GetNumOfClocks; + VidModeGetClocksProcPtr GetClocks; + VidModeCheckModeForMonitorProcPtr CheckModeForMonitor; + VidModeCheckModeForDriverProcPtr CheckModeForDriver; + VidModeSetCrtcForModeProcPtr SetCrtcForMode; + VidModeAddModelineProcPtr AddModeline; + VidModeGetDotClockProcPtr GetDotClock; + VidModeGetNumOfModesProcPtr GetNumOfModes; + VidModeSetGammaProcPtr SetGamma; + VidModeGetGammaProcPtr GetGamma; + VidModeSetGammaRampProcPtr SetGammaRamp; + VidModeGetGammaRampProcPtr GetGammaRamp; + VidModeGetGammaRampSizeProcPtr GetGammaRampSize; +} VidModeRec, *VidModePtr; + +#ifdef XF86VIDMODE +void VidModeAddExtension(Bool allow_non_local); +VidModePtr VidModeGetPtr(ScreenPtr pScreen); +VidModePtr VidModeInit(ScreenPtr pScreen); +#endif /* XF86VIDMODE */ + +#endif diff --git a/include/window.h b/include/window.h index f13ed5115..7a22febf8 100644 --- a/include/window.h +++ b/include/window.h @@ -72,6 +72,12 @@ struct _Cursor; typedef struct _BackingStore *BackingStorePtr; typedef struct _Window *WindowPtr; +enum RootClipMode { + ROOT_CLIP_NONE = 0, /**< resize the root window to 0x0 */ + ROOT_CLIP_FULL = 1, /**< resize the root window to fit screen */ + ROOT_CLIP_INPUT_ONLY = 2, /**< as above, but no rendering to screen */ +}; + typedef int (*VisitWindowProcPtr) (WindowPtr pWin, void *data); @@ -221,7 +227,7 @@ extern _X_EXPORT RegionPtr CreateBoundingShape(WindowPtr /* pWin */ ); extern _X_EXPORT RegionPtr CreateClipShape(WindowPtr /* pWin */ ); -extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, Bool enable); +extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, int enable); extern _X_EXPORT void PrintWindowTree(void); extern _X_EXPORT void PrintPassiveGrabs(void); diff --git a/present/present.c b/present/present.c index 8cf3b6f77..55f6aa7b1 100644 --- a/present/present.c +++ b/present/present.c @@ -46,6 +46,28 @@ static void present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc); /* + * Returns: + * TRUE if the first MSC value is after the second one + * FALSE if the first MSC value is equal to or before the second one + */ +static Bool +msc_is_after(uint64_t test, uint64_t reference) +{ + return (int64_t)(test - reference) > 0; +} + +/* + * Returns: + * TRUE if the first MSC value is equal to or after the second one + * FALSE if the first MSC value is before the second one + */ +static Bool +msc_is_equal_or_after(uint64_t test, uint64_t reference) +{ + return (int64_t)(test - reference) >= 0; +} + +/* * Copies the update region from a pixmap to the target drawable */ static void @@ -122,6 +144,10 @@ present_check_flip(RRCrtcPtr crtc, if (!screen_priv->info->flip) return FALSE; + /* Fail to flip if we have slave outputs */ + if (!xorg_list_is_empty(&screen->output_slave_list)) + return FALSE; + /* Make sure the window hasn't been redirected with Composite */ window_pixmap = screen->GetWindowPixmap(window); if (window_pixmap != screen->GetScreenPixmap(screen) && @@ -392,22 +418,44 @@ present_set_tree_pixmap(WindowPtr window, } static void -present_set_abort_flip(ScreenPtr screen) +present_restore_screen_pixmap(ScreenPtr screen) { present_screen_priv_ptr screen_priv = present_screen_priv(screen); - PixmapPtr pixmap = (*screen->GetScreenPixmap)(screen); + PixmapPtr screen_pixmap = (*screen->GetScreenPixmap)(screen); + PixmapPtr flip_pixmap; + WindowPtr flip_window; + + if (screen_priv->flip_pending) { + flip_window = screen_priv->flip_pending->window; + flip_pixmap = screen_priv->flip_pending->pixmap; + } else { + flip_window = screen_priv->flip_window; + flip_pixmap = screen_priv->flip_pixmap; + } + + assert (flip_pixmap); + + /* Update the screen pixmap with the current flip pixmap contents + * Only do this the first time for a particular unflip operation, or + * we'll probably scribble over other windows + */ + if (screen->GetWindowPixmap(screen->root) == flip_pixmap) + present_copy_region(&screen_pixmap->drawable, flip_pixmap, NULL, 0, 0); /* Switch back to using the screen pixmap now to avoid * 2D applications drawing to the wrong pixmap. */ + if (flip_window) + present_set_tree_pixmap(flip_window, flip_pixmap, screen_pixmap); + present_set_tree_pixmap(screen->root, NULL, screen_pixmap); +} - if (screen_priv->flip_window) - present_set_tree_pixmap(screen_priv->flip_window, - screen_priv->flip_pixmap, - pixmap); +static void +present_set_abort_flip(ScreenPtr screen) +{ + present_screen_priv_ptr screen_priv = present_screen_priv(screen); - if (screen->root) - present_set_tree_pixmap(screen->root, NULL, pixmap); + present_restore_screen_pixmap(screen); screen_priv->flip_pending->abort_flip = TRUE; } @@ -416,25 +464,12 @@ static void present_unflip(ScreenPtr screen) { present_screen_priv_ptr screen_priv = present_screen_priv(screen); - PixmapPtr pixmap = (*screen->GetScreenPixmap)(screen); assert (!screen_priv->unflip_event_id); assert (!screen_priv->flip_pending); - if (screen_priv->flip_pixmap && screen_priv->flip_window) - present_set_tree_pixmap(screen_priv->flip_window, - screen_priv->flip_pixmap, - pixmap); - - present_set_tree_pixmap(screen->root, NULL, pixmap); + present_restore_screen_pixmap(screen); - /* Update the screen pixmap with the current flip pixmap contents - */ - if (screen_priv->flip_pixmap && screen_priv->flip_window) { - present_copy_region(&pixmap->drawable, - screen_priv->flip_pixmap, - NULL, 0, 0); - } screen_priv->unflip_event_id = ++present_event_id; DebugPresent(("u %lld\n", screen_priv->unflip_event_id)); (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id); @@ -560,10 +595,8 @@ present_check_flip_window (WindowPtr window) xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) { if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0)) { vblank->flip = FALSE; - if (vblank->sync_flip) { + if (vblank->sync_flip) vblank->requeue = TRUE; - vblank->target_msc++; - } } } } @@ -600,7 +633,8 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (vblank->requeue) { vblank->requeue = FALSE; - if (Success == present_queue_vblank(screen, + if (msc_is_after(vblank->target_msc, crtc_msc) && + Success == present_queue_vblank(screen, vblank->crtc, vblank->event_id, vblank->target_msc)) @@ -690,6 +724,20 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) if (window == screen_priv->flip_window) present_unflip(screen); } + + /* If present_flip failed, we may have to requeue for the target MSC */ + if (msc_is_after(vblank->target_msc, crtc_msc) && + Success == present_queue_vblank(screen, + vblank->crtc, + vblank->event_id, + vblank->target_msc)) { + xorg_list_add(&vblank->event_queue, &present_exec_queue); + xorg_list_append(&vblank->window_list, + &present_get_window_priv(window, TRUE)->vblank); + vblank->queued = TRUE; + return; + } + present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off); /* present_copy_region sticks the region into a scratch GC, @@ -717,28 +765,6 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) present_vblank_destroy(vblank); } -/* - * Returns: - * TRUE if the first MSC value is after the second one - * FALSE if the first MSC value is equal to or before the second one - */ -static Bool -msc_is_after(uint64_t test, uint64_t reference) -{ - return (int64_t)(test - reference) > 0; -} - -/* - * Returns: - * TRUE if the first MSC value is equal to or after the second one - * FALSE if the first MSC value is before the second one - */ -static Bool -msc_is_equal_or_after(uint64_t test, uint64_t reference) -{ - return (int64_t)(test - reference) >= 0; -} - int present_pixmap(WindowPtr window, PixmapPtr pixmap, diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c index c37dcf8ab..ba310eaa4 100644 --- a/randr/rrmonitor.c +++ b/randr/rrmonitor.c @@ -326,7 +326,7 @@ RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret, RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon); mon++; } else if (list.server_primary >= 0) { - RRMonitorSetFromServer(pScrPriv->crtcs[list.server_primary], mon); + RRMonitorSetFromServer(list.server_crtc[list.server_primary], mon); mon++; } @@ -354,8 +354,8 @@ RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret, /* And finish with the list of crtc-inspired monitors */ - for (c = 0; c < pScrPriv->numCrtcs; c++) { - RRCrtcPtr crtc = pScrPriv->crtcs[c]; + for (c = 0; c < list.num_crtcs; c++) { + RRCrtcPtr crtc = list.server_crtc[c]; if (c == list.server_primary && list.client_primary < 0) continue; @@ -721,7 +721,9 @@ ProcRRSetMonitor(ClientPtr client) monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters; r = RRMonitorAdd(client, screen, monitor); - if (r != Success) + if (r == Success) + RRSendConfigNotify(screen); + else RRMonitorFree(monitor); return r; } @@ -745,5 +747,8 @@ ProcRRDeleteMonitor(ClientPtr client) return BadAtom; } - return RRMonitorDelete(client, screen, stuff->name); + r = RRMonitorDelete(client, screen, stuff->name); + if (r == Success) + RRSendConfigNotify(screen); + return r; } diff --git a/randr/rroutput.c b/randr/rroutput.c index d12b9ba12..686ae49a6 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -543,6 +543,7 @@ ProcRRSetOutputPrimary(ClientPtr client) WindowPtr pWin; rrScrPrivPtr pScrPriv; int ret; + ScreenPtr slave; REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); @@ -565,8 +566,19 @@ ProcRRSetOutputPrimary(ClientPtr client) pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); if (pScrPriv) + { RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output); + xorg_list_for_each_entry(slave, + &pWin->drawable.pScreen->output_slave_list, + output_head) { + rrScrPrivPtr pSlavePriv; + pSlavePriv = rrGetScrPriv(slave); + + RRSetPrimaryOutput(slave, pSlavePriv, output); + } + } + return Success; } diff --git a/record/record.c b/record/record.c index 1caf3f1db..82bb0607e 100644 --- a/record/record.c +++ b/record/record.c @@ -1878,7 +1878,6 @@ ProcRecordCreateContext(ClientPtr client) return Success; } else { - RecordDeleteContext((void *) pContext, pContext->id); return BadAlloc; } bailout: diff --git a/render/picture.c b/render/picture.c index 6d9c9df3a..9e4036e7d 100644 --- a/render/picture.c +++ b/render/picture.c @@ -665,6 +665,9 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) for (n = 0; n < nformats; n++) { if (!AddResource (formats[n].id, PictFormatType, (void *) (formats + n))) { + int i; + for (i = 0; i < n; i++) + FreeResource(formats[i].id, RT_NONE); free(formats); return FALSE; } diff --git a/test/Makefile.am b/test/Makefile.am index d151b02d0..9f13e269d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -56,6 +56,7 @@ libxservertest_la_LIBADD += \ $(top_builddir)/hw/xfree86/ddc/libddc.la \ $(top_builddir)/hw/xfree86/i2c/libi2c.la \ $(top_builddir)/hw/xfree86/dixmods/libxorgxkb.la \ + $(top_builddir)/Xext/libXvidmode.la \ @XORG_LIBS@ BUILT_SOURCES = sdksyms.c @@ -91,6 +92,7 @@ libxservertest_la_LIBADD += \ $(top_builddir)/render/librender.la \ $(top_builddir)/Xext/libXext.la \ $(top_builddir)/Xext/libXextdpmsstubs.la \ + $(top_builddir)/Xext/libXvidmode.la \ $(top_builddir)/Xi/libXi.la \ $(top_builddir)/Xi/libXistubs.la \ $(top_builddir)/xfixes/libxfixes.la \ diff --git a/xfixes/cursor.c b/xfixes/cursor.c index 5619aad2e..10f9b2346 100644 --- a/xfixes/cursor.c +++ b/xfixes/cursor.c @@ -774,10 +774,8 @@ createCursorHideCount(ClientPtr pClient, ScreenPtr pScreen) * Create a resource for this element so it can be deleted * when the client goes away. */ - if (!AddResource(pChc->resource, CursorHideCountType, (void *) pChc)) { - free(pChc); + if (!AddResource(pChc->resource, CursorHideCountType, (void *) pChc)) return BadAlloc; - } return Success; } |