summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dix/dispatch.c73
-rw-r--r--dix/dixutils.c6
-rw-r--r--dix/main.c15
-rw-r--r--dix/privates.c4
-rw-r--r--include/misc.h4
-rw-r--r--include/screenint.h9
-rw-r--r--include/scrnintstr.h4
-rw-r--r--render/glyph.c2
8 files changed, 115 insertions, 2 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 39d791d4c..fa397285c 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3724,7 +3724,7 @@ with its screen number, a pointer to its ScreenRec, argc, and argv.
*/
-static int init_screen(ScreenPtr pScreen, int i)
+static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
{
int scanlinepad, format, depth, bitsPerPixel, j, k;
@@ -3734,6 +3734,10 @@ static int init_screen(ScreenPtr pScreen, int i)
return -1;
}
pScreen->myNum = i;
+ if (gpu) {
+ pScreen->myNum += GPU_SCREEN_OFFSET;
+ pScreen->isGPU = TRUE;
+ }
pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */
pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
pScreen->CreateScreenResources = 0;
@@ -3790,7 +3794,7 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
if (!pScreen)
return -1;
- ret = init_screen(pScreen, i);
+ ret = init_screen(pScreen, i, FALSE);
if (ret != 0) {
free(pScreen);
return ret;
@@ -3820,3 +3824,68 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
return i;
}
+
+int
+AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
+ int /*argc */ ,
+ char ** /*argv */
+ ),
+ int argc, char **argv)
+{
+ int i;
+ ScreenPtr pScreen;
+ Bool ret;
+
+ i = screenInfo.numGPUScreens;
+ if (i == MAXGPUSCREENS)
+ return -1;
+
+ pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
+ if (!pScreen)
+ return -1;
+
+ ret = init_screen(pScreen, i, TRUE);
+ if (ret != 0) {
+ free(pScreen);
+ return ret;
+ }
+
+ /* This is where screen specific stuff gets initialized. Load the
+ screen structure, call the hardware, whatever.
+ This is also where the default colormap should be allocated and
+ also pixel values for blackPixel, whitePixel, and the cursor
+ Note that InitScreen is NOT allowed to modify argc, argv, or
+ any of the strings pointed to by argv. They may be passed to
+ multiple screens.
+ */
+ screenInfo.gpuscreens[i] = pScreen;
+ screenInfo.numGPUScreens++;
+ if (!(*pfnInit) (pScreen, argc, argv)) {
+ dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
+ free(pScreen);
+ screenInfo.numGPUScreens--;
+ return -1;
+ }
+
+ update_desktop_dimensions();
+
+ return i;
+}
+
+void
+RemoveGPUScreen(ScreenPtr pScreen)
+{
+ int idx, j;
+ if (!pScreen->isGPU)
+ return;
+
+ idx = pScreen->myNum - GPU_SCREEN_OFFSET;
+ for (j = idx; j < screenInfo.numGPUScreens - 1; j++) {
+ screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1];
+ screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET;
+ }
+ screenInfo.numGPUScreens--;
+
+ free(pScreen);
+
+}
diff --git a/dix/dixutils.c b/dix/dixutils.c
index b249a810b..3f24629b4 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -386,6 +386,9 @@ BlockHandler(pointer pTimeout, pointer pReadmask)
for (i = 0; i < screenInfo.numScreens; i++)
(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i],
pTimeout, pReadmask);
+ for (i = 0; i < screenInfo.numGPUScreens; i++)
+ (*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i],
+ pTimeout, pReadmask);
for (i = 0; i < numHandlers; i++)
if (!handlers[i].deleted)
(*handlers[i].BlockHandler) (handlers[i].blockData,
@@ -422,6 +425,9 @@ WakeupHandler(int result, pointer pReadmask)
for (i = 0; i < screenInfo.numScreens; i++)
(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i],
result, pReadmask);
+ for (i = 0; i < screenInfo.numGPUScreens; i++)
+ (*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i],
+ result, pReadmask);
if (handlerDeleted) {
for (i = 0; i < numHandlers;)
if (handlers[i].deleted) {
diff --git a/dix/main.c b/dix/main.c
index 9524189d0..42f517dfd 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -207,6 +207,12 @@ main(int argc, char *argv[], char *envp[])
FatalError("no screens found");
InitExtensions(argc, argv);
+ for (i = 0; i < screenInfo.numGPUScreens; i++) {
+ ScreenPtr pScreen = screenInfo.gpuscreens[i];
+ if (!CreateScratchPixmapsForScreen(pScreen))
+ FatalError("failed to create scratch pixmaps");
+ }
+
for (i = 0; i < screenInfo.numScreens; i++) {
ScreenPtr pScreen = screenInfo.screens[i];
@@ -336,6 +342,15 @@ main(int argc, char *argv[], char *envp[])
screenInfo.numScreens = i;
}
+ for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
+ ScreenPtr pScreen = screenInfo.gpuscreens[i];
+ FreeScratchPixmapsForScreen(pScreen);
+ (*pScreen->CloseScreen) (pScreen);
+ dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
+ free(pScreen);
+ screenInfo.numGPUScreens = i;
+ }
+
ReleaseClientIds(serverClient);
dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
serverClient->devPrivates = NULL;
diff --git a/dix/privates.c b/dix/privates.c
index b58085ffd..740ead739 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -222,6 +222,10 @@ fixupScreens(FixupFunc fixup, unsigned bytes)
for (s = 0; s < screenInfo.numScreens; s++)
if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes))
return FALSE;
+
+ for (s = 0; s < screenInfo.numGPUScreens; s++)
+ if (!fixupOneScreen (screenInfo.gpuscreens[s], fixup, bytes))
+ return FALSE;
return TRUE;
}
diff --git a/include/misc.h b/include/misc.h
index aa62f6a3a..6bea82f33 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -83,10 +83,14 @@ OF THIS SOFTWARE.
#ifndef MAXSCREENS
#define MAXSCREENS 16
#endif
+#ifndef MAXGPUSCREENS
+#define MAXGPUSCREENS 16
+#endif
#define MAXCLIENTS 256
#define MAXEXTENSIONS 128
#define MAXFORMATS 8
#define MAXDEVICES 40 /* input devices */
+#define GPU_SCREEN_OFFSET 256
/* 128 event opcodes for core + extension events, excluding GE */
#define MAXEVENTS 128
diff --git a/include/screenint.h b/include/screenint.h
index 6b0cc70ee..8205f6363 100644
--- a/include/screenint.h
+++ b/include/screenint.h
@@ -62,6 +62,15 @@ extern _X_EXPORT int AddScreen(Bool (* /*pfnInit */ )(
int /*argc */ ,
char ** /*argv */ );
+
+extern _X_EXPORT int AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
+ int /*argc */ ,
+ char ** /*argv */
+ ),
+ int argc, char **argv);
+
+extern _X_EXPORT void RemoveGPUScreen(ScreenPtr pScreen);
+
typedef struct _ColormapRec *ColormapPtr;
#endif /* SCREENINT_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 7af2bf53f..bcac47558 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -477,6 +477,8 @@ typedef struct _Screen {
* malicious users to steal framebuffer's content if that would be the
* default */
Bool canDoBGNoneRoot;
+
+ Bool isGPU;
} ScreenRec;
static inline RegionPtr
@@ -494,6 +496,8 @@ typedef struct _ScreenInfo {
PixmapFormatRec formats[MAXFORMATS];
int numScreens;
ScreenPtr screens[MAXSCREENS];
+ int numGPUScreens;
+ ScreenPtr gpuscreens[MAXGPUSCREENS];
int x; /* origin */
int y; /* origin */
int width; /* total width of all screens together */
diff --git a/render/glyph.c b/render/glyph.c
index acb573fe6..c121e64a2 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -687,6 +687,8 @@ miGlyphs(CARD8 op,
PicturePtr GetGlyphPicture(GlyphPtr glyph, ScreenPtr pScreen)
{
+ if (pScreen->isGPU)
+ return NULL;
return GlyphPicture(glyph)[pScreen->myNum];
}