summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-06-27 13:52:23 +0100
committerDave Airlie <airlied@redhat.com>2012-06-28 13:41:54 +0100
commit406b3925402017f2582ba8406511c40db4e15df2 (patch)
tree479fcdd458e42261f12bfb3e8129aa870246bd5f
parent70db5ac12131e89a234a6678ca9b26e684f4338f (diff)
add initial migration
-rw-r--r--dix/impedance.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/dix/impedance.c b/dix/impedance.c
index add8e89b5..0008268dd 100644
--- a/dix/impedance.c
+++ b/dix/impedance.c
@@ -1243,3 +1243,149 @@ impedRandR12Init(ScreenPtr pScreen)
return TRUE;
}
#endif
+
+static Bool
+dup_pixmap_contents(PixmapPtr pDst, PixmapPtr pSrc)
+{
+ char *image_ptr;
+ int size;
+ GCPtr pGC;
+
+ size = PixmapBytePad(pSrc->drawable.width, pSrc->drawable.depth) * pSrc->drawable.height;
+ image_ptr = malloc(size);
+
+ pSrc->drawable.pScreen->GetImage(&pSrc->drawable, 0, 0, pSrc->drawable.width,
+ pSrc->drawable.height, ZPixmap, ~0,
+ image_ptr);
+
+ pGC = GetScratchGC(pSrc->drawable.depth, pDst->drawable.pScreen);
+ pGC->stateChanges &= ~GCTile;
+
+ ValidateGC(&pDst->drawable, pGC);
+
+ pGC->ops->PutImage(&pDst->drawable, pGC, pDst->drawable.depth, 0, 0,
+ pSrc->drawable.width, pSrc->drawable.height, 0,
+ ZPixmap, image_ptr);
+
+ FreeScratchGC(pGC);
+ free(image_ptr);
+ return TRUE;
+}
+
+static void dup_pixmap(PixmapPtr pPixmap, ScreenPtr new, int new_gpu_idx)
+{
+ pPixmap->gpu[new_gpu_idx] = new->CreatePixmap(new, pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ pPixmap->drawable.depth,
+ pPixmap->usage_hint);
+
+ dup_pixmap_contents(pPixmap->gpu[new_gpu_idx], pPixmap->gpu[0]);
+}
+
+int
+impedAddScreen(ScreenPtr protocol_master, ScreenPtr new)
+{
+ int new_gpu_index;
+ int ret;
+
+ AttachGPU(protocol_master, new);
+
+ new_gpu_index = protocol_master->num_gpu - 1;
+ ErrorF("hot adding GPU %d\n", new_gpu_index);
+
+ {
+ GCPtr pGC;
+ xorg_list_for_each_entry(pGC, &protocol_master->gc_list, member) {
+ pGC->gpu[new_gpu_index] = NewGCObject(new, pGC->depth);
+ ret = new->CreateGC(pGC->gpu[new_gpu_index]);
+ if (ret == FALSE)
+ ErrorF("failed to create GC\n");
+ }
+ }
+
+ {
+ PixmapPtr pPixmap;
+ xorg_list_for_each_entry(pPixmap, &protocol_master->pixmap_list, member) {
+ dup_pixmap(pPixmap, new, new_gpu_index);
+ }
+ }
+
+ {
+ PicturePtr pPicture;
+ xorg_list_for_each_entry(pPicture, &protocol_master->picture_list, member) {
+ impedPictureDuplicate(pPicture, new_gpu_index);
+ }
+ }
+
+ /* set the screen pixmap up correctly */
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = protocol_master->GetScreenPixmap(protocol_master);
+
+ protocol_master->gpu[new_gpu_index]->SetScreenPixmap(pPixmap->gpu[new_gpu_index]);
+ }
+
+ return 0;
+}
+
+Bool
+impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave)
+{
+ int remove_index = -1;
+ int i;
+
+ for (i = 0; i < protocol_master->num_gpu; i++) {
+ if (protocol_master->gpu[i] == slave){
+ remove_index = i;
+ break;
+ }
+ }
+
+ if (remove_index == -1)
+ return FALSE;
+
+ ErrorF("ot removing GPU %d\n", remove_index);
+
+ {
+ PicturePtr pPicture;
+ xorg_list_for_each_entry(pPicture, &protocol_master->picture_list, member) {
+ PicturePtr tofree = pPicture->gpu[remove_index];
+ pPicture->gpu[remove_index] = NULL;
+ for (i = remove_index ; i < protocol_master->num_gpu - 1; i++)
+ pPicture->gpu[i] = pPicture->gpu[i + 1];
+ FreePicture(tofree, (XID)0);
+ }
+ }
+ {
+ GCPtr pGC;
+ xorg_list_for_each_entry(pGC, &protocol_master->gc_list, member) {
+ GCPtr tofree = pGC->gpu[remove_index];
+ pGC->serialNumber = NEXT_SERIAL_NUMBER;
+ pGC->gpu[remove_index] = NULL;
+ for (i = remove_index ; i < protocol_master->num_gpu - 1; i++)
+ pGC->gpu[i] = pGC->gpu[i + 1];
+ FreeGC(tofree, 0);
+ }
+ }
+
+ {
+ PixmapPtr pPixmap;
+ xorg_list_for_each_entry(pPixmap, &protocol_master->pixmap_list, member) {
+ PixmapPtr tofree = pPixmap->gpu[remove_index];
+ pPixmap->gpu[remove_index] = NULL;
+ for (i = remove_index ; i < protocol_master->num_gpu - 1; i++)
+ pPixmap->gpu[i] = pPixmap->gpu[i + 1];
+ (*slave->DestroyPixmap)(tofree);
+ }
+ }
+
+ protocol_master->gpu[remove_index] = NULL;
+ for (i = remove_index; i < protocol_master->num_gpu - 1; i++)
+ protocol_master->gpu[i] = protocol_master->gpu[i + 1];
+
+ protocol_master->num_gpu--;
+
+ return TRUE;
+}
+