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