diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c index b6fc34ff9..4345672ab 100644 --- a/Xext/xvdisp.c +++ b/Xext/xvdisp.c @@ -1850,110 +1850,91 @@ XineramaXvPutStill(ClientPtr client) return result; } +static Bool +isImageAdaptor(XvAdaptorPtr pAdapt) +{ + return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0); +} + +static Bool +hasOverlay(XvAdaptorPtr pAdapt) +{ + int i; + for(i = 0; i < pAdapt->nAttributes; i++) + if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY")) + return TRUE; + return FALSE; +} + +static XvAdaptorPtr +matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay) +{ + int i; + XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey()); + /* Do not try to go on if xv is not supported on this screen */ + if(xvsp == NULL) + return NULL; + + /* if the adaptor has the same name it's a perfect match */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(!strcmp(refAdapt->name, pAdapt->name)) + return pAdapt; + } + + /* otherwise we only look for XvImage adaptors */ + if(!isImageAdaptor(refAdapt)) + return NULL; + + /* prefer overlay/overlay non-overlay/non-overlay pairing */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt)) + return pAdapt; + } + + /* but we'll take any XvImage pairing if we can get it */ + for(i = 0; i < xvsp->nAdaptors; i++) { + XvAdaptorPtr pAdapt = xvsp->pAdaptors + i; + if(isImageAdaptor(pAdapt)) + return pAdapt; + } + return NULL; +} + void XineramifyXv(void) { - ScreenPtr pScreen, screen0 = screenInfo.screens[0]; - XvScreenPtr xvsp0 = (XvScreenPtr)dixLookupPrivate(&screen0->devPrivates, - XvGetScreenKey()); - XvAdaptorPtr refAdapt, pAdapt; - XvAttributePtr pAttr; - XvScreenPtr xvsp; - Bool isOverlay, hasOverlay; - PanoramiXRes *port; + XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey()); XvAdaptorPtr MatchingAdaptors[MAXSCREENS]; - int i, j, k, l; + int i, j, k; XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort"); if (!xvsp0 || !XvXRTPort) return; for(i = 0; i < xvsp0->nAdaptors; i++) { - refAdapt = xvsp0->pAdaptors + i; - - bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS); - - MatchingAdaptors[0] = refAdapt; - + Bool isOverlay; + XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i; if(!(refAdapt->type & XvInputMask)) continue; - - isOverlay = FALSE; - for(j = 0; j < refAdapt->nAttributes; j++) { - pAttr = refAdapt->pAttributes + j; - if(!strcmp(pAttr->name, "XV_COLORKEY")) { - isOverlay = TRUE; - break; - } - } - - for(j = 1; j < PanoramiXNumScreens; j++) { - pScreen = screenInfo.screens[j]; - xvsp = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, - XvGetScreenKey()); - /* Do not try to go on if xv is not supported on this screen */ - if (xvsp==NULL) continue ; - - /* if the adaptor has the same name it's a perfect match */ - for(k = 0; k < xvsp->nAdaptors; k++) { - pAdapt = xvsp->pAdaptors + k; - if(!strcmp(refAdapt->name, pAdapt->name)) { - MatchingAdaptors[j] = pAdapt; - break; - } - } - if(MatchingAdaptors[j]) continue; /* found it */ - - /* otherwise we only look for XvImage adaptors */ - if(!(refAdapt->type & XvImageMask)) continue; - if(refAdapt->nImages <= 0) continue; - - /* prefer overlay/overlay non-overlay/non-overlay pairing */ - for(k = 0; k < xvsp->nAdaptors; k++) { - pAdapt = xvsp->pAdaptors + k; - if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) { - hasOverlay = FALSE; - for(l = 0; l < pAdapt->nAttributes; l++) { - if(!strcmp(pAdapt->pAttributes[l].name, "XV_COLORKEY")) { - hasOverlay = TRUE; - break; - } - } - if(isOverlay && hasOverlay) { - MatchingAdaptors[j] = pAdapt; - break; - } - else if(!isOverlay && !hasOverlay) { - MatchingAdaptors[j] = pAdapt; - break; - } - } - } - - if(MatchingAdaptors[j]) continue; /* found it */ - - /* but we'll take any XvImage pairing if we can get it */ - - for(k = 0; k < xvsp->nAdaptors; k++) { - pAdapt = xvsp->pAdaptors + k; - if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) { - MatchingAdaptors[j] = pAdapt; - break; - } - } - } + + MatchingAdaptors[0] = refAdapt; + isOverlay = hasOverlay(refAdapt); + for(j = 1; j < PanoramiXNumScreens; j++) + MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay); /* now create a resource for each port */ for(j = 0; j < refAdapt->nPorts; j++) { - if(!(port = xalloc(sizeof(PanoramiXRes)))) + PanoramiXRes *port = xalloc(sizeof(PanoramiXRes)); + if(!port) break; - port->info[0].id = MatchingAdaptors[0]->base_id + j; - AddResource(port->info[0].id, XvXRTPort, port); - for(k = 1; k < PanoramiXNumScreens; k++) { + for(k = 0; k < PanoramiXNumScreens; k++) { if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) port->info[k].id = MatchingAdaptors[k]->base_id + j; else port->info[k].id = 0; } + AddResource(port->info[0].id, XvXRTPort, port); } } diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c index b2baa197f..29857877e 100644 --- a/hw/vfb/InitOutput.c +++ b/hw/vfb/InitOutput.c @@ -77,7 +77,6 @@ from The Open Group. typedef struct { - int scrnum; int width; int paddedBytesWidth; int paddedWidth; @@ -105,7 +104,15 @@ typedef struct } vfbScreenInfo, *vfbScreenInfoPtr; static int vfbNumScreens; -static vfbScreenInfo vfbScreens[MAXSCREENS]; +static vfbScreenInfo *vfbScreens; +static vfbScreenInfo defaultScreenInfo = { + .width = VFB_DEFAULT_WIDTH, + .height = VFB_DEFAULT_HEIGHT, + .depth = VFB_DEFAULT_DEPTH, + .blackPixel = VFB_DEFAULT_BLACKPIXEL, + .whitePixel = VFB_DEFAULT_WHITEPIXEL, + .lineBias = VFB_DEFAULT_LINEBIAS, +}; static Bool vfbPixmapDepths[33]; #ifdef HAS_MMAP static char *pfbdir = NULL; @@ -113,7 +120,6 @@ static char *pfbdir = NULL; typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType; static fbMemType fbmemtype = NORMAL_MEMORY_FB; static char needswap = 0; -static int lastScreen = -1; static Bool Render = TRUE; #define swapcopy16(_dst, _src) \ @@ -134,25 +140,6 @@ vfbInitializePixmapDepths(void) vfbPixmapDepths[i] = FALSE; } -static void -vfbInitializeDefaultScreens(void) -{ - int i; - - for (i = 0; i < MAXSCREENS; i++) - { - vfbScreens[i].scrnum = i; - vfbScreens[i].width = VFB_DEFAULT_WIDTH; - vfbScreens[i].height = VFB_DEFAULT_HEIGHT; - vfbScreens[i].depth = VFB_DEFAULT_DEPTH; - vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL; - vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL; - vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS; - vfbScreens[i].pfbMemory = NULL; - } - vfbNumScreens = 1; -} - static int vfbBitsPerPixel(int depth) { @@ -267,14 +254,20 @@ int ddxProcessArgument(int argc, char *argv[], int i) { static Bool firstTime = TRUE; + static int lastScreen = -1; + vfbScreenInfo *currentScreen; if (firstTime) { - vfbInitializeDefaultScreens(); vfbInitializePixmapDepths(); firstTime = FALSE; } + if (lastScreen == -1) + currentScreen = &defaultScreenInfo; + else + currentScreen = &vfbScreens[lastScreen]; + #define CHECK_FOR_REQUIRED_ARGUMENTS(num) \ if (((i + num) >= argc) || (!argv[i + num])) { \ ErrorF("Required argument to %s not specified\n", argv[i]); \ @@ -287,13 +280,23 @@ ddxProcessArgument(int argc, char *argv[], int i) int screenNum; CHECK_FOR_REQUIRED_ARGUMENTS(2); screenNum = atoi(argv[i+1]); - if (screenNum < 0 || screenNum >= MAXSCREENS) + if (screenNum < 0) { ErrorF("Invalid screen number %d\n", screenNum); UseMsg(); FatalError("Invalid screen number %d passed to -screen\n", screenNum); } + + if (vfbNumScreens <= screenNum) + { + vfbScreens = xrealloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1)); + if (!vfbScreens) + FatalError("Not enough memory for screen %d\n", screenNum); + for (; vfbNumScreens <= screenNum; ++vfbNumScreens) + vfbScreens[vfbNumScreens] = defaultScreenInfo; + } + if (3 != sscanf(argv[i+2], "%dx%dx%d", &vfbScreens[screenNum].width, &vfbScreens[screenNum].height, @@ -305,8 +308,6 @@ ddxProcessArgument(int argc, char *argv[], int i) argv[i+2], screenNum); } - if (screenNum >= vfbNumScreens) - vfbNumScreens = screenNum + 1; lastScreen = screenNum; return 3; } @@ -348,61 +349,22 @@ ddxProcessArgument(int argc, char *argv[], int i) if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */ { - Pixel pix; CHECK_FOR_REQUIRED_ARGUMENTS(1); - pix = atoi(argv[++i]); - if (-1 == lastScreen) - { - int i; - for (i = 0; i < MAXSCREENS; i++) - { - vfbScreens[i].blackPixel = pix; - } - } - else - { - vfbScreens[lastScreen].blackPixel = pix; - } + currentScreen->blackPixel = atoi(argv[++i]); return 2; } if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */ { - Pixel pix; CHECK_FOR_REQUIRED_ARGUMENTS(1); - pix = atoi(argv[++i]); - if (-1 == lastScreen) - { - int i; - for (i = 0; i < MAXSCREENS; i++) - { - vfbScreens[i].whitePixel = pix; - } - } - else - { - vfbScreens[lastScreen].whitePixel = pix; - } + currentScreen->whitePixel = atoi(argv[++i]); return 2; } if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */ { - unsigned int linebias; CHECK_FOR_REQUIRED_ARGUMENTS(1); - linebias = atoi(argv[++i]); - if (-1 == lastScreen) - { - int i; - for (i = 0; i < MAXSCREENS; i++) - { - vfbScreens[i].lineBias = linebias; - } - } - else - { - vfbScreens[lastScreen].lineBias = linebias; - } + currentScreen->lineBias = atoi(argv[++i]); return 2; } @@ -598,7 +560,7 @@ vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb) char dummyBuffer[DUMMY_BUFFER_SIZE]; int currentFileSize, writeThisTime; - sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum); + sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, (int) (pvfb - vfbScreens)); if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666))) { perror("open"); @@ -671,7 +633,7 @@ vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb) return; } - ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid); + ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid); } #endif /* HAS_SHM */ @@ -995,6 +957,11 @@ InitOutput(ScreenInfo *screenInfo, int argc, char **argv) /* initialize screens */ + if (vfbNumScreens < 1) + { + vfbScreens = &defaultScreenInfo; + vfbNumScreens = 1; + } for (i = 0; i < vfbNumScreens; i++) { if (-1 == AddScreen(vfbScreenInit, argc, argv)) diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c index 1503502b5..2cc2f6093 100644 --- a/hw/xfree86/common/xf86xv.c +++ b/hw/xfree86/common/xf86xv.c @@ -197,6 +197,9 @@ xf86XVRegisterOffscreenImages( int num ){ OffscreenImageRec *OffscreenImage; + /* This function may be called before xf86XVScreenInit, so there's + * no better place than this to call dixRequestPrivate to ensure we + * have space reserved. After the first call it is a no-op. */ if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) || !(OffscreenImage = GetOffscreenImage(pScreen))) /* Every X.org driver assumes this function always succeeds, so