예제 #1
0
void
ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    DrawablePtr pDrawable = &pWin->drawable;
    ScreenPtr pScreen = pDrawable->pScreen;

    EXA_PRE_FALLBACK(pScreen);
    EXA_FALLBACK(("from %p\n", pWin));

    /* Only need the source bits, the destination region will be overwritten */
    if (pExaScr->prepare_access_reg) {
        PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
        int xoff, yoff;

        exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
        RegionTranslate(prgnSrc, xoff, yoff);
        pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
        RegionTranslate(prgnSrc, -xoff, -yoff);
    }
    else
        exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);

    swap(pExaScr, pScreen, CopyWindow);
    pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
    swap(pExaScr, pScreen, CopyWindow);
    exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
    EXA_POST_FALLBACK(pScreen);
}
예제 #2
0
void
fbCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    RegionRec rgnDst;
    int dx, dy;

    PixmapPtr pPixmap = fbGetWindowPixmap(pWin);
    DrawablePtr pDrawable = &pPixmap->drawable;

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    RegionTranslate(prgnSrc, -dx, -dy);

    RegionNull(&rgnDst);

    RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);

#ifdef COMPOSITE
    if (pPixmap->screen_x || pPixmap->screen_y)
        RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y);
#endif

    miCopyRegion(pDrawable, pDrawable,
                 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);

    RegionUninit(&rgnDst);
    fbValidateDrawable(&pWin->drawable);
}
예제 #3
0
void
ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
                 BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
                 Bool upsidedown, Pixel bitplane, void *closure)
{
    RegionRec reg;
    int xoff, yoff;

    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
                  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));

    if (pExaScr->prepare_access_reg && RegionInitBoxes(&reg, pbox, nbox)) {
        PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);

        exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
        RegionTranslate(&reg, xoff + dx, yoff + dy);
        pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
        RegionUninit(&reg);
    }
    else
        exaPrepareAccess(pSrc, EXA_PREPARE_SRC);

    if (pExaScr->prepare_access_reg &&
        !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
                               pGC->alu, pGC->clientClipType) &&
        RegionInitBoxes(&reg, pbox, nbox)) {
        PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);

        exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
        RegionTranslate(&reg, xoff, yoff);
        pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
        RegionUninit(&reg);
    }
    else
        exaPrepareAccess(pDst, EXA_PREPARE_DEST);

    /* This will eventually call fbCopyNtoN, with some calculation overhead. */
    while (nbox--) {
        pGC->ops->CopyArea(pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx,
                           pbox->y1 - pSrc->y + dy, pbox->x2 - pbox->x1,
                           pbox->y2 - pbox->y1, pbox->x1 - pDst->x,
                           pbox->y1 - pDst->y);
        pbox++;
    }
    exaFinishAccess(pSrc, EXA_PREPARE_SRC);
    exaFinishAccess(pDst, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
예제 #4
0
파일: shadow.c 프로젝트: csulmone/X11
static void
ShadowCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgn)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;
    ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
    int num = 0;
    RegionRec rgnDst;

    if (pPriv->vtSema) {
        RegionNull(&rgnDst);
        RegionCopy(&rgnDst, prgn);

        RegionTranslate(&rgnDst,
                        pWin->drawable.x - ptOldOrg.x,
                        pWin->drawable.y - ptOldOrg.y);
        RegionIntersect(&rgnDst, &pWin->borderClip, &rgnDst);
        if ((num = RegionNumRects(&rgnDst))) {
            if (pPriv->preRefresh)
                (*pPriv->preRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst));
        }
        else {
            RegionUninit(&rgnDst);
        }
    }

    pScreen->CopyWindow = pPriv->CopyWindow;
    (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn);
    pScreen->CopyWindow = ShadowCopyWindow;

    if (num) {
        if (pPriv->postRefresh)
            (*pPriv->postRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst));
        RegionUninit(&rgnDst);
    }
}
예제 #5
0
파일: shape.c 프로젝트: coffee8651/turbovnc
static int
ProcShapeOffset(ClientPtr client)
{
    WindowPtr pWin;

    REQUEST(xShapeOffsetReq);
    RegionPtr srcRgn;
    int rc;

    REQUEST_SIZE_MATCH(xShapeOffsetReq);
    UpdateCurrentTime();
    rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->destKind) {
    case ShapeBounding:
        srcRgn = wBoundingShape(pWin);
        break;
    case ShapeClip:
        srcRgn = wClipShape(pWin);
        break;
    case ShapeInput:
        srcRgn = wInputShape(pWin);
        break;
    default:
        client->errorValue = stuff->destKind;
        return BadValue;
    }
    if (srcRgn) {
        RegionTranslate(srcRgn, stuff->xOff, stuff->yOff);
        (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind);
    }
    SendShapeNotify(pWin, (int) stuff->destKind);
    return Success;
}
예제 #6
0
void
XAACopyWindow(
    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));

    if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) { 
	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, XAACopyWindow);
    	return;
    }

    pwinRoot = pScreen->root;

    RegionNull(&rgnDst);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    RegionTranslate(prgnSrc, -dx, -dy);
    RegionIntersect(&rgnDst, &pWin->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 = ~0L;
    infoRec->ScratchGC.alu = GXcopy;

    XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
        		&(infoRec->ScratchGC), &rgnDst, pptSrc);

    free(pptSrc);
    RegionUninit(&rgnDst);
}
예제 #7
0
static Bool
glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
                    int w, int h, int leftPad, int format, char *bits)
{
    ScreenPtr screen = drawable->pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
    glamor_pixmap_private *pixmap_priv;
    uint32_t    byte_stride = PixmapBytePad(w, drawable->depth);
    RegionRec   region;
    BoxRec      box;
    int         off_x, off_y;

    pixmap_priv = glamor_get_pixmap_private(pixmap);

    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
        return FALSE;

    if (gc->alu != GXcopy)
        goto bail;

    if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
        goto bail;

    if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
        format = ZPixmap;

    if (format != ZPixmap)
        goto bail;

    x += drawable->x;
    y += drawable->y;
    box.x1 = x;
    box.y1 = y;
    box.x2 = box.x1 + w;
    box.y2 = box.y1 + h;
    RegionInit(&region, &box, 1);
    RegionIntersect(&region, &region, gc->pCompositeClip);

    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
    if (off_x || off_y) {
        x += off_x;
        y += off_y;
        RegionTranslate(&region, off_x, off_y);
    }

    glamor_make_current(glamor_priv);

    glamor_upload_region(pixmap, &region, x, y, (uint8_t *) bits, byte_stride);

    RegionUninit(&region);
    return TRUE;
bail:
    return FALSE;
}
예제 #8
0
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    RegionRec	rgnDst;
    int		dx, dy;
    PixmapPtr	pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
    ExaScreenPriv(pWin->drawable.pScreen);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    RegionTranslate(prgnSrc, -dx, -dy);

    RegionInit(&rgnDst, NullBox, 0);

    RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
#ifdef COMPOSITE
    if (pPixmap->screen_x || pPixmap->screen_y)
	RegionTranslate(&rgnDst,
			  -pPixmap->screen_x, -pPixmap->screen_y);
#endif

    if (pExaScr->fallback_counter) {
	pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
	goto fallback;
    }

    pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
    miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
		  NULL,
		  &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
    pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;

fallback:
    RegionUninit(&rgnDst);

    if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
	pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
	RegionTranslate(prgnSrc, dx, dy);
	ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
    }
}
예제 #9
0
int
ProcXFixesTranslateRegion (ClientPtr client)
{
    RegionPtr	pRegion;
    REQUEST(xXFixesTranslateRegionReq);

    REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
    VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);

    RegionTranslate(pRegion, stuff->dx, stuff->dy);
    return Success;
}
예제 #10
0
파일: region.c 프로젝트: mirror/xserver
int
PanoramiXFixesSetWindowShapeRegion(ClientPtr client)
{
    int result = Success, j;
    PanoramiXRes *win;
    RegionPtr reg = NULL;

    REQUEST(xXFixesSetWindowShapeRegionReq);

    REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);

    if ((result = dixLookupResourceByType((void **) &win, stuff->dest,
                                          XRT_WINDOW, client,
                                          DixWriteAccess))) {
        client->errorValue = stuff->dest;
        return result;
    }

    if (win->u.win.root)
        VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess);

    FOR_NSCREENS_FORWARD(j) {
        ScreenPtr screen = screenInfo.screens[j];
        stuff->dest = win->info[j].id;

        if (reg)
            RegionTranslate(reg, -screen->x, -screen->y);

        result =
            (*PanoramiXSaveXFixesVector[X_XFixesSetWindowShapeRegion]) (client);

        if (reg)
            RegionTranslate(reg, screen->x, screen->y);

        if (result != Success)
            break;
    }

    return result;
}
예제 #11
0
파일: region.c 프로젝트: mirror/xserver
int
PanoramiXFixesSetPictureClipRegion(ClientPtr client)
{
    REQUEST(xXFixesSetPictureClipRegionReq);
    int result = Success, j;
    PanoramiXRes *pict;
    RegionPtr reg = NULL;

    REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);

    if ((result = dixLookupResourceByType((void **) &pict, stuff->picture,
                                          XRT_PICTURE, client,
                                          DixWriteAccess))) {
        client->errorValue = stuff->picture;
        return result;
    }

    if (pict->u.pict.root)
        VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess);

    FOR_NSCREENS_BACKWARD(j) {
        ScreenPtr screen = screenInfo.screens[j];
        stuff->picture = pict->info[j].id;

        if (reg)
            RegionTranslate(reg, -screen->x, -screen->y);

        result =
            (*PanoramiXSaveXFixesVector[X_XFixesSetPictureClipRegion]) (client);

        if (reg)
            RegionTranslate(reg, screen->x, screen->y);

        if (result != Success)
            break;
    }

    return result;
}
예제 #12
0
static int
ProcDamageAdd (ClientPtr client)
{
    REQUEST(xDamageAddReq);
    DrawablePtr	    pDrawable;
    RegionPtr	    pRegion;
    int		    rc;

    REQUEST_SIZE_MATCH(xDamageAddReq);
    VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
			   DixWriteAccess);
    if (rc != Success)
	return rc;

    /* The region is relative to the drawable origin, so translate it out to
     * screen coordinates like damage expects.
     */
    RegionTranslate(pRegion, pDrawable->x, pDrawable->y);
    DamageDamageRegion(pDrawable, pRegion);
    RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y);

    return Success;
}
예제 #13
0
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;
}
/**
 * Helper function to implement video blit, handling clipping, damage, etc..
 *
 * TODO: move to EXA?
 */
int
OMAPVidCopyArea(DrawablePtr pSrcDraw, BoxPtr pSrcBox,
		DrawablePtr pOsdDraw, BoxPtr pOsdBox,
		DrawablePtr pDstDraw, BoxPtr pDstBox,
		OMAPPutTextureImageProc PutTextureImage, void *closure,
		RegionPtr clipBoxes)
{
	ScreenPtr pScreen = pDstDraw->pScreen;
	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
	PixmapPtr pSrcPix = draw2pix(pSrcDraw);
	PixmapPtr pOsdPix = draw2pix(pOsdDraw);
	PixmapPtr pDstPix = draw2pix(pDstDraw);
	pixman_fixed_t sx, sy, tx, ty;
	pixman_transform_t srcxfrm;
	BoxPtr pbox;
	int nbox, dx, dy, ret = Success;

#ifdef COMPOSITE
	DEBUG_MSG("--> %dx%d, %dx%d", pDstPix->screen_x, pDstPix->screen_y,
			pDstDraw->x, pDstDraw->y);
	/* Convert screen coords to pixmap coords */
	if (pDstPix->screen_x || pDstPix->screen_y) {
		RegionTranslate(clipBoxes, -pDstPix->screen_x, -pDstPix->screen_y);
	}
	dx = pDstPix->screen_x;
	dy = pDstPix->screen_y;
#else
	dx = 0;
	dy = 0;
#endif

	/* the clip-region gives coordinates in dst's coord space..  generate
	 * a transform that can be used to work backwards from dst->src coord
	 * space:
	 */
	sx = ((pixman_fixed_48_16_t) (pSrcBox->x2 - pSrcBox->x1) << 16) /
			(pDstBox->x2 - pDstBox->x1);
	sy = ((pixman_fixed_48_16_t) (pSrcBox->y2 - pSrcBox->y1) << 16) /
			(pDstBox->y2 - pDstBox->y1);
	tx = ((pixman_fixed_48_16_t)(pDstBox->x1 - pSrcBox->x1 - dx) << 16);
	ty = ((pixman_fixed_48_16_t)(pDstBox->y1 - pSrcBox->y1 - dy) << 16);

	pixman_transform_init_scale(&srcxfrm, sx, sy);
	pixman_transform_translate(NULL, &srcxfrm, tx, ty);

	// TODO generate transform for osd as well

	pbox = RegionRects(clipBoxes);
	nbox = RegionNumRects(clipBoxes);

	while (nbox--) {
		RegionRec damage;
		BoxRec dstb = *pbox;
		BoxRec srcb = *pbox;
		BoxRec osdb = *pbox;

		pixman_transform_bounds(&srcxfrm, &srcb);
		//pixman_transform_bounds(&osdxfrm, &osdb);

		DEBUG_MSG("%d,%d %d,%d -> %d,%d %d,%d",
				srcb.x1, srcb.y1, srcb.x2, srcb.y2,
				dstb.x1, dstb.y1, dstb.x2, dstb.y2);

		ret = PutTextureImage(pSrcPix, &srcb, pOsdPix, &osdb,
				pDstPix, &dstb, closure);
		if (ret != Success) {
			break;
		}

		RegionInit(&damage, &dstb, 1);

#ifdef COMPOSITE
		/* Convert screen coords to pixmap coords */
		if (pDstPix->screen_x || pDstPix->screen_y) {
			RegionTranslate(&damage, pDstPix->screen_x, pDstPix->screen_y);
		}
#endif

		DamageRegionAppend(pDstDraw, &damage);
		RegionUninit(&damage);

		pbox++;
	}

	DamageRegionProcessPending(pDstDraw);

	return ret;
}
예제 #15
0
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
 * Based on fbFillRegionTiled(), fbTile().
 */
Bool
exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
                   DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
                   Bool hasClientClip)
{
    ExaScreenPriv(pDrawable->pScreen);
    PixmapPtr pPixmap;
    ExaPixmapPrivPtr pExaPixmap;
    ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
    int xoff, yoff;
    int tileWidth, tileHeight;
    int nbox = RegionNumRects(pRegion);
    BoxPtr pBox = RegionRects(pRegion);
    Bool ret = FALSE;
    int i;

    tileWidth = pTile->drawable.width;
    tileHeight = pTile->drawable.height;

    /* If we're filling with a solid color, grab it out and go to
     * FillRegionSolid, saving numerous copies.
     */
    if (tileWidth == 1 && tileHeight == 1)
        return exaFillRegionSolid(pDrawable, pRegion,
                                  exaGetPixmapFirstPixel(pTile), planemask,
                                  alu, hasClientClip);

    pPixmap = exaGetDrawablePixmap(pDrawable);
    pExaPixmap = ExaGetPixmapPriv(pPixmap);

    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
        pTileExaPixmap->accel_blocked)
        return FALSE;

    if (pExaScr->do_migration) {
        ExaMigrationRec pixmaps[2];

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pPixmap;
        pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
                                                alu,
                                                hasClientClip) ? NULL : pRegion;
        pixmaps[1].as_dst = FALSE;
        pixmaps[1].as_src = TRUE;
        pixmaps[1].pPix = pTile;
        pixmaps[1].pReg = NULL;

        exaDoMigration(pixmaps, 2, TRUE);
    }

    pPixmap = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);

    if (!pPixmap || !exaPixmapHasGpuCopy(pTile))
        return FALSE;

    if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) {
        if (xoff || yoff)
            RegionTranslate(pRegion, xoff, yoff);

        for (i = 0; i < nbox; i++) {
            int height = pBox[i].y2 - pBox[i].y1;
            int dstY = pBox[i].y1;
            int tileY;

            if (alu == GXcopy)
                height = min(height, tileHeight);

            modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);

            while (height > 0) {
                int width = pBox[i].x2 - pBox[i].x1;
                int dstX = pBox[i].x1;
                int tileX;
                int h = tileHeight - tileY;

                if (alu == GXcopy)
                    width = min(width, tileWidth);

                if (h > height)
                    h = height;
                height -= h;

                modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
                        tileX);

                while (width > 0) {
                    int w = tileWidth - tileX;

                    if (w > width)
                        w = width;
                    width -= w;

                    (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
                                            w, h);
                    dstX += w;
                    tileX = 0;
                }
                dstY += h;
                tileY = 0;
            }
        }
        (*pExaScr->info->DoneCopy) (pPixmap);

        /* With GXcopy, we only need to do the basic algorithm up to the tile
         * size; then, we can just keep doubling the destination in each
         * direction until it fills the box. This way, the number of copy
         * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where
         * rx/ry is the ratio between box and tile width/height. This can make
         * a big difference if each driver copy incurs a significant constant
         * overhead.
         */
        if (alu != GXcopy)
            ret = TRUE;
        else {
            Bool more_copy = FALSE;

            for (i = 0; i < nbox; i++) {
                int dstX = pBox[i].x1 + tileWidth;
                int dstY = pBox[i].y1 + tileHeight;

                if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) {
                    more_copy = TRUE;
                    break;
                }
            }

            if (more_copy == FALSE)
                ret = TRUE;

            if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap,
                                                            1, 1, alu,
                                                            planemask)) {
                for (i = 0; i < nbox; i++) {
                    int dstX = pBox[i].x1 + tileWidth;
                    int dstY = pBox[i].y1 + tileHeight;
                    int width = min(pBox[i].x2 - dstX, tileWidth);
                    int height = min(pBox[i].y2 - pBox[i].y1, tileHeight);

                    while (dstX < pBox[i].x2) {
                        (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
                                                dstX, pBox[i].y1, width,
                                                height);
                        dstX += width;
                        width = min(pBox[i].x2 - dstX, width * 2);
                    }

                    width = pBox[i].x2 - pBox[i].x1;
                    height = min(pBox[i].y2 - dstY, tileHeight);

                    while (dstY < pBox[i].y2) {
                        (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
                                                pBox[i].x1, dstY, width,
                                                height);
                        dstY += height;
                        height = min(pBox[i].y2 - dstY, height * 2);
                    }
                }

                (*pExaScr->info->DoneCopy) (pPixmap);

                ret = TRUE;
            }
        }

        exaMarkSync(pDrawable->pScreen);

        if (xoff || yoff)
            RegionTranslate(pRegion, -xoff, -yoff);
    }

    return ret;
}
예제 #16
0
파일: dmxgcops.c 프로젝트: 4eremuxa/xserver
/** 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! */
    }
}
예제 #17
0
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(&region, &box, 1);
        clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
                                                             &region,
                                                             &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(&region);
    }
    else
        _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);

    glamor_set_alu(screen, GXcopy);
    return TRUE;
 fail:
    return FALSE;

}
void
winReshapeMultiWindow(WindowPtr pWin)
{
    int nRects;
    RegionRec rrNewShape;
    BoxPtr pShape, pRects, pEnd;
    HRGN hRgn, hRgnRect;

    winWindowPriv(pWin);

    winDebug("winReshape ()\n");

    /* Bail if the window is the root window */
    if (pWin->parent == NULL)
        return;

    /* Bail if the window is not top level */
    if (pWin->parent->parent != NULL)
        return;

    /* Bail if Windows window handle is invalid */
    if (pWinPriv->hWnd == NULL)
        return;

    /* Free any existing window region stored in the window privates */
    if (pWinPriv->hRgn != NULL) {
        DeleteObject(pWinPriv->hRgn);
        pWinPriv->hRgn = NULL;
    }

    /* Bail if the window has no bounding region defined */
    if (!wBoundingShape(pWin))
        return;

    RegionNull(&rrNewShape);
    RegionCopy(&rrNewShape, wBoundingShape(pWin));
    RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth);

    nRects = RegionNumRects(&rrNewShape);
    pShape = RegionRects(&rrNewShape);

    /* Don't do anything if there are no rectangles in the region */
    if (nRects > 0) {
        RECT rcClient;
        RECT rcWindow;
        int iOffsetX, iOffsetY;

        /* Get client rectangle */
        if (!GetClientRect(pWinPriv->hWnd, &rcClient)) {
            ErrorF("winReshape - GetClientRect failed, bailing: %d\n",
                   (int) GetLastError());
            return;
        }

        /* Translate client rectangle coords to screen coords */
        /* NOTE: Only transforms top and left members */
        ClientToScreen(pWinPriv->hWnd, (LPPOINT) &rcClient);

        /* Get window rectangle */
        if (!GetWindowRect(pWinPriv->hWnd, &rcWindow)) {
            ErrorF("winReshape - GetWindowRect failed, bailing: %d\n",
                   (int) GetLastError());
            return;
        }

        /* Calculate offset from window upper-left to client upper-left */
        iOffsetX = rcClient.left - rcWindow.left;
        iOffsetY = rcClient.top - rcWindow.top;

        /* Create initial Windows region for title bar */
        /* FIXME: Mean, nasty, ugly hack!!! */
        hRgn = CreateRectRgn(0, 0, rcWindow.right, iOffsetY);
        if (hRgn == NULL) {
            ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
                   "failed: %d\n",
                   0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError());
        }

        /* Loop through all rectangles in the X region */
        for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) {
            /* Create a Windows region for the X rectangle */
            hRgnRect = CreateRectRgn(pRects->x1 + iOffsetX,
                                     pRects->y1 + iOffsetY,
                                     pRects->x2 + iOffsetX,
                                     pRects->y2 + iOffsetY);
            if (hRgnRect == NULL) {
                ErrorF("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
                       "failed: %d\n"
                       "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n",
                       pRects->x1 + iOffsetX,
                       pRects->y1 + iOffsetY,
                       pRects->x2 + iOffsetX,
                       pRects->y2 + iOffsetY,
                       (int) GetLastError(),
                       pRects->x1, pRects->x2, iOffsetX,
                       pRects->y1, pRects->y2, iOffsetY);
            }

            /* Merge the Windows region with the accumulated region */
            if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) {
                ErrorF("winReshape - CombineRgn () failed: %d\n",
                       (int) GetLastError());
            }

            /* Delete the temporary Windows region */
            DeleteObject(hRgnRect);
        }

        /* Save a handle to the composite region in the window privates */
        pWinPriv->hRgn = hRgn;
    }

    RegionUninit(&rrNewShape);

    return;
}
예제 #19
0
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);
}
예제 #20
0
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(&region, box, nbox);
	extent = RegionExtents(&region);

	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(&region, dst_x_off, dst_y_off);
			if (!force_clip)
				clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
										     &region, &n_dst_region, 0,
										     reverse, upsidedown);
			else
				clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv,
										         &region, &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(&region);
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;
}
예제 #21
0
파일: region.c 프로젝트: mirror/xserver
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;
}
예제 #22
0
static Bool
ExaPrepareCompositeReg(ScreenPtr pScreen,
                       CARD8 op,
                       PicturePtr pSrc,
                       PicturePtr pMask,
                       PicturePtr pDst,
                       INT16 xSrc,
                       INT16 ySrc,
                       INT16 xMask,
                       INT16 yMask,
                       INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    RegionRec region;
    RegionPtr dstReg = NULL;
    RegionPtr srcReg = NULL;
    RegionPtr maskReg = NULL;
    PixmapPtr pSrcPix = NULL;
    PixmapPtr pMaskPix = NULL;
    PixmapPtr pDstPix;

    ExaScreenPriv(pScreen);
    Bool ret;

    RegionNull(&region);

    if (pSrc->pDrawable) {
        pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
        RegionNull(&pExaScr->srcReg);
        srcReg = &pExaScr->srcReg;
        pExaScr->srcPix = pSrcPix;
        if (pSrc != pDst)
            RegionTranslate(pSrc->pCompositeClip,
                            -pSrc->pDrawable->x, -pSrc->pDrawable->y);
    } else
        pExaScr->srcPix = NULL;

    if (pMask && pMask->pDrawable) {
        pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
        RegionNull(&pExaScr->maskReg);
        maskReg = &pExaScr->maskReg;
        pExaScr->maskPix = pMaskPix;
        if (pMask != pDst && pMask != pSrc)
            RegionTranslate(pMask->pCompositeClip,
                            -pMask->pDrawable->x, -pMask->pDrawable->y);
    } else
        pExaScr->maskPix = NULL;

    RegionTranslate(pDst->pCompositeClip,
                    -pDst->pDrawable->x, -pDst->pDrawable->y);

    pExaScr->SavedSourceValidate = ExaSrcValidate;
    swap(pExaScr, pScreen, SourceValidate);
    ret = miComputeCompositeRegion(&region, pSrc, pMask, pDst,
                                   xSrc, ySrc, xMask, yMask,
                                   xDst, yDst, width, height);
    swap(pExaScr, pScreen, SourceValidate);

    RegionTranslate(pDst->pCompositeClip,
                    pDst->pDrawable->x, pDst->pDrawable->y);
    if (pSrc->pDrawable && pSrc != pDst)
        RegionTranslate(pSrc->pCompositeClip,
                        pSrc->pDrawable->x, pSrc->pDrawable->y);
    if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
        RegionTranslate(pMask->pCompositeClip,
                        pMask->pDrawable->x, pMask->pDrawable->y);

    if (!ret) {
        if (srcReg)
            RegionUninit(srcReg);
        if (maskReg)
            RegionUninit(maskReg);

        return FALSE;
    }

    /**
     * Don't limit alphamaps readbacks for now until we've figured out how that
     * should be done.
     */

    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
        pExaScr->
            prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
                               EXA_PREPARE_AUX_SRC, NULL);
    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
        pExaScr->
            prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
                               EXA_PREPARE_AUX_MASK, NULL);

    if (pSrcPix)
        pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg);

    if (pMaskPix)
        pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg);

    if (srcReg)
        RegionUninit(srcReg);
    if (maskReg)
        RegionUninit(maskReg);

    pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
    if (!exaOpReadsDestination(op)) {
        int xoff;
        int yoff;

        exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff);
        RegionTranslate(&region, pDst->pDrawable->x + xoff,
                        pDst->pDrawable->y + yoff);
        dstReg = &region;
    }

    if (pDst->alphaMap && pDst->alphaMap->pDrawable)
        pExaScr->
            prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
                               EXA_PREPARE_AUX_DEST, dstReg);
    pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);

    RegionUninit(&region);
    return TRUE;
}
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 */
    }
}
예제 #24
0
파일: xaaOverlay.c 프로젝트: csulmone/X11
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);
}
예제 #25
0
bool
sna_tiling_fill_boxes(struct sna *sna,
		      CARD8 op,
		      PictFormat format,
		      const xRenderColor *color,
		      PixmapPtr dst, struct kgem_bo *dst_bo,
		      const BoxRec *box, int n)
{
	RegionRec region, tile, this;
	struct kgem_bo *bo;
	int step;
	bool ret = false;

	pixman_region_init_rects(&region, box, n);

	/* Use a small step to accommodate enlargement through tile alignment */
	step = sna->render.max_3d_size;
	if (region.extents.x1 & (8*512 / dst->drawable.bitsPerPixel - 1) ||
	    region.extents.y1 & 63)
		step /= 2;
	while (step * step * 4 > sna->kgem.max_copy_tile_size)
		step /= 2;

	DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n",
	     __FUNCTION__, op, (int)format,
	     color->red, color->green, color->blue, color->alpha,
	     step, n,
	     region.extents.x1, region.extents.y1,
	     region.extents.x2, region.extents.y2));

	for (tile.extents.y1 = tile.extents.y2 = region.extents.y1;
	     tile.extents.y2 < region.extents.y2;
	     tile.extents.y1 = tile.extents.y2) {
		int y2 = tile.extents.y1 + step;
		if (y2 > region.extents.y2)
			y2 = region.extents.y2;
		tile.extents.y2 = y2;

		for (tile.extents.x1 = tile.extents.x2 = region.extents.x1;
		     tile.extents.x2 < region.extents.x2;
		     tile.extents.x1 = tile.extents.x2) {
			PixmapRec tmp;
			int x2 = tile.extents.x1 + step;
			if (x2 > region.extents.x2)
				x2 = region.extents.x2;
			tile.extents.x2 = x2;

			tile.data = NULL;

			RegionNull(&this);
			RegionIntersect(&this, &region, &tile);
			if (RegionNil(&this))
				continue;

			tmp.drawable.width  = this.extents.x2 - this.extents.x1;
			tmp.drawable.height = this.extents.y2 - this.extents.y1;
			tmp.drawable.depth  = dst->drawable.depth;
			tmp.drawable.bitsPerPixel = dst->drawable.bitsPerPixel;
			tmp.devPrivate.ptr = NULL;

			bo = kgem_create_2d(&sna->kgem,
					    tmp.drawable.width,
					    tmp.drawable.height,
					    dst->drawable.bitsPerPixel,
					    kgem_choose_tiling(&sna->kgem,
							       I915_TILING_X,
							       tmp.drawable.width,
							       tmp.drawable.height,
							       dst->drawable.bitsPerPixel),
					    CREATE_TEMPORARY);
			if (bo) {
				int16_t dx = this.extents.x1;
				int16_t dy = this.extents.y1;

				assert(kgem_bo_can_blt(&sna->kgem, bo));

				if (!sna->render.copy_boxes(sna, GXcopy,
							     dst, dst_bo, 0, 0,
							     &tmp, bo, -dx, -dy,
							     REGION_RECTS(&this), REGION_NUM_RECTS(&this), 0))
					goto err;

				RegionTranslate(&this, -dx, -dy);
				if (!sna->render.fill_boxes(sna, op, format, color,
							     &tmp, bo,
							     REGION_RECTS(&this), REGION_NUM_RECTS(&this)))
					goto err;

				if (!sna->render.copy_boxes(sna, GXcopy,
							     &tmp, bo, 0, 0,
							     dst, dst_bo, dx, dy,
							     REGION_RECTS(&this), REGION_NUM_RECTS(&this), 0))
					goto err;

				kgem_bo_destroy(&sna->kgem, bo);
			}
			RegionUninit(&this);
		}
	}

	ret = true;
	goto done;
err:
	kgem_bo_destroy(&sna->kgem, bo);
	RegionUninit(&this);
done:
	pixman_region_fini(&region);
	return ret;
}
예제 #26
0
static int
ProcWindowsWMFrameDraw(ClientPtr client)
{
    REQUEST(xWindowsWMFrameDrawReq);
    WindowPtr pWin;
    win32RootlessWindowPtr pRLWinPriv;
    RECT rcNew;
    int nCmdShow, rc;
    RegionRec newShape;

    REQUEST_SIZE_MATCH(xWindowsWMFrameDrawReq);

#if CYGMULTIWINDOW_DEBUG
    ErrorF("ProcWindowsWMFrameDraw\n");
#endif
    rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
    if (rc != Success)
        return rc;
#if CYGMULTIWINDOW_DEBUG
    ErrorF("ProcWindowsWMFrameDraw - Window found\n");
#endif

    pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, TRUE);
    if (pRLWinPriv == 0)
        return BadWindow;

#if CYGMULTIWINDOW_DEBUG
    ErrorF("ProcWindowsWMFrameDraw - HWND %p 0x%08x 0x%08x\n",
           pRLWinPriv->hWnd, (int) stuff->frame_style,
           (int) stuff->frame_style_ex);
    ErrorF("ProcWindowsWMFrameDraw - %d %d %d %d\n",
           stuff->ix, stuff->iy, stuff->iw, stuff->ih);
#endif

    /* Store the origin, height, and width in a rectangle structure */
    SetRect(&rcNew, stuff->ix, stuff->iy,
            stuff->ix + stuff->iw, stuff->iy + stuff->ih);

    /*
     * Calculate the required size of the Windows window rectangle,
     * given the size of the Windows window client area.
     */
    AdjustWindowRectEx(&rcNew, stuff->frame_style, FALSE,
                       stuff->frame_style_ex);

    /* Set the window extended style flags */
    if (!SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex)) {
        return BadValue;
    }

    /* Set the window standard style flags */
    if (!SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style)) {
        return BadValue;
    }

    /* Flush the window style */
    if (!SetWindowPos(pRLWinPriv->hWnd, NULL,
                      rcNew.left, rcNew.top,
                      rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
                      SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE)) {
        return BadValue;
    }
    if (!IsWindowVisible(pRLWinPriv->hWnd))
        nCmdShow = SW_HIDE;
    else
        nCmdShow = SW_SHOWNA;

    ShowWindow(pRLWinPriv->hWnd, nCmdShow);

    if (wBoundingShape(pWin) != NULL) {
        /* wBoundingShape is relative to *inner* origin of window.
           Translate by borderWidth to get the outside-relative position. */

        RegionNull(&newShape);
        RegionCopy(&newShape, wBoundingShape(pWin));
        RegionTranslate(&newShape, pWin->borderWidth, pWin->borderWidth);
        winMWExtWMReshapeFrame(pRLWinPriv, &newShape);
        RegionUninit(&newShape);
    }
#if CYGMULTIWINDOW_DEBUG
    ErrorF("ProcWindowsWMFrameDraw - done\n");
#endif

    return Success;
}
예제 #27
0
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);
}
예제 #28
0
static
    void
winReshapeRootless(WindowPtr pWin)
{
    int nRects;
    RegionRec rrNewShape;
    BoxPtr pShape, pRects, pEnd;
    HRGN hRgn, hRgnRect;

    winWindowPriv(pWin);

    winDebug("winReshapeRootless ()\n");

    /* Bail if the window is the root window */
    if (pWin->parent == NULL)
        return;

    /* Bail if the window is not top level */
    if (pWin->parent->parent != NULL)
        return;

    /* Free any existing window region stored in the window privates */
    if (pWinPriv->hRgn != NULL) {
        DeleteObject(pWinPriv->hRgn);
        pWinPriv->hRgn = NULL;
    }

    /* Bail if the window has no bounding region defined */
    if (!wBoundingShape(pWin))
        return;

    RegionNull(&rrNewShape);
    RegionCopy(&rrNewShape, wBoundingShape(pWin));
    RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth);

    nRects = RegionNumRects(&rrNewShape);
    pShape = RegionRects(&rrNewShape);

    if (nRects > 0) {
        /* Create initial empty Windows region */
        hRgn = CreateRectRgn(0, 0, 0, 0);

        /* Loop through all rectangles in the X region */
        for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) {
            /* Create a Windows region for the X rectangle */
            hRgnRect = CreateRectRgn(pRects->x1, pRects->y1,
                                     pRects->x2, pRects->y2);
            if (hRgnRect == NULL) {
                ErrorF("winReshapeRootless - CreateRectRgn() failed\n");
            }

            /* Merge the Windows region with the accumulated region */
            if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) {
                ErrorF("winReshapeRootless - CombineRgn() failed\n");
            }

            /* Delete the temporary Windows region */
            DeleteObject(hRgnRect);
        }

        /* Save a handle to the composite region in the window privates */
        pWinPriv->hRgn = hRgn;
    }

    RegionUninit(&rrNewShape);

    return;
}
예제 #29
0
static Bool
exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
                   CARD32 planemask, CARD32 alu, Bool hasClientClip)
{
    ExaScreenPriv(pDrawable->pScreen);
    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);

    ExaPixmapPriv(pPixmap);
    int xoff, yoff;
    Bool ret = FALSE;

    exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
    RegionTranslate(pRegion, xoff, yoff);

    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
        goto out;

    if (pExaScr->do_migration) {
        ExaMigrationRec pixmaps[1];

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pPixmap;
        pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
                                                alu,
                                                hasClientClip) ? NULL : pRegion;

        exaDoMigration(pixmaps, 1, TRUE);
    }

    if (exaPixmapHasGpuCopy(pPixmap) &&
        (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) {
        int nbox;
        BoxPtr pBox;

        nbox = RegionNumRects(pRegion);
        pBox = RegionRects(pRegion);

        while (nbox--) {
            (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
                                     pBox->y2);
            pBox++;
        }
        (*pExaScr->info->DoneSolid) (pPixmap);
        exaMarkSync(pDrawable->pScreen);

        if (pExaPixmap->pDamage &&
            pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
            pDrawable->width == 1 && pDrawable->height == 1 &&
            pDrawable->bitsPerPixel != 24) {
            RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);

            switch (pDrawable->bitsPerPixel) {
            case 32:
                *(CARD32 *) pExaPixmap->sys_ptr = pixel;
                break;
            case 16:
                *(CARD16 *) pExaPixmap->sys_ptr = pixel;
                break;
            case 8:
            case 4:
            case 1:
                *(CARD8 *) pExaPixmap->sys_ptr = pixel;
            }

            RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, pRegion);
            RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, pRegion);
            RegionSubtract(pending_damage, pending_damage, pRegion);
        }

        ret = TRUE;
    }

 out:
    RegionTranslate(pRegion, -xoff, -yoff);

    return ret;
}
예제 #30
0
파일: migc.c 프로젝트: mirror/xserver
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 */