summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2010-04-30 12:40:53 -0700
committerKeith Packard <keithp@keithp.com>2010-04-30 12:40:53 -0700
commit986d46144b183a36b4e98aed95eca0c55a8b4251 (patch)
tree2c82ce4ec7e20d85a04b6e659716fdf6604f9985
parenta974c8e7cba40c8d7d1b91e07de8c414627b71a2 (diff)
parentb5b8f91b82d7b150c926dd3fecee6c3aafff6e39 (diff)
Merge remote branch 'jamey/for-keith'
Conflicts: hw/xfree86/common/xf86xv.c
-rw-r--r--Xext/xvdisp.c147
-rw-r--r--hw/vfb/InitOutput.c107
-rw-r--r--hw/xfree86/common/xf86xv.c3
3 files changed, 104 insertions, 153 deletions
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;
+ Bool isOverlay;
+ XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
+ if(!(refAdapt->type & XvInputMask)) continue;
- bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
-
MatchingAdaptors[0] = refAdapt;
-
- 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;
- }
- }
- }
+ 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