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