1 /*
2 (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29 #include <config.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <dfb_types.h>
36
37 #include <pthread.h>
38
39 #include <directfb.h>
40
41 #include <core/core.h>
42 #include <core/coredefs.h>
43 #include <core/coretypes.h>
44
45 #include <core/gfxcard.h>
46 #include <core/state.h>
47 #include <core/palette.h>
48
49 #include <misc/gfx_util.h>
50 #include <misc/util.h>
51 #include <misc/conf.h>
52
53 #include <direct/clock.h>
54 #include <direct/mem.h>
55 #include <direct/memcpy.h>
56 #include <direct/messages.h>
57 #include <direct/util.h>
58
59 #include <gfx/convert.h>
60 #include <gfx/util.h>
61
62 #include "generic.h"
63
64 /**********************************************************************************************************************/
65 /**********************************************************************************************************************/
66
gBlit(CardState * state,DFBRectangle * rect,int dx,int dy)67 void gBlit( CardState *state, DFBRectangle *rect, int dx, int dy )
68 {
69 GenefxState *gfxs = state->gfxs;
70 int h;
71 XopAdvanceFunc Aop_advance;
72 XopAdvanceFunc Bop_advance;
73 int Aop_X;
74 int Aop_Y;
75 int Bop_X;
76 int Bop_Y;
77
78 DFBSurfaceBlittingFlags rotflip_blittingflags = state->blittingflags;
79
80 dfb_simplify_blittingflags( &rotflip_blittingflags );
81 rotflip_blittingflags &= (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL | DSBLIT_ROTATE90 );
82
83 D_ASSERT( gfxs != NULL );
84
85 if (dfb_config->software_warn) {
86 D_WARN( "Blit (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, funcs %d/%d, color 0x%02x%02x%02x%02x, source (%4d,%4d) %6s",
87 dx, dy, rect->w, rect->h, dfb_pixelformat_name(gfxs->dst_format), state->blittingflags,
88 state->src_blend, state->dst_blend,
89 state->color.a, state->color.r, state->color.g, state->color.b, rect->x, rect->y,
90 dfb_pixelformat_name(gfxs->src_format) );
91 }
92
93 D_ASSERT( state->clip.x1 <= dx );
94 D_ASSERT( state->clip.y1 <= dy );
95 D_ASSERT( (rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.x2 >= (dx + rect->w - 1) );
96 D_ASSERT( (rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.y2 >= (dy + rect->h - 1) );
97 D_ASSERT( !(rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.x2 >= (dx + rect->h - 1) );
98 D_ASSERT( !(rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.y2 >= (dy + rect->w - 1) );
99
100 CHECK_PIPELINE();
101
102 if (!Genefx_ABacc_prepare( gfxs, rect->w ))
103 return;
104
105
106 switch (gfxs->src_format) {
107 case DSPF_A4:
108 case DSPF_YUY2:
109 case DSPF_UYVY:
110 rect->x &= ~1;
111 break;
112 default:
113 break;
114 }
115
116 switch (gfxs->dst_format) {
117 case DSPF_A4:
118 case DSPF_YUY2:
119 case DSPF_UYVY:
120 dx &= ~1;
121 break;
122 default:
123 break;
124 }
125
126 gfxs->length = rect->w;
127
128
129 if (gfxs->src_org[0] == gfxs->dst_org[0] && dy == rect->y && dx > rect->x)
130 /* we must blit from right to left */
131 gfxs->Astep = gfxs->Bstep = -1;
132 else
133 /* we must blit from left to right*/
134 gfxs->Astep = gfxs->Bstep = 1;
135
136
137 if (rotflip_blittingflags == (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL)) { // 180 deg
138 gfxs->Astep *= -1;
139
140 Aop_X = dx + rect->w - 1;
141 Aop_Y = dy;
142
143 Bop_X = rect->x;
144 Bop_Y = rect->y + rect->h - 1;
145
146 Aop_advance = Genefx_Aop_next;
147 Bop_advance = Genefx_Bop_prev;
148 }
149 else if (rotflip_blittingflags == DSBLIT_FLIP_HORIZONTAL) {
150 gfxs->Astep *= -1;
151
152 Aop_X = dx + rect->w - 1;
153 Aop_Y = dy;
154
155 Bop_X = rect->x;
156 Bop_Y = rect->y;
157
158 Aop_advance = Genefx_Aop_next;
159 Bop_advance = Genefx_Bop_next;
160 }
161 else if (rotflip_blittingflags == DSBLIT_FLIP_VERTICAL) {
162 Aop_X = dx;
163 Aop_Y = dy + rect->h - 1;
164
165 Bop_X = rect->x;
166 Bop_Y = rect->y;
167
168 Aop_advance = Genefx_Aop_prev;
169 Bop_advance = Genefx_Bop_next;
170 }
171 else if (rotflip_blittingflags == (DSBLIT_ROTATE90 | DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL)) { // 270 deg ccw
172 gfxs->Astep *= gfxs->dst_pitch / gfxs->dst_bpp;
173
174 Aop_X = dx;
175 Aop_Y = dy;
176
177 Bop_X = rect->x;
178 Bop_Y = rect->y + rect->h - 1;
179
180 Aop_advance = Genefx_Aop_crab;
181 Bop_advance = Genefx_Bop_prev;
182 }
183 else if (rotflip_blittingflags == DSBLIT_ROTATE90) { // 90 deg ccw
184 gfxs->Astep *= -gfxs->dst_pitch / gfxs->dst_bpp;
185
186 Aop_X = dx;
187 Aop_Y = dy + rect->w - 1;
188
189 Bop_X = rect->x;
190 Bop_Y = rect->y;
191
192 Aop_advance = Genefx_Aop_crab;
193 Bop_advance = Genefx_Bop_next;
194 }
195 else if (rotflip_blittingflags == (DSBLIT_ROTATE90 | DSBLIT_FLIP_VERTICAL)) {
196 gfxs->Astep *= -gfxs->dst_pitch / gfxs->dst_bpp;
197
198 Aop_X = dx + rect->h - 1;
199 Aop_Y = dy + rect->w - 1;
200
201 Bop_X = rect->x;
202 Bop_Y = rect->y;
203
204 Aop_advance = Genefx_Aop_prev_crab;
205 Bop_advance = Genefx_Bop_next;
206 }
207 else if (rotflip_blittingflags == (DSBLIT_ROTATE90 | DSBLIT_FLIP_HORIZONTAL)) {
208 gfxs->Astep *= gfxs->dst_pitch / gfxs->dst_bpp;
209
210 Aop_X = dx;
211 Aop_Y = dy;
212
213 Bop_X = rect->x;
214 Bop_Y = rect->y;
215
216 Aop_advance = Genefx_Aop_crab;
217 Bop_advance = Genefx_Bop_next;
218 }
219 else if (gfxs->src_org[0] == gfxs->dst_org[0] && dy > rect->y && !(state->blittingflags & DSBLIT_DEINTERLACE)) {
220 /* we must blit from bottom to top */
221 Aop_X = dx;
222 Aop_Y = dy + rect->h - 1;
223
224 Bop_X = rect->x;
225 Bop_Y = rect->y + rect->h - 1;
226
227 Aop_advance = Genefx_Aop_prev;
228 Bop_advance = Genefx_Bop_prev;
229 }
230 else {
231 /* we must blit from top to bottom */
232 Aop_X = dx;
233 Aop_Y = dy;
234
235 Bop_X = rect->x;
236 Bop_Y = rect->y;
237
238 Aop_advance = Genefx_Aop_next;
239 Bop_advance = Genefx_Bop_next;
240 }
241
242
243
244 Genefx_Aop_xy( gfxs, Aop_X, Aop_Y );
245 Genefx_Bop_xy( gfxs, Bop_X, Bop_Y );
246
247 if (state->blittingflags & DSBLIT_DEINTERLACE) {
248 if (state->source->field) {
249 Aop_advance( gfxs );
250 Bop_advance( gfxs );
251 rect->h--;
252 }
253
254 for (h = rect->h/2; h; h--) {
255 RUN_PIPELINE();
256
257 Aop_advance( gfxs );
258
259 RUN_PIPELINE();
260
261 Aop_advance( gfxs );
262
263 Bop_advance( gfxs );
264 Bop_advance( gfxs );
265 }
266 } /* ! DSBLIT_DEINTERLACE */
267 else {
268 for (h = rect->h; h; h--) {
269 RUN_PIPELINE();
270
271 Aop_advance( gfxs );
272 Bop_advance( gfxs );
273 }
274 }
275
276 Genefx_ABacc_flush( gfxs );
277 }
278
279