int ProcXFixesSetRegion(ClientPtr client) { int things; RegionPtr pRegion, pNew; REQUEST(xXFixesSetRegionReq); REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq); if (things & 4) return BadLength; things >>= 3; pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED); if (!pNew) return BadAlloc; if (!RegionCopy(pRegion, pNew)) { RegionDestroy(pNew); return BadAlloc; } RegionDestroy(pNew); return Success; }
static Bool xf86FBCloseScreen(ScreenPtr pScreen) { FBLinkPtr pLink, tmp; FBLinearLinkPtr pLinearLink, tmp2; FBManagerPtr offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey); pScreen->CloseScreen = offman->CloseScreen; pLink = offman->UsedAreas; while (pLink) { tmp = pLink; pLink = pLink->next; free(tmp); } pLinearLink = offman->LinearAreas; while (pLinearLink) { tmp2 = pLinearLink; pLinearLink = pLinearLink->next; free(tmp2); } RegionDestroy(offman->InitialBoxes); RegionDestroy(offman->FreeBoxes); free(offman->FreeBoxesUpdateCallback); free(offman->devPrivates); free(offman); dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, NULL); return (*pScreen->CloseScreen) (pScreen); }
void miDestroyClip(GCPtr pGC) { if (pGC->clientClip) RegionDestroy(pGC->clientClip); pGC->clientClip = NULL; }
/* See Porting Layer Definition - p. 46 */ static void winDestroyGCNativeGDI (GCPtr pGC) { winGCPriv(pGC); winScreenPriv(pGC->pScreen); if (pGC->freeCompClip) RegionDestroy(pGC->pCompositeClip); /* Free the memory DC */ if (pGCPriv->hdcMem != NULL) { DeleteDC (pGCPriv->hdcMem); pGCPriv->hdcMem = NULL; } /* Release the screen DC for the display window */ if (pGCPriv->hdc != NULL) { ReleaseDC (pScreenPriv->hwndScreen, pGCPriv->hdc); pGCPriv->hdc = NULL; } /* Invalidate the GC privates pointer */ winSetGCPriv (pGC, NULL); }
int draw_item_remove(rdpPixmapRec *priv, struct rdp_draw_item *di) { if (di->prev != 0) { di->prev->next = di->next; } if (di->next != 0) { di->next->prev = di->prev; } if (priv->draw_item_head == di) { priv->draw_item_head = di->next; } if (priv->draw_item_tail == di) { priv->draw_item_tail = di->prev; } if (di->type == RDI_LINE) { if (di->u.line.segs != 0) { g_free(di->u.line.segs); } } RegionDestroy(di->reg); g_free(di); return 0; }
void miDestroyPictureClip(PicturePtr pPicture) { if (pPicture->clientClip) RegionDestroy(pPicture->clientClip); pPicture->clientClip = NULL; }
static int RegionResFree(void *data, XID id) { RegionPtr pRegion = (RegionPtr) data; RegionDestroy(pRegion); return Success; }
void xnestDestroyClipHelper(GCPtr pGC) { switch (pGC->clientClipType) { default: case CT_NONE: break; case CT_REGION: RegionDestroy(pGC->clientClip); break; } }
RegionPtr XFixesRegionCopy(RegionPtr pRegion) { RegionPtr pNew = RegionCreate(RegionExtents(pRegion), RegionNumRects(pRegion)); if (!pNew) return 0; if (!RegionCopy(pNew, pRegion)) { RegionDestroy(pNew); return 0; } return pNew; }
Bool glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, unsigned long fg_pixel) { glamor_pixmap_private *pixmap_priv; GLfloat color[4]; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return FALSE; glamor_get_rgba_from_pixel(fg_pixel, &color[0], &color[1], &color[2], &color[3], format_for_pixmap(pixmap)); if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { RegionRec region; int n_region; glamor_pixmap_clipped_regions *clipped_regions; int i; RegionInitBoxes(®ion, box, nbox); clipped_regions = glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0, 0, 0); for (i = 0; i < n_region; i++) { BoxPtr inner_box; int inner_nbox; SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx); inner_box = RegionRects(clipped_regions[i].region); inner_nbox = RegionNumRects(clipped_regions[i].region); _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color); RegionDestroy(clipped_regions[i].region); } free(clipped_regions); RegionUninit(®ion); } else _glamor_solid_boxes(pixmap, box, nbox, color); return TRUE; }
void miDestroyPictureClip (PicturePtr pPicture) { switch (pPicture->clientClipType) { case CT_NONE: return; case CT_PIXMAP: (*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip)); break; default: /* * we know we'll never have a list of rectangles, since ChangeClip * immediately turns them into a region */ RegionDestroy(pPicture->clientClip); break; } pPicture->clientClip = NULL; pPicture->clientClipType = CT_NONE; }
RegionPtr miDoCopy(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut, miCopyProc copyProc, Pixel bitPlane, void *closure) { RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ Bool freeSrcClip = FALSE; RegionPtr prgnExposed = NULL; RegionRec rgnDst; int dx; int dy; int numRects; int box_x1; int box_y1; int box_x2; int box_y2; Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ Bool fastDst = FALSE; /* for fast clipping with one rect dest */ Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ /* Short cut for unmapped or fully clipped windows */ if (pDstDrawable->type == DRAWABLE_WINDOW && RegionNil(&((WindowPtr)pDstDrawable)->clipList)) { return NULL; } if (pSrcDrawable->pScreen->SourceValidate) { (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc, pGC->subWindowMode); } /* Compute source clip region */ if (pSrcDrawable->type == DRAWABLE_PIXMAP) { if ((pSrcDrawable == pDstDrawable) && (!pGC->clientClip)) prgnSrcClip = miGetCompositeClip(pGC); else fastSrc = TRUE; } else { if (pGC->subWindowMode == IncludeInferiors) { /* * XFree86 DDX empties the border clip when the * VT is inactive, make sure the region isn't empty */ if (!((WindowPtr) pSrcDrawable)->parent && RegionNotEmpty(&((WindowPtr) pSrcDrawable)->borderClip)) { /* * special case bitblt from root window in * IncludeInferiors mode; just like from a pixmap */ fastSrc = TRUE; } else if ((pSrcDrawable == pDstDrawable) && (!pGC->clientClip)) { prgnSrcClip = miGetCompositeClip(pGC); } else { prgnSrcClip = NotClippedByChildren((WindowPtr) pSrcDrawable); freeSrcClip = TRUE; } } else { prgnSrcClip = &((WindowPtr) pSrcDrawable)->clipList; } } xIn += pSrcDrawable->x; yIn += pSrcDrawable->y; xOut += pDstDrawable->x; yOut += pDstDrawable->y; box_x1 = xIn; box_y1 = yIn; box_x2 = xIn + widthSrc; box_y2 = yIn + heightSrc; dx = xIn - xOut; dy = yIn - yOut; /* Don't create a source region if we are doing a fast clip */ if (fastSrc) { RegionPtr cclip; fastExpose = TRUE; /* * clip the source; if regions extend beyond the source size, * make sure exposure events get sent */ if (box_x1 < pSrcDrawable->x) { box_x1 = pSrcDrawable->x; fastExpose = FALSE; } if (box_y1 < pSrcDrawable->y) { box_y1 = pSrcDrawable->y; fastExpose = FALSE; } if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) { box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; fastExpose = FALSE; } if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) { box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; fastExpose = FALSE; } /* Translate and clip the dst to the destination composite clip */ box_x1 -= dx; box_x2 -= dx; box_y1 -= dy; box_y2 -= dy; /* If the destination composite clip is one rectangle we can do the clip directly. Otherwise we have to create a full blown region and call intersect */ cclip = miGetCompositeClip(pGC); if (RegionNumRects(cclip) == 1) { BoxPtr pBox = RegionRects(cclip); if (box_x1 < pBox->x1) box_x1 = pBox->x1; if (box_x2 > pBox->x2) box_x2 = pBox->x2; if (box_y1 < pBox->y1) box_y1 = pBox->y1; if (box_y2 > pBox->y2) box_y2 = pBox->y2; fastDst = TRUE; } } /* Check to see if the region is empty */ if (box_x1 >= box_x2 || box_y1 >= box_y2) { RegionNull(&rgnDst); } else { BoxRec box; box.x1 = box_x1; box.y1 = box_y1; box.x2 = box_x2; box.y2 = box_y2; RegionInit(&rgnDst, &box, 1); } /* Clip against complex source if needed */ if (!fastSrc) { RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); RegionTranslate(&rgnDst, -dx, -dy); } /* Clip against complex dest if needed */ if (!fastDst) { RegionIntersect(&rgnDst, &rgnDst, miGetCompositeClip(pGC)); } /* Do bit blitting */ numRects = RegionNumRects(&rgnDst); if (numRects && widthSrc && heightSrc) miCopyRegion(pSrcDrawable, pDstDrawable, pGC, &rgnDst, dx, dy, copyProc, bitPlane, closure); /* Pixmap sources generate a NoExposed (we return NULL to do this) */ if (!fastExpose && pGC->fExpose) prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn - pSrcDrawable->x, yIn - pSrcDrawable->y, widthSrc, heightSrc, xOut - pDstDrawable->x, yOut - pDstDrawable->y); RegionUninit(&rgnDst); if (freeSrcClip) RegionDestroy(prgnSrcClip); return prgnExposed; }
static Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, int stride, void *bits, int pbo, PictFormatShort pict_format) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); GLenum format, type; int no_alpha, revert, swap_rb; glamor_pixmap_private *pixmap_priv; Bool force_clip; if (glamor_get_tex_format_type_from_pixmap(pixmap, pict_format, &format, &type, &no_alpha, &revert, &swap_rb, 1)) { glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); return FALSE; } if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb)) return FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && !glamor_check_fbo_size(glamor_priv, w, h); if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) { RegionRec region; BoxRec box; int n_region; glamor_pixmap_clipped_regions *clipped_regions; void *sub_bits; int i, j; sub_bits = xallocarray(h, stride); if (sub_bits == NULL) return FALSE; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; RegionInitBoxes(®ion, &box, 1); if (!force_clip) clipped_regions = glamor_compute_clipped_regions(pixmap, ®ion, &n_region, 0, 0, 0); else clipped_regions = glamor_compute_clipped_regions_ext(pixmap, ®ion, &n_region, pixmap_priv->block_w, pixmap_priv->block_h, 0, 0); DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap); for (i = 0; i < n_region; i++) { BoxPtr boxes; int nbox; int temp_stride; void *temp_bits; assert(pbo == 0); glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx); boxes = RegionRects(clipped_regions[i].region); nbox = RegionNumRects(clipped_regions[i].region); DEBUGF("split to %d boxes\n", nbox); for (j = 0; j < nbox; j++) { temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1, pixmap->drawable.depth); if (boxes[j].x1 == x && temp_stride == stride) { temp_bits = (char *) bits + (boxes[j].y1 - y) * stride; } else { temp_bits = sub_bits; glamor_put_bits(temp_bits, temp_stride, bits, stride, pixmap->drawable.bitsPerPixel, boxes[j].x1 - x, boxes[j].y1 - y, boxes[j].x2 - boxes[j].x1, boxes[j].y2 - boxes[j].y1); } DEBUGF("upload x %d y %d w %d h %d temp stride %d \n", boxes[j].x1 - x, boxes[j].y1 - y, boxes[j].x2 - boxes[j].x1, boxes[j].y2 - boxes[j].y1, temp_stride); if (_glamor_upload_bits_to_pixmap_texture (pixmap, format, type, no_alpha, revert, swap_rb, boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1, boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo) == FALSE) { RegionUninit(®ion); free(sub_bits); assert(0); return FALSE; } } RegionDestroy(clipped_regions[i].region); } free(sub_bits); free(clipped_regions); RegionUninit(®ion); return TRUE; } else return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb, x, y, w, h, stride, bits, pbo); }
static Bool _glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure, Bool fallback) { PixmapPtr dst_pixmap, src_pixmap; glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; glamor_screen_private *glamor_priv; glamor_gl_dispatch *dispatch; BoxPtr extent; RegionRec region; int src_x_off, src_y_off, dst_x_off, dst_y_off; Bool ok = FALSE; int force_clip = 0; if (nbox == 0) return TRUE; dst_pixmap = glamor_get_drawable_pixmap(dst); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); src_pixmap = glamor_get_drawable_pixmap(src); src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); glamor_priv = glamor_get_screen_private(dst->pScreen); DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", box[0].x1, box[0].y1, box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, dx, dy, src_pixmap, dst_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) goto fall_back; if (gc) { if (!glamor_set_planemask(dst_pixmap, gc->planemask)) goto fall_back; dispatch = glamor_get_dispatch(glamor_priv); if (!glamor_set_alu(dispatch, gc->alu)) { glamor_put_dispatch(glamor_priv); goto fail_noregion; } glamor_put_dispatch(glamor_priv); } if (!src_pixmap_priv) { glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY); src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); } glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); RegionInitBoxes(®ion, box, nbox); extent = RegionExtents(®ion); if (!glamor_check_fbo_size(glamor_priv, extent->x2 - extent->x1, extent->y2 - extent->y1) && (src_pixmap_priv->type == GLAMOR_MEMORY || (src_pixmap_priv == dst_pixmap_priv))) { force_clip = 1; } if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { glamor_pixmap_clipped_regions *clipped_dst_regions; int n_dst_region, i, j; PixmapPtr temp_source_pixmap; glamor_pixmap_private *temp_source_priv = NULL; RegionTranslate(®ion, dst_x_off, dst_y_off); if (!force_clip) clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv, ®ion, &n_dst_region, 0, reverse, upsidedown); else clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv, ®ion, &n_dst_region, glamor_priv->max_fbo_size, glamor_priv->max_fbo_size, reverse, upsidedown); for(i = 0; i < n_dst_region; i++) { int n_src_region; glamor_pixmap_clipped_regions *clipped_src_regions; BoxPtr current_boxes; int n_current_boxes; SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx); temp_source_pixmap = NULL; if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { RegionTranslate(clipped_dst_regions[i].region, -dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy); clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv, clipped_dst_regions[i].region, &n_src_region, 0, reverse, upsidedown); DEBUGF("Source is large pixmap.\n"); for (j = 0; j < n_src_region; j++) { if (src_pixmap_priv != dst_pixmap_priv) SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx); else if (src_pixmap_priv == dst_pixmap_priv && clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx) { /* source and the dest are the same, but need different block_idx. * we create a empty pixmap and fill the required source fbo and box to * it. It's a little hacky, but avoid extra copy. */ temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0, src->depth, 0); if (!temp_source_pixmap) { ok = FALSE; goto fail; } src->pScreen->ModifyPixmapHeader(temp_source_pixmap, src_pixmap->drawable.width, src_pixmap->drawable.height, 0, 0, src_pixmap->devKind, NULL); temp_source_priv = glamor_get_pixmap_private(temp_source_pixmap); *temp_source_priv = *src_pixmap_priv; temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx]; temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx]; temp_source_priv->base.pixmap = temp_source_pixmap; } assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv && (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx))); RegionTranslate(clipped_src_regions[j].region, -src_x_off - dx, -src_y_off - dy); current_boxes = RegionRects(clipped_src_regions[j].region); n_current_boxes = RegionNumRects(clipped_src_regions[j].region); DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n", clipped_dst_regions[i].block_idx, clipped_src_regions[j].block_idx); DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", current_boxes[0].x1, current_boxes[0].y1, current_boxes[0].x2, current_boxes[0].y2, dx, dy, src_pixmap, dst_pixmap); if (!temp_source_pixmap) ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, n_current_boxes, dx, dy, reverse, upsidedown, bitplane, closure); else { ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, dst, gc, current_boxes, n_current_boxes, dx, dy, reverse, upsidedown, bitplane, closure); temp_source_priv->type = GLAMOR_MEMORY; temp_source_priv->base.fbo = NULL; glamor_destroy_pixmap(temp_source_pixmap); temp_source_pixmap = NULL; } RegionDestroy(clipped_src_regions[j].region); if (!ok) { assert(0); goto fail; } } if (n_src_region == 0) ok = TRUE; free(clipped_src_regions); } else { RegionTranslate(clipped_dst_regions[i].region, - dst_x_off, - dst_y_off); current_boxes = RegionRects(clipped_dst_regions[i].region); n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); DEBUGF("dest pixmap fbo idx %d \n", clipped_dst_regions[i].block_idx); DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", current_boxes[0].x1, current_boxes[0].y1, current_boxes[0].x2, current_boxes[0].y2, dx, dy, src_pixmap, dst_pixmap); ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, n_current_boxes, dx, dy, reverse, upsidedown, bitplane, closure); } RegionDestroy(clipped_dst_regions[i].region); } if (n_dst_region == 0) ok = TRUE; free(clipped_dst_regions); } else { ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } fail: RegionUninit(®ion); fail_noregion: dispatch = glamor_get_dispatch(glamor_priv); glamor_set_alu(dispatch, GXcopy); glamor_put_dispatch(glamor_priv); if (ok) return TRUE; fall_back: if (!fallback && glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst)) goto done; if (src_pixmap_priv->type == GLAMOR_DRM_ONLY || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) { LogMessage(X_WARNING, "Access a DRM only pixmap is not allowed within glamor.\n"); return TRUE; } glamor_report_delayed_fallbacks(src->pScreen); glamor_report_delayed_fallbacks(dst->pScreen); glamor_fallback("from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO) && glamor_prepare_access_gc(gc)) { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } glamor_finish_access_gc(gc); glamor_finish_access(src); glamor_finish_access(dst); ok = TRUE; done: glamor_clear_delayed_fallbacks(src->pScreen); glamor_clear_delayed_fallbacks(dst->pScreen); return ok; }
static void XAACopyWindow8_32(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { DDXPointPtr pptSrc, ppt; RegionRec rgnDst; BoxPtr pbox; int dx, dy, nbox; WindowPtr pwinRoot; ScreenPtr pScreen = pWin->drawable.pScreen; XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable)); Bool doUnderlay = miOverlayCopyUnderlay(pScreen); RegionPtr borderClip = &pWin->borderClip; Bool freeReg = FALSE; if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt || (infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK)) { XAA_SCREEN_PROLOGUE(pScreen, CopyWindow); if (infoRec->pScrn->vtSema && infoRec->NeedToSync) { (*infoRec->Sync) (infoRec->pScrn); infoRec->NeedToSync = FALSE; } (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); XAA_SCREEN_EPILOGUE(pScreen, CopyWindow, XAACopyWindow8_32); return; } pwinRoot = pScreen->root; if (doUnderlay) freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip); RegionNull(&rgnDst); dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; RegionTranslate(prgnSrc, -dx, -dy); RegionIntersect(&rgnDst, borderClip, prgnSrc); pbox = RegionRects(&rgnDst); nbox = RegionNumRects(&rgnDst); if (!nbox || !(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec)))) { RegionUninit(&rgnDst); return; } ppt = pptSrc; while (nbox--) { ppt->x = pbox->x1 + dx; ppt->y = pbox->y1 + dy; ppt++; pbox++; } infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000; infoRec->ScratchGC.alu = GXcopy; XAADoBitBlt((DrawablePtr) pwinRoot, (DrawablePtr) pwinRoot, &(infoRec->ScratchGC), &rgnDst, pptSrc); free(pptSrc); RegionUninit(&rgnDst); if (freeReg) RegionDestroy(borderClip); }
Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, int tile_x, int tile_y) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *dst_pixmap_priv; glamor_pixmap_private *src_pixmap_priv; dst_pixmap_priv = glamor_get_pixmap_private(pixmap); src_pixmap_priv = glamor_get_pixmap_private(tile); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) return FALSE; if (glamor_priv->tile_prog == 0) { glamor_fallback("Tiling unsupported\n"); goto fail; } if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { /* XXX dynamic uploading candidate. */ glamor_fallback("Non-texture tile pixmap\n"); goto fail; } if (!glamor_set_planemask(pixmap, planemask)) { glamor_fallback("unsupported planemask %lx\n", planemask); goto fail; } glamor_make_current(glamor_priv); if (!glamor_set_alu(screen, alu)) { glamor_fallback("unsupported alu %x\n", alu); goto fail; } if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { glamor_pixmap_clipped_regions *clipped_dst_regions; int n_dst_region, i, j, k; BoxRec box; RegionRec region; box.x1 = x; box.y1 = y; box.x2 = x + width; box.y2 = y + height; RegionInitBoxes(®ion, &box, 1); clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv, ®ion, &n_dst_region, 0, 0, 0); for (i = 0; i < n_dst_region; i++) { int n_src_region; glamor_pixmap_clipped_regions *clipped_src_regions; BoxPtr current_boxes; int n_current_boxes; SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx); if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { RegionTranslate(clipped_dst_regions[i].region, tile_x - x, tile_y - y); DEBUGF("tiled a large src pixmap. %dx%d \n", tile->drawable.width, tile->drawable.height); clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv, clipped_dst_regions[i]. region, &n_src_region, 1, 0, 0); DEBUGF("got %d src regions %d \n", n_src_region); for (j = 0; j < n_src_region; j++) { SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx); RegionTranslate(clipped_src_regions[j].region, x - tile_x, y - tile_y); current_boxes = RegionRects(clipped_src_regions[j].region); n_current_boxes = RegionNumRects(clipped_src_regions[j].region); for (k = 0; k < n_current_boxes; k++) { DEBUGF ("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n", current_boxes[k].x1, current_boxes[k].y1, current_boxes[k].x2 - current_boxes[k].x1, current_boxes[k].y2 - current_boxes[k].y1, clipped_dst_regions[i].block_idx, clipped_src_regions[j].block_idx, (tile_x + (current_boxes[k].x1 - x)), tile_y + (current_boxes[k].y1 - y)); _glamor_tile(pixmap, tile, current_boxes[k].x1, current_boxes[k].y1, current_boxes[k].x2 - current_boxes[k].x1, current_boxes[k].y2 - current_boxes[k].y1, (tile_x + (current_boxes[k].x1 - x)), (tile_y + (current_boxes[k].y1 - y))); } RegionDestroy(clipped_src_regions[j].region); } free(clipped_src_regions); } else { current_boxes = RegionRects(clipped_dst_regions[i].region); n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); for (k = 0; k < n_current_boxes; k++) { _glamor_tile(pixmap, tile, current_boxes[k].x1, current_boxes[k].y1, current_boxes[k].x2 - current_boxes[k].x1, current_boxes[k].y2 - current_boxes[k].y1, (tile_x + (current_boxes[k].x1 - x)), (tile_y + (current_boxes[k].y1 - y))); } } RegionDestroy(clipped_dst_regions[i].region); } free(clipped_dst_regions); RegionUninit(®ion); } else _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y); glamor_set_alu(screen, GXcopy); return TRUE; fail: return FALSE; }
static Bool localQueryLargestOffscreenArea(ScreenPtr pScreen, int *width, int *height, int granularity, int preferences, int severity) { FBManagerPtr offman; RegionPtr newRegion = NULL; BoxPtr pbox; int nbox; int x, w, h, area, oldArea; *width = *height = oldArea = 0; if (granularity <= 1) granularity = 0; if ((preferences < 0) || (preferences > 3)) return FALSE; offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey); if (severity < 0) severity = 0; if (severity > 2) severity = 2; switch (severity) { case 2: if (offman->NumUsedAreas) { FBLinkPtr pLink; RegionRec tmpRegion; newRegion = RegionCreate(NULL, 1); RegionCopy(newRegion, offman->InitialBoxes); pLink = offman->UsedAreas; while (pLink) { if (!pLink->area.RemoveAreaCallback) { RegionInit(&tmpRegion, &(pLink->area.box), 1); RegionSubtract(newRegion, newRegion, &tmpRegion); RegionUninit(&tmpRegion); } pLink = pLink->next; } nbox = RegionNumRects(newRegion); pbox = RegionRects(newRegion); break; } case 1: if (offman->NumUsedAreas) { FBLinkPtr pLink; RegionRec tmpRegion; newRegion = RegionCreate(NULL, 1); RegionCopy(newRegion, offman->FreeBoxes); pLink = offman->UsedAreas; while (pLink) { if (pLink->area.RemoveAreaCallback) { RegionInit(&tmpRegion, &(pLink->area.box), 1); RegionAppend(newRegion, &tmpRegion); RegionUninit(&tmpRegion); } pLink = pLink->next; } nbox = RegionNumRects(newRegion); pbox = RegionRects(newRegion); break; } default: nbox = RegionNumRects(offman->FreeBoxes); pbox = RegionRects(offman->FreeBoxes); break; } while (nbox--) { x = pbox->x1; if (granularity > 1) x = ((x + granularity - 1) / granularity) * granularity; w = pbox->x2 - x; h = pbox->y2 - pbox->y1; area = w * h; if (w > 0) { Bool gotIt = FALSE; switch (preferences) { case FAVOR_AREA_THEN_WIDTH: if ((area > oldArea) || ((area == oldArea) && (w > *width))) gotIt = TRUE; break; case FAVOR_AREA_THEN_HEIGHT: if ((area > oldArea) || ((area == oldArea) && (h > *height))) gotIt = TRUE; break; case FAVOR_WIDTH_THEN_AREA: if ((w > *width) || ((w == *width) && (area > oldArea))) gotIt = TRUE; break; case FAVOR_HEIGHT_THEN_AREA: if ((h > *height) || ((h == *height) && (area > oldArea))) gotIt = TRUE; break; } if (gotIt) { *width = w; *height = h; oldArea = area; } } pbox++; } if (newRegion) RegionDestroy(newRegion); return TRUE; }
void rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { RegionRec clip_reg; RegionPtr tmpRegion; int cd; int lw; int extra; int i; int num_clips; int got_id; int dirty_type; int post_process; int reset_surface; xRectangle *rects; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec *pDstPriv; rdpPixmapRec *pDirtyPriv; LLOGLN(10, ("rdpPolyFillArc:")); rects = 0; if (narcs > 0) { rects = (xRectangle *)g_malloc(narcs * sizeof(xRectangle), 0); lw = pGC->lineWidth; if (lw == 0) { lw = 1; } extra = lw / 2; for (i = 0; i < narcs; i++) { rects[i].x = (parcs[i].x - extra) + pDrawable->x; rects[i].y = (parcs[i].y - extra) + pDrawable->y; rects[i].width = parcs[i].width + lw; rects[i].height = parcs[i].height + lw; } } /* do original call */ rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs); dirty_type = 0; pDirtyPriv = 0; post_process = 0; reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { pDstPixmap = (PixmapPtr)pDrawable; pDstPriv = GETPIXPRIV(pDstPixmap); if (xrdp_is_os(pDstPixmap, pDstPriv)) { post_process = 1; if (g_do_dirty_os) { LLOGLN(10, ("rdpPolyFillArc: getting dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; dirty_type = RDI_IMGLY; } else { rdpup_switch_os_surface(pDstPriv->rdpindex); reset_surface = 1; rdpup_get_pixmap_image_rect(pDstPixmap, &id); got_id = 1; } } } else { if (pDrawable->type == DRAWABLE_WINDOW) { pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { post_process = 1; if (g_do_dirty_ons) { LLOGLN(10, ("rdpPolyFillArc: getting dirty")); g_screenPriv.is_dirty = 1; pDirtyPriv = &g_screenPriv; dirty_type = RDI_IMGLL; } else { rdpup_get_screen_image_rect(&id); got_id = 1; } } } } if (!post_process) { g_free(rects); return; } RegionInit(&clip_reg, NullBox, 0); cd = rdp_get_clip(&clip_reg, pDrawable, pGC); if (cd == 1) { if (rects != 0) { tmpRegion = RegionFromRects(narcs, rects, CT_NONE); num_clips = REGION_NUM_RECTS(tmpRegion); if (num_clips > 0) { if (dirty_type != 0) { draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYFILLARC); } else if (got_id) { rdpup_begin_update(); for (i = num_clips - 1; i >= 0; i--) { box = REGION_RECTS(tmpRegion)[i]; rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); } } RegionDestroy(tmpRegion); } } else if (cd == 2) { if (rects != 0) { tmpRegion = RegionFromRects(narcs, rects, CT_NONE); RegionIntersect(tmpRegion, tmpRegion, &clip_reg); num_clips = REGION_NUM_RECTS(tmpRegion); if (num_clips > 0) { if (dirty_type != 0) { draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYFILLARC); } else if (got_id) { rdpup_begin_update(); for (i = num_clips - 1; i >= 0; i--) { box = REGION_RECTS(tmpRegion)[i]; rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); } } RegionDestroy(tmpRegion); } } RegionUninit(&clip_reg); g_free(rects); if (reset_surface) { rdpup_switch_os_surface(-1); } }
Bool exaHWCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown) { ExaScreenPriv(pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; RegionPtr srcregion = NULL, dstregion = NULL; xRectangle *rects; Bool ret = TRUE; /* avoid doing copy operations if no boxes */ if (nbox == 0) return TRUE; pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable); pDstPixmap = exaGetDrawablePixmap(pDstDrawable); exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); rects = malloc(nbox * sizeof(xRectangle)); if (rects) { int i; int ordering; for (i = 0; i < nbox; i++) { rects[i].x = pbox[i].x1 + dx + src_off_x; rects[i].y = pbox[i].y1 + dy + src_off_y; rects[i].width = pbox[i].x2 - pbox[i].x1; rects[i].height = pbox[i].y2 - pbox[i].y1; } /* This must match the RegionCopy() logic for reversing rect order */ if (nbox == 1 || (dx > 0 && dy > 0) || (pDstDrawable != pSrcDrawable && (pDstDrawable->type != DRAWABLE_WINDOW || pSrcDrawable->type != DRAWABLE_WINDOW))) ordering = CT_YXBANDED; else ordering = CT_UNSORTED; srcregion = RegionFromRects(nbox, rects, ordering); free(rects); if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL)) { dstregion = RegionCreate(NullBox, 0); RegionCopy(dstregion, srcregion); RegionTranslate(dstregion, dst_off_x - dx - src_off_x, dst_off_y - dy - src_off_y); } } pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap); pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap); /* Check whether the accelerator can use this pixmap. * If the pitch of the pixmaps is out of range, there's nothing * we can do but fall back to software rendering. */ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) goto fallback; /* If the width or the height of either of the pixmaps * is out of range, check whether the boxes are actually out of the * addressable range as well. If they aren't, we can still do * the copying in hardware. */ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { int i; for (i = 0; i < nbox; i++) { /* src */ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) goto fallback; /* dst */ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) goto fallback; } } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[2]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pDstPixmap; pixmaps[0].pReg = dstregion; pixmaps[1].as_dst = FALSE; pixmaps[1].as_src = TRUE; pixmaps[1].pPix = pSrcPixmap; pixmaps[1].pReg = srcregion; exaDoMigration(pixmaps, 2, TRUE); } /* Mixed directions must be handled specially if the card is lame */ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && reverse != upsidedown) { if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy)) goto out; goto fallback; } if (exaPixmapHasGpuCopy(pDstPixmap)) { /* Normal blitting. */ if (exaPixmapHasGpuCopy(pSrcPixmap)) { if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) { goto fallback; } while (nbox--) { (*pExaScr->info->Copy) (pDstPixmap, pbox->x1 + dx + src_off_x, pbox->y1 + dy + src_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*pExaScr->info->DoneCopy) (pDstPixmap); exaMarkSync(pDstDrawable->pScreen); /* UTS: mainly for SHM PutImage's secondary path. * * Only taking this path for directly accessible pixmaps. */ } else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) { int bpp = pSrcDrawable->bitsPerPixel; int src_stride = exaGetPixmapPitch(pSrcPixmap); CARD8 *src = NULL; if (!pExaScr->info->UploadToScreen) goto fallback; if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) goto fallback; if (pSrcDrawable->bitsPerPixel < 8) goto fallback; if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) goto fallback; while (nbox--) { src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); if (!pExaScr->info-> UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, (char *) src, src_stride)) goto fallback; pbox++; } } else goto fallback; } else goto fallback; goto out; fallback: ret = FALSE; out: if (dstregion) { RegionUninit(dstregion); RegionDestroy(dstregion); } if (srcregion) { RegionUninit(srcregion); RegionDestroy(srcregion); } return ret; }
void miComputeCompositeClip(GCPtr pGC, DrawablePtr pDrawable) { if (pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr) pDrawable; RegionPtr pregWin; Bool freeTmpClip, freeCompClip; if (pGC->subWindowMode == IncludeInferiors) { pregWin = NotClippedByChildren(pWin); freeTmpClip = TRUE; } else { pregWin = &pWin->clipList; freeTmpClip = FALSE; } freeCompClip = pGC->freeCompClip; /* * if there is no client clip, we can get by with just keeping the * pointer we got, and remembering whether or not should destroy (or * maybe re-use) it later. this way, we avoid unnecessary copying of * regions. (this wins especially if many clients clip by children * and have no client clip.) */ if (!pGC->clientClip) { if (freeCompClip) RegionDestroy(pGC->pCompositeClip); pGC->pCompositeClip = pregWin; pGC->freeCompClip = freeTmpClip; } else { /* * we need one 'real' region to put into the composite clip. if * pregWin the current composite clip are real, we can get rid of * one. if pregWin is real and the current composite clip isn't, * use pregWin for the composite clip. if the current composite * clip is real and pregWin isn't, use the current composite * clip. if neither is real, create a new region. */ RegionTranslate(pGC->clientClip, pDrawable->x + pGC->clipOrg.x, pDrawable->y + pGC->clipOrg.y); if (freeCompClip) { RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); if (freeTmpClip) RegionDestroy(pregWin); } else if (freeTmpClip) { RegionIntersect(pregWin, pregWin, pGC->clientClip); pGC->pCompositeClip = pregWin; } else { pGC->pCompositeClip = RegionCreate(NullBox, 0); RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); } pGC->freeCompClip = TRUE; RegionTranslate(pGC->clientClip, -(pDrawable->x + pGC->clipOrg.x), -(pDrawable->y + pGC->clipOrg.y)); } } /* end of composite clip for a window */ else { BoxRec pixbounds; /* XXX should we translate by drawable.x/y here ? */ /* If you want pixmaps in offscreen memory, yes */ pixbounds.x1 = pDrawable->x; pixbounds.y1 = pDrawable->y; pixbounds.x2 = pDrawable->x + pDrawable->width; pixbounds.y2 = pDrawable->y + pDrawable->height; if (pGC->freeCompClip) { RegionReset(pGC->pCompositeClip, &pixbounds); } else { pGC->freeCompClip = TRUE; pGC->pCompositeClip = RegionCreate(&pixbounds, 1); } if (pGC->clientClip) { if (pDrawable->x || pDrawable->y) { RegionTranslate(pGC->clientClip, pDrawable->x + pGC->clipOrg.x, pDrawable->y + pGC->clipOrg.y); RegionIntersect(pGC->pCompositeClip, pGC->pCompositeClip, pGC->clientClip); RegionTranslate(pGC->clientClip, -(pDrawable->x + pGC->clipOrg.x), -(pDrawable->y + pGC->clipOrg.y)); } else { RegionTranslate(pGC->pCompositeClip, -pGC->clipOrg.x, -pGC->clipOrg.y); RegionIntersect(pGC->pCompositeClip, pGC->pCompositeClip, pGC->clientClip); RegionTranslate(pGC->pCompositeClip, pGC->clipOrg.x, pGC->clipOrg.y); } } } /* end of composite clip for pixmap */ } /* end miComputeCompositeClip */
/* *----------------------------------------------------------------------- * miComputeClips -- * Recompute the clipList, borderClip, exposed and borderExposed * regions for pParent and its children. Only viewable windows are * taken into account. * * Results: * None. * * Side Effects: * clipList, borderClip, exposed and borderExposed are altered. * A VisibilityNotify event may be generated on the parent window. * *----------------------------------------------------------------------- */ static void miComputeClips ( WindowPtr pParent, ScreenPtr pScreen, RegionPtr universe, VTKind kind, RegionPtr exposed ) /* for intermediate calculations */ { int dx, dy; RegionRec childUniverse; WindowPtr pChild; int oldVis, newVis; BoxRec borderSize; RegionRec childUnion; Bool overlap; RegionPtr borderVisible; /* * Figure out the new visibility of this window. * The extent of the universe should be the same as the extent of * the borderSize region. If the window is unobscured, this rectangle * will be completely inside the universe (the universe will cover it * completely). If the window is completely obscured, none of the * universe will cover the rectangle. */ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); if (dx > 32767) dx = 32767; borderSize.x2 = dx; dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); if (dy > 32767) dy = 32767; borderSize.y2 = dy; #ifdef COMPOSITE /* * In redirected drawing case, reset universe to borderSize */ if (pParent->redirectDraw != RedirectDrawNone) { if (miSetRedirectBorderClipProc) { if (TreatAsTransparent (pParent)) RegionEmpty(universe); (*miSetRedirectBorderClipProc) (pParent, universe); } RegionCopy(universe, &pParent->borderSize); } #endif oldVis = pParent->visibility; switch (RegionContainsRect(universe, &borderSize)) { case rgnIN: newVis = VisibilityUnobscured; break; case rgnPART: newVis = VisibilityPartiallyObscured; { RegionPtr pBounding; if ((pBounding = wBoundingShape (pParent))) { switch (miShapedWindowIn (universe, pBounding, &borderSize, pParent->drawable.x, pParent->drawable.y)) { case rgnIN: newVis = VisibilityUnobscured; break; case rgnOUT: newVis = VisibilityFullyObscured; break; } } } break; default: newVis = VisibilityFullyObscured; break; } pParent->visibility = newVis; if (oldVis != newVis && ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) SendVisibilityNotify(pParent); dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; /* * avoid computations when dealing with simple operations */ switch (kind) { case VTMap: case VTStack: case VTUnmap: break; case VTMove: if ((oldVis == newVis) && ((oldVis == VisibilityFullyObscured) || (oldVis == VisibilityUnobscured))) { pChild = pParent; while (1) { if (pChild->viewable) { if (pChild->visibility != VisibilityFullyObscured) { RegionTranslate(&pChild->borderClip, dx, dy); RegionTranslate(&pChild->clipList, dx, dy); pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pChild, dx, dy); } if (pChild->valdata) { RegionNull(&pChild->valdata->after.borderExposed); if (HasParentRelativeBorder(pChild)) { RegionSubtract(&pChild->valdata->after.borderExposed, &pChild->borderClip, &pChild->winSize); } RegionNull(&pChild->valdata->after.exposed); } if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pParent)) pChild = pChild->parent; if (pChild == pParent) break; pChild = pChild->nextSib; } return; } /* fall through */ default: /* * To calculate exposures correctly, we have to translate the old * borderClip and clipList regions to the window's new location so there * is a correspondence between pieces of the new and old clipping regions. */ if (dx || dy) { /* * We translate the old clipList because that will be exposed or copied * if gravity is right. */ RegionTranslate(&pParent->borderClip, dx, dy); RegionTranslate(&pParent->clipList, dx, dy); } break; case VTBroken: RegionEmpty(&pParent->borderClip); RegionEmpty(&pParent->clipList); break; } borderVisible = pParent->valdata->before.borderVisible; RegionNull(&pParent->valdata->after.borderExposed); RegionNull(&pParent->valdata->after.exposed); /* * Since the borderClip must not be clipped by the children, we do * the border exposure first... * * 'universe' is the window's borderClip. To figure the exposures, remove * the area that used to be exposed from the new. * This leaves a region of pieces that weren't exposed before. */ if (HasBorder (pParent)) { if (borderVisible) { /* * when the border changes shape, the old visible portions * of the border will be saved by DIX in borderVisible -- * use that region and destroy it */ RegionSubtract(exposed, universe, borderVisible); RegionDestroy(borderVisible); } else { RegionSubtract(exposed, universe, &pParent->borderClip); } if (HasParentRelativeBorder(pParent) && (dx || dy)) RegionSubtract(&pParent->valdata->after.borderExposed, universe, &pParent->winSize); else RegionSubtract(&pParent->valdata->after.borderExposed, exposed, &pParent->winSize); RegionCopy(&pParent->borderClip, universe); /* * To get the right clipList for the parent, and to make doubly sure * that no child overlaps the parent's border, we remove the parent's * border from the universe before proceeding. */ RegionIntersect(universe, universe, &pParent->winSize); } else RegionCopy(&pParent->borderClip, universe); if ((pChild = pParent->firstChild) && pParent->mapped) { RegionNull(&childUniverse); RegionNull(&childUnion); if ((pChild->drawable.y < pParent->lastChild->drawable.y) || ((pChild->drawable.y == pParent->lastChild->drawable.y) && (pChild->drawable.x < pParent->lastChild->drawable.x))) { for (; pChild; pChild = pChild->nextSib) { if (pChild->viewable && !TreatAsTransparent(pChild)) RegionAppend(&childUnion, &pChild->borderSize); } } else { for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) { if (pChild->viewable && !TreatAsTransparent(pChild)) RegionAppend(&childUnion, &pChild->borderSize); } } RegionValidate(&childUnion, &overlap); for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->viewable) { /* * If the child is viewable, we want to remove its extents * from the current universe, but we only re-clip it if * it's been marked. */ if (pChild->valdata) { /* * Figure out the new universe from the child's * perspective and recurse. */ RegionIntersect(&childUniverse, universe, &pChild->borderSize); miComputeClips (pChild, pScreen, &childUniverse, kind, exposed); } /* * Once the child has been processed, we remove its extents * from the current universe, thus denying its space to any * other sibling. */ if (overlap && !TreatAsTransparent (pChild)) RegionSubtract(universe, universe, &pChild->borderSize); } } if (!overlap) RegionSubtract(universe, universe, &childUnion); RegionUninit(&childUnion); RegionUninit(&childUniverse); } /* if any children */ /* * 'universe' now contains the new clipList for the parent window. * * To figure the exposure of the window we subtract the old clip from the * new, just as for the border. */ if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) { RegionCopy(&pParent->valdata->after.exposed, universe); } else if (newVis != VisibilityFullyObscured && newVis != VisibilityNotViewable) { RegionSubtract(&pParent->valdata->after.exposed, universe, &pParent->clipList); } /* HACK ALERT - copying contents of regions, instead of regions */ { RegionRec tmp; tmp = pParent->clipList; pParent->clipList = *universe; *universe = tmp; } #ifdef NOTDEF RegionCopy(&pParent->clipList, universe); #endif pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pParent, dx, dy); }
void miDestroyGC(GCPtr pGC) { if (pGC->freeCompClip) RegionDestroy(pGC->pCompositeClip); }
int ProcXFixesSetWindowShapeRegion(ClientPtr client) { WindowPtr pWin; RegionPtr pRegion; RegionPtr *pDestRegion; int rc; REQUEST(xXFixesSetWindowShapeRegionReq); REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); rc = dixLookupResourceByType((void **) &pWin, stuff->dest, RT_WINDOW, client, DixSetAttrAccess); if (rc != Success) { client->errorValue = stuff->dest; return rc; } VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess); switch (stuff->destKind) { case ShapeBounding: case ShapeClip: case ShapeInput: break; default: client->errorValue = stuff->destKind; return BadValue; } if (pRegion) { pRegion = XFixesRegionCopy(pRegion); if (!pRegion) return BadAlloc; if (!pWin->optional) MakeWindowOptional(pWin); switch (stuff->destKind) { default: case ShapeBounding: pDestRegion = &pWin->optional->boundingShape; break; case ShapeClip: pDestRegion = &pWin->optional->clipShape; break; case ShapeInput: pDestRegion = &pWin->optional->inputShape; break; } if (stuff->xOff || stuff->yOff) RegionTranslate(pRegion, stuff->xOff, stuff->yOff); } else { if (pWin->optional) { switch (stuff->destKind) { default: case ShapeBounding: pDestRegion = &pWin->optional->boundingShape; break; case ShapeClip: pDestRegion = &pWin->optional->clipShape; break; case ShapeInput: pDestRegion = &pWin->optional->inputShape; break; } } else pDestRegion = &pRegion; /* a NULL region pointer */ } if (*pDestRegion) RegionDestroy(*pDestRegion); *pDestRegion = pRegion; (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind); SendShapeNotify(pWin, stuff->destKind); return Success; }
void miValidatePicture (PicturePtr pPicture, Mask mask) { DrawablePtr pDrawable = pPicture->pDrawable; if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) || (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS))) { if (pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr) pDrawable; RegionPtr pregWin; Bool freeTmpClip, freeCompClip; if (pPicture->subWindowMode == IncludeInferiors) { pregWin = NotClippedByChildren(pWin); freeTmpClip = TRUE; } else { pregWin = &pWin->clipList; freeTmpClip = FALSE; } freeCompClip = pPicture->freeCompClip; /* * if there is no client clip, we can get by with just keeping the * pointer we got, and remembering whether or not should destroy * (or maybe re-use) it later. this way, we avoid unnecessary * copying of regions. (this wins especially if many clients clip * by children and have no client clip.) */ if (pPicture->clientClipType == CT_NONE) { if (freeCompClip) RegionDestroy(pPicture->pCompositeClip); pPicture->pCompositeClip = pregWin; pPicture->freeCompClip = freeTmpClip; } else { /* * we need one 'real' region to put into the composite clip. if * pregWin the current composite clip are real, we can get rid of * one. if pregWin is real and the current composite clip isn't, * use pregWin for the composite clip. if the current composite * clip is real and pregWin isn't, use the current composite * clip. if neither is real, create a new region. */ RegionTranslate(pPicture->clientClip, pDrawable->x + pPicture->clipOrigin.x, pDrawable->y + pPicture->clipOrigin.y); if (freeCompClip) { RegionIntersect(pPicture->pCompositeClip, pregWin, pPicture->clientClip); if (freeTmpClip) RegionDestroy(pregWin); } else if (freeTmpClip) { RegionIntersect(pregWin, pregWin, pPicture->clientClip); pPicture->pCompositeClip = pregWin; } else { pPicture->pCompositeClip = RegionCreate(NullBox, 0); RegionIntersect(pPicture->pCompositeClip, pregWin, pPicture->clientClip); } pPicture->freeCompClip = TRUE; RegionTranslate(pPicture->clientClip, -(pDrawable->x + pPicture->clipOrigin.x), -(pDrawable->y + pPicture->clipOrigin.y)); } } /* end of composite clip for a window */ else { BoxRec pixbounds; /* XXX should we translate by drawable.x/y here ? */ /* If you want pixmaps in offscreen memory, yes */ pixbounds.x1 = pDrawable->x; pixbounds.y1 = pDrawable->y; pixbounds.x2 = pDrawable->x + pDrawable->width; pixbounds.y2 = pDrawable->y + pDrawable->height; if (pPicture->freeCompClip) { RegionReset(pPicture->pCompositeClip, &pixbounds); } else { pPicture->freeCompClip = TRUE; pPicture->pCompositeClip = RegionCreate(&pixbounds, 1); } if (pPicture->clientClipType == CT_REGION) { if(pDrawable->x || pDrawable->y) { RegionTranslate(pPicture->clientClip, pDrawable->x + pPicture->clipOrigin.x, pDrawable->y + pPicture->clipOrigin.y); RegionIntersect(pPicture->pCompositeClip, pPicture->pCompositeClip, pPicture->clientClip); RegionTranslate(pPicture->clientClip, -(pDrawable->x + pPicture->clipOrigin.x), -(pDrawable->y + pPicture->clipOrigin.y)); } else { RegionTranslate(pPicture->pCompositeClip, -pPicture->clipOrigin.x, -pPicture->clipOrigin.y); RegionIntersect(pPicture->pCompositeClip, pPicture->pCompositeClip, pPicture->clientClip); RegionTranslate(pPicture->pCompositeClip, pPicture->clipOrigin.x, pPicture->clipOrigin.y); } } } /* end of composite clip for pixmap */ } }
/** Transfer \a pBits image to back-end server associated with \a * pDrawable's screen. If primitive subdivision optimization is * enabled, then only transfer the sections of \a pBits that are * visible (i.e., not-clipped) to the back-end server. */ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) { DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); XImage *img; if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; img = XCreateImage(dmxScreen->beDisplay, dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, depth, format, leftPad, pBits, w, h, BitmapPad(dmxScreen->beDisplay), (format == ZPixmap) ? PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); if (img) { Drawable draw; DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); if (dmxSubdividePrimitives && pGC->pCompositeClip) { RegionPtr pSubImages; RegionPtr pClip; BoxRec box; BoxPtr pBox; int nBox; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; pSubImages = RegionCreate(&box, 1); pClip = RegionCreate(NullBox, 1); RegionCopy(pClip, pGC->pCompositeClip); RegionTranslate(pClip, -pDrawable->x, -pDrawable->y); RegionIntersect(pSubImages, pSubImages, pClip); nBox = RegionNumRects(pSubImages); pBox = RegionRects(pSubImages); while (nBox--) { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, pBox->x1 - box.x1, pBox->y1 - box.y1, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); pBox++; } RegionDestroy(pClip); RegionDestroy(pSubImages); } else { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, 0, 0, x, y, w, h); } XFree(img); /* Use XFree instead of XDestroyImage * because pBits is passed in from the * caller. */ dmxSync(dmxScreen, FALSE); } else { /* Error -- this should not happen! */ } }
void miDestroyPicture (PicturePtr pPicture) { if (pPicture->freeCompClip) RegionDestroy(pPicture->pCompositeClip); }
/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */ void rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects) { RegionRec clip_reg; RegionPtr fill_reg; int num_clips; int cd; int lw; int i; int j; int up; int down; int got_id; int dirty_type; int post_process; int reset_surface; xRectangle *regRects; xRectangle *r; xRectangle *rect1; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec *pDstPriv; rdpPixmapRec *pDirtyPriv; LLOGLN(10, ("rdpPolyRectangle:")); /* make a copy of rects */ rect1 = (xRectangle *)g_malloc(sizeof(xRectangle) * nrects, 0); for (i = 0; i < nrects; i++) { rect1[i] = rects[i]; } /* do original call */ rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects); dirty_type = 0; pDirtyPriv = 0; post_process = 0; reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { pDstPixmap = (PixmapPtr)pDrawable; pDstPriv = GETPIXPRIV(pDstPixmap); if (xrdp_is_os(pDstPixmap, pDstPriv)) { post_process = 1; if (g_do_dirty_os) { LLOGLN(10, ("rdpPolyRectangle: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; dirty_type = RDI_IMGLL; } else { rdpup_switch_os_surface(pDstPriv->rdpindex); reset_surface = 1; rdpup_get_pixmap_image_rect(pDstPixmap, &id); got_id = 1; } } } else { if (pDrawable->type == DRAWABLE_WINDOW) { pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { post_process = 1; if (g_do_dirty_ons) { LLOGLN(0, ("rdpPolyRectangle: gettig dirty")); g_screenPriv.is_dirty = 1; pDirtyPriv = &g_screenPriv; dirty_type = RDI_IMGLL; } else { rdpup_get_screen_image_rect(&id); got_id = 1; } } } } if (!post_process) { g_free(rect1); return; } RegionInit(&clip_reg, NullBox, 0); cd = rdp_get_clip(&clip_reg, pDrawable, pGC); regRects = 0; if ((cd != 0) && (nrects > 0)) { regRects = (xRectangle *)g_malloc(nrects * 4 * sizeof(xRectangle), 0); lw = pGC->lineWidth; if (lw < 1) { lw = 1; } up = lw / 2; down = 1 + (lw - 1) / 2; for (i = 0; i < nrects; i++) { r = regRects + i * 4; r->x = (rect1[i].x + pDrawable->x) - up; r->y = (rect1[i].y + pDrawable->y) - up; r->width = rect1[i].width + up + down; r->height = lw; r++; r->x = (rect1[i].x + pDrawable->x) - up; r->y = (rect1[i].y + pDrawable->y) + down; r->width = lw; r->height = MAX(rect1[i].height - (up + down), 0); r++; r->x = ((rect1[i].x + rect1[i].width) + pDrawable->x) - up; r->y = (rect1[i].y + pDrawable->y) + down; r->width = lw; r->height = MAX(rect1[i].height - (up + down), 0); r++; r->x = (rect1[i].x + pDrawable->x) - up; r->y = ((rect1[i].y + rect1[i].height) + pDrawable->y) - up; r->width = rect1[i].width + up + down; r->height = lw; } } if (cd == 1) { if (regRects != 0) { if (dirty_type != 0) { fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); if (pGC->lineStyle == LineSolid) { draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, pGC->alu); } else { draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type); } RegionDestroy(fill_reg); } else if (got_id) { rdpup_begin_update(); if (pGC->lineStyle == LineSolid) { rdpup_set_fgcolor(pGC->fgPixel); rdpup_set_opcode(pGC->alu); for (i = 0; i < nrects * 4; i++) { r = regRects + i; rdpup_fill_rect(r->x, r->y, r->width, r->height); } rdpup_set_opcode(GXcopy); } else { for (i = 0; i < nrects * 4; i++) { r = regRects + i; rdpup_send_area(&id, r->x, r->y, r->width, r->height); } } rdpup_end_update(); } } } else if (cd == 2) { if (regRects != 0) { fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); RegionIntersect(&clip_reg, &clip_reg, fill_reg); num_clips = REGION_NUM_RECTS(&clip_reg); if (num_clips > 0) { if (dirty_type != 0) { if (pGC->lineStyle == LineSolid) { draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, pGC->alu); } else { draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); } } else if (got_id) { rdpup_begin_update(); if (pGC->lineStyle == LineSolid) { rdpup_set_fgcolor(pGC->fgPixel); rdpup_set_opcode(pGC->alu); for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(&clip_reg)[j]; rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_set_opcode(GXcopy); } else { for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(&clip_reg)[j]; rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } } rdpup_end_update(); } } RegionDestroy(fill_reg); } } RegionUninit(&clip_reg); g_free(regRects); g_free(rect1); if (reset_surface) { rdpup_switch_os_surface(-1); } }
void winCopyWindowNativeGDI(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { DDXPointPtr pptSrc; DDXPointPtr ppt; RegionPtr prgnDst; BoxPtr pBox; int dx, dy; int i, nbox; WindowPtr pwinRoot; BoxPtr pBoxDst; ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); /* Get a pointer to the root window */ pwinRoot = pWin->drawable.pScreen->root; /* Create a region for the destination */ prgnDst = RegionCreate(NULL, 1); /* Calculate the shift from the source to the destination */ dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; /* Translate the region from the destination to the source? */ RegionTranslate(prgnSrc, -dx, -dy); RegionIntersect(prgnDst, &pWin->borderClip, prgnSrc); /* Get a pointer to the first box in the region to be copied */ pBox = RegionRects(prgnDst); /* Get the number of boxes in the region */ nbox = RegionNumRects(prgnDst); /* Allocate source points for each box */ if (!(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec)))) return; /* Set an iterator pointer */ ppt = pptSrc; /* Calculate the source point of each box? */ for (i = nbox; --i >= 0; ppt++, pBox++) { ppt->x = pBox->x1 + dx; ppt->y = pBox->y1 + dy; } /* Setup loop pointers again */ pBoxDst = RegionRects(prgnDst); ppt = pptSrc; /* BitBlt each source to the destination point */ for (i = nbox; --i >= 0; pBoxDst++, ppt++) { BitBlt(pScreenPriv->hdcScreen, pBoxDst->x1, pBoxDst->y1, pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1, pScreenPriv->hdcScreen, ppt->x, ppt->y, SRCCOPY); } /* Cleanup the regions, etc. */ free(pptSrc); RegionDestroy(prgnDst); }
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 = RegionFromRects(nrect, prect, CT_UNSORTED); /* Compute intersection of rects and clip region */ RegionTranslate(pReg, pDrawable->x, pDrawable->y); RegionIntersect(pReg, pClip, pReg); if (!RegionNumRects(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->clientClip != NULL)) || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, pGC->planemask, pGC->alu, pGC->clientClip != NULL))) { 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 (!exaPixmapHasGpuCopy(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 = RegionExtents(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 = RegionNumRects(pClip); if (n == 1) { (*pExaScr->info->Solid) (pPixmap, fullX1 + xoff, fullY1 + yoff, fullX2 + xoff, fullY2 + yoff); } else { pbox = RegionRects(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: RegionUninit(pReg); RegionDestroy(pReg); }
Bool xf86InitFBManagerArea(ScreenPtr pScreen, int PixelArea, int Verbosity) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); xRectangle Rect[3]; RegionPtr pRegion, pScreenRegion; int nRect; Bool ret = FALSE; if (PixelArea < (pScrn->displayWidth * pScrn->virtualY)) return FALSE; Rect[0].x = Rect[0].y = 0; Rect[0].width = pScrn->displayWidth; Rect[0].height = PixelArea / pScrn->displayWidth; nRect = 1; /* Add a possible partial scanline */ if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) { Rect[1].x = 0; Rect[1].y = Rect[0].height; Rect[1].height = 1; nRect++; } /* Factor out virtual resolution */ pRegion = RegionFromRects(nRect, Rect, 0); if (pRegion) { if (!RegionNar(pRegion)) { Rect[2].x = Rect[2].y = 0; Rect[2].width = pScrn->virtualX; Rect[2].height = pScrn->virtualY; pScreenRegion = RegionFromRects(1, &Rect[2], 0); if (pScreenRegion) { if (!RegionNar(pScreenRegion)) { RegionSubtract(pRegion, pRegion, pScreenRegion); ret = xf86InitFBManagerRegion(pScreen, pRegion); if (ret && xf86GetVerbosity() >= Verbosity) { int scrnIndex = pScrn->scrnIndex; xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity, "Largest offscreen areas (with overlaps):\n"); if (Rect[2].width < Rect[0].width) { xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity, "\t%d x %d rectangle at %d,0\n", Rect[0].width - Rect[2].width, Rect[0].height, Rect[2].width); } if (Rect[2].width < Rect[1].width) { xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity, "\t%d x %d rectangle at %d,0\n", Rect[1].width - Rect[2].width, Rect[0].height + Rect[1].height, Rect[2].width); } if (Rect[2].height < Rect[0].height) { xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity, "\t%d x %d rectangle at 0,%d\n", Rect[0].width, Rect[0].height - Rect[2].height, Rect[2].height); } if (Rect[1].height) { xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity, "\t%d x %d rectangle at 0,%d\n", Rect[1].width, Rect[0].height - Rect[2].height + Rect[1].height, Rect[2].height); } } } RegionDestroy(pScreenRegion); } } RegionDestroy(pRegion); } return ret; }