static inline Bool exchangebufs(DrawablePtr pDraw, DRI2BufferPtr a, DRI2BufferPtr b) { msm_pixmap_exchange(draw2pix(dri2draw(pDraw, a)), draw2pix(dri2draw(pDraw, b))); exchange(a->name, b->name); return TRUE; }
static inline Bool exchangebufs(DrawablePtr pDraw, DRI2BufferPtr a, DRI2BufferPtr b) { PixmapPtr aPix = draw2pix(dri2draw(pDraw, a)); PixmapPtr bPix = draw2pix(dri2draw(pDraw, b)); ARMSOCPixmapExchange(aPix, bPix); exchange(a->name, b->name); return TRUE; }
/** * Create Buffer. */ static DRI2BufferPtr MSMDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); MSMDRI2BufferPtr buf = calloc(1, sizeof(*buf)); PixmapPtr pPixmap; int ret; DEBUG_MSG("pDraw=%p, attachment=%d, format=%08x", pDraw, attachment, format); if (!buf) { return NULL; } if (attachment == DRI2BufferFrontLeft) { pPixmap = draw2pix(pDraw); pPixmap->refcnt++; } else { pPixmap = createpix(pDraw); } DRIBUF(buf)->attachment = attachment; DRIBUF(buf)->cpp = pPixmap->drawable.bitsPerPixel / 8; DRIBUF(buf)->format = format; buf->refcnt = 1; buf->pPixmap = pPixmap; ret = msm_get_pixmap_name(pPixmap, &DRIBUF(buf)->name, &DRIBUF(buf)->pitch); if (ret) { ERROR_MSG("could not get buffer name: %d", ret); MSMDRI2DestroyBuffer(pDraw, DRIBUF(buf)); return NULL; } return DRIBUF(buf); }
/** * 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; }
static Bool create_buffer(DrawablePtr pDraw, struct ARMSOCDRI2BufferRec *buf) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); DRI2BufferPtr buffer = DRIBUF(buf); PixmapPtr pPixmap = NULL; struct armsoc_bo *bo; int ret; if (buffer->attachment == DRI2BufferFrontLeft) { pPixmap = draw2pix(pDraw); pPixmap->refcnt++; } else { pPixmap = createpix(pDraw); } if (!pPixmap) { assert(buffer->attachment != DRI2BufferFrontLeft); ERROR_MSG("Failed to create back buffer for window"); goto fail; } if (buffer->attachment == DRI2BufferBackLeft && pARMSOC->driNumBufs > 2) { buf->pPixmaps = calloc(pARMSOC->driNumBufs-1, sizeof(PixmapPtr)); buf->numPixmaps = pARMSOC->driNumBufs-1; } else { buf->pPixmaps = malloc(sizeof(PixmapPtr)); buf->numPixmaps = 1; } if (!buf->pPixmaps) { ERROR_MSG("Failed to allocate PixmapPtr array for DRI2Buffer"); goto fail; } buf->pPixmaps[0] = pPixmap; assert(buf->currentPixmap == 0); bo = ARMSOCPixmapBo(pPixmap); if (!bo) { ERROR_MSG( "Attempting to DRI2 wrap a pixmap with no DRM buffer object backing"); goto fail; } DRIBUF(buf)->pitch = exaGetPixmapPitch(pPixmap); DRIBUF(buf)->cpp = pPixmap->drawable.bitsPerPixel / 8; DRIBUF(buf)->flags = 0; buf->refcnt = 1; buf->previous_canflip = canflip(pDraw); ret = armsoc_bo_get_name(bo, &DRIBUF(buf)->name); if (ret) { ERROR_MSG("could not get buffer name: %d", ret); goto fail; } if (canflip(pDraw) && buffer->attachment != DRI2BufferFrontLeft) { /* Create an fb around this buffer. This will fail and we will * fall back to blitting if the display controller hardware * cannot scan out this buffer (for example, if it doesn't * support the format or there was insufficient scanout memory * at buffer creation time). */ int ret = armsoc_bo_add_fb(bo); if (ret) { WARNING_MSG( "Falling back to blitting a flippable window"); } #if DRI2INFOREC_VERSION >= 6 else if (FALSE == DRI2SwapLimit(pDraw, pARMSOC->swap_chain_size)) { WARNING_MSG( "Failed to set DRI2SwapLimit(%x,%d)", (unsigned int)pDraw, pARMSOC->swap_chain_size); } #endif /* DRI2INFOREC_VERSION >= 6 */ } DRI2_BUFFER_SET_FB(DRIBUF(buf)->flags, armsoc_bo_get_fb(bo) > 0 ? 1 : 0); DRI2_BUFFER_SET_REUSED(DRIBUF(buf)->flags, 0); /* Register Pixmap as having a buffer that can be accessed externally, * so needs synchronised access */ ARMSOCRegisterExternalAccess(pPixmap); return TRUE; fail: if (pPixmap != NULL) { if (buffer->attachment != DRI2BufferFrontLeft) pScreen->DestroyPixmap(pPixmap); else pPixmap->refcnt--; } return FALSE; }