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__SURFACE_BUFFER_H__
30 #define __CORE__SURFACE_BUFFER_H__
31 
32 #include <direct/debug.h>
33 
34 #include <fusion/object.h>
35 #include <fusion/vector.h>
36 
37 #include <core/surface.h>
38 #include <core/surface_allocation.h>
39 
40 #include <directfb.h>
41 
42 
43 /*
44  * Configuration and State flags of a Surface Buffer
45  */
46 typedef enum {
47      CSBF_NONE      = 0x00000000,  /* None of these. */
48 
49      CSBF_STICKED   = 0x00000001,  /* Sticked to one Surface Pool, e.g. system only. */
50 
51      CSBF_ALL       = 0x00000001   /* All of these. */
52 } CoreSurfaceBufferFlags;
53 
54 
55 typedef enum {
56      CSBNF_NONE     = 0x00000000
57 } CoreSurfaceBufferNotificationFlags;
58 
59 typedef struct {
60      CoreSurfaceBufferNotificationFlags  flags;
61 } CoreSurfaceBufferNotification;
62 
63 
64 /*
65  * A Lock on a Surface Buffer
66  */
67 struct __DFB_CoreSurfaceBufferLock {
68      int                      magic;              /* Must be valid before calling dfb_surface_pool_lock() */
69 
70      CoreSurfaceAccessorID    accessor;           /* " */
71      CoreSurfaceAccessFlags   access;             /* " */
72 
73      CoreSurfaceBuffer       *buffer;             /* Set by dfb_surface_pool_lock() */
74      CoreSurfaceAllocation   *allocation;         /* " */
75 
76      void                    *addr;               /* " */
77      unsigned long            phys;               /* " */
78      unsigned long            offset;             /* " */
79      unsigned int             pitch;              /* " */
80 
81      void                    *handle;             /* " */
82 };
83 
84 static inline void
dfb_surface_buffer_lock_reset(CoreSurfaceBufferLock * lock)85 dfb_surface_buffer_lock_reset( CoreSurfaceBufferLock *lock )
86 {
87      D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
88 
89      lock->buffer     = NULL;
90      lock->allocation = NULL;
91      lock->addr       = NULL;
92      lock->phys       = 0;
93      lock->offset     = ~0;
94      lock->pitch      = 0;
95      lock->handle     = NULL;
96 }
97 
98 static inline void
dfb_surface_buffer_lock_init(CoreSurfaceBufferLock * lock,CoreSurfaceAccessorID accessor,CoreSurfaceAccessFlags access)99 dfb_surface_buffer_lock_init( CoreSurfaceBufferLock *lock, CoreSurfaceAccessorID accessor, CoreSurfaceAccessFlags access )
100 {
101      D_MAGIC_SET( lock, CoreSurfaceBufferLock );
102 
103      lock->accessor = accessor;
104      lock->access   = access;
105 
106      dfb_surface_buffer_lock_reset( lock );
107 }
108 
109 static inline void
dfb_surface_buffer_lock_deinit(CoreSurfaceBufferLock * lock)110 dfb_surface_buffer_lock_deinit( CoreSurfaceBufferLock *lock )
111 {
112      D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
113 
114      lock->accessor = CSAID_NONE;
115      lock->access   = CSAF_NONE;
116 
117      D_MAGIC_CLEAR( lock );
118 }
119 
120 #define CORE_SURFACE_BUFFER_LOCK_ASSERT(lock)                                                       \
121      do {                                                                                           \
122           D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );                                            \
123           D_FLAGS_ASSERT( (lock)->access, CSAF_ALL );                                               \
124           if ((lock)->allocation) {                                                                 \
125                /*D_ASSERT( (lock)->buffer == (lock)->allocation->buffer );*/                            \
126                D_ASSUME( (lock)->addr != NULL || (lock)->phys != 0 || (lock)->offset != ~0 || (lock)->handle != NULL );\
127                D_ASSUME( (lock)->offset == (lock)->allocation->offset || (lock)->offset == ~0 );    \
128                D_ASSERT( (lock)->pitch > 0 || ((lock)->addr == NULL && (lock)->phys == 0) );        \
129           }                                                                                         \
130           else {                                                                                    \
131                D_ASSERT( (lock)->buffer == NULL );                                                  \
132                D_ASSERT( (lock)->addr == NULL );                                                    \
133                D_ASSERT( (lock)->phys == 0 );                                                       \
134                D_ASSERT( (lock)->offset == ~0 );                                                    \
135                D_ASSERT( (lock)->pitch == 0 );                                                      \
136                D_ASSERT( (lock)->handle == NULL );                                                  \
137           }                                                                                         \
138      } while (0)
139 
140 /*
141  * A Surface Buffer of a Surface
142  */
143 struct __DFB_CoreSurfaceBuffer {
144      FusionObject             object;
145 
146      int                      magic;
147 
148      DirectSerial             serial;        /* Increased when content is written. */
149      CoreSurfaceAllocation   *written;       /* Allocation with the last write access. */
150      CoreSurfaceAllocation   *read;          /* Allocation with the last read access. */
151 
152      CoreSurface             *surface;       /* Surface owning this Surface Buffer. */
153      CoreSurfacePolicy        policy;
154 
155      CoreSurfaceBufferFlags   flags;         /* Configuration and State flags. */
156      DFBSurfacePixelFormat    format;        /* Pixel format of buffer data. */
157 
158      FusionVector             allocs;        /* Allocations within Surface Pools. */
159 
160      CoreSurfaceConfig        config;        /* Configuration of its surface at the time of the buffer creation */
161      CoreSurfaceTypeFlags     type;
162      unsigned long            resource_id;   /* layer id, window id, or user specified */
163 };
164 
165 #define CORE_SURFACE_BUFFER_ASSERT(buffer)                                                     \
166      do {                                                                                      \
167           D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );                                         \
168      } while (0)
169 
170 
171 DFBResult dfb_surface_buffer_create ( CoreDFB                 *core,
172                                       CoreSurface             *surface,
173                                       CoreSurfaceBufferFlags   flags,
174                                       CoreSurfaceBuffer      **ret_buffer );
175 
176 DFBResult dfb_surface_buffer_decouple( CoreSurfaceBuffer       *buffer );
177 
178 DFBResult dfb_surface_buffer_deallocate( CoreSurfaceBuffer    *buffer );
179 
180 DFBResult dfb_surface_buffer_lock   ( CoreSurfaceBuffer       *buffer,
181                                       CoreSurfaceAccessorID    accessor,
182                                       CoreSurfaceAccessFlags   access,
183                                       CoreSurfaceBufferLock   *ret_lock );
184 
185 DFBResult dfb_surface_buffer_unlock ( CoreSurfaceBufferLock   *lock );
186 
187 DFBResult dfb_surface_buffer_read   ( CoreSurfaceBuffer       *buffer,
188                                       void                    *destination,
189                                       int                      pitch,
190                                       const DFBRectangle      *rect );
191 
192 DFBResult dfb_surface_buffer_write  ( CoreSurfaceBuffer       *buffer,
193                                       const void              *source,
194                                       int                      pitch,
195                                       const DFBRectangle      *rect );
196 
197 DFBResult dfb_surface_buffer_dump   ( CoreSurfaceBuffer       *buffer,
198                                       const char              *directory,
199                                       const char              *prefix );
200 
201 CoreSurfaceAllocation *
202 dfb_surface_buffer_find_allocation( CoreSurfaceBuffer       *buffer,
203                                     CoreSurfaceAccessorID    accessor,
204                                     CoreSurfaceAccessFlags   flags,
205                                     bool                     lock );
206 
207 static inline int
dfb_surface_buffer_index(CoreSurfaceBuffer * buffer)208 dfb_surface_buffer_index( CoreSurfaceBuffer *buffer )
209 {
210      int          index;
211      CoreSurface *surface;
212 
213      D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
214 
215      surface = buffer->surface;
216      D_MAGIC_ASSERT( surface, CoreSurface );
217 
218      for (index=0; index<MAX_SURFACE_BUFFERS; index++) {
219           if (surface->buffers[index] == buffer)
220                return index;
221      }
222 
223      D_ASSERT( index<MAX_SURFACE_BUFFERS );
224 
225      return 0;
226 }
227 
228 
229 FUSION_OBJECT_METHODS( CoreSurfaceBuffer, dfb_surface_buffer )
230 
231 FusionObjectPool *dfb_surface_buffer_pool_create( const FusionWorld *world );
232 
233 #endif
234 
235