xserver-multidpi/fb/fbtrap.c
Dave Airlie 2d6a8f6683 fb: backport fb changes from master for src window operations.
This rolls up the following commits and also keeps the image_from_pict
API compatiblity. It introduces a new image_from_pict_18 API that is
used by the server leaving the old API alone.

I've rolled this up as I don't want to introduce ABI breaks in bisection.

a72c65e917 fb: Adjust transform or composite coordinates for pixman operations
bd567061c8 Split fbGetDrawable into fbGetDrawablePixmap and fbGetPixmapBitsData
6133505297 Revert "Fix clipping when windows are used as sources"
071b3c1810 Revert "Use IncludeInferiors when copying windows before compositing."
8e640d6b13 Revert "Reserve space for two GC values in copy_drawable()."

Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2009-12-23 14:29:26 +10:00

164 lines
4.0 KiB
C

/*
* Copyright © 2004 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "fb.h"
#ifdef RENDER
#include "picturestr.h"
#include "mipict.h"
#include "renderedge.h"
#include "fbpict.h"
void
fbAddTraps (PicturePtr pPicture,
INT16 x_off,
INT16 y_off,
int ntrap,
xTrap *traps)
{
int image_xoff, image_yoff;
pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &image_xoff, &image_yoff);
if (!image)
return;
pixman_add_traps (image, x_off, y_off, ntrap, (pixman_trap_t *)traps);
free_pixman_pict (pPicture, image);
}
void
fbRasterizeTrapezoid (PicturePtr pPicture,
xTrapezoid *trap,
int x_off,
int y_off)
{
int mask_xoff, mask_yoff;
pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &mask_xoff, &mask_yoff);
if (!image)
return;
pixman_rasterize_trapezoid (image, (pixman_trapezoid_t *)trap, x_off, y_off);
free_pixman_pict (pPicture, image);
}
static int
_GreaterY (xPointFixed *a, xPointFixed *b)
{
if (a->y == b->y)
return a->x > b->x;
return a->y > b->y;
}
/*
* Note that the definition of this function is a bit odd because
* of the X coordinate space (y increasing downwards).
*/
static int
_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b)
{
xPointFixed ad, bd;
ad.x = a->x - ref->x;
ad.y = a->y - ref->y;
bd.x = b->x - ref->x;
bd.y = b->y - ref->y;
return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
}
/* FIXME -- this could be made more efficient */
void
fbAddTriangles (PicturePtr pPicture,
INT16 x_off,
INT16 y_off,
int ntri,
xTriangle *tris)
{
xPointFixed *top, *left, *right, *tmp;
xTrapezoid trap;
for (; ntri; ntri--, tris++)
{
top = &tris->p1;
left = &tris->p2;
right = &tris->p3;
if (_GreaterY (top, left)) {
tmp = left; left = top; top = tmp;
}
if (_GreaterY (top, right)) {
tmp = right; right = top; top = tmp;
}
if (_Clockwise (top, right, left)) {
tmp = right; right = left; left = tmp;
}
/*
* Two cases:
*
* + +
* / \ / \
* / \ / \
* / + + \
* / -- -- \
* / -- -- \
* / --- --- \
* +-- --+
*/
trap.top = top->y;
trap.left.p1 = *top;
trap.left.p2 = *left;
trap.right.p1 = *top;
trap.right.p2 = *right;
if (right->y < left->y)
trap.bottom = right->y;
else
trap.bottom = left->y;
fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
if (right->y < left->y)
{
trap.top = right->y;
trap.bottom = left->y;
trap.right.p1 = *right;
trap.right.p2 = *left;
}
else
{
trap.top = left->y;
trap.bottom = right->y;
trap.left.p1 = *left;
trap.left.p2 = *right;
}
fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
}
}
#endif /* RENDER */