diff options
author | Rob Clark <robdclark@gmail.com> | 2014-03-25 18:22:19 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2014-05-04 19:55:25 -0400 |
commit | 8b38461c8ab4cabba63be2f572fa024d6d8241a5 (patch) | |
tree | 5a837e8f6e4df0c7d811815f1b524efcfc22e195 | |
parent | 81baded8e385d8e1b9cb937a327d6fe564a70c69 (diff) |
xa: add composite
Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r-- | src/msm-exa-xa.c | 220 | ||||
-rw-r--r-- | src/msm-exa.c | 16 | ||||
-rw-r--r-- | src/msm.h | 1 |
3 files changed, 213 insertions, 24 deletions
diff --git a/src/msm-exa-xa.c b/src/msm-exa-xa.c index dadfbad..5cd4b7e 100644 --- a/src/msm-exa-xa.c +++ b/src/msm-exa-xa.c @@ -54,6 +54,8 @@ struct exa_state { struct xa_context *ctx; struct xa_composite comp; + struct xa_picture dst_pict, src_pict, mask_pict; + union xa_source_pict dst_spict, src_spict, mask_spict; }; /** @@ -226,12 +228,207 @@ XADoneCopy(PixmapPtr pDstPixmap) xa_copy_done(exa->ctx); } +/* + * Composite: + */ + +static const enum xa_surface_type stype_map[] = { + [PICT_TYPE_OTHER] = xa_type_other, + [PICT_TYPE_A] = xa_type_a, + [PICT_TYPE_ARGB] = xa_type_argb, + [PICT_TYPE_ABGR] = xa_type_abgr, + [PICT_TYPE_BGRA] = xa_type_bgra +}; + + +/* + * Create an xa format from a PICT format. + */ +enum xa_formats +to_xa_format(enum _PictFormatShort format) +{ + uint32_t ptype = PICT_FORMAT_TYPE(format); + + if ((ptype >= ARRAY_SIZE(stype_map)) || + (stype_map[ptype] == 0) || + (stype_map[ptype] == xa_type_other)) + return xa_format_unknown; + + return xa_format(PICT_FORMAT_BPP(format), + stype_map[ptype], + PICT_FORMAT_A(format), + PICT_FORMAT_R(format), + PICT_FORMAT_G(format), + PICT_FORMAT_B(format)); +} + + +static Bool +matrix_from_pict_transform(PictTransform *trans, float *matrix) +{ + if (!trans) + return FALSE; + + matrix[0] = pixman_fixed_to_double(trans->matrix[0][0]); + matrix[3] = pixman_fixed_to_double(trans->matrix[0][1]); + matrix[6] = pixman_fixed_to_double(trans->matrix[0][2]); + + matrix[1] = pixman_fixed_to_double(trans->matrix[1][0]); + matrix[4] = pixman_fixed_to_double(trans->matrix[1][1]); + matrix[7] = pixman_fixed_to_double(trans->matrix[1][2]); + + matrix[2] = pixman_fixed_to_double(trans->matrix[2][0]); + matrix[5] = pixman_fixed_to_double(trans->matrix[2][1]); + matrix[8] = pixman_fixed_to_double(trans->matrix[2][2]); + + return TRUE; +} + +static enum xa_composite_wrap +xa_setup_wrap(Bool pict_has_repeat, int pict_repeat) +{ + enum xa_composite_wrap wrap = xa_wrap_clamp_to_border; + + if (!pict_has_repeat) + return wrap; + + switch(pict_repeat) { + case RepeatNormal: + wrap = xa_wrap_repeat; + break; + case RepeatReflect: + wrap = xa_wrap_mirror_repeat; + break; + case RepeatPad: + wrap = xa_wrap_clamp_to_edge; + break; + default: + break; + } + return wrap; +} + +static enum xa_composite_filter +xa_setup_filter(int xrender_filter) +{ + switch (xrender_filter) { + case PictFilterConvolution: + case PictFilterNearest: + case PictFilterFast: + default: + return xa_filter_nearest; + case PictFilterBest: + case PictFilterGood: + case PictFilterBilinear: + return xa_filter_linear; + } +} + +static Bool +xa_setup_spict(union xa_source_pict *spict, SourcePictPtr pSourcePict) +{ + switch (pSourcePict->type) { + case SourcePictTypeSolidFill: + spict->type = xa_src_pict_solid_fill; + spict->solid_fill.color = pSourcePict->solidFill.color; + return TRUE; + default: + /* TODO */ + TRACE_EXA("unhandled spict type: %u", pSourcePict->type); + return FALSE; + } +} + static Bool -xa_setup_composite(struct xa_composite *comp, int op, PicturePtr pSrcPicture, +xa_setup_pict(struct xa_picture *pict, union xa_source_pict *spict, + PicturePtr pPict) +{ + memset(pict, 0, sizeof(*pict)); + + pict->pict_format = to_xa_format(pPict->format); + EXA_FAIL_IF(pict->pict_format == xa_format_unknown); + + pict->alpha_map = NULL; + pict->component_alpha = pPict->componentAlpha; + pict->has_transform = matrix_from_pict_transform( + pPict->transform, pict->transform); + pict->wrap = xa_setup_wrap(pPict->repeat, pPict->repeatType); + pict->filter = xa_setup_filter(pPict->filter); + + if (pPict->pSourcePict) { + if (!xa_setup_spict(spict, pPict->pSourcePict)) + return FALSE; + pict->src_pict = spict; + } else { + pict->src_pict = NULL; + } + + return TRUE; +} + +static const enum xa_composite_op op_map[] = { + [PictOpClear] = xa_op_clear, + [PictOpSrc] = xa_op_src, + [PictOpDst] = xa_op_dst, + [PictOpOver] = xa_op_over, + [PictOpOverReverse] = xa_op_over_reverse, + [PictOpIn] = xa_op_in, + [PictOpInReverse] = xa_op_in_reverse, + [PictOpOut] = xa_op_out, + [PictOpOutReverse] = xa_op_out_reverse, + [PictOpAtop] = xa_op_atop, + [PictOpAtopReverse] = xa_op_atop_reverse, + [PictOpXor] = xa_op_xor, + [PictOpAdd] = xa_op_add +}; + +static Bool +xa_setup_composite(struct exa_state *exa, int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) { - // XXX - return FALSE; + struct xa_composite *comp = &exa->comp; + + EXA_FAIL_IF(op >= ARRAY_SIZE(op_map)); + + comp->op = op_map[op]; + EXA_FAIL_IF((comp->op == xa_op_clear) && (op != PictOpClear)); + + EXA_FAIL_IF(!xa_setup_pict(&exa->dst_pict, &exa->dst_spict, pDstPicture)); + EXA_FAIL_IF(!xa_setup_pict(&exa->src_pict, &exa->src_spict, pSrcPicture)); + EXA_FAIL_IF(pMaskPicture && + !xa_setup_pict(&exa->mask_pict, &exa->mask_spict, pMaskPicture)); + + comp->dst = &exa->dst_pict; + comp->src = &exa->src_pict; + comp->mask = pMaskPicture ? &exa->mask_pict : NULL; + + return TRUE; +} + +static Bool +xa_update_composite(struct xa_composite *comp, PixmapPtr pSrc, + PixmapPtr pMask, PixmapPtr pDst) +{ + comp->dst->srf = msm_get_pixmap_surf(pDst); + EXA_FAIL_IF(!comp->dst->srf); + + if (pSrc) { + comp->src->srf = msm_get_pixmap_surf(pSrc); + EXA_FAIL_IF(!comp->src->srf); + } else { + comp->src->srf = NULL; + } + + if (comp->mask) { + if (pMask) { + comp->mask->srf = msm_get_pixmap_surf(pMask); + EXA_FAIL_IF(!comp->mask->srf); + } else { + comp->mask->srf = NULL; + } + } + + return TRUE; } /** @@ -264,9 +461,10 @@ XACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) { MSM_LOCALS(pDstPicture->pDrawable); - return xa_setup_composite(&exa->comp, op, pSrcPicture, - pMaskPicture, pDstPicture) && - (xa_composite_check_accelerated(&exa->comp) == XA_ERR_NONE); + if (!xa_setup_composite(exa, op, pSrcPicture, pMaskPicture, pDstPicture)) + return FALSE; + EXA_FAIL_IF(xa_composite_check_accelerated(&exa->comp) != XA_ERR_NONE); + return TRUE; } /** @@ -330,7 +528,10 @@ XAPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) { MSM_LOCALS(pDst); - return xa_composite_prepare(exa->ctx, &exa->comp) == XA_ERR_NONE; + if (!xa_update_composite(&exa->comp, pSrc, pMask, pDst)) + return FALSE; + EXA_FAIL_IF(xa_composite_prepare(exa->ctx, &exa->comp) != XA_ERR_NONE); + return TRUE; } /** @@ -454,6 +655,8 @@ XAPixmapIsOffscreen(PixmapPtr pPixmap) return FALSE; } +static void XAFinishAccess(PixmapPtr pPixmap, int index); + static Bool XAPrepareAccess(PixmapPtr pPixmap, int index) { @@ -467,6 +670,9 @@ XAPrepareAccess(PixmapPtr pPixmap, int index) }; MSM_LOCALS(pPixmap); + if (pPixmap->devPrivate.ptr) + XAFinishAccess(pPixmap, 0); + if (pPixmap->devPrivate.ptr == NULL) { struct xa_surface *surf = msm_get_pixmap_surf(pPixmap); void *ptr; diff --git a/src/msm-exa.c b/src/msm-exa.c index 92ab255..5c04ef5 100644 --- a/src/msm-exa.c +++ b/src/msm-exa.c @@ -42,28 +42,12 @@ #define xFixedtoDouble(_f) (double) ((_f)/(double) xFixed1) -#define ENABLE_EXA_TRACE 0 -#define ENABLE_SW_FALLBACK_REPORTS 0 - #define MSM_LOCALS(pDraw) \ ScrnInfoPtr pScrn = xf86ScreenToScrn(((DrawablePtr)(pDraw))->pScreen); \ MSMPtr pMsm = MSMPTR(pScrn); \ struct fd_ringbuffer *ring = NULL; (void)ring; \ struct exa_state *exa = pMsm->exa; (void)exa -#define TRACE_EXA(fmt, ...) do { \ - if (ENABLE_EXA_TRACE) \ - ErrorF("EXA: " fmt"\n", ##__VA_ARGS__); \ - } while (0) - -#define EXA_FAIL_IF(cond) do { \ - if (cond) { \ - if (ENABLE_SW_FALLBACK_REPORTS) { \ - ErrorF("FALLBACK: " #cond"\n"); \ - } \ - return FALSE; \ - } \ - } while (0) struct exa_state { /* solid state: */ @@ -105,7 +105,6 @@ typedef struct _MSMRec struct exa_state *exa; struct fd_bo *scanout; - struct xa_surface *scanout_surf; OptionInfoPtr options; } MSMRec, *MSMPtr; |