int BindSwapBarrierSGIX(DrawablePtr pDraw, int barrier) { /* FIXME: Check for errors when pDraw->type != DRAWABLE_WINDOW */ if (barrier < 0 || barrier > GLX_MAX_SWAP_BARRIERS) return BadValue; if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDraw; dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin); SwapGroupPtr pSwapGroup = pWinPriv->swapGroup; SwapGroupPtr pCur; if (!pSwapGroup) return BadDrawable; if (barrier && pSwapGroup->barrier) return BadValue; /* Update the swap barrier list */ if (barrier) { if (!BindSwapGroupToBarrier(barrier, pSwapGroup)) return BadAlloc; } else { if (!UnbindSwapGroupFromBarrier(pSwapGroup->barrier, pSwapGroup)) return BadDrawable; } /* Set the barrier for each member of this swap group */ for (pCur = pSwapGroup; pCur; pCur = pCur->pNext) pCur->barrier = barrier; } return Success; }
static void SGWindowUnmapped(WindowPtr pWin) { dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin); SwapGroupPtr pSwap = pWinPriv->swapGroup; /* Now that one of the windows in the swap group has been unmapped, * see if the entire swap group/barrier is ready to swap */ if (pSwap->barrier && SwapBarrierIsReadyToSwap(pSwap->barrier)) { SwapSwapBarrier(pSwap->barrier); } else if (!pSwap->barrier && SwapGroupIsReadyToSwap(pSwap)) { SwapSwapGroup(pSwap); } }
/** Create a picture on the appropriate screen. This is the actual * function that creates the picture. However, if the associated * window has not yet been created due to lazy window creation, then * delay the picture creation until the window is mapped. */ static Picture dmxDoCreatePicture(PicturePtr pPicture) { DrawablePtr pDraw = pPicture->pDrawable; ScreenPtr pScreen = pDraw->pScreen; DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; XRenderPictFormat *pFormat; Drawable draw; if (pPicture->pDrawable->type == DRAWABLE_WINDOW) { dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV((WindowPtr) (pDraw)); if (!(draw = pWinPriv->window)) { /* Window has not been created yet due to the window * optimization. Delay picture creation until window is * mapped. */ pWinPriv->hasPict = TRUE; return 0; } } else { dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV((PixmapPtr) (pDraw)); if (!(draw = pPixPriv->pixmap)) { /* FIXME: Zero width/height pixmap?? */ return 0; } } /* This should not be reached if the back-end display has been * detached because the pWinPriv->window or the pPixPriv->pixmap * will be NULL; however, we add it here for completeness */ if (!dmxScreen->beDisplay) return 0; pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat); return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0); }
int SGSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag, DrawablePtr pDraw) { WindowPtr pWin = (WindowPtr)pDraw; dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin); SwapGroupPtr pSwap = pWinPriv->swapGroup; SwapGroupPtr pCur; for (pCur = pSwap; pCur && pCur->pWin != pWin; pCur = pCur->pNext); if (!pCur) return BadDrawable; pCur->clState = cl; pCur->drawable = drawId; pCur->tag = tag; /* We are now in the process of swapping */ pCur->swapping = TRUE; if (pSwap->barrier && SwapBarrierIsReadyToSwap(pSwap->barrier)) { /* The swap group is bound to a barrier and the barrier is ready * to swap, so swap all the swap groups that are bound to this * group's swap barrier */ SwapSwapBarrier(pSwap->barrier); } else if (!pSwap->barrier && SwapGroupIsReadyToSwap(pSwap)) { /* Do the swap if the entire swap group is ready to swap and the * group is not bound to a swap barrier */ SwapSwapGroup(pSwap); } else { /* The swap group/barrier is not yet ready to swap, so put * client to sleep until the rest are ready to swap */ ClientSleep(cl->client, SGSwapCleanup, (pointer)pWin); pCur->sleeping = TRUE; } return Success; }
int JoinSwapGroupSGIX(DrawablePtr pDraw, DrawablePtr pMember) { if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDraw; dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin); SwapGroupPtr pOldSwap = NULL; SwapGroupPtr pEntry; /* If pDraw and pMember are already members of the same swap * group, just return Success since there is nothing to do */ for (pEntry = pWinPriv->swapGroup; pEntry; pEntry = pEntry->pNext) if (pEntry->pWin == (WindowPtr)pMember) return Success; /* Remove pDraw from its current swap group */ if (pWinPriv->swapGroup) { SwapGroupPtr pSwapGroup = pWinPriv->swapGroup; SwapGroupPtr pPrev; /* Find old swap entry in swap group and save in pOldSwap * for later use */ for (pOldSwap = pWinPriv->swapGroup, pPrev = NULL; pOldSwap && pOldSwap->pWin != pWin; pPrev = pOldSwap, pOldSwap = pOldSwap->pNext); if (!pOldSwap) return BadDrawable; /* Remove pDraw's swap group entry from swap group list */ if (pPrev) { pPrev->pNext = pOldSwap->pNext; } else { /* pWin is at the head of the swap group list, so we * need to update all other members of this swap * group */ for (pEntry = pOldSwap->pNext; pEntry; pEntry = pEntry->pNext) DMX_GET_WINDOW_PRIV(pEntry->pWin)->swapGroup = pOldSwap->pNext; /* Update the barrier list as well */ if (pOldSwap->barrier) UpdateSwapBarrierList(pOldSwap->barrier, pOldSwap, pOldSwap->pNext); /* Set pSwapGroup to point to the swap group without * pOldSwap */ pSwapGroup = pOldSwap->pNext; } /* Check to see if current swap group can now swap since we * know at this point that pDraw and pMember are guaranteed * to previously be in different swap groups */ if (pSwapGroup && SwapGroupIsReadyToSwap(pSwapGroup)) { SwapSwapGroup(pSwapGroup); } /* Make the old swap entry a standalone group */ pOldSwap->pNext = NULL; pOldSwap->barrier = 0; /* Reset pWin's swap group */ pWinPriv->swapGroup = NULL; pWinPriv->windowDestroyed = NULL; pWinPriv->windowUnmapped = NULL; } if (!pMember || pMember->type != DRAWABLE_WINDOW) { /* Free old swap group since it is no longer needed */ if (pOldSwap) FreeSwapEntry(pOldSwap); } else if (pDraw == pMember && pOldSwap) { /* Special case where pDraw was previously created and we * are now just putting it to its own swap group */ pWinPriv->swapGroup = pOldSwap; pWinPriv->windowDestroyed = SGWindowDestroyed; pWinPriv->windowUnmapped = SGWindowUnmapped; /* Check to see if pDraw is ready to swap */ if (SwapGroupIsReadyToSwap(pOldSwap)) SwapSwapGroup(pOldSwap); } else if (pMember->type == DRAWABLE_WINDOW) { WindowPtr pMemberWin = (WindowPtr)pMember; dmxWinPrivPtr pMemberPriv = DMX_GET_WINDOW_PRIV(pMemberWin); SwapGroupPtr pMemberSwapGroup = pMemberPriv->swapGroup; /* Finally, how we can add pDraw to pMember's swap group */ /* If pMember is not currently in a swap group, then create * one for it since we are just about to add pDraw to it. */ if (!pMemberSwapGroup) { /* Create new swap group */ pMemberSwapGroup = CreateSwapEntry(pMemberWin); if (!pMemberSwapGroup) { if (pOldSwap) FreeSwapEntry(pOldSwap); return BadAlloc; } /* Set pMember's swap group */ pMemberPriv->swapGroup = pMemberSwapGroup; pMemberPriv->windowDestroyed = SGWindowDestroyed; pMemberPriv->windowUnmapped = SGWindowUnmapped; } /* If pDraw == pMember, that means pDraw was not a member of * a group previously (or it would have been handled by the * special case above), so no additional work is required * since we just created a new swap group for pMember (i.e., * pDraw). */ if (pDraw != pMember) { /* If pDraw was not previously in a swap group, then create * an entry for it */ if (!pOldSwap) { /* Create new swap group */ pOldSwap = CreateSwapEntry(pWin); if (!pOldSwap) { /* If we just created a swap group for pMember, we * need to free it here */ if (pMemberSwapGroup->pNext == NULL) { FreeSwapEntry(pMemberSwapGroup); pMemberPriv->swapGroup = NULL; } return BadAlloc; } } /* Find last entry in pMember's swap group */ for (pEntry = pMemberSwapGroup; pEntry->pNext; pEntry = pEntry->pNext); /* Add pDraw's swap group entry to pMember's swap group list */ pEntry->pNext = pOldSwap; /* Add pDraw to pMember's swap barrier */ pOldSwap->barrier = pEntry->barrier; /* Set pDraw's swap group */ pWinPriv->swapGroup = pMemberSwapGroup; pWinPriv->windowDestroyed = SGWindowDestroyed; pWinPriv->windowUnmapped = SGWindowUnmapped; } } } return Success; }