void xglAddCurrentBitDamage (DrawablePtr pDrawable) { XGL_DRAWABLE_PIXMAP_PRIV (pDrawable); if (REGION_NOTEMPTY (pDrawable->pScreen, &pPixmapPriv->bitRegion)) { BoxPtr pBitExt; pBitExt = REGION_EXTENTS (pDrawable->pScreen, &pPixmapPriv->bitRegion); if (pPixmapPriv->damageBox.x1 < pBitExt->x2 && pPixmapPriv->damageBox.y1 < pBitExt->y2 && pPixmapPriv->damageBox.x2 > pBitExt->x1 && pPixmapPriv->damageBox.y2 > pBitExt->y1) { REGION_UNINIT (pDrawable->pScreen, &pPixmapPriv->bitRegion); REGION_INIT (pDrawable->pScreen, &pPixmapPriv->bitRegion, NullBox, 0); pPixmapPriv->allBits = FALSE; } } pPixmapPriv->damageBox = miEmptyBox; }
static void VMWARECopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWin->drawable.pScreen; VMWAREPtr pVMWARE = VMWAREPTR(infoFromScreen(pWin->drawable.pScreen)); BoxPtr pBB; Bool hidden = FALSE; /* * We only worry about the source region here, since shadowfb will * take care of the destination region. */ pBB = REGION_EXTENTS(pWin->drawable.pScreen, prgnSrc); VmwareLog(("VMWARECopyWindow(%p, (%d, %d), (%d, %d - %d, %d)\n", pWin, ptOldOrg.x, ptOldOrg.y, pBB->x1, pBB->y1, pBB->x2, pBB->y2)); if (BOX_INTERSECT(*pBB, pVMWARE->hwcur.box)) { PRE_OP_HIDE_CURSOR(); hidden = TRUE; } pScreen->CopyWindow = pVMWARE->ScrnFuncs.CopyWindow; (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); pScreen->CopyWindow = VMWARECopyWindow; if (hidden) { POST_OP_SHOW_CURSOR(); } }
Bool fbGlyphIn (RegionPtr pRegion, int x, int y, int width, int height) { BoxRec box; BoxPtr pExtents = REGION_EXTENTS (dummyScreen, pRegion); /* * Check extents by hand to avoid 16 bit overflows */ if (x < (int) pExtents->x1) return FALSE; if ((int) pExtents->x2 < x + width) return FALSE; if (y < (int) pExtents->y1) return FALSE; if ((int) pExtents->y2 < y + height) return FALSE; box.x1 = x; box.x2 = x + width; box.y1 = y; box.y2 = y + height; return RECT_IN_REGION (dummyScreen, pRegion, &box) == rgnIN; }
void xglAddBitDamage (DrawablePtr pDrawable, RegionPtr pRegion) { XGL_DRAWABLE_PIXMAP_PRIV (pDrawable); if (REGION_NOTEMPTY (pDrawable->pScreen, &pPixmapPriv->bitRegion)) { BoxPtr pBox; BoxPtr pExt, pBitExt; int nBox; pBox = REGION_RECTS (pRegion); pExt = REGION_EXTENTS (pDrawable->pScreen, pRegion); nBox = REGION_NUM_RECTS (pRegion); pBitExt = REGION_EXTENTS (pDrawable->pScreen, &pPixmapPriv->bitRegion); if (pExt->x1 < pBitExt->x2 && pExt->y1 < pBitExt->y2 && pExt->x2 > pBitExt->x1 && pExt->y2 > pBitExt->y1) { while (nBox--) { if (pBox->x1 < pBitExt->x2 && pBox->y1 < pBitExt->y2 && pBox->x2 > pBitExt->x1 && pBox->y2 > pBitExt->y1) { REGION_UNINIT (pDrawable->pScreen, &pPixmapPriv->bitRegion); REGION_INIT (pDrawable->pScreen, &pPixmapPriv->bitRegion, NullBox, 0); pPixmapPriv->allBits = FALSE; return; } pBox++; } } } }
int ProcXFixesFetchRegion (ClientPtr client) { RegionPtr pRegion; xXFixesFetchRegionReply *reply; xRectangle *pRect; BoxPtr pExtent; BoxPtr pBox; int i, nBox; REQUEST(xXFixesFetchRegionReq); REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); pExtent = REGION_EXTENTS (0, pRegion); pBox = REGION_RECTS (pRegion); nBox = REGION_NUM_RECTS (pRegion); reply = xalloc (sizeof (xXFixesFetchRegionReply) + nBox * sizeof (xRectangle)); if (!reply) return BadAlloc; reply->type = X_Reply; reply->sequenceNumber = client->sequence; reply->length = nBox << 1; reply->x = pExtent->x1; reply->y = pExtent->y1; reply->width = pExtent->x2 - pExtent->x1; reply->height = pExtent->y2 - pExtent->y1; pRect = (xRectangle *) (reply + 1); for (i = 0; i < nBox; i++) { pRect[i].x = pBox[i].x1; pRect[i].y = pBox[i].y1; pRect[i].width = pBox[i].x2 - pBox[i].x1; pRect[i].height = pBox[i].y2 - pBox[i].y1; } if (client->swapped) { int n; swaps (&reply->sequenceNumber, n); swapl (&reply->length, n); swaps (&reply->x, n); swaps (&reply->y, n); swaps (&reply->width, n); swaps (&reply->height, n); SwapShorts ((INT16 *) pRect, nBox * 4); } (void) WriteToClient(client, sizeof (xXFixesFetchRegionReply) + nBox * sizeof (xRectangle), (char *) reply); xfree (reply); return (client->noClientException); }
static Bool localQueryLargestOffscreenLinear( ScreenPtr pScreen, int *size, int gran, int priority ) { FBManagerPtr offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; FBLinearLinkPtr pLink; FBLinearLinkPtr pLinkRet; *size = 0; if (!offman->LinearAreas) return FALSE; pLink = offman->LinearAreas; pLinkRet = pLink; if (!pLink->area) { while (pLink) { if (pLink->free) { if (pLink->linear.size > pLinkRet->linear.size) pLinkRet = pLink; } pLink = pLink->next; } if (pLinkRet->free) { *size = pLinkRet->linear.size; return TRUE; } } else { int w, h; if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran, FAVOR_WIDTH_THEN_AREA, priority)) { FBManagerPtr offman; BoxPtr extents; offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); if((extents->x2 - extents->x1) == w) *size = w * h; return TRUE; } } return FALSE; }
RegionPtr XFixesRegionCopy (RegionPtr pRegion) { RegionPtr pNew = REGION_CREATE (0, REGION_EXTENTS(0, pRegion), REGION_NUM_RECTS(pRegion)); if (!pNew) return 0; if (!REGION_COPY (0, pNew, pRegion)) { REGION_DESTROY (0, pNew); return 0; } return pNew; }
int ProcXFixesRegionExtents (ClientPtr client) { RegionPtr pSource, pDestination; REQUEST(xXFixesRegionExtentsReq); REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); REGION_RESET (0, pDestination, REGION_EXTENTS (0, pSource)); return (client->noClientException); }
static Bool localResizeOffscreenLinear(FBLinearPtr resize, int length) { FBManagerPtr offman; FBLinearLinkPtr pLink; ScreenPtr pScreen = resize->pScreen; offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; pLink = offman->LinearAreas; if(!pLink) return FALSE; while(&(pLink->linear) != resize) { pLink = pLink->next; if(!pLink) return FALSE; } /* This could actually be alot smarter and try to move allocations from XY to linear when available. For now if it was XY, we keep it XY */ if(pLink->area) { /* really an XY area */ BoxPtr extents; int pitch, w, h; extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); pitch = extents->x2 - extents->x1; if(length < pitch) { /* special case */ w = length; h = 1; } else { w = pitch; h = (length + pitch - 1) / pitch; } if(localResizeOffscreenArea(pLink->area, w, h)) { resize->size = h * w; resize->offset = (pitch * pLink->area->box.y1) + pLink->area->box.x1; return TRUE; } } else { /* TODO!!!! resize the linear area */ } return FALSE; }
Bool xglFillGlyph (DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nGlyph, CharInfoPtr *ppci, pointer pglyphBase) { BoxPtr pExtent; xglGeometryRec geometry; if (nGlyph < 1) return TRUE; pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip); x += pDrawable->x; y += pDrawable->y; GEOMETRY_INIT (pDrawable->pScreen, &geometry, GLITZ_GEOMETRY_TYPE_BITMAP, GEOMETRY_USAGE_SYSMEM, 0); GEOMETRY_FOR_GLYPH (pDrawable->pScreen, &geometry, nGlyph, ppci, pglyphBase); GEOMETRY_TRANSLATE (&geometry, x, y); if (xglFill (pDrawable, pGC, &geometry, pExtent->x1, pExtent->y1, pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1, REGION_RECTS (pGC->pCompositeClip), REGION_NUM_RECTS (pGC->pCompositeClip))) { GEOMETRY_UNINIT (&geometry); xglAddCurrentBitDamage (pDrawable); return TRUE; } GEOMETRY_UNINIT (&geometry); return FALSE; }
void xglSaveAreas (PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; BoxRec box; XGL_SCREEN_PRIV (pScreen); XGL_PIXMAP_PRIV (pPixmap); box = *(REGION_EXTENTS (pScreen, prgnSave)); pPixmapPriv->damageBox = box; if (xglCopy (&pWin->drawable, &pPixmap->drawable, xorg, yorg, REGION_RECTS (prgnSave), REGION_NUM_RECTS (prgnSave))) { xglAddCurrentBitDamage (&pPixmap->drawable); return; } box.x1 += xorg; box.y1 += yorg; box.x2 += xorg; box.y2 += yorg; if (!xglSyncBits (&pWin->drawable, &box)) FatalError (XGL_SW_FAILURE_STRING); XGL_BSTORE_FALLBACK_PROLOGUE (&pPixmap->drawable, BackingStoreFuncs.SaveAreas); (*pScreen->BackingStoreFuncs.SaveAreas) (pPixmap, prgnSave, xorg, yorg, pWin); XGL_BSTORE_FALLBACK_EPILOGUE (&pPixmap->drawable, BackingStoreFuncs.SaveAreas, xglSaveAreas); }
FBAreaPtr xf86AllocateLinearOffscreenArea ( ScreenPtr pScreen, int length, int gran, MoveAreaCallbackProcPtr moveCB, RemoveAreaCallbackProcPtr removeCB, pointer privData ){ FBManagerFuncsPtr funcs; FBManagerPtr offman; BoxPtr extents; int w, h; if(xf86FBMangerIndex < 0) return NULL; if(!(funcs = (FBManagerFuncsPtr)pScreen->devPrivates[xf86FBMangerIndex].ptr)) return NULL; offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); w = extents->x2 - extents->x1; if (gran > 1) { if (gran > w) return NULL; if (w % gran) length += gran - 1; } if(length <= w) { /* special case */ h = 1; w = length; } else { h = (length + w - 1) / w; } return (*funcs->AllocateOffscreenArea)( pScreen, w, h, gran, moveCB, removeCB, privData); }
static void DamageExtReport (DamagePtr pDamage, RegionPtr pRegion, void *closure) { DamageExtPtr pDamageExt = closure; switch (pDamageExt->level) { case DamageReportRawRegion: case DamageReportDeltaRegion: DamageExtNotify (pDamageExt, REGION_RECTS(pRegion), REGION_NUM_RECTS(pRegion)); break; case DamageReportBoundingBox: DamageExtNotify (pDamageExt, REGION_EXTENTS(prScreen, pRegion), 1); break; case DamageReportNonEmpty: DamageExtNotify (pDamageExt, NullBox, 0); break; case DamageReportNone: break; } }
void xglRestoreAreas (PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; BoxPtr pExt; BoxRec box; XGL_SCREEN_PRIV (pScreen); if (xglCopy (&pPixmap->drawable, &pWin->drawable, -xorg, -yorg, REGION_RECTS (prgnRestore), REGION_NUM_RECTS (prgnRestore))) { xglAddCurrentBitDamage (&pPixmap->drawable); return; } pExt = REGION_EXTENTS (pScreen, prgnRestore); box.x1 = pExt->x1 - xorg; box.y1 = pExt->y1 - yorg; box.x2 = pExt->x2 - xorg; box.y2 = pExt->y2 - yorg; if (!xglSyncBits (&pPixmap->drawable, &box)) FatalError (XGL_SW_FAILURE_STRING); XGL_BSTORE_FALLBACK_PROLOGUE (&pWin->drawable, BackingStoreFuncs.RestoreAreas); (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgnRestore, xorg, yorg, pWin); XGL_BSTORE_FALLBACK_EPILOGUE (&pWin->drawable, BackingStoreFuncs.RestoreAreas, xglRestoreAreas); }
static void exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv (pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); ExaPixmapPriv (pPixmap); BoxPtr pextent, pbox; int nbox; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1; int partX1, partX2; int off_x, off_y; if (pExaScr->fallback_counter || pExaScr->swappedOut || pGC->fillStyle != FillSolid || pExaPixmap->accel_blocked) { ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); return; } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = NULL; exaDoMigration (pixmaps, 1, TRUE); } if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); return; } pextent = REGION_EXTENTS(pGC->pScreen, pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (n--) { fullX1 = ppt->x; fullY1 = ppt->y; fullX2 = fullX1 + (int) *pwidth; ppt++; pwidth++; if (fullY1 < extentY1 || extentY2 <= fullY1) continue; if (fullX1 < extentX1) fullX1 = extentX1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullX1 >= fullX2) continue; nbox = REGION_NUM_RECTS (pClip); if (nbox == 1) { (*pExaScr->info->Solid) (pPixmap, fullX1 + off_x, fullY1 + off_y, fullX2 + off_x, fullY1 + 1 + off_y); } else { pbox = REGION_RECTS(pClip); while(nbox--) { if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; if (partX2 > partX1) { (*pExaScr->info->Solid) (pPixmap, partX1 + off_x, fullY1 + off_y, partX2 + off_x, fullY1 + 1 + off_y); } } pbox++; } } } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pScreen); }
static void winShadowUpdateDD (ScreenPtr pScreen, shadowBufPtr pBuf) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RegionPtr damage = shadowDamage(pBuf); HRESULT ddrval = DD_OK; RECT rcDest, rcSrc; POINT ptOrigin; DWORD dwBox = REGION_NUM_RECTS (damage); BoxPtr pBox = REGION_RECTS (damage); HRGN hrgnTemp = NULL, hrgnCombined = NULL; /* * Return immediately if the app is not active * and we are fullscreen, or if we have a bad display depth */ if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) || pScreenPriv->fBadDepth) return; /* Get the origin of the window in the screen coords */ ptOrigin.x = pScreenInfo->dwXOffset; ptOrigin.y = pScreenInfo->dwYOffset; MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&ptOrigin, 1); /* Unlock the shadow surface, so we can blit */ ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDD - Unlock failed\n"); return; } /* * Handle small regions with multiple blits, * handle large regions by creating a clipping region and * doing a single blit constrained to that clipping region. */ if (pScreenInfo->dwClipUpdatesNBoxes == 0 || dwBox < pScreenInfo->dwClipUpdatesNBoxes) { /* Loop through all boxes in the damaged region */ while (dwBox--) { /* Assign damage box to source rectangle */ rcSrc.left = pBox->x1; rcSrc.top = pBox->y1; rcSrc.right = pBox->x2; rcSrc.bottom = pBox->y2; /* Calculate destination rectange */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Blit the damaged areas */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); /* Get a pointer to the next box */ ++pBox; } } else { BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); /* Compute a GDI region from the damaged region */ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); dwBox--; pBox++; while (dwBox--) { hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); DeleteObject (hrgnTemp); pBox++; } /* Install the GDI region as a clipping region */ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); DeleteObject (hrgnCombined); hrgnCombined = NULL; /* Calculating a bounding box for the source is easy */ rcSrc.left = pBoxExtents->x1; rcSrc.top = pBoxExtents->y1; rcSrc.right = pBoxExtents->x2; rcSrc.bottom = pBoxExtents->y2; /* Calculating a bounding box for the destination is trickier */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Our Blt should be clipped to the invalidated region */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); /* Reset the clip region */ SelectClipRgn (pScreenPriv->hdcScreen, NULL); } /* Relock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDD - Lock failed\n"); return; } /* Has our memory pointer changed? */ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) { ErrorF ("winShadowUpdateDD - Memory location of the shadow " "surface has changed, trying to update the root window " "pixmap header to point to the new address. If you get " "this message and "PROJECT_NAME" freezes or crashes " "after this message then send a problem report and your " "%s file to " BUILDERADDR, g_pszLogFile); /* Location of shadow framebuffer has changed */ pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface; /* Update the screen pixmap */ if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate, pScreen->width, pScreen->height, pScreen->rootDepth, BitsPerPixel (pScreen->rootDepth), PixmapBytePad (pScreenInfo->dwStride, pScreenInfo->dwBPP), pScreenInfo->pfb)) { ErrorF ("winShadowUpdateDD - Bits changed, could not " "notify fb.\n"); return; } } }
Bool xglSyncBits (DrawablePtr pDrawable, BoxPtr pExtents) { RegionRec region; BoxRec box; XGL_DRAWABLE_PIXMAP (pDrawable); XGL_PIXMAP_PRIV (pPixmap); if (pPixmapPriv->allBits) return xglMapPixmapBits (pPixmap); if (pPixmapPriv->target == xglPixmapTargetIn && pExtents) { box.x1 = 0; box.y1 = 0; box.x2 = pPixmap->drawable.width; box.y2 = pPixmap->drawable.height; if (pExtents->x1 > box.x1) box.x1 = pExtents->x1; if (pExtents->y1 > box.y1) box.y1 = pExtents->y1; if (pExtents->x2 < box.x2) box.x2 = pExtents->x2; if (pExtents->y2 < box.y2) box.y2 = pExtents->y2; if (box.x2 <= box.x1 || box.y2 <= box.y1) return xglMapPixmapBits (pPixmap); if (REGION_NOTEMPTY (pDrawable->pScreen, &pPixmapPriv->bitRegion)) { switch (RECT_IN_REGION (pDrawable->pScreen, &pPixmapPriv->bitRegion, &box)) { case rgnIN: REGION_INIT (pDrawable->pScreen, ®ion, NullBox, 0); break; case rgnOUT: REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_UNION (pDrawable->pScreen, &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion, ®ion); break; case rgnPART: REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_SUBTRACT (pDrawable->pScreen, ®ion, ®ion, &pPixmapPriv->bitRegion); REGION_UNION (pDrawable->pScreen, &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion, ®ion); break; } } else { REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_SUBTRACT (pDrawable->pScreen, &pPixmapPriv->bitRegion, ®ion, &pPixmapPriv->bitRegion); } if (REGION_NUM_RECTS (&pPixmapPriv->bitRegion) == 1) { BoxPtr pBox; pBox = REGION_RECTS (&pPixmapPriv->bitRegion); if (pBox->x1 <= 0 && pBox->y1 <= 0 && pBox->x2 >= pPixmap->drawable.width && pBox->y2 >= pPixmap->drawable.height) pPixmapPriv->allBits = TRUE; } } else { box.x1 = 0; box.y1 = 0; box.x2 = pPixmap->drawable.width; box.y2 = pPixmap->drawable.height; REGION_INIT (pDrawable->pScreen, ®ion, &box, 1); REGION_SUBTRACT (pDrawable->pScreen, ®ion, ®ion, &pPixmapPriv->bitRegion); pPixmapPriv->allBits = TRUE; } if (!pPixmapPriv->buffer) if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT)) return FALSE; if (REGION_NOTEMPTY (pDrawable->pScreen, ®ion) && pPixmapPriv->surface) { glitz_pixel_format_t format; BoxPtr pBox; BoxPtr pExt; int nBox; if (!xglSyncSurface (pDrawable)) FatalError (XGL_SW_FAILURE_STRING); xglUnmapPixmapBits (pPixmap); pBox = REGION_RECTS (®ion); nBox = REGION_NUM_RECTS (®ion); pExt = REGION_EXTENTS (pDrawable->pScreen, ®ion); format.fourcc = GLITZ_FOURCC_RGB; format.masks = pPixmapPriv->pVisual->pPixel->masks; format.xoffset = pExt->x1; if (pPixmapPriv->stride < 0) { format.skip_lines = pPixmap->drawable.height - pExt->y2; format.bytes_per_line = -pPixmapPriv->stride; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; } else { format.skip_lines = pExt->y1; format.bytes_per_line = pPixmapPriv->stride; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; } glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, (glitz_box_t *) pBox, nBox); glitz_get_pixels (pPixmapPriv->surface, pExt->x1, pExt->y1, pExt->x2 - pExt->x1, pExt->y2 - pExt->y1, &format, pPixmapPriv->buffer); glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, NULL, 0); } REGION_UNINIT (pDrawable->pScreen, ®ion); if (pPixmapPriv->allBits) { box.x1 = 0; box.y1 = 0; box.x2 = pPixmap->drawable.width; box.y2 = pPixmap->drawable.height; REGION_UNINIT (pDrawable->pScreen, &pPixmapPriv->bitRegion); REGION_INIT (pDrawable->pScreen, &pPixmapPriv->bitRegion, &box, 1); } return xglMapPixmapBits (pPixmap); }
Bool xglCompositeGeneral (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, xglGeometryPtr pGeometry, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr pScreen = pDst->pDrawable->pScreen; INT16 xOff, yOff; glitz_surface_t *src, *mask = NULL, *dst; int dstXoff, dstYoff; RegionRec region; BoxPtr pBox, pExt; int nBox; if (pDst->alphaMap) return FALSE; if (op >= NUM_XGL_OPERATORS) return FALSE; if (pSrc->pDrawable) { if (pSrc->pDrawable->type != DRAWABLE_PIXMAP) return FALSE; if (pSrc->pDrawable->bitsPerPixel == 1) return FALSE; } if (pMask) { if (pMask->pDrawable) { if (pMask->pDrawable->type != DRAWABLE_PIXMAP) return FALSE; if (pSrc->pDrawable == pMask->pDrawable && pSrc != pMask) return FALSE; } } if (!xglPrepareTarget (pDst->pDrawable)) return FALSE; if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return TRUE; pBox = REGION_RECTS (®ion); nBox = REGION_NUM_RECTS (®ion); pExt = REGION_EXTENTS (pScreen, ®ion); XGL_GET_DRAWABLE (pDst->pDrawable, dst, dstXoff, dstYoff); if (!xglSyncPicture (pScreen, pSrc, pExt->x1 + xSrc - xDst, pExt->y1 + ySrc - yDst, pExt->x2 - pExt->x1, pExt->y2 - pExt->y1, &xOff, &yOff)) { REGION_UNINIT (pScreen, ®ion); return FALSE; } xSrc -= xOff; ySrc -= yOff; XGL_GET_SOURCE_PICTURE (pSrc, src); if (pMask) { /* bitmap as mask */ if (pMask->pDrawable && pMask->pDrawable->bitsPerPixel == 1) { if (pGeometry) { REGION_UNINIT (pScreen, ®ion); return FALSE; } pGeometry = xglPixmapToGeometry ((PixmapPtr) pMask->pDrawable, xDst - xMask, yDst - yMask); if (!pGeometry) { REGION_UNINIT (pScreen, ®ion); return FALSE; } } else { if (!xglSyncPicture (pScreen, pMask, pExt->x1 + xMask - xDst, pExt->y1 + yMask - yDst, pExt->x2 - pExt->x1, pExt->y2 - pExt->y1, &xOff, &yOff)) { REGION_UNINIT (pScreen, ®ion); return FALSE; } xMask -= xOff; yMask -= yOff; XGL_GET_SOURCE_PICTURE (pMask, mask); } } if (!pGeometry) { if (!pSrc->transform && pSrc->filter != PictFilterConvolution) { if (pSrc->pDrawable && pSrc->repeat == RepeatNormal) { XGL_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable); /* tile */ if (!pPixmapPriv->acceleratedTile) { pGeometry = xglTiledBoxGeometry ((PixmapPtr) pSrc->pDrawable, xSrc - xDst, ySrc - yDst, pBox, nBox); if (!pGeometry) { REGION_UNINIT (pScreen, ®ion); return FALSE; } pBox = pExt; nBox = 1; } } else { /* copy */ if (op == PictOpSrc && !mask) { if (xglCopy (pSrc->pDrawable, pDst->pDrawable, xSrc - xDst, ySrc - yDst, pBox, nBox)) { REGION_UNINIT (pScreen, ®ion); return TRUE; } } } } if (nBox > 1) { pGeometry = xglGetScratchVertexGeometry (pScreen, 4 * nBox); GEOMETRY_ADD_BOX (pScreen, pGeometry, pBox, nBox); pBox = pExt; } xSrc += pBox->x1 - xDst; ySrc += pBox->y1 - yDst; if (pMask) { xMask += pBox->x1 - xDst; yMask += pBox->y1 - yDst; } xDst = pBox->x1; yDst = pBox->y1; width = pBox->x2 - pBox->x1; height = pBox->y2 - pBox->y1; } else { glitz_surface_set_clip_region (dst, dstXoff, dstYoff, (glitz_box_t *) pBox, nBox); } if (pGeometry) { GEOMETRY_TRANSLATE (pGeometry, dstXoff, dstYoff); if (!GEOMETRY_ENABLE (pGeometry, dst)) { REGION_UNINIT (pScreen, ®ion); return FALSE; } } else GEOMETRY_DISABLE (dst); glitz_composite (XGL_OPERATOR (op), src, mask, dst, xSrc, ySrc, xMask, yMask, xDst + dstXoff, yDst + dstYoff, width, height); glitz_surface_set_clip_region (dst, 0, 0, NULL, 0); REGION_UNINIT (pScreen, ®ion); if (glitz_surface_get_status (dst)) return FALSE; return TRUE; }
void winShadowUpdateGDI (ScreenPtr pScreen, shadowBufPtr pBuf) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RegionPtr damage = &pBuf->damage; DWORD dwBox = REGION_NUM_RECTS (damage); BoxPtr pBox = REGION_RECTS (damage); int x, y, w, h; HRGN hrgnTemp = NULL, hrgnCombined = NULL; #if WIN_UPDATE_STATS static DWORD s_dwNonUnitRegions = 0; static DWORD s_dwTotalUpdates = 0; static DWORD s_dwTotalBoxes = 0; #endif /* * Return immediately if we have a bad display depth. */ if (pScreenPriv->fBadDepth) return; #if WIN_UPDATE_STATS ++s_dwTotalUpdates; s_dwTotalBoxes += dwBox; if (dwBox != 1) { ++s_dwNonUnitRegions; ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox); } if ((s_dwTotalUpdates % 100) == 0) ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " "nu: %d tu: %d\n", (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, s_dwTotalBoxes / s_dwTotalUpdates, s_dwNonUnitRegions, s_dwTotalUpdates); #endif /* WIN_UPDATE_STATS */ /* * Handle small regions with multiple blits, * handle large regions by creating a clipping region and * doing a single blit constrained to that clipping region. */ if (pScreenInfo->dwClipUpdatesNBoxes == 0 || dwBox < pScreenInfo->dwClipUpdatesNBoxes) { /* Loop through all boxes in the damaged region */ while (dwBox--) { /* * Calculate x offset, y offset, width, and height for * current damage box */ x = pBox->x1; y = pBox->y1; w = pBox->x2 - pBox->x1; h = pBox->y2 - pBox->y1; BitBlt (pScreenPriv->hdcScreen, x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY); /* Get a pointer to the next box */ ++pBox; } } else { BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); /* Compute a GDI region from the damaged region */ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); dwBox--; pBox++; while (dwBox--) { hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); DeleteObject (hrgnTemp); pBox++; } /* Install the GDI region as a clipping region */ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); DeleteObject (hrgnCombined); hrgnCombined = NULL; /* * Blit the shadow buffer to the screen, * constrained to the clipping region. */ BitBlt (pScreenPriv->hdcScreen, pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2 - pBoxExtents->x1, pBoxExtents->y2 - pBoxExtents->y1, pScreenPriv->hdcShadow, pBoxExtents->x1, pBoxExtents->y1, SRCCOPY); /* Reset the clip region */ SelectClipRgn (pScreenPriv->hdcScreen, NULL); } /* Redraw all windows */ if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0); }
Bool miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) { BoxPtr box; WindowPtr pChild, pLast; Bool anyMarked = FALSE; MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; ScreenPtr pScreen; pScreen = pWin->drawable.pScreen; /* single layered systems are easy */ if (ppLayerWin) *ppLayerWin = pWin; if (pWin == pFirst) { /* Blindly mark pWin and all of its inferiors. This is a slight * overkill if there are mapped windows that outside pWin's border, * but it's better than wasting time on RectIn checks. */ pChild = pWin; while (1) { if (pChild->viewable) { if (REGION_BROKEN (pScreen, &pChild->winSize)) SetWinSize (pChild); if (REGION_BROKEN (pScreen, &pChild->borderSize)) SetBorderSize (pChild); (* MarkWindow)(pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } anyMarked = TRUE; pFirst = pFirst->nextSib; } if ( (pChild = pFirst) ) { box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize); pLast = pChild->parent->lastChild; while (1) { if (pChild->viewable) { if (REGION_BROKEN (pScreen, &pChild->winSize)) SetWinSize (pChild); if (REGION_BROKEN (pScreen, &pChild->borderSize)) SetBorderSize (pChild); if (RECT_IN_REGION(pScreen, &pChild->borderSize, box)) { (* MarkWindow)(pChild); anyMarked = TRUE; if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } } while (!pChild->nextSib && (pChild != pLast)) pChild = pChild->parent; if (pChild == pLast) break; pChild = pChild->nextSib; } } if (anyMarked) (* MarkWindow)(pWin->parent); return anyMarked; }
static void kaaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect) { KdScreenPriv (pDrawable->pScreen); KaaScreenPriv (pDrawable->pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap; register BoxPtr pbox; BoxPtr pextent; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1, fullY2; int partX1, partX2, partY1, partY2; int xoff, yoff; int xorg, yorg; int n; if (!pScreenPriv->enabled || pGC->fillStyle != FillSolid || !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(*pKaaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { KdCheckPolyFillRect (pDrawable, pGC, nrect, prect); return; } xorg = pDrawable->x; yorg = pDrawable->y; pextent = REGION_EXTENTS(pGC->pScreen, pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (nrect--) { fullX1 = prect->x + xorg; fullY1 = prect->y + yorg; fullX2 = fullX1 + (int) prect->width; fullY2 = fullY1 + (int) prect->height; prect++; if (fullX1 < extentX1) fullX1 = extentX1; if (fullY1 < extentY1) fullY1 = extentY1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullY2 > extentY2) fullY2 = extentY2; if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) continue; n = REGION_NUM_RECTS (pClip); if (n == 1) { (*pKaaScr->info->Solid) (fullX1 + xoff, fullY1 + yoff, fullX2 + xoff, fullY2 + yoff); } else { pbox = REGION_RECTS(pClip); /* * clip the rectangle to each box in the clip region * this is logically equivalent to calling Intersect() */ while(n--) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partY1 = pbox->y1; if (partY1 < fullY1) partY1 = fullY1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; partY2 = pbox->y2; if (partY2 > fullY2) partY2 = fullY2; pbox++; if (partX1 < partX2 && partY1 < partY2) (*pKaaScr->info->Solid) (partX1 + xoff, partY1 + yoff, partX2 + xoff, partY2 + yoff); } } } (*pKaaScr->info->DoneSolid) (); kaaDrawableDirty (pDrawable); kaaMarkSync (pDrawable->pScreen); }
static void kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { ScreenPtr pScreen = pDrawable->pScreen; KdScreenPriv (pScreen); KaaScreenPriv (pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap; BoxPtr pextent, pbox; int nbox; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1; int partX1, partX2; int off_x, off_y; if (!pScreenPriv->enabled || pGC->fillStyle != FillSolid || !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(*pKaaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); return; } pextent = REGION_EXTENTS(pGC->pScreen, pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (n--) { fullX1 = ppt->x; fullY1 = ppt->y; fullX2 = fullX1 + (int) *pwidth; ppt++; pwidth++; if (fullY1 < extentY1 || extentY2 <= fullY1) continue; if (fullX1 < extentX1) fullX1 = extentX1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullX1 >= fullX2) continue; nbox = REGION_NUM_RECTS (pClip); if (nbox == 1) { (*pKaaScr->info->Solid) (fullX1 + off_x, fullY1 + off_y, fullX2 + off_x, fullY1 + 1 + off_y); } else { pbox = REGION_RECTS(pClip); while(nbox--) { if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; if (partX2 > partX1) (*pKaaScr->info->Solid) (partX1 + off_x, fullY1 + off_y, partX2 + off_x, fullY1 + 1 + off_y); } pbox++; } } } (*pKaaScr->info->DoneSolid) (); kaaDrawableDirty (pDrawable); kaaMarkSync (pDrawable->pScreen); }
void fbFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { RegionPtr pClip = fbGetCompositeClip(pGC); BoxPtr pextent, pbox; int nbox; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1; int partX1, partX2; pextent = REGION_EXTENTS(pGC->pScreen, pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (n--) { fullX1 = ppt->x; fullY1 = ppt->y; fullX2 = fullX1 + (int) *pwidth; ppt++; pwidth++; if (fullY1 < extentY1 || extentY2 <= fullY1) continue; if (fullX1 < extentX1) fullX1 = extentX1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullX1 >= fullX2) continue; nbox = REGION_NUM_RECTS (pClip); if (nbox == 1) { fbFill (pDrawable, pGC, fullX1, fullY1, fullX2-fullX1, 1); } else { pbox = REGION_RECTS(pClip); while(nbox--) { if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; if (partX2 > partX1) { fbFill (pDrawable, pGC, partX1, fullY1, partX2 - partX1, 1); } } pbox++; } } } }
Rect Region::getBounds() const { const BoxRec *boxPtr = REGION_EXTENTS(&m_reg); return Rect(boxPtr->x1, boxPtr->y1, boxPtr->x2, boxPtr->y2); }
void LeoPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, xRectangle *prectInit) { LeoPtr pLeo = LeoGetScreenPrivate (pDrawable->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; xRectangle *prect; RegionPtr prgnClip; register BoxPtr pbox; BoxPtr pextent; int n; int xorg, yorg; /* No garbage please. */ if(nrectFill <= 0) return; prgnClip = cfbGetCompositeClip(pGC); prect = prectInit; xorg = pDrawable->x; yorg = pDrawable->y; if (xorg || yorg) { prect = prectInit; n = nrectFill; while(n--) { prect->x += xorg; prect->y += yorg; prect++; } } prect = prectInit; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; ld0->fg = pGC->fgPixel; if (REGION_NUM_RECTS(prgnClip) == 1) { int x1, y1, x2, y2; int x, y, xx, yy; pextent = REGION_RECTS(prgnClip); x1 = pextent->x1; y1 = pextent->y1; x2 = pextent->x2; y2 = pextent->y2; while (nrectFill--) { x = prect->x; y = prect->y; xx = x + prect->width; yy = y + prect->height; if (x < x1) x = x1; if (y < y1) y = y1; prect++; if (xx > x2) xx = x2; if (yy > y2) yy = y2; if (x >= xx) continue; if (y >= yy) continue; lc0->extent = (xx - x - 1) | ((yy - y - 1) << 11); lc0->fill = x | (y << 11); while (lc0->csr & LEO_CSR_BLT_BUSY); } } else { int x1, y1, x2, y2, bx1, by1, bx2, by2; int x, y, w, h; pextent = REGION_EXTENTS(pGC->pScreen, prgnClip); x1 = pextent->x1; y1 = pextent->y1; x2 = pextent->x2; y2 = pextent->y2; while (nrectFill--) { if ((bx1 = prect->x) < x1) bx1 = x1; if ((by1 = prect->y) < y1) by1 = y1; bx2 = (int) prect->x + (int) prect->width; if (bx2 > x2) bx2 = x2; by2 = (int) prect->y + (int) prect->height; if (by2 > y2) by2 = y2; prect++; if (bx1 >= bx2 || by1 >= by2) continue; n = REGION_NUM_RECTS (prgnClip); pbox = REGION_RECTS(prgnClip); /* clip the rectangle to each box in the clip region this is logically equivalent to calling Intersect() */ while(n--) { x = max(bx1, pbox->x1); y = max(by1, pbox->y1); w = min(bx2, pbox->x2) - x; h = min(by2, pbox->y2) - y; pbox++; /* see if clipping left anything */ if (w > 0 && h > 0) { lc0->extent = (w - 1) | ((h - 1) << 11); lc0->fill = x | (y << 11); while (lc0->csr & LEO_CSR_BLT_BUSY); } } } } if (pGC->alu != GXcopy) ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW; if (pGC->planemask != 0xffffff) ld0->planemask = 0xffffff; }
int XAAGetRectClipBoxes( GCPtr pGC, BoxPtr pboxClippedBase, int nrectFill, xRectangle *prectInit ){ int Right, Bottom; BoxPtr pextent, pboxClipped = pboxClippedBase; xRectangle *prect = prectInit; RegionPtr prgnClip = pGC->pCompositeClip; if (REGION_NUM_RECTS(prgnClip) == 1) { pextent = REGION_RECTS(prgnClip); while (nrectFill--) { pboxClipped->x1 = max(pextent->x1, prect->x); pboxClipped->y1 = max(pextent->y1, prect->y); Right = (int)prect->x + (int)prect->width; pboxClipped->x2 = min(pextent->x2, Right); Bottom = (int)prect->y + (int)prect->height; pboxClipped->y2 = min(pextent->y2, Bottom); prect++; if ((pboxClipped->x1 < pboxClipped->x2) && (pboxClipped->y1 < pboxClipped->y2)) { pboxClipped++; } } } else { pextent = REGION_EXTENTS(pGC->pScreen, prgnClip); while (nrectFill--) { int n; BoxRec box, *pbox; box.x1 = max(pextent->x1, prect->x); box.y1 = max(pextent->y1, prect->y); Right = (int)prect->x + (int)prect->width; box.x2 = min(pextent->x2, Right); Bottom = (int)prect->y + (int)prect->height; box.y2 = min(pextent->y2, Bottom); prect++; if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) continue; n = REGION_NUM_RECTS (prgnClip); pbox = REGION_RECTS(prgnClip); /* clip the rectangle to each box in the clip region this is logically equivalent to calling Intersect() */ while(n--) { pboxClipped->x1 = max(box.x1, pbox->x1); pboxClipped->y1 = max(box.y1, pbox->y1); pboxClipped->x2 = min(box.x2, pbox->x2); pboxClipped->y2 = min(box.y2, pbox->y2); pbox++; /* see if clipping left anything */ if(pboxClipped->x1 < pboxClipped->x2 && pboxClipped->y1 < pboxClipped->y2) { pboxClipped++; } } } } return(pboxClipped - pboxClippedBase); }
static Bool CHIPSClipVideo( BoxPtr dst, INT32 *x1, INT32 *x2, INT32 *y1, INT32 *y2, RegionPtr reg, INT32 width, INT32 height ){ INT32 vscale, hscale, delta; BoxPtr extents = REGION_EXTENTS(DummyScreen, reg); int diff; hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); *x1 <<= 16; *x2 <<= 16; *y1 <<= 16; *y2 <<= 16; diff = extents->x1 - dst->x1; if(diff > 0) { dst->x1 = extents->x1; *x1 += diff * hscale; } diff = dst->x2 - extents->x2; if(diff > 0) { dst->x2 = extents->x2; *x2 -= diff * hscale; } diff = extents->y1 - dst->y1; if(diff > 0) { dst->y1 = extents->y1; *y1 += diff * vscale; } diff = dst->y2 - extents->y2; if(diff > 0) { dst->y2 = extents->y2; *y2 -= diff * vscale; } if(*x1 < 0) { diff = (- *x1 + hscale - 1)/ hscale; dst->x1 += diff; *x1 += diff * hscale; } delta = *x2 - (width << 16); if(delta > 0) { diff = (delta + hscale - 1)/ hscale; dst->x2 -= diff; *x2 -= diff * hscale; } if(*x1 >= *x2) return FALSE; if(*y1 < 0) { diff = (- *y1 + vscale - 1)/ vscale; dst->y1 += diff; *y1 += diff * vscale; } delta = *y2 - (height << 16); if(delta > 0) { diff = (delta + vscale - 1)/ vscale; dst->y2 -= diff; *y2 -= diff * vscale; } if(*y1 >= *y2) return FALSE; if((dst->x1 != extents->x1) || (dst->x2 != extents->x2) || (dst->y1 != extents->y1) || (dst->y2 != extents->y2)) { RegionRec clipReg; REGION_INIT(DummyScreen, &clipReg, dst, 1); REGION_INTERSECT(DummyScreen, reg, reg, &clipReg); REGION_UNINIT(DummyScreen, &clipReg); } return TRUE; }
void XAAClipAndRenderRects( GCPtr pGC, ClipAndRenderRectsFunc BoxFunc, int nrectFill, xRectangle *prect, int xorg, int yorg ){ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); int Right, Bottom, MaxBoxes; BoxPtr pextent, pboxClipped, pboxClippedBase; MaxBoxes = infoRec->PreAllocSize/sizeof(BoxRec); pboxClippedBase = (BoxPtr)infoRec->PreAllocMem; pboxClipped = pboxClippedBase; if (REGION_NUM_RECTS(pGC->pCompositeClip) == 1) { pextent = REGION_RECTS(pGC->pCompositeClip); while (nrectFill--) { pboxClipped->x1 = max(pextent->x1, prect->x); pboxClipped->y1 = max(pextent->y1, prect->y); Right = (int)prect->x + (int)prect->width; pboxClipped->x2 = min(pextent->x2, Right); Bottom = (int)prect->y + (int)prect->height; pboxClipped->y2 = min(pextent->y2, Bottom); prect++; if ((pboxClipped->x1 < pboxClipped->x2) && (pboxClipped->y1 < pboxClipped->y2)) { pboxClipped++; if(pboxClipped >= (pboxClippedBase + MaxBoxes)) { (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg); pboxClipped = pboxClippedBase; } } } } else { pextent = REGION_EXTENTS(pGC->pScreen, pGC->pCompositeClip); while (nrectFill--) { int n; BoxRec box, *pbox; box.x1 = max(pextent->x1, prect->x); box.y1 = max(pextent->y1, prect->y); Right = (int)prect->x + (int)prect->width; box.x2 = min(pextent->x2, Right); Bottom = (int)prect->y + (int)prect->height; box.y2 = min(pextent->y2, Bottom); prect++; if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) continue; n = REGION_NUM_RECTS (pGC->pCompositeClip); pbox = REGION_RECTS(pGC->pCompositeClip); /* clip the rectangle to each box in the clip region this is logically equivalent to calling Intersect() */ while(n--) { pboxClipped->x1 = max(box.x1, pbox->x1); pboxClipped->y1 = max(box.y1, pbox->y1); pboxClipped->x2 = min(box.x2, pbox->x2); pboxClipped->y2 = min(box.y2, pbox->y2); pbox++; /* see if clipping left anything */ if(pboxClipped->x1 < pboxClipped->x2 && pboxClipped->y1 < pboxClipped->y2) { pboxClipped++; if(pboxClipped >= (pboxClippedBase + MaxBoxes)) { (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg); pboxClipped = pboxClippedBase; } } } } } if(pboxClipped != pboxClippedBase) (*BoxFunc)(pGC, pboxClipped - pboxClippedBase, pboxClippedBase, xorg, yorg); }
static FBLinearPtr localAllocateOffscreenLinear( ScreenPtr pScreen, int length, int gran, MoveLinearCallbackProcPtr moveCB, RemoveLinearCallbackProcPtr removeCB, pointer privData ){ FBManagerPtr offman; FBLinearLinkPtr link; FBAreaPtr area; FBLinearPtr linear = NULL; BoxPtr extents; int w, h, pitch; offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; /* Try to allocate from linear memory first...... */ #ifdef DEBUG ErrorF("ALLOCATING LINEAR\n"); #endif if ((linear = AllocateLinear(offman, length, gran, privData))) return linear; #ifdef DEBUG ErrorF("NOPE, ALLOCATING AREA\n"); #endif if(!(link = xalloc(sizeof(FBLinearLink)))) return NULL; /* No linear available, so try and pinch some from the XY areas */ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); pitch = extents->x2 - extents->x1; if(gran && ((gran > pitch) || (pitch % gran))) { /* we can't match the specified alignment with XY allocations */ xfree(link); return NULL; } if(length < pitch) { /* special case */ w = length; h = 1; } else { w = pitch; h = (length + pitch - 1) / pitch; } if((area = localAllocateOffscreenArea(pScreen, w, h, gran, moveCB ? LinearMoveCBWrapper : NULL, removeCB ? LinearRemoveCBWrapper : NULL, privData))) { link->area = area; link->free = 0; link->next = offman->LinearAreas; offman->LinearAreas = link; linear = &(link->linear); linear->pScreen = pScreen; linear->size = h * w; linear->offset = (pitch * area->box.y1) + area->box.x1; linear->granularity = gran; linear->MoveLinearCallback = moveCB; linear->RemoveLinearCallback = removeCB; linear->devPrivate.ptr = privData; } else xfree(link); #ifdef DEBUG Dump(offman->LinearAreas); #endif return linear; }
static void exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect) { ExaScreenPriv (pDrawable->pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv (pPixmap); register BoxPtr pbox; BoxPtr pextent; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1, fullY2; int partX1, partX2, partY1, partY2; int xoff, yoff; int xorg, yorg; int n; RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); /* Compute intersection of rects and clip region */ REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y); REGION_INTERSECT(pScreen, pReg, pClip, pReg); if (!REGION_NUM_RECTS(pReg)) { goto out; } exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); if (pExaScr->fallback_counter || pExaScr->swappedOut || pExaPixmap->accel_blocked) { goto fallback; } /* For ROPs where overlaps don't matter, convert rectangles to region and * call exaFillRegion{Solid,Tiled}. */ if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) && (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop || pGC->alu == GXcopyInverted || pGC->alu == GXset)) { if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) && exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ? pGC->fgPixel : pGC->tile.pixel, pGC->planemask, pGC->alu, pGC->clientClipType)) || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, pGC->planemask, pGC->alu, pGC->clientClipType))) { goto out; } } if (pGC->fillStyle != FillSolid && !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) { goto fallback; } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = NULL; exaDoMigration (pixmaps, 1, TRUE); } if (!exaPixmapIsOffscreen (pPixmap) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { fallback: ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect); goto out; } xorg = pDrawable->x; yorg = pDrawable->y; pextent = REGION_EXTENTS(pGC->pScreen, pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (nrect--) { fullX1 = prect->x + xorg; fullY1 = prect->y + yorg; fullX2 = fullX1 + (int) prect->width; fullY2 = fullY1 + (int) prect->height; prect++; if (fullX1 < extentX1) fullX1 = extentX1; if (fullY1 < extentY1) fullY1 = extentY1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullY2 > extentY2) fullY2 = extentY2; if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) continue; n = REGION_NUM_RECTS (pClip); if (n == 1) { (*pExaScr->info->Solid) (pPixmap, fullX1 + xoff, fullY1 + yoff, fullX2 + xoff, fullY2 + yoff); } else { pbox = REGION_RECTS(pClip); /* * clip the rectangle to each box in the clip region * this is logically equivalent to calling Intersect(), * but rectangles may overlap each other here. */ while(n--) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partY1 = pbox->y1; if (partY1 < fullY1) partY1 = fullY1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; partY2 = pbox->y2; if (partY2 > fullY2) partY2 = fullY2; pbox++; if (partX1 < partX2 && partY1 < partY2) { (*pExaScr->info->Solid) (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff, partY2 + yoff); } } } } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); out: REGION_UNINIT(pScreen, pReg); REGION_DESTROY(pScreen, pReg); }