/* (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) (c) Copyright 2000-2004 Convergence (integrated media) GmbH All rights reserved. Written by Denis Oliver Kropp , Andreas Hundt , Sven Neumann , Ville Syrjälä and Claudio Ciccani . This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CORE__STATE_H__ #define __CORE__STATE_H__ #include #include #include #include #include #include #include #include #include #include #include typedef enum { SMF_DRAWING_FLAGS = 0x00000001, SMF_BLITTING_FLAGS = 0x00000002, SMF_CLIP = 0x00000004, SMF_COLOR = 0x00000008, SMF_SRC_BLEND = 0x00000010, SMF_DST_BLEND = 0x00000020, SMF_SRC_COLORKEY = 0x00000040, SMF_DST_COLORKEY = 0x00000080, SMF_DESTINATION = 0x00000100, SMF_SOURCE = 0x00000200, SMF_SOURCE_MASK = 0x00000400, SMF_SOURCE_MASK_VALS = 0x00000800, SMF_INDEX_TRANSLATION = 0x00001000, SMF_COLORKEY = 0x00002000, SMF_RENDER_OPTIONS = 0x00010000, SMF_MATRIX = 0x00020000, SMF_ALL = 0x00033FFF } StateModificationFlags; typedef enum { CSF_NONE = 0x00000000, CSF_DESTINATION = 0x00000001, /* destination is set using dfb_state_set_destination() */ CSF_SOURCE = 0x00000002, /* source is set using dfb_state_set_source() */ CSF_SOURCE_MASK = 0x00000008, /* source mask is set using dfb_state_set_source_mask() */ CSF_SOURCE_LOCKED = 0x00000010, /* source surface is locked */ CSF_SOURCE_MASK_LOCKED = 0x00000020, /* source mask surface is locked */ CSF_DRAWING = 0x00010000, /* something has been rendered with this state, this is cleared by flushing the state, e.g. upon flip */ CSF_ALL = 0x0001003B } CardStateFlags; struct _CardState { int magic; CoreDFB *core; CoreGraphicsDevice *device; FusionID fusion_id; pthread_mutex_t lock; /* lock for state handling */ CardStateFlags flags; StateModificationFlags modified; /* indicate which fields have been modified, these flags will be cleared by the gfx drivers */ StateModificationFlags mod_hw; /* values forming the state for graphics operations */ DFBSurfaceDrawingFlags drawingflags; /* drawing flags */ DFBSurfaceBlittingFlags blittingflags; /* blitting flags */ DFBRegion clip; /* clipping rectangle */ DFBColor color; /* color for drawing or modulation */ unsigned int color_index; /* index to color in palette */ DFBSurfaceBlendFunction src_blend; /* blend function for source */ DFBSurfaceBlendFunction dst_blend; /* blend function for destination */ u32 src_colorkey; /* colorkey for source */ u32 dst_colorkey; /* colorkey for destination */ CoreSurface *destination; /* destination surface */ CoreSurface *source; /* source surface */ DirectSerial dst_serial; /* last destination surface serial */ DirectSerial src_serial; /* last source surface serial */ int *index_translation; int num_translation; /* hardware abstraction and state handling helpers */ DFBAccelerationMask accel; /* remember checked commands if they are accelerated */ DFBAccelerationMask checked; /* commands for which a state has been checked */ DFBAccelerationMask set; /* commands for which a state is valid */ DFBAccelerationMask disabled; /* commands which are disabled temporarily */ CoreGraphicsSerial serial; /* hardware serial of the last operation */ /* from/to buffers */ CoreSurfaceBufferRole from; /* usually CSBR_FRONT */ CoreSurfaceBufferRole to; /* usually CSBR_BACK */ /* read/write locks during operation */ CoreSurfaceBufferLock dst; CoreSurfaceBufferLock src; /* software driver */ GenefxState *gfxs; /* extended state */ DFBSurfaceRenderOptions render_options; DFBColorKey colorkey; /* key for color key protection */ s32 matrix[9]; /* transformation matrix for DSRO_MATRIX (fixed 16.16) */ DFBBoolean affine_matrix; CoreSurface *source_mask; /* source mask surface */ CoreSurfaceBufferLock src_mask; /* source mask surface lock */ DirectSerial src_mask_serial; /* last source mask surface serial */ DFBPoint src_mask_offset; /* relative or absolute coordinates */ DFBSurfaceMaskFlags src_mask_flags; /* controls coordinate mode and more */ DFBColor colors[DFB_COLOR_IDS_MAX]; /* colors for drawing or modulation */ unsigned int color_indices[DFB_COLOR_IDS_MAX]; /* indices to colors in palette */ }; int dfb_state_init( CardState *state, CoreDFB *core ); void dfb_state_destroy( CardState *state ); DFBResult dfb_state_set_destination( CardState *state, CoreSurface *destination ); DFBResult dfb_state_set_source( CardState *state, CoreSurface *source ); DFBResult dfb_state_set_source_mask( CardState *state, CoreSurface *source_mask ); void dfb_state_update( CardState *state, bool update_source ); DFBResult dfb_state_set_index_translation( CardState *state, const int *indices, int num_indices ); void dfb_state_set_matrix( CardState *state, const s32 *matrix ); static inline void dfb_state_get_serial( const CardState *state, CoreGraphicsSerial *ret_serial ) { D_ASSERT( state != NULL ); D_ASSERT( ret_serial != NULL ); *ret_serial = state->serial; } static inline void dfb_state_lock( CardState *state ) { D_MAGIC_ASSERT( state, CardState ); DFB_REGION_ASSERT( &state->clip ); pthread_mutex_lock( &state->lock ); } static inline void dfb_state_start_drawing( CardState *state, CoreGraphicsDevice *device ) { D_MAGIC_ASSERT( state, CardState ); D_ASSERT( device != NULL ); D_ASSERT( state->destination != NULL ); if (dfb_config->startstop) { if (state->flags & CSF_DRAWING) D_ASSERT( state->device == device ); else { dfb_gfxcard_start_drawing( device, state ); state->flags = (CardStateFlags)(state->flags | CSF_DRAWING); state->device = device; } } } static inline void dfb_state_stop_drawing( CardState *state ) { D_MAGIC_ASSERT( state, CardState ); D_ASSERT( state->destination != NULL ); if (dfb_config->startstop) { if (state->flags & CSF_DRAWING) { D_ASSERT( state->device != NULL ); dfb_gfxcard_stop_drawing( state->device, state ); state->flags = (CardStateFlags)(state->flags & ~CSF_DRAWING); state->device = NULL; } else D_ASSERT( state->device == NULL ); } } static inline void dfb_state_unlock( CardState *state ) { D_MAGIC_ASSERT( state, CardState ); DFB_REGION_ASSERT( &state->clip ); pthread_mutex_unlock( &state->lock ); } #define _dfb_state_set_checked(member,flag,state,value) \ do { \ D_MAGIC_ASSERT( state, CardState ); \ \ if ((value) != (state)->member) { \ (state)->member = (value); \ (state)->modified |= SMF_##flag; \ } \ } while (0) #define dfb_state_set_blitting_flags(state,flags) _dfb_state_set_checked( blittingflags, \ BLITTING_FLAGS, \ state, flags ) #define dfb_state_set_drawing_flags(state,flags) _dfb_state_set_checked( drawingflags, \ DRAWING_FLAGS, \ state, flags ) #define dfb_state_set_color_index(state,index) _dfb_state_set_checked( color_index, \ COLOR, \ state, index ) #define dfb_state_set_src_blend(state,blend) _dfb_state_set_checked( src_blend, \ SRC_BLEND, \ state, blend ) #define dfb_state_set_dst_blend(state,blend) _dfb_state_set_checked( dst_blend, \ DST_BLEND, \ state, blend ) #define dfb_state_set_src_colorkey(state,key) _dfb_state_set_checked( src_colorkey, \ SRC_COLORKEY, \ state, key ) #define dfb_state_set_dst_colorkey(state,key) _dfb_state_set_checked( dst_colorkey, \ DST_COLORKEY, \ state, key ) #define dfb_state_set_render_options(state,opts) _dfb_state_set_checked( render_options, \ RENDER_OPTIONS, \ state, opts ) static inline void dfb_state_set_clip( CardState *state, const DFBRegion *clip ) { D_MAGIC_ASSERT( state, CardState ); DFB_REGION_ASSERT( clip ); if (! DFB_REGION_EQUAL( state->clip, *clip )) { state->clip = *clip; state->modified = (StateModificationFlags)( state->modified | SMF_CLIP ); } } static inline void dfb_state_set_color( CardState *state, const DFBColor *color ) { D_MAGIC_ASSERT( state, CardState ); D_ASSERT( color != NULL ); if (! DFB_COLOR_EQUAL( state->color, *color )) { state->color = *color; state->modified = (StateModificationFlags)( state->modified | SMF_COLOR ); } } static inline void dfb_state_set_colorkey( CardState *state, const DFBColorKey *key ) { D_MAGIC_ASSERT( state, CardState ); D_ASSERT( key != NULL ); if (! DFB_COLORKEY_EQUAL( state->colorkey, *key )) { state->colorkey = *key; state->modified = (StateModificationFlags)( state->modified | SMF_COLOR ); } } static inline void dfb_state_set_source_mask_vals( CardState *state, const DFBPoint *offset, DFBSurfaceMaskFlags flags ) { D_MAGIC_ASSERT( state, CardState ); D_ASSERT( offset != NULL ); D_FLAGS_ASSERT( flags, DSMF_ALL ); if (! DFB_POINT_EQUAL( state->src_mask_offset, *offset ) || state->src_mask_flags != flags) { state->src_mask_offset = *offset; state->src_mask_flags = flags; state->modified = (StateModificationFlags)( state->modified | SMF_SOURCE_MASK_VALS ); } } /* * Multifunctional color configuration function. * * Always tries to set both color and index. * * If color index is -1, color is used and searched in palette of destination surface if present. * If color index is valid the color is looked up in palette if present. */ void dfb_state_set_color_or_index( CardState *state, const DFBColor *color, int index ); #endif