diff options
author | Dave Airlie <airlied@redhat.com> | 2012-05-11 16:29:56 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-11 16:29:56 +0100 |
commit | 78040dba52351651f02412b4db9418e7fcf66311 (patch) | |
tree | 7177af7240d569c5d478c9b9eb7fd9aae8ef23bc | |
parent | 4362804f9cc745078aa916e3c79cab4cd8c01f27 (diff) |
WIP RANDR checkpointdrvmodelv3
nouveau can now scanout on intel frontbuffer again
-rw-r--r-- | drv/imped.h | 12 | ||||
-rw-r--r-- | drv/imped_gc.c | 12 | ||||
-rw-r--r-- | drv/imped_plug.c | 13 | ||||
-rw-r--r-- | drv/imped_scrn.c | 77 | ||||
-rw-r--r-- | hw/xfree86/common/xf86.h | 5 | ||||
-rw-r--r-- | hw/xfree86/common/xf86AutoConfig.c | 2 | ||||
-rw-r--r-- | hw/xfree86/common/xf86DrvHelper.c | 24 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.h | 4 | ||||
-rw-r--r-- | hw/xfree86/dri2/imped_dri2.c | 102 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.h | 5 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86RandR12.c | 52 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Rotate.c | 7 | ||||
-rw-r--r-- | include/pixmapstr.h | 2 | ||||
-rw-r--r-- | miext/damage/damage.c | 10 | ||||
-rw-r--r-- | randr/randr.c | 3 | ||||
-rw-r--r-- | randr/randrstr.h | 7 | ||||
-rw-r--r-- | randr/rrcrtc.c | 182 | ||||
-rw-r--r-- | randr/rrinfo.c | 3 | ||||
-rw-r--r-- | randr/rrscreen.c | 214 |
19 files changed, 598 insertions, 138 deletions
diff --git a/drv/imped.h b/drv/imped.h index 1f8873c6f..36ebaeefd 100644 --- a/drv/imped.h +++ b/drv/imped.h @@ -1,6 +1,7 @@ #ifndef IMPED_H #define IMPED_H +#include "randrstr.h" #include "picturestr.h" extern _X_EXPORT Bool impedSetupScreen(ScreenPtr pScreen); @@ -27,6 +28,8 @@ impedCreateGC(GCPtr pGC); extern _X_EXPORT void impedAttachUnboundScreen(ScreenPtr pScreen, ScreenPtr new); +extern _X_EXPORT void +impedDetachUnboundScreen(ScreenPtr pScreen, ScreenPtr slave); extern _X_EXPORT void impedAttachScreen(ScreenPtr pScreen, ScreenPtr slave); @@ -44,9 +47,6 @@ extern _X_EXPORT void impedDetachOffloadSlave(ScreenPtr pScreen, ScreenPtr slave); extern _X_EXPORT void -impedDetachAllSlaves(ScreenPtr pScreen); - -extern _X_EXPORT void impedMigrateOutputSlaves(ScreenPtr pOldMaster, ScreenPtr pNewMaster); extern _X_EXPORT void @@ -101,4 +101,10 @@ impedAddScreen(ScreenPtr protocol_master, ScreenPtr new); extern _X_EXPORT Bool impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave); + +extern _X_EXPORT Bool +impedRandR12Init(ScreenPtr pScreen); + +Bool impedCheckPixmapBounding(ScreenPtr pScreen, + RRCrtcPtr rr_crtc, int x, int y, int w, int h); #endif diff --git a/drv/imped_gc.c b/drv/imped_gc.c index 797dcdd8b..c7f34b874 100644 --- a/drv/imped_gc.c +++ b/drv/imped_gc.c @@ -68,12 +68,18 @@ impedValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) miComputeCompositeClip (pGC, pDrawable); } + if (pGC->pCompositeClip) + ErrorF("clip %d %d %d %d\n", + pGC->pCompositeClip->extents.x1, + pGC->pCompositeClip->extents.y1, + pGC->pCompositeClip->extents.x2, + pGC->pCompositeClip->extents.y2); /* have to translate the composite clip before syncing it */ #ifdef COMPOSITE if (pDrawable->type == DRAWABLE_WINDOW) { - x_off = -pPixmap->screen_x; - y_off = -pPixmap->screen_y; - RegionTranslate(pGC->pCompositeClip, x_off, y_off); + x_off = -pPixmap->screen_x; + y_off = -pPixmap->screen_y; + RegionTranslate(pGC->pCompositeClip, x_off, y_off); } #endif for (i = 0; i < pGC->pScreen->num_gpu; i++) { diff --git a/drv/imped_plug.c b/drv/imped_plug.c index 938b3d91b..c44360952 100644 --- a/drv/imped_plug.c +++ b/drv/imped_plug.c @@ -94,6 +94,15 @@ impedAddScreen(ScreenPtr protocol_master, ScreenPtr new) } } + /* 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; } @@ -119,6 +128,7 @@ impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave) 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); @@ -129,6 +139,7 @@ impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave) 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); @@ -139,12 +150,14 @@ impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave) 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); } } + xorg_list_del(&slave->gpu_screen_head); 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]; diff --git a/drv/imped_scrn.c b/drv/imped_scrn.c index 1fe16be25..83082ace3 100644 --- a/drv/imped_scrn.c +++ b/drv/imped_scrn.c @@ -274,7 +274,7 @@ impedDestroyPixmap(PixmapPtr pPixmap) ScreenPtr pScreen = pPixmap->drawable.pScreen; if (--pPixmap->refcnt) return TRUE; - + xorg_list_del(&pPixmap->member); for (i = 0; i < pScreen->num_gpu; i++) { pScreen->gpu[i]->DestroyPixmap(pPixmap->gpu[i]); @@ -293,6 +293,20 @@ static void impedBlockHandler(ScreenPtr pScreen, pointer blockData, pointer pTimeout, pointer pReadmask) { + int i; + ScreenPtr master, slave; + + for (i = 0; i < pScreen->num_gpu; i++) { + master = pScreen->gpu[i]; + + master->BlockHandler(master, blockData, pTimeout, pReadmask); + xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) { + slave->BlockHandler(slave, blockData, pTimeout, pReadmask); + } + xorg_list_for_each_entry(slave, &master->output_slave_list, output_head) { + slave->BlockHandler(slave, blockData, pTimeout, pReadmask); + } + } } PixmapPtr @@ -404,6 +418,14 @@ impedAttachUnboundScreen(ScreenPtr pScreen, ScreenPtr new) assert(!pScreen->isGPU); assert(new->isGPU); xorg_list_add(&new->unattached_head, &pScreen->unattached_list); + new->protocol_master = pScreen; +} + +void +impedDetachUnboundScreen(ScreenPtr pScreen, ScreenPtr slave) +{ + xorg_list_del(&slave->unattached_head); + slave->protocol_master = NULL; } /* attach a gpu screen to a protocol screen */ @@ -461,24 +483,6 @@ impedDetachOffloadSlave(ScreenPtr master, ScreenPtr slave) } void -impedDetachAllSlaves(ScreenPtr pScreen) -{ - ScreenPtr iter, safe; - - assert(pScreen->isGPU); - - xorg_list_for_each_entry_safe(iter, safe, &pScreen->offload_slave_list, offload_head) { - impedDetachOffloadSlave(pScreen, iter); - } - - - xorg_list_for_each_entry_safe(iter, safe, &pScreen->output_slave_list, output_head) { - impedDetachOutputSlave(pScreen, iter); - } - -} - -void impedMigrateOutputSlaves(ScreenPtr pOldMaster, ScreenPtr pNewMaster) { ScreenPtr iter, safe; @@ -494,3 +498,38 @@ impedMigrateOutputSlaves(ScreenPtr pOldMaster, ScreenPtr pNewMaster) xorg_list_add(&iter->output_head, &pNewMaster->output_slave_list); } } + +static Bool +impedScreenSetSize(ScreenPtr pScreen, + CARD16 width, CARD16 height, + CARD32 mmWidth, CARD32 mmHeight) +{ + PixmapPtr pScrnPix; + + SetRootClip(pScreen, FALSE); + + pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); + pScreen->width = pScrnPix->drawable.width = width; + pScreen->height = pScrnPix->drawable.width = height; + + update_desktop_dimensions(); + + SetRootClip(pScreen, TRUE); + + if (pScreen->root) + RRScreenSizeNotify(pScreen); + return TRUE; +} + +Bool +impedRandR12Init(ScreenPtr pScreen) +{ + rrScrPrivPtr rp; + if (!RRScreenInit(pScreen)) + return FALSE; + + rp = rrGetScrPriv(pScreen); + rp->rrScreenSetSize = impedScreenSetSize; + + return TRUE; +} diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index f326b95ec..6b51ce8bb 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -454,7 +454,12 @@ VidModeExtensionInit(ScreenPtr pScreen); extern _X_EXPORT ScrnInfoPtr xf86ScreenToScrn(ScreenPtr pScreen); /* convert ScrnInfoPtr to ScreenPtr */ extern _X_EXPORT ScreenPtr xf86ScrnToScreen(ScrnInfoPtr pScrn); +extern _X_EXPORT Bool (*drv_dri2_hook)(ScreenPtr); #endif /* _NO_XF86_PROTOTYPES */ +#define XF86_HAS_SCRN_CONV 1 + +#define XF86_SCRN_INTERFACE 1 + #endif /* _XF86_H */ diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 7d75b1c09..4977e27d5 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -278,7 +278,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches) #if !defined(__linux__) && defined(__sparc__) matches[i++] = xnfstrdup("wsfb"); #else - matches[i++] = xnfstrdup("fbdev"); + matches[i++] = xnfstrdup("modesetting"); #endif } #endif /* !sun */ diff --git a/hw/xfree86/common/xf86DrvHelper.c b/hw/xfree86/common/xf86DrvHelper.c index 189f65ba8..1aa44e6e1 100644 --- a/hw/xfree86/common/xf86DrvHelper.c +++ b/hw/xfree86/common/xf86DrvHelper.c @@ -14,6 +14,9 @@ #include "micmap.h" #include "imped.h" #include "xf86Priv.h" +#include "xf86Crtc.h" + +Bool (*drv_dri2_hook)(ScreenPtr); static void xf86FixupRGBOrdering(ScrnInfoPtr scrn, ScreenPtr screen) { @@ -44,7 +47,7 @@ impedHelperScreenInit(ScreenPtr pScreen, int i; Bool allow_slave = FALSE; ScrnInfoPtr master = NULL; - + if (!impedSetupScreen(pScreen)) return FALSE; @@ -63,8 +66,8 @@ retry: if (xf86GPUScreens[i]->numEntities != 1) continue; - if (!xf86IsEntityPrimary(xf86GPUScreens[i]->entityList[0])) - continue; + if (!xf86IsEntityPrimary(xf86GPUScreens[i]->entityList[0])) + continue; master = xf86GPUScreens[i]; @@ -126,15 +129,20 @@ retry: return FALSE; } + /* do dri2 init */ + if (xf86LoaderCheckSymbol("DRI2Connect") && drv_dri2_hook) + drv_dri2_hook(pScreen); + pScreen->SaveScreen = impedSaveScreen; xf86DisableRandR(); /* disable old randr extension */ - // impedRandR12Init(pScreen); + + /* need to create a dumb randr 12 to handle protocol stuff */ + impedRandR12Init(pScreen); return TRUE; } -static Bool impedPointerMoved(ScrnInfoPtr pScrn, int x, int y) +static void impedPointerMoved(ScrnInfoPtr pScrn, int x, int y) { - return TRUE; } static void @@ -143,10 +151,10 @@ impedLeaveVT(ScrnInfoPtr pScrn, int flags) } -static void +static Bool impedEnterVT(ScrnInfoPtr pScrn, int flags) { - + return TRUE; } void xf86HelperAddProtoScreens(int screennum) diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index ca8490e4d..edc920003 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -222,10 +222,10 @@ typedef PixmapPtr (*DRI2CreateBufferPixmapProcPtr)(ScreenPtr pScreen, typedef void (*DRI2DestroyBufferPixmapProcPtr)(PixmapPtr pPixmap); typedef void (*DRI2CopyPixmapPtrCB)(PixmapPtr src, PixmapPtr dst, - RegionPtr pRegion, RegionPtr front_clip); + RegionPtr pRegion, int x, int y); typedef void (*DRI2CopyRegionPixmapProcPtr)(PixmapPtr src, PixmapPtr dst, - RegionPtr pRegion, RegionPtr f_c, + RegionPtr pRegion, int x, int y, DRI2CopyPixmapPtrCB cb); typedef int (*DRI2ScheduleSwapPixmapProcPtr) (PixmapPtr pDraw, diff --git a/hw/xfree86/dri2/imped_dri2.c b/hw/xfree86/dri2/imped_dri2.c index fc09e4df4..3d8d8fc81 100644 --- a/hw/xfree86/dri2/imped_dri2.c +++ b/hw/xfree86/dri2/imped_dri2.c @@ -10,9 +10,12 @@ #include "list.h" #include "windowstr.h" +#include "imped.h" #include "dri2.h" #include "dri2_priv.h" +#include "gcstruct.h" +#include "damagestr.h" typedef struct { int refcnt; PixmapPtr pixmap; @@ -35,15 +38,14 @@ GetScreenPrime(ScreenPtr master, int prime_id) return master->gpu[master->primary_gpu_index]; } i = 0; - xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) { + xorg_list_for_each_entry(slave, &master->gpu[master->primary_gpu_index]->offload_slave_list, offload_head) { if (i == (prime_id - 1)) break; i++; } if (!slave) return master->gpu[master->primary_gpu_index]; - /* TODO */ - return master->gpu[master->primary_gpu_index]; + return slave; } @@ -198,9 +200,41 @@ static void imped_dri2_destroy_buffer(DrawablePtr pDraw, imped_dri2_unref_buffer(NULL, buffer); } +static Bool +update_prime_state(DRI2BufferPtr buffer, RegionPtr region, + PixmapPtr mpix) +{ + impedDRI2BufferPrivatePtr private; + ScreenPtr master, slave; + int fd_handle, ret; + PixmapPtr spix; + private = buffer->driverPrivate; + + master = mpix->drawable.pScreen; + ret = master->SharePixmapBacking(mpix, &fd_handle); + + slave = GetScreenPrime(mpix->drawable.pScreen->protocol_master, private->prime_id); + + spix = slave->CreatePixmap(slave, 0, 0, (buffer->format != 0) ? buffer->format : mpix->drawable.depth, CREATE_PIXMAP_USAGE_SHARED); + + slave->ModifyPixmapHeader(spix, mpix->drawable.width, mpix->drawable.height, + (buffer->format != 0) ? buffer->format : mpix->drawable.depth, + 0, mpix->devKind, NULL); + + ret = slave->SetSharedPixmapBacking(spix, fd_handle); + if (ret == FALSE) { + ErrorF("failed to slave pixmap\n"); + return FALSE; + } + + private->pixmap = spix; + /* share pixmap + import pixmap */ + return TRUE; +} + static void imped_dri2_copy_region_callback(PixmapPtr src, PixmapPtr dst, - RegionPtr pRegion, RegionPtr front_clip) + RegionPtr pRegion, int x, int y) { miCopyProc copy; int nbox; @@ -216,26 +250,41 @@ imped_dri2_copy_region_callback(PixmapPtr src, PixmapPtr dst, ValidateGC(&dst->drawable, gc); nbox = RegionNumRects(pRegion); pbox = RegionRects(pRegion); - copy(&src->drawable, &dst->drawable, gc, pbox, nbox, 0, 0, 0, 0, 0, NULL); + copy(&src->drawable, &dst->drawable, gc, pbox, nbox, -x, -y, 0, 0, 0, NULL); FreeScratchGC(gc); } static void imped_copy_region(PixmapPtr pixmap, RegionPtr pRegion, - DRI2BufferPtr dst_buffer, DRI2BufferPtr src_buffer) + DRI2BufferPtr dst_buffer, DRI2BufferPtr src_buffer, int x, int y) { impedDRI2BufferPrivatePtr src_private = src_buffer->driverPrivate; impedDRI2BufferPrivatePtr dst_private = dst_buffer->driverPrivate; PixmapPtr src, dst; - + int ret; ScreenPtr pScreen = pixmap->drawable.pScreen; DRI2ScreenPtr gpu_ds = DRI2GetScreen(pScreen); src = src_private->pixmap; dst = dst_private->pixmap; - gpu_ds->CopyRegionPixmap(src, dst, pRegion, NULL, imped_dri2_copy_region_callback); + if (src_private->attachment == DRI2BufferFrontLeft) { + if (!src || src->drawable.pScreen != pixmap->drawable.pScreen) { + ErrorF("copying prime in reverse %p\n", src); + return; + } + } else if (dst_private->attachment == DRI2BufferFrontLeft) { + if (!dst || dst->drawable.pScreen != pixmap->drawable.pScreen) { + ret = update_prime_state(dst_buffer, NULL, pixmap); + if (ret == FALSE) + return; + dst = dst_private->pixmap; + } + gpu_ds = DRI2GetScreen(dst->drawable.pScreen); + } + + gpu_ds->CopyRegionPixmap(src, dst, pRegion, x, y, imped_dri2_copy_region_callback); } static void imped_dri2_copy_region(DrawablePtr pDraw, @@ -247,15 +296,48 @@ static void imped_dri2_copy_region(DrawablePtr pDraw, PixmapPtr pPixmap = GetDrawablePixmap(pDraw); PixmapPtr src; PixmapPtr dst; + GCPtr gc; + RegionPtr pCopyClip; + int x, y; + int scr_x, scr_y; + + impedGetDrawableDeltas(pDraw, pPixmap, &x, &y); + impedGetCompositeDeltas(pDraw, pPixmap, &scr_x, &scr_y); + gc = GetScratchGC(pDraw->depth, pDraw->pScreen); + pCopyClip = RegionCreate(NULL, 0); + RegionCopy(pCopyClip, pRegion); + (*gc->funcs->ChangeClip)(gc, CT_REGION, pCopyClip, 0); + ValidateGC(pDraw, gc); + + ErrorF("draw copy region %d %dx%d vs p %dx%d @ %dx%d, scr %dx%d\n", pDraw->type, pDraw->width, pDraw->height, pPixmap->drawable.width, pPixmap->drawable.height, x, y, scr_x, scr_y); - ErrorF("draw copy region %d %dx%d vs p %dx%d\n", pDraw->type, pDraw->width, pDraw->height, pPixmap->drawable.width, pPixmap->drawable.height); + // RegionTranslate(gc->pCompositeClip, -scr_x, -scr_y); - imped_copy_region(pPixmap->gpu[pDraw->pScreen->primary_gpu_index], pRegion, pDestBuffer, pSrcBuffer); + { + int nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr pbox = RegionRects(gc->pCompositeClip); + int ind; + + for (ind = 0; ind < nbox; ind++) { + ErrorF("%d: %d %d %d %d\n", ind, pbox[ind].x1, pbox[ind].y1, + pbox[ind].x2, pbox[ind].y2); + /* debugging */ + } + } + + DamageRegionAppend(pDraw, gc->pCompositeClip); + + RegionTranslate(gc->pCompositeClip, -scr_x, -scr_y); + imped_copy_region(pPixmap->gpu[pDraw->pScreen->primary_gpu_index], gc->pCompositeClip, pDestBuffer, pSrcBuffer, x, y); + + RegionTranslate(gc->pCompositeClip, scr_x, scr_y); if (pDraw->type == DRAWABLE_WINDOW) { /* translate */ } + DamageRegionProcessPending(pDraw); + FreeScratchGC(gc); } static int imped_dri2_schedule_swap(ClientPtr client, diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index acc579145..3d53f38e4 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -219,6 +219,11 @@ typedef struct _xf86CrtcFuncs { void (*set_origin) (xf86CrtcPtr crtc, int x, int y); + /** + */ + Bool + (*set_slave_pixmap)(xf86CrtcPtr crtc, PixmapPtr pixmap); + } xf86CrtcFuncsRec, *xf86CrtcFuncsPtr; #define XF86_CRTC_VERSION 4 diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 7ab000b97..e62faab4b 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -1758,12 +1758,32 @@ xf86RandR12EnterVT(ScrnInfoPtr pScrn, int flags) return RRGetInfo(pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ } +static void +detach_all_slaves(ScreenPtr pScreen) +{ + ScreenPtr iter, safe; + + assert(pScreen->isGPU); + + xorg_list_for_each_entry_safe(iter, safe, &pScreen->offload_slave_list, offload_head) { + impedDetachOffloadSlave(pScreen, iter); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), 0); + } + + xorg_list_for_each_entry_safe(iter, safe, &pScreen->output_slave_list, output_head) { + impedDetachOutputSlave(pScreen, iter); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), 0); + } + +} + static Bool xf86RandR12ProviderSetRole(ScreenPtr pScreen, RRProviderPtr provider, uint32_t new_role) { ScreenPtr protocol_master; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); if (!pScreen->isGPU) return FALSE; @@ -1777,7 +1797,7 @@ xf86RandR12ProviderSetRole(ScreenPtr pScreen, pNewMaster = pScreen; impedMigrateOutputSlaves(pOldMaster, pNewMaster); - impedDetachAllSlaves(pOldMaster); + detach_all_slaves(pOldMaster); impedAddScreen(protocol_master, pNewMaster); impedRemoveScreen(protocol_master, pOldMaster); @@ -1787,31 +1807,51 @@ xf86RandR12ProviderSetRole(ScreenPtr pScreen, if (pOldMaster->roles & RR_Role_Slave_Output) { impedAttachOutputSlave(pNewMaster, pOldMaster, 0); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), RR_Role_Slave_Output); } - if (pOldMaster->roles & RR_Role_Slave_Offload) + if (pOldMaster->roles & RR_Role_Slave_Offload) { impedAttachOffloadSlave(pNewMaster, pOldMaster, 0); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), RR_Role_Slave_Offload); + } } if (new_role == RR_Role_Slave_Output) { + if (provider->current_role == 0) + impedDetachUnboundScreen(protocol_master, pScreen); impedAttachOutputSlave(protocol_master->gpu[0], pScreen, 0); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), RR_Role_Slave_Output); } if (!new_role) { - if (provider->current_role == RR_Role_Slave_Output) + if (provider->current_role == RR_Role_Slave_Output) { impedDetachOutputSlave(protocol_master->gpu[0], pScreen); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), 0); + } - if (provider->current_role == RR_Role_Slave_Offload) + if (provider->current_role == RR_Role_Slave_Offload) { impedDetachOffloadSlave(protocol_master->gpu[0], pScreen); + xf86SetCurrentRole(xf86ScreenToScrn(pScreen), 0); + } + impedAttachUnboundScreen(protocol_master, pScreen); } - // RRTellChanged(protocol_master); + RRTellChanged(protocol_master); SetRootClip(protocol_master, TRUE); return TRUE; } static Bool +xf86CrtcSetSlavePixmap(RRCrtcPtr randr_crtc, PixmapPtr pixmap) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + if (!crtc->funcs->set_slave_pixmap) + return FALSE; + return crtc->funcs->set_slave_pixmap(crtc, pixmap); +} + +static Bool xf86RandR12Init12(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); @@ -1835,6 +1875,7 @@ xf86RandR12Init12(ScreenPtr pScreen) rp->rrSetConfig = NULL; rp->rrProviderSetRole = xf86RandR12ProviderSetRole; + rp->rrCrtcSlavePixmap = xf86CrtcSetSlavePixmap; pScrn->PointerMoved = xf86RandR12PointerMoved; pScrn->ChangeGamma = xf86RandR12ChangeGamma; @@ -1862,3 +1903,4 @@ xf86RandR12PreInit(ScrnInfoPtr pScrn) { return TRUE; } + diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index 1f09ce563..d295c27c7 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -339,9 +339,12 @@ xf86CrtcFitsScreen(xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb) /* When called before PreInit, the driver is * presumably doing load detect */ - if (pScrn->virtualX == 0 || pScrn->virtualY == 0) + if (pScrn->is_gpu) { return TRUE; - + } + else if (pScrn->virtualX == 0 || pScrn->virtualY == 0) + return TRUE; + b.x1 = 0; b.y1 = 0; b.x2 = crtc->mode.HDisplay; diff --git a/include/pixmapstr.h b/include/pixmapstr.h index 2b2cd0914..a1a49c12f 100644 --- a/include/pixmapstr.h +++ b/include/pixmapstr.h @@ -84,6 +84,8 @@ typedef struct _Pixmap { struct xorg_list member; PixmapPtr gpu[MAXGPU]; Bool shattered; + + PixmapPtr master_pixmap; } PixmapRec; static inline void diff --git a/miext/damage/damage.c b/miext/damage/damage.c index 85b54fc56..d12acf0ec 100644 --- a/miext/damage/damage.c +++ b/miext/damage/damage.c @@ -58,7 +58,7 @@ (a)->y2 == (b)->y2) #define DAMAGE_VALIDATE_ENABLE 0 -#define DAMAGE_DEBUG_ENABLE 0 +#define DAMAGE_DEBUG_ENABLE 1 #if DAMAGE_DEBUG_ENABLE #define DAMAGE_DEBUG(x) ErrorF x #else @@ -263,9 +263,16 @@ damageRegionAppend(DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, */ pDamageRegion = pRegion; + DAMAGE_DEBUG(("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n", + where, + pDamageRegion->extents.x2 - pDamageRegion->extents.x1, + pDamageRegion->extents.y2 - pDamageRegion->extents.y1, + pDamageRegion->extents.x1, pDamageRegion->extents.y1, + pDrawable->id, pDamage->pDrawable->id)); if (clip || pDamage->pDrawable != pDrawable) { pDamageRegion = &clippedRec; if (pDamage->pDrawable->type == DRAWABLE_WINDOW) { + ErrorF("clipping against border clip\n"); RegionIntersect(pDamageRegion, pRegion, &((WindowPtr) (pDamage->pDrawable))-> borderClip); @@ -280,6 +287,7 @@ damageRegionAppend(DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, RegionInit(&pixClip, &box, 1); RegionIntersect(pDamageRegion, pRegion, &pixClip); RegionUninit(&pixClip); + ErrorF("clipping against pixmap clip\n"); } /* * Short circuit empty results diff --git a/randr/randr.c b/randr/randr.c index b43a58788..46258e6a2 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -93,7 +93,8 @@ RRCloseScreen(ScreenPtr pScreen) RRCrtcDestroy(pScrPriv->crtcs[j]); for (j = pScrPriv->numOutputs - 1; j >= 0; j--) RROutputDestroy(pScrPriv->outputs[j]); - RRProviderDestroy(pScrPriv->provider); + if (pScrPriv->provider) + RRProviderDestroy(pScrPriv->provider); free(pScrPriv->crtcs); free(pScrPriv->outputs); diff --git a/randr/randrstr.h b/randr/randrstr.h index b224c94b0..356fa1da3 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -127,6 +127,8 @@ struct _rrCrtc { PictTransform transform; struct pict_f_transform f_transform; struct pict_f_transform f_inverse; + + PixmapPtr slave_pixmap; /* may need to go in xf86 */ }; struct _rrOutput { @@ -238,6 +240,8 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, #endif +typedef Bool (*RRCrtcSetSlavePixmapProcPtr)(RRCrtcPtr crtc, PixmapPtr pixmap); + typedef struct _rrScrPriv { /* * 'public' part of the structure; DDXen fill this in @@ -261,6 +265,9 @@ typedef struct _rrScrPriv { RRGetPanningProcPtr rrGetPanning; RRSetPanningProcPtr rrSetPanning; #endif + /* TODO #if RANDR_15_INTERFACE */ + RRCrtcSetSlavePixmapProcPtr rrCrtcSlavePixmap; + RRProviderSetRoleProcPtr rrProviderSetRole; /* diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 36caa5822..b5af260f8 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -24,7 +24,7 @@ #include "randrstr.h" #include "swaprep.h" #include "mipointer.h" - +#include "imped.h" RESTYPE RRCrtcType; /* @@ -367,6 +367,161 @@ RRComputeContiguity(ScreenPtr pScreen) pScrPriv->discontiguous = discontiguous; } + +static Bool +impedCreateSharedPixmap(RRCrtcPtr crtc, int width, int height, + int x, int y) +{ + PixmapPtr mpix, spix; + ScreenPtr master = crtc->pScreen->output_master; + int fd_handle = -1; + Bool ret; + int depth; + PixmapPtr mscreenpix; + PixmapPtr protopix = crtc->pScreen->protocol_master->GetScreenPixmap(crtc->pScreen->protocol_master); + rrScrPriv(crtc->pScreen); + + /* create a pixmap on the master screen, + then get a shared handle for it + create a shared pixmap on the slave screen using the handle + + set the master screen to do dirty updates to the shared pixmap + from the screen pixmap. + set slave screen to scanout shared linear pixmap + */ + + mscreenpix = master->GetScreenPixmap(master); + depth = protopix->drawable.depth; + + if (width == 0 && height == 0) { + ret = pScrPriv->rrCrtcSlavePixmap(crtc, NULL); + if (crtc->slave_pixmap) { + master->StopPixmapTracking(mscreenpix, crtc->slave_pixmap->master_pixmap); + master->DestroyPixmap(crtc->slave_pixmap->master_pixmap); + crtc->pScreen->DestroyPixmap(crtc->slave_pixmap); + } + crtc->slave_pixmap = NULL; + return TRUE; + } + + if (crtc->slave_pixmap) + master->StopPixmapTracking(mscreenpix, crtc->slave_pixmap->master_pixmap); + + mpix = master->CreatePixmap(master, width, height, depth, + CREATE_PIXMAP_USAGE_SHARED); + if (!mpix) + return FALSE; + + ret = master->SharePixmapBacking(mpix, &fd_handle); + if (ret == FALSE) { + master->DestroyPixmap(mpix); + return FALSE; + } + + spix = crtc->pScreen->CreatePixmap(crtc->pScreen, 0, 0, depth, + CREATE_PIXMAP_USAGE_SHARED); + crtc->pScreen->ModifyPixmapHeader(spix, width, height, depth, 0, + mpix->devKind, NULL); + + ret = crtc->pScreen->SetSharedPixmapBacking(spix, fd_handle); + if (ret == FALSE) { + ErrorF("failed to slave pixmap\n"); + crtc->pScreen->DestroyPixmap(spix); + master->DestroyPixmap(mpix); + return FALSE; + } + + spix->master_pixmap = mpix; + ret = pScrPriv->rrCrtcSlavePixmap(crtc, spix); + if (ret == FALSE) { + ErrorF("failed to set shadow slave pixmap\n"); + return FALSE; + } + + crtc->slave_pixmap = spix; + + master->StartPixmapTracking(mpix, mscreenpix, spix, x, y); + return TRUE; +} + +Bool +impedCheckPixmapBounding(ScreenPtr pScreen, + RRCrtcPtr rr_crtc, int x, int y, int w, int h) +{ + RegionRec root_pixmap_region, total_region, new_crtc_region; + int i, c; + BoxRec newbox; + BoxPtr newsize; + ScreenPtr slave; + int new_width, new_height; + PixmapPtr screen_pixmap = pScreen->GetScreenPixmap(pScreen); + PixmapRegionInit(&root_pixmap_region, screen_pixmap); + RegionInit(&total_region, NULL, 0); + + /* have to iterate all the crtcs of the attached gpu masters + and all their output slaves */ + if (pScreen->num_gpu > 1) + ErrorF("TODO shatter\n"); + + for (i = 0; i < pScreen->num_gpu; i++) { + rrScrPriv(pScreen->gpu[i]); + for (c = 0; c < pScrPriv->numCrtcs; c++) { + if (pScrPriv->crtcs[c] == rr_crtc) { + newbox.x1 = x; + newbox.x2 = x + w; + newbox.y1 = y; + newbox.y2 = y + h; + } else { + if (!pScrPriv->crtcs[c]->mode) + continue; + newbox.x1 = pScrPriv->crtcs[c]->x; + newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; + newbox.y1 = pScrPriv->crtcs[c]->y; + newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; + } + RegionInit(&new_crtc_region, &newbox, 1); + RegionUnion(&total_region, &total_region, &new_crtc_region); + } + + xorg_list_for_each_entry(slave, &pScreen->gpu[i]->output_slave_list, output_head) { + rrScrPriv(slave); + for (c = 0; c < pScrPriv->numCrtcs; c++) + if (pScrPriv->crtcs[c] == rr_crtc) { + newbox.x1 = x; + newbox.x2 = x + w; + newbox.y1 = y; + newbox.y2 = y + h; + } + else { + if (!pScrPriv->crtcs[c]->mode) + continue; + newbox.x1 = pScrPriv->crtcs[c]->x; + newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; + newbox.y1 = pScrPriv->crtcs[c]->y; + newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; + } + RegionInit(&new_crtc_region, &newbox, 1); + RegionUnion(&total_region, &total_region, &new_crtc_region); + } + } + newsize = RegionExtents(&total_region); + new_width = newsize->x2 - newsize->x1; + new_height = newsize->y2 - newsize->y1; + + if (new_width == screen_pixmap->drawable.width && + new_height == screen_pixmap->drawable.height) { + ErrorF("adjust shatters %d %d\n", newsize->x1, newsize->x2); + } else { + int ret; + rrScrPriv(pScreen->gpu[0]); + ret = pScrPriv->rrScreenSetSize(pScreen->gpu[0], + new_width, new_height, 0, 0); + } + + /* set shatters TODO */ + return TRUE; +} + /* * Request that the Crtc be reconfigured */ @@ -394,6 +549,27 @@ RRCrtcSet(RRCrtcPtr crtc, ret = TRUE; } else { + if (pScreen->isGPU) { + ScreenPtr protocol_screen = pScreen->protocol_master; + int width = 0, height = 0; + + if (mode) { + width = mode->mode.width; + height = mode->mode.height; + } + ErrorF("have a master to look out for\n"); + ret = impedCheckPixmapBounding(protocol_screen, crtc, + x, y, width, height); + if (!ret) + return FALSE; + + if (pScreen->output_master) { + ret = impedCreateSharedPixmap(crtc, width, height, x, y); + ErrorF("need to create shared pixmap %d", ret); + + } + + } #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, @@ -965,6 +1141,9 @@ ProcRRSetCrtcConfig(ClientPtr client) RRModeGetScanoutSize(mode, &transform, &source_width, &source_height); +#if 0 /*TODO*/ + ErrorF("%d %d %d\n", stuff->x, source_width, pScreen->width); + ErrorF("%d %d %d\n", stuff->y, source_height, pScreen->height); if (stuff->x + source_width > pScreen->width) { client->errorValue = stuff->x; free(outputs); @@ -976,6 +1155,7 @@ ProcRRSetCrtcConfig(ClientPtr client) free(outputs); return BadValue; } +#endif } #endif } diff --git a/randr/rrinfo.c b/randr/rrinfo.c index 114ec3471..31a83c424 100644 --- a/randr/rrinfo.c +++ b/randr/rrinfo.c @@ -192,6 +192,9 @@ RRGetInfo(ScreenPtr pScreen, Bool force_query) pScrPriv->changed = FALSE; pScrPriv->configChanged = FALSE; + if (!pScrPriv->rrGetInfo) + return TRUE; + if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) return FALSE; diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 92ea78fc9..e521abb02 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -73,6 +73,9 @@ RRSendConfigNotify(ScreenPtr pScreen) WindowPtr pWin = pScreen->root; xEvent event; + if (!pWin) + return; + event.u.u.type = ConfigureNotify; event.u.configureNotify.window = pWin->drawable.id; event.u.configureNotify.aboveSibling = None; @@ -208,7 +211,16 @@ ProcRRGetScreenSizeRange(ClientPtr client) rep.sequenceNumber = client->sequence; rep.length = 0; - if (pScrPriv) { + if (pScreen->num_gpu) { + rrScrPrivPtr gpupriv = rrGetScrPriv(pScreen->gpu[0]); + if (!RRGetInfo(pScreen->gpu[0], FALSE)) + return BadAlloc; + rep.minWidth = gpupriv->minWidth; + rep.minHeight = gpupriv->minHeight; + rep.maxWidth = gpupriv->maxWidth; + rep.maxHeight = gpupriv->maxHeight; + + } else if (pScrPriv) { if (!RRGetInfo(pScreen, FALSE)) return BadAlloc; rep.minWidth = pScrPriv->minWidth; @@ -232,29 +244,18 @@ ProcRRGetScreenSizeRange(ClientPtr client) return Success; } -int -ProcRRSetScreenSize(ClientPtr client) +static int rr_check_single_size(ClientPtr client, + rrScrPrivPtr pScrPriv, int width, int height) { - REQUEST(xRRSetScreenSizeReq); - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - int i, rc; - - REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) { - client->errorValue = stuff->width; + int i; + if (width < pScrPriv->minWidth || pScrPriv->maxWidth < width) { + ErrorF("pScrPriv w/h %d %d\n", pScrPriv->minWidth, pScrPriv->maxWidth); + client->errorValue = width; return BadValue; } - if (stuff->height < pScrPriv->minHeight || - pScrPriv->maxHeight < stuff->height) { - client->errorValue = stuff->height; + if (height < pScrPriv->minHeight || + pScrPriv->maxHeight < height) { + client->errorValue = height; return BadValue; } for (i = 0; i < pScrPriv->numCrtcs; i++) { @@ -271,11 +272,51 @@ ProcRRSetScreenSize(ClientPtr client) source_height = mode->mode.width; } - if (crtc->x + source_width > stuff->width || - crtc->y + source_height > stuff->height) + if (crtc->x + source_width > width || + crtc->y + source_height > height) return BadMatch; } } + return Success; +} +static int rrCheckMultiScreenSize(ClientPtr client, + ScreenPtr pScreen, int width, int height) +{ + rrScrPrivPtr pScrPriv, gpupriv; + ScreenPtr gpuscreen; + int ret; + pScrPriv = rrGetScrPriv(pScreen); + + gpuscreen = pScreen->gpu[0]; + gpupriv = rrGetScrPriv(gpuscreen); + + ret = rr_check_single_size(client, gpupriv, width, height); + return ret; +} + +int +ProcRRSetScreenSize(ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int i, rc; + int ret; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (pScreen->num_gpu) + ret = rrCheckMultiScreenSize(client, pScreen, stuff->width, stuff->height); + else + ret = rr_check_single_size(client, pScrPriv, stuff->width, stuff->height); + if (ret) + return ret; if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) { client->errorValue = 0; return BadValue; @@ -289,6 +330,65 @@ ProcRRSetScreenSize(ClientPtr client) return Success; } +#define update_totals(gpuscreen, pScrPriv) do { \ + total_crtcs += pScrPriv->numCrtcs; \ + total_outputs += pScrPriv->numOutputs; \ + modes = RRModesForScreen(gpuscreen, &num_modes); \ + if (!modes) \ + return BadAlloc; \ + for (j = 0; j < num_modes; j++) \ + total_name_len += modes[j]->mode.nameLength; \ + total_modes += num_modes; \ + free(modes); \ +} while(0) + +static inline void swap_modeinfos(xRRModeInfo *modeinfos, int i) +{ + swapl(&modeinfos[i].id); + swaps(&modeinfos[i].width); + swaps(&modeinfos[i].height); + swapl(&modeinfos[i].dotClock); + swaps(&modeinfos[i].hSyncStart); + swaps(&modeinfos[i].hSyncEnd); + swaps(&modeinfos[i].hTotal); + swaps(&modeinfos[i].hSkew); + swaps(&modeinfos[i].vSyncStart); + swaps(&modeinfos[i].vSyncEnd); + swaps(&modeinfos[i].vTotal); + swaps(&modeinfos[i].nameLength); + swapl(&modeinfos[i].modeFlags); +} + +#define update_arrays(gpuscreen, pScrPriv) do { \ + for (j = 0; j < pScrPriv->numCrtcs; j++) { \ + crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \ + if (client->swapped) \ + swapl(&crtcs[crtc_count]); \ + crtc_count++; \ + } \ + for (j = 0; j < pScrPriv->numOutputs; j++) { \ + outputs[output_count] = pScrPriv->outputs[j]->id; \ + if (client->swapped) \ + swapl(&outputs[output_count]); \ + output_count++; \ + } \ + { \ + RRModePtr mode; \ + modes = RRModesForScreen(gpuscreen, &num_modes); \ + for (j = 0; j < num_modes; j++) { \ + mode = modes[j]; \ + modeinfos[mode_count] = mode->mode; \ + if (client->swapped) { \ + swap_modeinfos(modeinfos, i); \ + } \ + memcpy(names, mode->name, mode->mode.nameLength); \ + names += mode->mode.nameLength; \ + mode_count++; \ + } \ + free(modes); \ + } \ + } while (0) + static int rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) { @@ -319,32 +419,16 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) pScrPriv = rrGetScrPriv(gpuscreen); - total_crtcs += pScrPriv->numCrtcs; - total_outputs += pScrPriv->numOutputs; + if (query && pScrPriv) + if (!RRGetInfo(gpuscreen, query)) + return BadAlloc; - /* maybe add a mode count fn */ - modes = RRModesForScreen(gpuscreen, &num_modes); - if (!modes) - return BadAlloc; - - for (j = 0; j < num_modes; j++) - total_name_len += modes[j]->mode.nameLength; - total_modes += num_modes; - free(modes); + update_totals(gpuscreen, pScrPriv); xorg_list_for_each_entry(iter, &gpuscreen->output_slave_list, output_head) { pScrPriv = rrGetScrPriv(iter); - total_crtcs += pScrPriv->numCrtcs; - total_outputs += pScrPriv->numOutputs; - - modes = RRModesForScreen(gpuscreen, &num_modes); - if (!modes) - return BadAlloc; - for (j = 0; j < num_modes; j++) - total_name_len += modes[j]->mode.nameLength; - total_modes += num_modes; - free(modes); + update_totals(iter, pScrPriv); } } @@ -389,46 +473,12 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) gpuscreen = pScreen->gpu[i]; pScrPriv = rrGetScrPriv(gpuscreen); - for (j = 0; j < pScrPriv->numCrtcs; j++) { - crtcs[crtc_count] = pScrPriv->crtcs[j]->id; - if (client->swapped) - swapl(&crtcs[crtc_count]); - crtc_count++; - } + update_arrays(gpuscreen, pScrPriv); - for (j = 0; j < pScrPriv->numOutputs; j++) { - outputs[output_count] = pScrPriv->outputs[j]->id; - if (client->swapped) - swapl(&outputs[output_count]); - output_count++; - } + xorg_list_for_each_entry(iter, &gpuscreen->output_slave_list, output_head) { + pScrPriv = rrGetScrPriv(iter); - { - RRModePtr mode; - modes = RRModesForScreen(gpuscreen, &num_modes); - for (j = 0; j < num_modes; j++) { - mode = modes[j]; - modeinfos[mode_count] = mode->mode; - if (client->swapped) { - swapl(&modeinfos[i].id); - swaps(&modeinfos[i].width); - swaps(&modeinfos[i].height); - swapl(&modeinfos[i].dotClock); - swaps(&modeinfos[i].hSyncStart); - swaps(&modeinfos[i].hSyncEnd); - swaps(&modeinfos[i].hTotal); - swaps(&modeinfos[i].hSkew); - swaps(&modeinfos[i].vSyncStart); - swaps(&modeinfos[i].vSyncEnd); - swaps(&modeinfos[i].vTotal); - swaps(&modeinfos[i].nameLength); - swapl(&modeinfos[i].modeFlags); - } - memcpy(names, mode->name, mode->mode.nameLength); - names += mode->mode.nameLength; - mode_count++; - } - free(modes); + update_arrays(iter, pScrPriv); } } |