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