135c4bbdfSmrg/*
235c4bbdfSmrg * Copyright © 2009 Intel Corporation
335c4bbdfSmrg *
435c4bbdfSmrg * Permission is hereby granted, free of charge, to any person obtaining a
535c4bbdfSmrg * copy of this software and associated documentation files (the "Software"),
635c4bbdfSmrg * to deal in the Software without restriction, including without limitation
735c4bbdfSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
835c4bbdfSmrg * and/or sell copies of the Software, and to permit persons to whom the
935c4bbdfSmrg * Software is furnished to do so, subject to the following conditions:
1035c4bbdfSmrg *
1135c4bbdfSmrg * The above copyright notice and this permission notice (including the next
1235c4bbdfSmrg * paragraph) shall be included in all copies or substantial portions of the
1335c4bbdfSmrg * Software.
1435c4bbdfSmrg *
1535c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1635c4bbdfSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1735c4bbdfSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1835c4bbdfSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1935c4bbdfSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2035c4bbdfSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2135c4bbdfSmrg * IN THE SOFTWARE.
2235c4bbdfSmrg *
2335c4bbdfSmrg * Authors:
2435c4bbdfSmrg *    Junyan He <junyan.he@linux.intel.com>
2535c4bbdfSmrg *
2635c4bbdfSmrg */
2735c4bbdfSmrg
2835c4bbdfSmrg/** @file glamor_trapezoid.c
2935c4bbdfSmrg *
3035c4bbdfSmrg * Trapezoid acceleration implementation
3135c4bbdfSmrg */
3235c4bbdfSmrg
3335c4bbdfSmrg#include "glamor_priv.h"
3435c4bbdfSmrg
3535c4bbdfSmrg#include "mipict.h"
3635c4bbdfSmrg#include "fbpict.h"
3735c4bbdfSmrg
3835c4bbdfSmrg/**
3935c4bbdfSmrg * Creates an appropriate picture for temp mask use.
4035c4bbdfSmrg */
4135c4bbdfSmrgstatic PicturePtr
4235c4bbdfSmrgglamor_create_mask_picture(ScreenPtr screen,
4335c4bbdfSmrg                           PicturePtr dst,
4435c4bbdfSmrg                           PictFormatPtr pict_format,
4535c4bbdfSmrg                           CARD16 width, CARD16 height)
4635c4bbdfSmrg{
4735c4bbdfSmrg    PixmapPtr pixmap;
4835c4bbdfSmrg    PicturePtr picture;
4935c4bbdfSmrg    int error;
5035c4bbdfSmrg
5135c4bbdfSmrg    if (!pict_format) {
5235c4bbdfSmrg        if (dst->polyEdge == PolyEdgeSharp)
5335c4bbdfSmrg            pict_format = PictureMatchFormat(screen, 1, PICT_a1);
5435c4bbdfSmrg        else
5535c4bbdfSmrg            pict_format = PictureMatchFormat(screen, 8, PICT_a8);
5635c4bbdfSmrg        if (!pict_format)
5735c4bbdfSmrg            return 0;
5835c4bbdfSmrg    }
5935c4bbdfSmrg
6035c4bbdfSmrg    pixmap = glamor_create_pixmap(screen, 0, 0,
6135c4bbdfSmrg                                  pict_format->depth,
6235c4bbdfSmrg                                  GLAMOR_CREATE_PIXMAP_CPU);
6335c4bbdfSmrg
6435c4bbdfSmrg    if (!pixmap)
6535c4bbdfSmrg        return 0;
6635c4bbdfSmrg    picture = CreatePicture(0, &pixmap->drawable, pict_format,
6735c4bbdfSmrg                            0, 0, serverClient, &error);
6835c4bbdfSmrg    glamor_destroy_pixmap(pixmap);
6935c4bbdfSmrg    return picture;
7035c4bbdfSmrg}
7135c4bbdfSmrg
7235c4bbdfSmrg/**
7335c4bbdfSmrg * glamor_trapezoids will generate trapezoid mask accumulating in
7435c4bbdfSmrg * system memory.
7535c4bbdfSmrg */
7635c4bbdfSmrgvoid
7735c4bbdfSmrgglamor_trapezoids(CARD8 op,
7835c4bbdfSmrg                  PicturePtr src, PicturePtr dst,
7935c4bbdfSmrg                  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
8035c4bbdfSmrg                  int ntrap, xTrapezoid *traps)
8135c4bbdfSmrg{
8235c4bbdfSmrg    ScreenPtr screen = dst->pDrawable->pScreen;
8335c4bbdfSmrg    BoxRec bounds;
8435c4bbdfSmrg    PicturePtr picture;
8535c4bbdfSmrg    INT16 x_dst, y_dst;
8635c4bbdfSmrg    INT16 x_rel, y_rel;
8735c4bbdfSmrg    int width, height, stride;
8835c4bbdfSmrg    PixmapPtr pixmap;
8935c4bbdfSmrg    pixman_image_t *image = NULL;
9035c4bbdfSmrg
9135c4bbdfSmrg    /* If a mask format wasn't provided, we get to choose, but behavior should
9235c4bbdfSmrg     * be as if there was no temporary mask the traps were accumulated into.
9335c4bbdfSmrg     */
9435c4bbdfSmrg    if (!mask_format) {
9535c4bbdfSmrg        if (dst->polyEdge == PolyEdgeSharp)
9635c4bbdfSmrg            mask_format = PictureMatchFormat(screen, 1, PICT_a1);
9735c4bbdfSmrg        else
9835c4bbdfSmrg            mask_format = PictureMatchFormat(screen, 8, PICT_a8);
9935c4bbdfSmrg        for (; ntrap; ntrap--, traps++)
10035c4bbdfSmrg            glamor_trapezoids(op, src, dst, mask_format, x_src,
10135c4bbdfSmrg                              y_src, 1, traps);
10235c4bbdfSmrg        return;
10335c4bbdfSmrg    }
10435c4bbdfSmrg
10535c4bbdfSmrg    miTrapezoidBounds(ntrap, traps, &bounds);
10635c4bbdfSmrg
10735c4bbdfSmrg    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
10835c4bbdfSmrg        return;
10935c4bbdfSmrg
11035c4bbdfSmrg    x_dst = traps[0].left.p1.x >> 16;
11135c4bbdfSmrg    y_dst = traps[0].left.p1.y >> 16;
11235c4bbdfSmrg
11335c4bbdfSmrg    width = bounds.x2 - bounds.x1;
11435c4bbdfSmrg    height = bounds.y2 - bounds.y1;
11535c4bbdfSmrg    stride = PixmapBytePad(width, mask_format->depth);
11635c4bbdfSmrg
11735c4bbdfSmrg    picture = glamor_create_mask_picture(screen, dst, mask_format,
11835c4bbdfSmrg                                         width, height);
11935c4bbdfSmrg    if (!picture)
12035c4bbdfSmrg        return;
12135c4bbdfSmrg
12235c4bbdfSmrg    image = pixman_image_create_bits(picture->format,
12335c4bbdfSmrg                                     width, height, NULL, stride);
12435c4bbdfSmrg    if (!image) {
12535c4bbdfSmrg        FreePicture(picture, 0);
12635c4bbdfSmrg        return;
12735c4bbdfSmrg    }
12835c4bbdfSmrg
12935c4bbdfSmrg    for (; ntrap; ntrap--, traps++)
13035c4bbdfSmrg        pixman_rasterize_trapezoid(image,
13135c4bbdfSmrg                                   (pixman_trapezoid_t *) traps,
13235c4bbdfSmrg                                   -bounds.x1, -bounds.y1);
13335c4bbdfSmrg
13435c4bbdfSmrg    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
13535c4bbdfSmrg
13635c4bbdfSmrg    screen->ModifyPixmapHeader(pixmap, width, height,
13735c4bbdfSmrg                               mask_format->depth,
13835c4bbdfSmrg                               BitsPerPixel(mask_format->depth),
13935c4bbdfSmrg                               PixmapBytePad(width,
14035c4bbdfSmrg                                             mask_format->depth),
14135c4bbdfSmrg                               pixman_image_get_data(image));
14235c4bbdfSmrg
14335c4bbdfSmrg    x_rel = bounds.x1 + x_src - x_dst;
14435c4bbdfSmrg    y_rel = bounds.y1 + y_src - y_dst;
14535c4bbdfSmrg
14635c4bbdfSmrg    CompositePicture(op, src, picture, dst,
14735c4bbdfSmrg                     x_rel, y_rel,
14835c4bbdfSmrg                     0, 0,
14935c4bbdfSmrg                     bounds.x1, bounds.y1,
15035c4bbdfSmrg                     bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
15135c4bbdfSmrg
15235c4bbdfSmrg    if (image)
15335c4bbdfSmrg        pixman_image_unref(image);
15435c4bbdfSmrg
15535c4bbdfSmrg    FreePicture(picture, 0);
15635c4bbdfSmrg}
157