[intel] By default, output batchbuffer decode to stderr like other debug info.
[mesa.git] / src / mesa / drivers / dri / i915 / intel_rotate.c
1
2 /**
3 * Routines for simple 2D->2D transformations for rotated, flipped screens.
4 *
5 * XXX This code is not intel-specific. Move it into a common/utility
6 * someday.
7 */
8
9 #include "intel_rotate.h"
10
11 #define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) )
12
13 #define ABS(A) ( ((A) < 0) ? -(A) : (A) )
14
15
16 void
17 matrix23Set(struct matrix23 *m,
18 int m00, int m01, int m02, int m10, int m11, int m12)
19 {
20 m->m00 = m00;
21 m->m01 = m01;
22 m->m02 = m02;
23 m->m10 = m10;
24 m->m11 = m11;
25 m->m12 = m12;
26 }
27
28
29 /*
30 * Transform (x,y) coordinate by the given matrix.
31 */
32 void
33 matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y)
34 {
35 const float x0 = *x;
36 const float y0 = *y;
37
38 *x = m->m00 * x0 + m->m01 * y0 + m->m02;
39 *y = m->m10 * x0 + m->m11 * y0 + m->m12;
40 }
41
42
43 void
44 matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y)
45 {
46 const int x0 = *x;
47 const int y0 = *y;
48
49 *x = m->m00 * x0 + m->m01 * y0 + m->m02;
50 *y = m->m10 * x0 + m->m11 * y0 + m->m12;
51 }
52
53
54 /*
55 * Transform a width and height by the given matrix.
56 * XXX this could be optimized quite a bit.
57 */
58 void
59 matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist)
60 {
61 int x0 = 0, y0 = 0;
62 int x1 = *xDist, y1 = 0;
63 int x2 = 0, y2 = *yDist;
64 matrix23TransformCoordi(m, &x0, &y0);
65 matrix23TransformCoordi(m, &x1, &y1);
66 matrix23TransformCoordi(m, &x2, &y2);
67
68 *xDist = (x1 - x0) + (x2 - x0);
69 *yDist = (y1 - y0) + (y2 - y0);
70
71 if (*xDist < 0)
72 *xDist = -*xDist;
73 if (*yDist < 0)
74 *yDist = -*yDist;
75 }
76
77
78 /**
79 * Transform the rect defined by (x, y, w, h) by m.
80 */
81 void
82 matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w,
83 int *h)
84 {
85 int x0 = *x, y0 = *y;
86 int x1 = *x + *w, y1 = *y;
87 int x2 = *x + *w, y2 = *y + *h;
88 int x3 = *x, y3 = *y + *h;
89 matrix23TransformCoordi(m, &x0, &y0);
90 matrix23TransformCoordi(m, &x1, &y1);
91 matrix23TransformCoordi(m, &x2, &y2);
92 matrix23TransformCoordi(m, &x3, &y3);
93 *w = ABS(x1 - x0) + ABS(x2 - x1);
94 /**w = ABS(*w);*/
95 *h = ABS(y1 - y0) + ABS(y2 - y1);
96 /**h = ABS(*h);*/
97 *x = MIN2(x0, x1);
98 *x = MIN2(*x, x2);
99 *y = MIN2(y0, y1);
100 *y = MIN2(*y, y2);
101 }
102
103
104 /*
105 * Make rotation matrix for width X height screen.
106 */
107 void
108 matrix23Rotate(struct matrix23 *m, int width, int height, int angle)
109 {
110 switch (angle) {
111 case 0:
112 matrix23Set(m, 1, 0, 0, 0, 1, 0);
113 break;
114 case 90:
115 matrix23Set(m, 0, 1, 0, -1, 0, width);
116 break;
117 case 180:
118 matrix23Set(m, -1, 0, width, 0, -1, height);
119 break;
120 case 270:
121 matrix23Set(m, 0, -1, height, 1, 0, 0);
122 break;
123 default:
124 /*abort() */ ;
125 }
126 }
127
128
129 /*
130 * Make flip/reflection matrix for width X height screen.
131 */
132 void
133 matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip)
134 {
135 if (xflip) {
136 m->m00 = -1;
137 m->m01 = 0;
138 m->m02 = width - 1;
139 }
140 else {
141 m->m00 = 1;
142 m->m01 = 0;
143 m->m02 = 0;
144 }
145 if (yflip) {
146 m->m10 = 0;
147 m->m11 = -1;
148 m->m12 = height - 1;
149 }
150 else {
151 m->m10 = 0;
152 m->m11 = 1;
153 m->m12 = 0;
154 }
155 }
156
157
158 /*
159 * result = a * b
160 */
161 void
162 matrix23Multiply(struct matrix23 *result,
163 const struct matrix23 *a, const struct matrix23 *b)
164 {
165 result->m00 = a->m00 * b->m00 + a->m01 * b->m10;
166 result->m01 = a->m00 * b->m01 + a->m01 * b->m11;
167 result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02;
168
169 result->m10 = a->m10 * b->m00 + a->m11 * b->m10;
170 result->m11 = a->m10 * b->m01 + a->m11 * b->m11;
171 result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12;
172 }
173
174
175 #if 000
176
177 #include <stdio.h>
178
179 int
180 main(int argc, char *argv[])
181 {
182 int width = 500, height = 400;
183 int rot;
184 int fx = 0, fy = 0; /* flip x and/or y ? */
185 int coords[4][2];
186
187 /* four corner coords to test with */
188 coords[0][0] = 0;
189 coords[0][1] = 0;
190 coords[1][0] = width - 1;
191 coords[1][1] = 0;
192 coords[2][0] = width - 1;
193 coords[2][1] = height - 1;
194 coords[3][0] = 0;
195 coords[3][1] = height - 1;
196
197
198 for (rot = 0; rot < 360; rot += 90) {
199 struct matrix23 rotate, flip, m;
200 int i;
201
202 printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy);
203
204 /* make transformation matrix 'm' */
205 matrix23Rotate(&rotate, width, height, rot);
206 matrix23Flip(&flip, width, height, fx, fy);
207 matrix23Multiply(&m, &rotate, &flip);
208
209 /* xform four coords */
210 for (i = 0; i < 4; i++) {
211 int x = coords[i][0];
212 int y = coords[i][1];
213 matrix23TransformCoordi(&m, &x, &y);
214 printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y);
215 }
216
217 /* xform width, height */
218 {
219 int x = width;
220 int y = height;
221 matrix23TransformDistance(&m, &x, &y);
222 printf(" %d x %d -> %d x %d\n", width, height, x, y);
223 }
224
225 /* xform rect */
226 {
227 int x = 50, y = 10, w = 200, h = 100;
228 matrix23TransformRect(&m, &x, &y, &w, &h);
229 printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100,
230 x, y, w, h);
231 }
232
233 }
234
235 return 0;
236 }
237 #endif