13bfa90b6Smrg/*
23bfa90b6Smrg * Copyright 2009-2011 VMWare, Inc.
33bfa90b6Smrg * All Rights Reserved.
43bfa90b6Smrg *
53bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a
63bfa90b6Smrg * copy of this software and associated documentation files (the
73bfa90b6Smrg * "Software"), to deal in the Software without restriction, including
83bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish,
93bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to
103bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to
113bfa90b6Smrg * the following conditions:
123bfa90b6Smrg *
133bfa90b6Smrg * The above copyright notice and this permission notice (including the
143bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions
153bfa90b6Smrg * of the Software.
163bfa90b6Smrg *
173bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
183bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
193bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
203bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
213bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
223bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
233bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
243bfa90b6Smrg *
253bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com>
263bfa90b6Smrg * Author: Zack Ruzin <zackr@vmware.com>
273bfa90b6Smrg *
283bfa90b6Smrg * The code in this file translates XRender PICT composite stuff
293bfa90b6Smrg * to fit the libxatracker API.
303bfa90b6Smrg */
313bfa90b6Smrg
323bfa90b6Smrg#ifdef HAVE_CONFIG_H
333bfa90b6Smrg#include "config.h"
343bfa90b6Smrg#endif
353bfa90b6Smrg
363bfa90b6Smrg#include <pixman.h>
373bfa90b6Smrg#include <picturestr.h>
383bfa90b6Smrg#include "xa_composite.h"
393bfa90b6Smrg#include "vmwgfx_saa.h"
403bfa90b6Smrg#include "vmwgfx_saa_priv.h"
413bfa90b6Smrg
423bfa90b6Smrg
433bfa90b6Smrgstruct vmwgfx_composite {
443bfa90b6Smrg    union xa_source_pict *src_spict;
453bfa90b6Smrg    union xa_source_pict *mask_spict;
463bfa90b6Smrg    union xa_source_pict *dst_spict;
473bfa90b6Smrg    struct xa_picture *src_pict;
483bfa90b6Smrg    struct xa_picture *mask_pict;
493bfa90b6Smrg    struct xa_picture *dst_pict;
503bfa90b6Smrg    struct xa_composite *comp;
513bfa90b6Smrg};
523bfa90b6Smrg
533bfa90b6Smrgstatic const enum xa_composite_op vmwgfx_op_map[] = {
543bfa90b6Smrg    [PictOpClear] = xa_op_clear,
553bfa90b6Smrg    [PictOpSrc] = xa_op_src,
563bfa90b6Smrg    [PictOpDst] = xa_op_dst,
573bfa90b6Smrg    [PictOpOver] = xa_op_over,
583bfa90b6Smrg    [PictOpOverReverse] = xa_op_over_reverse,
593bfa90b6Smrg    [PictOpIn] = xa_op_in,
603bfa90b6Smrg    [PictOpInReverse] = xa_op_in_reverse,
613bfa90b6Smrg    [PictOpOut] = xa_op_out,
623bfa90b6Smrg    [PictOpOutReverse] = xa_op_out_reverse,
633bfa90b6Smrg    [PictOpAtop] = xa_op_atop,
643bfa90b6Smrg    [PictOpAtopReverse] = xa_op_atop_reverse,
653bfa90b6Smrg    [PictOpXor] = xa_op_xor,
663bfa90b6Smrg    [PictOpAdd] = xa_op_add
673bfa90b6Smrg};
683bfa90b6Smrg
693bfa90b6Smrgstatic const unsigned int vmwgfx_op_map_size =
703bfa90b6Smrg    sizeof(vmwgfx_op_map) / sizeof(enum xa_composite_op);
713bfa90b6Smrg
723bfa90b6Smrgstatic Bool
733bfa90b6Smrgvmwgfx_matrix_from_pict_transform(PictTransform *trans, float *matrix)
743bfa90b6Smrg{
753bfa90b6Smrg   if (!trans)
763bfa90b6Smrg      return FALSE;
773bfa90b6Smrg
783bfa90b6Smrg   matrix[0] = pixman_fixed_to_double(trans->matrix[0][0]);
793bfa90b6Smrg   matrix[3] = pixman_fixed_to_double(trans->matrix[0][1]);
803bfa90b6Smrg   matrix[6] = pixman_fixed_to_double(trans->matrix[0][2]);
813bfa90b6Smrg
823bfa90b6Smrg   matrix[1] = pixman_fixed_to_double(trans->matrix[1][0]);
833bfa90b6Smrg   matrix[4] = pixman_fixed_to_double(trans->matrix[1][1]);
843bfa90b6Smrg   matrix[7] = pixman_fixed_to_double(trans->matrix[1][2]);
853bfa90b6Smrg
863bfa90b6Smrg   matrix[2] = pixman_fixed_to_double(trans->matrix[2][0]);
873bfa90b6Smrg   matrix[5] = pixman_fixed_to_double(trans->matrix[2][1]);
883bfa90b6Smrg   matrix[8] = pixman_fixed_to_double(trans->matrix[2][2]);
893bfa90b6Smrg
903bfa90b6Smrg   return TRUE;
913bfa90b6Smrg}
923bfa90b6Smrg
933bfa90b6Smrgstatic enum xa_composite_wrap
943bfa90b6Smrgvmwgfx_xa_setup_wrap(Bool pict_has_repeat, int pict_repeat)
953bfa90b6Smrg{
963bfa90b6Smrg    enum xa_composite_wrap wrap = xa_wrap_clamp_to_border;
973bfa90b6Smrg
983bfa90b6Smrg    if (!pict_has_repeat)
993bfa90b6Smrg	return wrap;
1003bfa90b6Smrg
1013bfa90b6Smrg    switch(pict_repeat) {
1023bfa90b6Smrg    case RepeatNormal:
1033bfa90b6Smrg	wrap = xa_wrap_repeat;
1043bfa90b6Smrg	break;
1053bfa90b6Smrg    case RepeatReflect:
1063bfa90b6Smrg	wrap = xa_wrap_mirror_repeat;
1073bfa90b6Smrg	break;
1083bfa90b6Smrg    case RepeatPad:
1093bfa90b6Smrg	wrap = xa_wrap_clamp_to_edge;
1103bfa90b6Smrg	break;
1113bfa90b6Smrg    default:
1123bfa90b6Smrg	break;
1133bfa90b6Smrg    }
1143bfa90b6Smrg    return wrap;
1153bfa90b6Smrg}
1163bfa90b6Smrg
1173bfa90b6Smrgstatic Bool
1183bfa90b6Smrgvmwgfx_render_filter_to_xa(int xrender_filter,
1193bfa90b6Smrg			   enum xa_composite_filter *out_filter)
1203bfa90b6Smrg{
1213bfa90b6Smrg   switch (xrender_filter) {
1223bfa90b6Smrg   case PictFilterConvolution:
1233bfa90b6Smrg   case PictFilterNearest:
1243bfa90b6Smrg   case PictFilterFast:
1253bfa90b6Smrg       *out_filter = xa_filter_nearest;
1263bfa90b6Smrg      break;
1273bfa90b6Smrg   case PictFilterBest:
1283bfa90b6Smrg   case PictFilterGood:
1293bfa90b6Smrg   case PictFilterBilinear:
1303bfa90b6Smrg       *out_filter = xa_filter_linear;
1313bfa90b6Smrg      break;
1323bfa90b6Smrg   default:
1333bfa90b6Smrg       *out_filter = xa_filter_nearest;
1343bfa90b6Smrg       return FALSE;
1353bfa90b6Smrg   }
1363bfa90b6Smrg   return TRUE;
1373bfa90b6Smrg}
1383bfa90b6Smrg
1393bfa90b6Smrgstatic Bool
1403bfa90b6Smrgvmwgfx_xa_setup_pict(PicturePtr pict,
1413bfa90b6Smrg		     struct xa_picture *xa_pict,
1423bfa90b6Smrg		     union xa_source_pict *src_pict)
1433bfa90b6Smrg{
1443bfa90b6Smrg    if (!pict)
1453bfa90b6Smrg	return FALSE;
1463bfa90b6Smrg
1473bfa90b6Smrg    memset(xa_pict, 0, sizeof(*xa_pict));
1483bfa90b6Smrg
1493bfa90b6Smrg    xa_pict->pict_format = vmwgfx_xa_format(pict->format);
1503bfa90b6Smrg    if (xa_pict->pict_format == xa_format_unknown)
1513bfa90b6Smrg	return FALSE;
1523bfa90b6Smrg
1533bfa90b6Smrg    /*
1543bfa90b6Smrg     * Saa doesn't let drivers accelerate alpha maps.
1553bfa90b6Smrg     */
1563bfa90b6Smrg    xa_pict->alpha_map = NULL;
1573bfa90b6Smrg    xa_pict->component_alpha = pict->componentAlpha;
1583bfa90b6Smrg
1593bfa90b6Smrg    xa_pict->has_transform =
1603bfa90b6Smrg	vmwgfx_matrix_from_pict_transform(pict->transform,
1613bfa90b6Smrg					  xa_pict->transform);
1623bfa90b6Smrg
1633bfa90b6Smrg    xa_pict->wrap = vmwgfx_xa_setup_wrap(pict->repeat,
1643bfa90b6Smrg					 pict->repeatType);
1653bfa90b6Smrg
1663bfa90b6Smrg    (void) vmwgfx_render_filter_to_xa(pict->filter, &xa_pict->filter);
1673bfa90b6Smrg
1683bfa90b6Smrg    if (pict->pSourcePict) {
1693bfa90b6Smrg	if (pict->pSourcePict->type != SourcePictTypeSolidFill)
1703bfa90b6Smrg	    return FALSE;
1713bfa90b6Smrg
1723bfa90b6Smrg	src_pict->type = xa_src_pict_solid_fill;
1733bfa90b6Smrg	src_pict->solid_fill.color = pict->pSourcePict->solidFill.color;
1743bfa90b6Smrg	xa_pict->src_pict = src_pict;
1753bfa90b6Smrg    }
1763bfa90b6Smrg
1773bfa90b6Smrg    return TRUE;
1783bfa90b6Smrg}
1793bfa90b6Smrg
1803bfa90b6Smrgstruct xa_composite *
1813bfa90b6Smrgvmwgfx_xa_setup_comp(struct vmwgfx_composite *vcomp,
1823bfa90b6Smrg		     int op,
1833bfa90b6Smrg		     PicturePtr src_pict,
1843bfa90b6Smrg		     PicturePtr mask_pict,
1853bfa90b6Smrg		     PicturePtr dst_pict)
1863bfa90b6Smrg{
1873bfa90b6Smrg    struct xa_composite *comp = vcomp->comp;
1883bfa90b6Smrg
1893bfa90b6Smrg    if (op >= vmwgfx_op_map_size)
1903bfa90b6Smrg	return NULL;
1913bfa90b6Smrg
1923bfa90b6Smrg    comp->op = vmwgfx_op_map[op];
1933bfa90b6Smrg    if (comp->op == xa_op_clear && op != PictOpClear)
1943bfa90b6Smrg	return NULL;
1953bfa90b6Smrg
1963bfa90b6Smrg    if (!vmwgfx_xa_setup_pict(dst_pict, vcomp->dst_pict,
1973bfa90b6Smrg			      vcomp->dst_spict))
1983bfa90b6Smrg	return NULL;
1993bfa90b6Smrg    if (!vmwgfx_xa_setup_pict(src_pict, vcomp->src_pict,
2003bfa90b6Smrg			      vcomp->src_spict))
2013bfa90b6Smrg	return NULL;
2023bfa90b6Smrg    if (mask_pict && !vmwgfx_xa_setup_pict(mask_pict,
2033bfa90b6Smrg					   vcomp->mask_pict,
2043bfa90b6Smrg					   vcomp->mask_spict))
2053bfa90b6Smrg	return NULL;
2063bfa90b6Smrg
2073bfa90b6Smrg    comp->dst = vcomp->dst_pict;
2083bfa90b6Smrg    comp->src = vcomp->src_pict;
2093bfa90b6Smrg    comp->mask = (mask_pict) ? vcomp->mask_pict : NULL;
2103bfa90b6Smrg
2113bfa90b6Smrg    return comp;
2123bfa90b6Smrg}
2133bfa90b6Smrg
2143bfa90b6SmrgBool
2153bfa90b6Smrgvmwgfx_xa_update_comp(struct xa_composite *comp,
2163bfa90b6Smrg		      PixmapPtr src_pix,
2173bfa90b6Smrg		      PixmapPtr mask_pix,
2183bfa90b6Smrg		      PixmapPtr dst_pix)
2193bfa90b6Smrg{
2203bfa90b6Smrg    comp->dst->srf = vmwgfx_saa_pixmap(dst_pix)->hw;
2213bfa90b6Smrg    if (src_pix)
2223bfa90b6Smrg	comp->src->srf = vmwgfx_saa_pixmap(src_pix)->hw;
2233bfa90b6Smrg    if (mask_pix && comp->mask)
2243bfa90b6Smrg	comp->mask->srf = vmwgfx_saa_pixmap(mask_pix)->hw;
2253bfa90b6Smrg    return TRUE;
2263bfa90b6Smrg}
2273bfa90b6Smrg
2283bfa90b6Smrg
2293bfa90b6Smrgvoid
2303bfa90b6Smrgvmwgfx_free_composite(struct vmwgfx_composite *vcomp)
2313bfa90b6Smrg{
2323bfa90b6Smrg    if (!vcomp)
2333bfa90b6Smrg	return;
2343bfa90b6Smrg
2353bfa90b6Smrg    if (vcomp->src_spict)
2363bfa90b6Smrg	free(vcomp->src_spict);
2373bfa90b6Smrg    if (vcomp->mask_spict)
2383bfa90b6Smrg	free(vcomp->mask_spict);
2393bfa90b6Smrg    if (vcomp->dst_spict)
2403bfa90b6Smrg	free(vcomp->dst_spict);
2413bfa90b6Smrg    if (vcomp->src_pict)
2423bfa90b6Smrg	free(vcomp->src_pict);
2433bfa90b6Smrg    if (vcomp->mask_pict)
2443bfa90b6Smrg	free(vcomp->mask_pict);
2453bfa90b6Smrg    if (vcomp->dst_pict)
2463bfa90b6Smrg	free(vcomp->dst_pict);
2473bfa90b6Smrg    if (vcomp->comp)
2483bfa90b6Smrg	free(vcomp->comp);
2493bfa90b6Smrg    free(vcomp);
2503bfa90b6Smrg}
2513bfa90b6Smrg
2523bfa90b6Smrgstruct vmwgfx_composite *
2533bfa90b6Smrgvmwgfx_alloc_composite(void)
2543bfa90b6Smrg{
2553bfa90b6Smrg    const struct xa_composite_allocation *a = xa_composite_allocation();
2563bfa90b6Smrg    struct vmwgfx_composite *vcomp = calloc(1, sizeof(*vcomp));
2573bfa90b6Smrg
2583bfa90b6Smrg    if (!vcomp)
2593bfa90b6Smrg	return NULL;
2603bfa90b6Smrg
2613bfa90b6Smrg    vcomp->src_spict = calloc(1, a->xa_source_pict_size);
2623bfa90b6Smrg    vcomp->mask_spict = calloc(1, a->xa_source_pict_size);
2633bfa90b6Smrg    vcomp->dst_spict = calloc(1, a->xa_source_pict_size);
2643bfa90b6Smrg    vcomp->src_pict = calloc(1, a->xa_picture_size);
2653bfa90b6Smrg    vcomp->mask_pict = calloc(1, a->xa_picture_size);
2663bfa90b6Smrg    vcomp->dst_pict = calloc(1, a->xa_picture_size);
2673bfa90b6Smrg    vcomp->comp = calloc(1, a->xa_composite_size);
2683bfa90b6Smrg
2693bfa90b6Smrg    if (!vcomp->src_spict || !vcomp->mask_spict || !vcomp->dst_spict ||
2703bfa90b6Smrg	!vcomp->src_pict || !vcomp->mask_pict || !vcomp->dst_pict ||
2713bfa90b6Smrg	!vcomp->comp) {
2723bfa90b6Smrg	vmwgfx_free_composite(vcomp);
2733bfa90b6Smrg	return NULL;
2743bfa90b6Smrg    }
2753bfa90b6Smrg
2763bfa90b6Smrg    return vcomp;
2773bfa90b6Smrg}
278