summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2014-03-25 18:22:19 -0400
committerRob Clark <robdclark@gmail.com>2014-05-04 19:55:25 -0400
commit8b38461c8ab4cabba63be2f572fa024d6d8241a5 (patch)
tree5a837e8f6e4df0c7d811815f1b524efcfc22e195
parent81baded8e385d8e1b9cb937a327d6fe564a70c69 (diff)
xa: add composite
Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--src/msm-exa-xa.c220
-rw-r--r--src/msm-exa.c16
-rw-r--r--src/msm.h1
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: */
diff --git a/src/msm.h b/src/msm.h
index c0230f3..ab3a2e5 100644
--- a/src/msm.h
+++ b/src/msm.h
@@ -105,7 +105,6 @@ typedef struct _MSMRec
struct exa_state *exa;
struct fd_bo *scanout;
- struct xa_surface *scanout_surf;
OptionInfoPtr options;
} MSMRec, *MSMPtr;