summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-08-16 14:39:07 +0100
committerDave Airlie <airlied@redhat.com>2011-08-16 14:39:07 +0100
commit33e1a2110552fcc00333f57533fdd27356f55624 (patch)
treee1936574719406d4ff3a597cd07dde6283b124fb
parentcfc66e76815f193355b1fa003768309b7b65cbaa (diff)
drv: add start of plug code.
this keep a list of gc/pixmap/pictures that we need to migrate, and does step one of adding them to a new screen
-rw-r--r--drv/Makefile.am3
-rw-r--r--drv/drv_imped.h25
-rw-r--r--drv/impedgc.c15
-rw-r--r--drv/impedpict.c33
-rw-r--r--drv/impedplug.c79
-rw-r--r--drv/impedscrn.c10
6 files changed, 155 insertions, 10 deletions
diff --git a/drv/Makefile.am b/drv/Makefile.am
index 4e3c880ec..20775076f 100644
--- a/drv/Makefile.am
+++ b/drv/Makefile.am
@@ -34,4 +34,5 @@ libdrv_la_SOURCES = \
drv_screen.c \
impedscrn.c \
impedgc.c \
- impedpict.c
+ impedpict.c \
+ impedplug.c
diff --git a/drv/drv_imped.h b/drv/drv_imped.h
index 68647c836..86d15f7c8 100644
--- a/drv/drv_imped.h
+++ b/drv/drv_imped.h
@@ -2,6 +2,8 @@
#ifndef IMPED_H
#define IMPED_H
+#include <X11/Xdefs.h> /* for Bool */
+#include "list.h"
#include "drv_types.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
@@ -14,21 +16,30 @@
#define MAX_GPU 4
typedef struct _impedScreenPriv {
- DrvScreenPtr gpu[MAX_GPU];
- int num_gpu;
+ DrvScreenPtr gpu[MAX_GPU];
+ int num_gpu;
+ struct list gc_list_head;
+ struct list pixmap_list_head;
+ struct list picture_list_head;
} impedScreenPrivRec, *impedScreenPrivPtr;
typedef struct _impedPixmapPriv {
- DrvPixmapPtr gpu[MAX_GPU];
- Bool shattered; /* the root pixmap is shattered */
+ DrvPixmapPtr gpu[MAX_GPU];
+ Bool shattered; /* the root pixmap is shattered */
+ struct list member;
+ PixmapPtr parent;
} impedPixmapPrivRec, *impedPixmapPrivPtr;
typedef struct _impedGCPriv {
- DrvGCPtr gpu[MAX_GPU];
+ DrvGCPtr gpu[MAX_GPU];
+ struct list member;
+ GCPtr parent; /* pointer to parent */
} impedGCPrivRec, *impedGCPrivPtr;
typedef struct _impedPicturePriv {
- DrvPicturePtr gpu[MAX_GPU];
+ DrvPicturePtr gpu[MAX_GPU];
+ struct list member;
+ PicturePtr parent;
} impedPictPrivRec, *impedPictPrivPtr;
DevPrivateKey impedGetScreenPrivKey(void);
@@ -110,4 +121,6 @@ extern _X_EXPORT Bool impedFinishScreenInit(ScreenPtr pScreen,
int width,
int bpp);
extern _X_EXPORT void impedInit(void);
+
+void impedPictureDuplicate(PicturePtr pPicture, int new_gpu_index);
#endif
diff --git a/drv/impedgc.c b/drv/impedgc.c
index dc341d71d..ca92a6654 100644
--- a/drv/impedgc.c
+++ b/drv/impedgc.c
@@ -104,11 +104,21 @@ impedValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
}
+static void impedDestroyGC(GCPtr pGC)
+{
+ impedGCPrivPtr imped_gc = impedGetGC(pGC);
+
+ list_del(&imped_gc->member);
+
+ // TODO destroy driver GC
+ miDestroyGC(pGC);
+}
+
const GCFuncs impedGCFuncs = {
impedValidateGC,
miChangeGC,
miCopyGC,
- miDestroyGC,
+ impedDestroyGC,
miChangeClip,
miDestroyClip,
miCopyClip,
@@ -729,6 +739,9 @@ impedCreateGC(GCPtr pGC)
pGC->miTranslate = 1;
pGC->fExpose = 1;
+ list_add(&imped_gc->member, &imped_screen->gc_list_head);
+
+ imped_gc->parent = pGC;
for (i = 0; i < imped_screen->num_gpu; i++) {
pDrvGC = DrvCreateGC(imped_screen->gpu[i], pGC->depth);
diff --git a/drv/impedpict.c b/drv/impedpict.c
index 639033b64..0fe162cac 100644
--- a/drv/impedpict.c
+++ b/drv/impedpict.c
@@ -69,6 +69,10 @@ static Bool CreateSourcePict(PicturePtr pPicture, PictureScreenPtr ps, int num_g
impedPictPrivPtr imped_pict = impedGetPict(pPicture);
int i;
+ if (!imped_pict->parent) {
+ imped_pict->parent = pPicture;
+ }
+
for (i = 0; i < num_gpu; i++) {
if (!imped_pict->gpu[i]) {
imped_pict->gpu[i] = DrvCreatePicture(NULL, pPicture->pFormat, 0, NULL);
@@ -94,6 +98,11 @@ impedCreatePicture (PicturePtr pPicture)
imped_pixmap = impedGetPixmap(pPixmap);
+ if (!imped_pict->parent) {
+ imped_pict->parent = pPicture;
+ list_add(&imped_pict->member, &imped_screen->picture_list_head);
+ }
+
for (i = 0; i < imped_screen->num_gpu; i++) {
imped_pict->gpu[i] = DrvCreatePicture(imped_pixmap->gpu[i], pPicture->pFormat,
0, 0);
@@ -453,6 +462,17 @@ impedGlyphs(CARD8 op,
}
}
+static void
+impedDestroyPicture(PicturePtr pPicture)
+{
+ impedPictPrivPtr imped_pict = impedGetPict(pPicture);
+ miDestroyPicture(pPicture);
+
+ list_del(&imped_pict->member);
+
+ /* TODO free sub pictures */
+}
+
Bool
impedPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
{
@@ -471,6 +491,19 @@ impedPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->AddTriangles = impedAddTriangles;
ps->Triangles = impedTriangles;
ps->Glyphs = impedGlyphs;
+ ps->DestroyPicture = impedDestroyPicture;
return TRUE;
}
+void
+impedPictureDuplicate(PicturePtr pPicture, int new_gpu_index)
+{
+ impedPictPrivPtr imped_pict = impedGetPict(pPicture);
+ PixmapPtr pPixmap;
+ impedPixmapPrivPtr imped_pixmap;
+
+ pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+ imped_pixmap = impedGetPixmap(pPixmap);
+ imped_pict->gpu[new_gpu_index] = DrvCreatePicture(imped_pixmap->gpu[new_gpu_index], pPicture->pFormat, 0, 0);
+ SyncDrvPicture(pPicture, imped_pict->gpu[new_gpu_index], new_gpu_index);
+}
diff --git a/drv/impedplug.c b/drv/impedplug.c
new file mode 100644
index 000000000..60a43c4ea
--- /dev/null
+++ b/drv/impedplug.c
@@ -0,0 +1,79 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include "drv_imped.h"
+#include "drv_gcstruct.h"
+#include "drv_pixmapstr.h"
+#include "drv_scrnintstr.h"
+#include "drv_picturestr.h"
+/* add/remove drvscreen support */
+#include "picturestr.h"
+
+struct duplicate_info {
+ int client_id;
+ int new_gpu_index;
+};
+
+static void dup_pixmap(PixmapPtr pPixmap, DrvScreenPtr pDrvScreen, int new_gpu_id)
+{
+ impedScreenPrivPtr imped_screen = impedGetScreen(pPixmap->drawable.pScreen);
+ impedPixmapPrivPtr imped_pixmap = impedGetPixmap(pPixmap);
+
+ imped_pixmap->gpu[new_gpu_id] = imped_screen->gpu[new_gpu_id]->CreatePixmap(imped_screen->gpu[new_gpu_id], pPixmap->drawable.width, pPixmap->drawable.height, pPixmap->drawable.depth, pPixmap->usage_hint, pPixmap);
+}
+
+int
+impedAddDrvScreen(ScreenPtr pScreen, DrvScreenPtr new)
+{
+ impedScreenPrivPtr imped_screen = impedGetScreen(pScreen);
+ int i;
+ int new_gpu_index;
+
+ impedAttachDrvScreen(pScreen, new);
+
+ new_gpu_index = imped_screen->num_gpu - 1;
+ ErrorF("hot adding GPU %d\n", new_gpu_index);
+
+ /* need to find all GCs, Pixmaps, Pictures - non-trivial then? */
+ {
+ impedGCPrivPtr imped_gc;
+ list_for_each_entry(imped_gc, &imped_screen->gc_list_head, member) {
+ GCPtr pGC = imped_gc->parent;
+
+ imped_gc->gpu[new_gpu_index] = DrvCreateGC(imped_screen->gpu[new_gpu_index], pGC->depth);
+ }
+ }
+
+ {
+ impedPixmapPrivPtr imped_pixmap;
+ list_for_each_entry(imped_pixmap, &imped_screen->pixmap_list_head, member) {
+ PixmapPtr pPixmap = imped_pixmap->parent;
+
+ dup_pixmap(pPixmap, imped_screen->gpu[new_gpu_index], new_gpu_index);
+ }
+ }
+
+ {
+ impedPictPrivPtr imped_pict;
+ list_for_each_entry(imped_pict, &imped_screen->picture_list_head, member) {
+ PicturePtr pPicture = imped_pict->parent;
+ impedPictureDuplicate(pPicture, new_gpu_index);
+ }
+ }
+
+ /* set the screen pixmap up correctly */
+ {
+ PixmapPtr pPixmap;
+ impedPixmapPrivPtr imped_pixmap;
+ pPixmap = pScreen->GetScreenPixmap(pScreen);
+ imped_pixmap = impedGetPixmap(pPixmap);
+
+ imped_screen->gpu[new_gpu_index]->SetScreenPixmap(imped_screen->gpu[new_gpu_index],
+ imped_pixmap->gpu[new_gpu_index]);
+ }
+ /* for composite probably need to migrate all pixmaps attached as window
+ storage */
+}
diff --git a/drv/impedscrn.c b/drv/impedscrn.c
index 168e972b6..043ed9166 100644
--- a/drv/impedscrn.c
+++ b/drv/impedscrn.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include "windowstr.h"
-#include "windowstr.h"
#include "servermd.h"
#include "drv_imped.h"
@@ -79,6 +78,10 @@ impedCreateScreenResources(ScreenPtr pScreen)
Bool ret;
int i;
+ list_init(&imped_screen->gc_list_head);
+ list_init(&imped_screen->pixmap_list_head);
+ list_init(&imped_screen->picture_list_head);
+
ret = miCreateScreenResources(pScreen);
if (!ret)
return ret;
@@ -337,10 +340,12 @@ impedCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
pPixmap->usage_hint = usage_hint;
-
{
impedPixmapPrivPtr imped_pixmap = impedGetPixmap(pPixmap);
int i;
+
+ list_add(&imped_pixmap->member, &imped_screen->pixmap_list_head);
+ imped_pixmap->parent = pPixmap;
imped_pixmap->shattered = FALSE;
for (i = 0; i < imped_screen->num_gpu; i++) {
imped_pixmap->gpu[i] = imped_screen->gpu[i]->CreatePixmap(imped_screen->gpu[i], width, height, depth, usage_hint, pPixmap);
@@ -362,6 +367,7 @@ impedDestroyPixmap(PixmapPtr pPixmap)
imped_screen = impedGetScreen(pPixmap->drawable.pScreen);
for (i = 0; i < imped_screen->num_gpu; i++)
imped_screen->gpu[i]->DestroyPixmap(imped_pixmap->gpu[i]);
+ list_del(&imped_pixmap->member);
FreePixmap(pPixmap);
return TRUE;
}