Imported Upstream version 0.3.0
[ubuntu-omap:rsalvetis-xf86-video-omap.git] / src / omap_exa_utils.c
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3 /*
4  * Copyright © 2012 Texas Instruments, Inc
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * Authors:
26  *    Rob Clark <rob@ti.com>
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "omap_driver.h"
34 #include "omap_exa.h"
35
36
37 /***** move to common helper code??  in EXA or DRI2? *****/
38 /* if this is in DRI2, then the driver can't rely on pixmap migration, etc
39  * before PutTextureImage cb is called.. I guess it should be in EXA..
40  */
41 #include <pixman.h>
42
43 /**
44  * Helper function to implement video blit, handling clipping, damage, etc..
45  *
46  * TODO: move to EXA?
47  */
48 int
49 OMAPVidCopyArea(DrawablePtr pSrcDraw, BoxPtr pSrcBox,
50                 DrawablePtr pOsdDraw, BoxPtr pOsdBox,
51                 DrawablePtr pDstDraw, BoxPtr pDstBox,
52                 OMAPPutTextureImageProc PutTextureImage, void *closure,
53                 RegionPtr clipBoxes)
54 {
55         ScreenPtr pScreen = pDstDraw->pScreen;
56         ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
57         PixmapPtr pSrcPix = draw2pix(pSrcDraw);
58         PixmapPtr pOsdPix = draw2pix(pOsdDraw);
59         PixmapPtr pDstPix = draw2pix(pDstDraw);
60         pixman_fixed_t sx, sy, tx, ty;
61         pixman_transform_t srcxfrm;
62         BoxPtr pbox;
63         int nbox, dx, dy, ret = Success;
64
65 #ifdef COMPOSITE
66         DEBUG_MSG("--> %dx%d, %dx%d", pDstPix->screen_x, pDstPix->screen_y,
67                         pDstDraw->x, pDstDraw->y);
68         /* Convert screen coords to pixmap coords */
69         if (pDstPix->screen_x || pDstPix->screen_y) {
70                 RegionTranslate(clipBoxes, -pDstPix->screen_x, -pDstPix->screen_y);
71         }
72         dx = pDstPix->screen_x;
73         dy = pDstPix->screen_y;
74 #else
75         dx = 0;
76         dy = 0;
77 #endif
78
79         /* the clip-region gives coordinates in dst's coord space..  generate
80          * a transform that can be used to work backwards from dst->src coord
81          * space:
82          */
83         sx = ((pixman_fixed_48_16_t) (pSrcBox->x2 - pSrcBox->x1) << 16) /
84                         (pDstBox->x2 - pDstBox->x1);
85         sy = ((pixman_fixed_48_16_t) (pSrcBox->y2 - pSrcBox->y1) << 16) /
86                         (pDstBox->y2 - pDstBox->y1);
87         tx = ((pixman_fixed_48_16_t)(pDstBox->x1 - dx) << 16);
88         ty = ((pixman_fixed_48_16_t)(pDstBox->y1 - dy) << 16);
89
90         pixman_transform_init_scale(&srcxfrm, sx, sy);
91         pixman_transform_translate(NULL, &srcxfrm, tx, ty);
92
93         // TODO generate transform for osd as well
94
95         pbox = RegionRects(clipBoxes);
96         nbox = RegionNumRects(clipBoxes);
97
98         while (nbox--) {
99                 RegionRec damage;
100                 BoxRec dstb = *pbox;
101                 BoxRec srcb = *pbox;
102                 BoxRec osdb = *pbox;
103
104                 pixman_transform_bounds(&srcxfrm, &srcb);
105                 //pixman_transform_bounds(&osdxfrm, &osdb);
106
107                 /* cropping is done in src coord space, post transform: */
108                 srcb.x1 += pSrcBox->x1;
109                 srcb.y1 += pSrcBox->y1;
110                 srcb.x2 += pSrcBox->x1;
111                 srcb.y2 += pSrcBox->y1;
112
113                 DEBUG_MSG("%d,%d %d,%d -> %d,%d %d,%d",
114                                 srcb.x1, srcb.y1, srcb.x2, srcb.y2,
115                                 dstb.x1, dstb.y1, dstb.x2, dstb.y2);
116
117                 ret = PutTextureImage(pSrcPix, &srcb, pOsdPix, &osdb,
118                                 pDstPix, &dstb, closure);
119                 if (ret != Success) {
120                         break;
121                 }
122
123                 RegionInit(&damage, &dstb, 1);
124
125 #ifdef COMPOSITE
126                 /* Convert screen coords to pixmap coords */
127                 if (pDstPix->screen_x || pDstPix->screen_y) {
128                         RegionTranslate(&damage, pDstPix->screen_x, pDstPix->screen_y);
129                 }
130 #endif
131
132                 DamageRegionAppend(pDstDraw, &damage);
133                 RegionUninit(&damage);
134
135                 pbox++;
136         }
137
138         DamageRegionProcessPending(pDstDraw);
139
140         return ret;
141 }