[PATCH 02/11] dix: introduce gpu screens.
Dave Airlie
airlied at gmail.com
Wed Jun 13 06:53:14 PDT 2012
From: Dave Airlie <airlied at redhat.com>
This patch introduces gpu screens into screenInfo. It adds interfaces
for adding and removing gpu screens, along with adding private fixup,
block handler support, and scratch pixmap init.
GPU screens have a myNum that is offset by GPU_SCREEN_OFFSET (256),
this is used for logging etc.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
dix/dispatch.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--
dix/dixutils.c | 6 ++++
dix/main.c | 15 ++++++++++
dix/privates.c | 5 ++++
include/misc.h | 1 +
include/screenint.h | 9 ++++++
include/scrnintstr.h | 4 +++
7 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 5448298..58d594a 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;
@@ -3732,6 +3732,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;
@@ -3788,7 +3792,7 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
if (!pScreen)
return -1;
- ret = init_screen(pScreen, i);
+ ret = init_screen(pScreen, i, FALSE);
if (ret) {
free(pScreen);
return ret;
@@ -3817,3 +3821,70 @@ 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 == MAXSCREENS)
+ return -1;
+
+ pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
+ if (!pScreen)
+ return -1;
+
+ ret = init_screen(pScreen, i, TRUE);
+ if (ret) {
+ 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();
+
+ dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR,
+ 0);
+
+ 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.numGPUScreens--;
+
+ free(pScreen);
+
+}
diff --git a/dix/dixutils.c b/dix/dixutils.c
index b249a81..c06315e 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 83efa7d..e9b3d9c 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -206,6 +206,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];
@@ -331,6 +337,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 15fbf75..c2bdeae 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -119,6 +119,11 @@ fixupScreens(FixupFunc fixup, unsigned bytes)
(&screenInfo.screens[s]->devPrivates, keys[PRIVATE_SCREEN].offset,
bytes))
return FALSE;
+ for (s = 0; s < screenInfo.numGPUScreens; s++)
+ if (!fixup
+ (&screenInfo.gpuscreens[s]->devPrivates, keys[PRIVATE_SCREEN].offset,
+ bytes))
+ return FALSE;
return TRUE;
}
diff --git a/include/misc.h b/include/misc.h
index 41c1333..6445fd7 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -87,6 +87,7 @@ OF THIS SOFTWARE.
#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 6b0cc70..8205f63 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 c592d1f..4d633fe 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -475,6 +475,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
@@ -492,6 +494,8 @@ typedef struct _ScreenInfo {
PixmapFormatRec formats[MAXFORMATS];
int numScreens;
ScreenPtr screens[MAXSCREENS];
+ int numGPUScreens;
+ ScreenPtr gpuscreens[MAXSCREENS];
int x; /* origin */
int y; /* origin */
int width; /* total width of all screens together */
--
1.7.10.2
More information about the xorg-devel
mailing list