diff options
-rw-r--r-- | dix/dispatch.c | 73 | ||||
-rw-r--r-- | dix/dixutils.c | 6 | ||||
-rw-r--r-- | dix/main.c | 15 | ||||
-rw-r--r-- | dix/privates.c | 4 | ||||
-rw-r--r-- | include/misc.h | 4 | ||||
-rw-r--r-- | include/screenint.h | 9 | ||||
-rw-r--r-- | include/scrnintstr.h | 4 | ||||
-rw-r--r-- | render/glyph.c | 2 |
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]; } |