diff options
author | Dave Airlie <airlied@redhat.com> | 2011-08-16 14:39:07 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-08-16 14:39:07 +0100 |
commit | 33e1a2110552fcc00333f57533fdd27356f55624 (patch) | |
tree | e1936574719406d4ff3a597cd07dde6283b124fb | |
parent | cfc66e76815f193355b1fa003768309b7b65cbaa (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.am | 3 | ||||
-rw-r--r-- | drv/drv_imped.h | 25 | ||||
-rw-r--r-- | drv/impedgc.c | 15 | ||||
-rw-r--r-- | drv/impedpict.c | 33 | ||||
-rw-r--r-- | drv/impedplug.c | 79 | ||||
-rw-r--r-- | drv/impedscrn.c | 10 |
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; } |