1 /*
2 (c) Copyright 2001-2009 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 #ifndef __CORE__STATE_H__
30 #define __CORE__STATE_H__
31
32 #include <pthread.h>
33
34 #include <directfb.h>
35
36 #include <direct/serial.h>
37
38 #include <fusion/reactor.h>
39
40 #include <core/coredefs.h>
41 #include <core/coretypes.h>
42 #include <core/gfxcard.h>
43 #include <core/surface_buffer.h>
44
45 #include <gfx/generic/generic.h>
46
47 #include <misc/conf.h>
48 #include <misc/util.h>
49
50
51 typedef enum {
52 SMF_DRAWING_FLAGS = 0x00000001,
53 SMF_BLITTING_FLAGS = 0x00000002,
54 SMF_CLIP = 0x00000004,
55 SMF_COLOR = 0x00000008,
56 SMF_SRC_BLEND = 0x00000010,
57 SMF_DST_BLEND = 0x00000020,
58 SMF_SRC_COLORKEY = 0x00000040,
59 SMF_DST_COLORKEY = 0x00000080,
60
61 SMF_DESTINATION = 0x00000100,
62 SMF_SOURCE = 0x00000200,
63 SMF_SOURCE_MASK = 0x00000400,
64 SMF_SOURCE_MASK_VALS = 0x00000800,
65
66 SMF_INDEX_TRANSLATION = 0x00001000,
67 SMF_COLORKEY = 0x00002000,
68
69 SMF_RENDER_OPTIONS = 0x00010000,
70 SMF_MATRIX = 0x00020000,
71
72 SMF_SOURCE2 = 0x00100000,
73
74 SMF_ALL = 0x00133FFF
75 } StateModificationFlags;
76
77 typedef enum {
78 CSF_NONE = 0x00000000,
79
80 CSF_DESTINATION = 0x00000001, /* destination is set using dfb_state_set_destination() */
81 CSF_SOURCE = 0x00000002, /* source is set using dfb_state_set_source() */
82 CSF_SOURCE_MASK = 0x00000008, /* source mask is set using dfb_state_set_source_mask() */
83
84 CSF_SOURCE_LOCKED = 0x00000010, /* source surface is locked */
85 CSF_SOURCE_MASK_LOCKED = 0x00000020, /* source mask surface is locked */
86
87 CSF_SOURCE2 = 0x00000100, /* source2 is set using dfb_state_set_source2() */
88 CSF_SOURCE2_LOCKED = 0x00000200, /* source2 surface is locked */
89
90 CSF_DRAWING = 0x00010000, /* something has been rendered with this state,
91 this is cleared by flushing the state, e.g. upon flip */
92
93 CSF_ALL = 0x0001033B
94 } CardStateFlags;
95
96 struct _CardState {
97 int magic;
98
99 CoreDFB *core;
100 CoreGraphicsDevice *device;
101 FusionID fusion_id;
102
103 pthread_mutex_t lock; /* lock for state handling */
104
105 CardStateFlags flags;
106
107 StateModificationFlags modified; /* indicate which fields have been
108 modified, these flags will be
109 cleared by the gfx drivers */
110 StateModificationFlags mod_hw;
111
112 /* values forming the state for graphics operations */
113
114 DFBSurfaceDrawingFlags drawingflags; /* drawing flags */
115 DFBSurfaceBlittingFlags blittingflags; /* blitting flags */
116
117 DFBRegion clip; /* clipping rectangle */
118 DFBColor color; /* color for drawing or modulation */
119 unsigned int color_index; /* index to color in palette */
120 DFBSurfaceBlendFunction src_blend; /* blend function for source */
121 DFBSurfaceBlendFunction dst_blend; /* blend function for destination */
122 u32 src_colorkey; /* colorkey for source */
123 u32 dst_colorkey; /* colorkey for destination */
124
125 CoreSurface *destination; /* destination surface */
126 CoreSurface *source; /* source surface */
127
128 DirectSerial dst_serial; /* last destination surface serial */
129 DirectSerial src_serial; /* last source surface serial */
130
131 int *index_translation;
132 int num_translation;
133
134 /* hardware abstraction and state handling helpers */
135
136 DFBAccelerationMask accel; /* remember checked commands if they are accelerated */
137 DFBAccelerationMask checked; /* commands for which a state has been checked */
138 DFBAccelerationMask set; /* commands for which a state is valid */
139 DFBAccelerationMask disabled; /* commands which are disabled temporarily */
140
141 CoreGraphicsSerial serial; /* hardware serial of the last operation */
142
143 /* from/to buffers */
144
145 CoreSurfaceBufferRole from; /* usually CSBR_FRONT */
146 CoreSurfaceBufferRole to; /* usually CSBR_BACK */
147
148 /* read/write locks during operation */
149
150 CoreSurfaceBufferLock dst;
151 CoreSurfaceBufferLock src;
152
153 /* software driver */
154
155 GenefxState *gfxs;
156
157
158 /* extended state */
159
160 DFBSurfaceRenderOptions render_options;
161
162 DFBColorKey colorkey; /* key for color key protection */
163
164 s32 matrix[9]; /* transformation matrix for DSRO_MATRIX (fixed 16.16) */
165 DFBBoolean affine_matrix;
166
167 CoreSurface *source_mask; /* source mask surface */
168 CoreSurfaceBufferLock src_mask; /* source mask surface lock */
169 DirectSerial src_mask_serial; /* last source mask surface serial */
170 DFBPoint src_mask_offset; /* relative or absolute coordinates */
171 DFBSurfaceMaskFlags src_mask_flags; /* controls coordinate mode and more */
172
173 CoreSurface *source2; /* source2 surface */
174 DirectSerial src2_serial; /* last source2 surface serial */
175 CoreSurfaceBufferLock src2;
176
177 DFBColor colors[DFB_COLOR_IDS_MAX]; /* colors for drawing or modulation */
178 unsigned int color_indices[DFB_COLOR_IDS_MAX]; /* indices to colors in palette */
179 };
180
181 int dfb_state_init( CardState *state, CoreDFB *core );
182 void dfb_state_destroy( CardState *state );
183
184 DFBResult dfb_state_set_destination( CardState *state, CoreSurface *destination );
185 DFBResult dfb_state_set_source( CardState *state, CoreSurface *source );
186 DFBResult dfb_state_set_source_mask( CardState *state, CoreSurface *source_mask );
187 DFBResult dfb_state_set_source2( CardState *state, CoreSurface *source2 );
188
189 void dfb_state_update( CardState *state, bool update_source );
190
191 DFBResult dfb_state_set_index_translation( CardState *state,
192 const int *indices,
193 int num_indices );
194
195 void dfb_state_set_matrix( CardState *state,
196 const s32 *matrix );
197
198 static inline void
dfb_state_get_serial(const CardState * state,CoreGraphicsSerial * ret_serial)199 dfb_state_get_serial( const CardState *state, CoreGraphicsSerial *ret_serial )
200 {
201 D_ASSERT( state != NULL );
202 D_ASSERT( ret_serial != NULL );
203
204 *ret_serial = state->serial;
205 }
206
207 static inline void
dfb_state_lock(CardState * state)208 dfb_state_lock( CardState *state )
209 {
210 D_MAGIC_ASSERT( state, CardState );
211
212 DFB_REGION_ASSERT( &state->clip );
213
214 pthread_mutex_lock( &state->lock );
215 }
216
217 static inline void
dfb_state_start_drawing(CardState * state,CoreGraphicsDevice * device)218 dfb_state_start_drawing( CardState *state, CoreGraphicsDevice *device )
219 {
220 D_MAGIC_ASSERT( state, CardState );
221 D_ASSERT( device != NULL );
222 D_ASSERT( state->destination != NULL );
223
224 if (dfb_config->startstop) {
225 if (state->flags & CSF_DRAWING)
226 D_ASSERT( state->device == device );
227 else {
228 dfb_gfxcard_start_drawing( device, state );
229
230 state->flags = (CardStateFlags)(state->flags | CSF_DRAWING);
231 state->device = device;
232 }
233 }
234 }
235
236 static inline void
dfb_state_stop_drawing(CardState * state)237 dfb_state_stop_drawing( CardState *state )
238 {
239 D_MAGIC_ASSERT( state, CardState );
240 D_ASSERT( state->destination != NULL );
241
242 if (dfb_config->startstop) {
243 if (state->flags & CSF_DRAWING) {
244 D_ASSERT( state->device != NULL );
245
246 dfb_gfxcard_stop_drawing( state->device, state );
247
248 state->flags = (CardStateFlags)(state->flags & ~CSF_DRAWING);
249 state->device = NULL;
250 }
251 else
252 D_ASSERT( state->device == NULL );
253 }
254 }
255
256 static inline void
dfb_state_unlock(CardState * state)257 dfb_state_unlock( CardState *state )
258 {
259 D_MAGIC_ASSERT( state, CardState );
260
261 DFB_REGION_ASSERT( &state->clip );
262
263 pthread_mutex_unlock( &state->lock );
264 }
265
266
267 #define _dfb_state_set_checked(member,flag,state,value) \
268 do { \
269 D_MAGIC_ASSERT( state, CardState ); \
270 \
271 if ((value) != (state)->member) { \
272 (state)->member = (value); \
273 (state)->modified = (StateModificationFlags)((state)->modified | SMF_##flag); \
274 } \
275 } while (0)
276
277
278 #define dfb_state_set_blitting_flags(state,flags) _dfb_state_set_checked( blittingflags, \
279 BLITTING_FLAGS, \
280 state, flags )
281
282 #define dfb_state_set_drawing_flags(state,flags) _dfb_state_set_checked( drawingflags, \
283 DRAWING_FLAGS, \
284 state, flags )
285
286 #define dfb_state_set_color_index(state,index) _dfb_state_set_checked( color_index, \
287 COLOR, \
288 state, index )
289
290 #define dfb_state_set_src_blend(state,blend) _dfb_state_set_checked( src_blend, \
291 SRC_BLEND, \
292 state, blend )
293
294 #define dfb_state_set_dst_blend(state,blend) _dfb_state_set_checked( dst_blend, \
295 DST_BLEND, \
296 state, blend )
297
298 #define dfb_state_set_src_colorkey(state,key) _dfb_state_set_checked( src_colorkey, \
299 SRC_COLORKEY, \
300 state, key )
301
302 #define dfb_state_set_dst_colorkey(state,key) _dfb_state_set_checked( dst_colorkey, \
303 DST_COLORKEY, \
304 state, key )
305
306 #define dfb_state_set_render_options(state,opts) _dfb_state_set_checked( render_options, \
307 RENDER_OPTIONS, \
308 state, opts )
309
dfb_state_set_clip(CardState * state,const DFBRegion * clip)310 static inline void dfb_state_set_clip( CardState *state, const DFBRegion *clip )
311 {
312 D_MAGIC_ASSERT( state, CardState );
313 DFB_REGION_ASSERT( clip );
314
315 if (! DFB_REGION_EQUAL( state->clip, *clip )) {
316 state->clip = *clip;
317 state->modified = (StateModificationFlags)( state->modified | SMF_CLIP );
318 }
319 }
320
dfb_state_set_color(CardState * state,const DFBColor * color)321 static inline void dfb_state_set_color( CardState *state, const DFBColor *color )
322 {
323 D_MAGIC_ASSERT( state, CardState );
324 D_ASSERT( color != NULL );
325
326 if (! DFB_COLOR_EQUAL( state->color, *color )) {
327 state->color = *color;
328 state->modified = (StateModificationFlags)( state->modified | SMF_COLOR );
329 }
330 }
331
dfb_state_set_colorkey(CardState * state,const DFBColorKey * key)332 static inline void dfb_state_set_colorkey( CardState *state, const DFBColorKey *key )
333 {
334 D_MAGIC_ASSERT( state, CardState );
335 D_ASSERT( key != NULL );
336
337 if (! DFB_COLORKEY_EQUAL( state->colorkey, *key )) {
338 state->colorkey = *key;
339 state->modified = (StateModificationFlags)( state->modified | SMF_COLORKEY );
340 }
341 }
342
dfb_state_set_source_mask_vals(CardState * state,const DFBPoint * offset,DFBSurfaceMaskFlags flags)343 static inline void dfb_state_set_source_mask_vals( CardState *state,
344 const DFBPoint *offset,
345 DFBSurfaceMaskFlags flags )
346 {
347 D_MAGIC_ASSERT( state, CardState );
348 D_ASSERT( offset != NULL );
349 D_FLAGS_ASSERT( flags, DSMF_ALL );
350
351 if (! DFB_POINT_EQUAL( state->src_mask_offset, *offset ) || state->src_mask_flags != flags) {
352 state->src_mask_offset = *offset;
353 state->src_mask_flags = flags;
354
355 state->modified = (StateModificationFlags)( state->modified | SMF_SOURCE_MASK_VALS );
356 }
357 }
358
359 /*
360 * Multifunctional color configuration function.
361 *
362 * Always tries to set both color and index.
363 *
364 * If color index is -1, color is used and searched in palette of destination surface if present.
365 * If color index is valid the color is looked up in palette if present.
366 */
367 void dfb_state_set_color_or_index( CardState *state,
368 const DFBColor *color,
369 int index );
370
371 #endif
372
373