1 /*
2 (c) Copyright 2001-2010 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_H__
30 #define __CORE__SURFACE_H__
31
32 #include <directfb.h>
33
34 #include <direct/list.h>
35 #include <direct/serial.h>
36 #include <direct/util.h>
37
38 #include <fusion/object.h>
39 #include <fusion/reactor.h>
40
41 #include <core/coredefs.h>
42 #include <core/coretypes.h>
43
44
45 typedef enum {
46 CSNF_NONE = 0x00000000,
47
48 CSNF_SIZEFORMAT = 0x00000001, /* width, height, format */
49 CSNF_SYSTEM = 0x00000002, /* system instance information */
50 CSNF_VIDEO = 0x00000004, /* video instance information */
51 CSNF_DESTROY = 0x00000008, /* surface is about to be destroyed */
52 CSNF_FLIP = 0x00000010, /* surface buffer pointer swapped */
53 CSNF_FIELD = 0x00000020, /* active (displayed) field switched */
54 CSNF_PALETTE_CHANGE = 0x00000040, /* another palette has been set */
55 CSNF_PALETTE_UPDATE = 0x00000080, /* current palette has been altered */
56 CSNF_ALPHA_RAMP = 0x00000100, /* alpha ramp was modified */
57 CSNF_DISPLAY = 0x00000200, /* surface buffer displayed */
58
59 CSNF_ALL = 0x000003FF
60 } CoreSurfaceNotificationFlags;
61
62 typedef struct {
63 CoreSurfaceNotificationFlags flags;
64 CoreSurface *surface;
65
66 int index;
67 } CoreSurfaceNotification;
68
69
70 typedef enum {
71 CSCONF_NONE = 0x00000000,
72
73 CSCONF_SIZE = 0x00000001,
74 CSCONF_FORMAT = 0x00000002,
75 CSCONF_CAPS = 0x00000004,
76
77 CSCONF_PREALLOCATED = 0x00000010,
78
79 CSCONF_ALL = 0x00000017
80 } CoreSurfaceConfigFlags;
81
82 typedef enum {
83 CSTF_NONE = 0x00000000,
84
85 CSTF_LAYER = 0x00000001, /* surface for layer */
86 CSTF_WINDOW = 0x00000002, /* surface for window */
87 CSTF_CURSOR = 0x00000004, /* surface for cursor */
88 CSTF_FONT = 0x00000008, /* surface for font */
89
90 CSTF_SHARED = 0x00000010, /* accessable by other processes */
91
92 CSTF_INTERNAL = 0x00000100, /* system memory */
93 CSTF_EXTERNAL = 0x00000200, /* video memory */
94
95 CSTF_PREALLOCATED = 0x00000400, /* preallocated memory */
96
97 CSTF_ALL = 0x0000071F
98 } CoreSurfaceTypeFlags;
99
100 typedef struct {
101 CoreSurfaceConfigFlags flags;
102
103 DFBDimension size;
104 DFBSurfacePixelFormat format;
105 DFBSurfaceCapabilities caps;
106
107 struct {
108 void *addr; /* " */
109 unsigned long phys; /* " */
110 unsigned long offset; /* " */
111 unsigned int pitch; /* " */
112
113 void *handle; /* " */
114 } preallocated[MAX_SURFACE_BUFFERS];
115
116 CoreSurfacePoolID preallocated_pool_id;
117
118 DFBDimension min_size;
119 } CoreSurfaceConfig;
120
121 typedef enum {
122 CSP_SYSTEMONLY = 0x00000000, /* never try to swap
123 into video memory */
124 CSP_VIDEOLOW = 0x00000001, /* try to store in video memory,
125 low priority */
126 CSP_VIDEOHIGH = 0x00000002, /* try to store in video memory,
127 high priority */
128 CSP_VIDEOONLY = 0x00000003 /* always and only
129 store in video memory */
130 } CoreSurfacePolicy;
131
132 typedef enum {
133 CSAF_NONE = 0x00000000,
134
135 CSAF_READ = 0x00000001, /* accessor may read */
136 CSAF_WRITE = 0x00000002, /* accessor may write */
137
138 CSAF_SHARED = 0x00000010, /* other processes can read/write at the same time (shared mapping) */
139
140 CSAF_ALL = 0x00000013
141 } CoreSurfaceAccessFlags;
142
143 typedef enum {
144 CSAID_NONE = 0x00000000, /* none or unknown accessor */
145
146 CSAID_CPU = 0x00000001, /* local processor, where DirectFB is running on, could be app or sw fallback */
147
148 CSAID_GPU = 0x00000002, /* primary accelerator, as in traditional 'gfxcard' core (ACCEL0) */
149
150 CSAID_ACCEL0 = 0x00000002, /* accelerators, decoders etc. (CSAID_ACCEL0 + accel_id<0-5>) */
151 CSAID_ACCEL1 = 0x00000003,
152 CSAID_ACCEL2 = 0x00000004,
153 CSAID_ACCEL3 = 0x00000005,
154 CSAID_ACCEL4 = 0x00000006,
155 CSAID_ACCEL5 = 0x00000007,
156
157 CSAID_LAYER0 = 0x00000008, /* display layers, registered by layer core (CSAID_LAYER0 + layer_id<0-MAX_LAYERS>) */
158 CSAID_LAYER1 = 0x00000009,
159 CSAID_LAYER2 = 0x0000000a,
160 CSAID_LAYER3 = 0x0000000b,
161 CSAID_LAYER4 = 0x0000000c,
162 CSAID_LAYER5 = 0x0000000d,
163 CSAID_LAYER6 = 0x0000000e,
164 CSAID_LAYER7 = 0x0000000f,
165 CSAID_LAYER8 = 0x00000010,
166 CSAID_LAYER9 = 0x00000011,
167 CSAID_LAYER10 = 0x00000012,
168 CSAID_LAYER11 = 0x00000013,
169 CSAID_LAYER12 = 0x00000014,
170 CSAID_LAYER13 = 0x00000015,
171 CSAID_LAYER14 = 0x00000016,
172 CSAID_LAYER15 = 0x00000017,
173
174 _CSAID_NUM = 0x00000018, /* number of statically assigned IDs for usage in static arrays */
175
176 CSAID_ANY = 0x00000100, /* any other accessor needs to be registered using IDs starting from here */
177 } CoreSurfaceAccessorID;
178
179 typedef enum {
180 CSBR_FRONT = 0,
181 CSBR_BACK = 1,
182 CSBR_IDLE = 2
183 } CoreSurfaceBufferRole;
184
185 typedef enum {
186 CSSF_NONE = 0x00000000,
187
188 CSSF_DESTROYED = 0x00000001, /* surface is being or has been destroyed */
189
190 CSSF_ALL = 0x00000001
191 } CoreSurfaceStateFlags;
192
193 struct __DFB_CoreSurface
194 {
195 FusionObject object;
196 int magic;
197
198 FusionSkirmish lock;
199
200 CoreSurfaceStateFlags state;
201
202 CoreSurfaceConfig config;
203 CoreSurfaceTypeFlags type;
204 unsigned long resource_id; /* layer id, window id, or user specified */
205
206 int rotation;
207
208 CoreSurfaceNotificationFlags notifications;
209
210 DirectSerial serial;
211
212 int field;
213 u8 alpha_ramp[4];
214
215 CoreSurfaceBuffer *buffers[MAX_SURFACE_BUFFERS];
216 int num_buffers;
217
218 int buffer_indices[MAX_SURFACE_BUFFERS];
219
220 unsigned int flips;
221
222 CorePalette *palette;
223 GlobalReaction palette_reaction;
224
225 FusionSHMPoolShared *shmpool;
226
227 void *data; /* Shared system driver-specific data for this surface. */
228
229 FusionCall call;
230 };
231
232 #define CORE_SURFACE_ASSERT(surface) \
233 do { \
234 D_MAGIC_ASSERT( surface, CoreSurface ); \
235 } while (0)
236
237
238 /*
239 * Creates a pool of surface objects.
240 */
241 FusionObjectPool *dfb_surface_pool_create( const FusionWorld *world );
242
243 /*
244 * Generates dfb_surface_ref(), dfb_surface_attach() etc.
245 */
246 FUSION_OBJECT_METHODS( CoreSurface, dfb_surface )
247
248
249 DFBResult dfb_surface_create ( CoreDFB *core,
250 const CoreSurfaceConfig *config,
251 CoreSurfaceTypeFlags type,
252 unsigned long resource_id,
253 CorePalette *palette,
254 CoreSurface **ret_surface );
255
256 DFBResult dfb_surface_create_simple ( CoreDFB *core,
257 int width,
258 int height,
259 DFBSurfacePixelFormat format,
260 DFBSurfaceCapabilities caps,
261 CoreSurfaceTypeFlags type,
262 unsigned long resource_id,
263 CorePalette *palette,
264 CoreSurface **ret_surface );
265
266 DFBResult dfb_surface_init_palette ( CoreDFB *core,
267 CoreSurface *surface );
268
269 DFBResult dfb_surface_notify ( CoreSurface *surface,
270 CoreSurfaceNotificationFlags flags);
271
272 DFBResult dfb_surface_notify_display( CoreSurface *surface,
273 CoreSurfaceBuffer *buffer);
274
275 DFBResult dfb_surface_flip ( CoreSurface *surface,
276 bool swap );
277
278 DFBResult dfb_surface_reconfig ( CoreSurface *surface,
279 const CoreSurfaceConfig *config );
280
281 DFBResult dfb_surface_destroy_buffers( CoreSurface *surface );
282
283 DFBResult dfb_surface_deallocate_buffers( CoreSurface *surface );
284
285 DFBResult dfb_surface_lock_buffer ( CoreSurface *surface,
286 CoreSurfaceBufferRole role,
287 CoreSurfaceAccessorID accessor,
288 CoreSurfaceAccessFlags access,
289 CoreSurfaceBufferLock *ret_lock );
290
291 DFBResult dfb_surface_unlock_buffer ( CoreSurface *surface,
292 CoreSurfaceBufferLock *lock );
293
294 DFBResult dfb_surface_read_buffer ( CoreSurface *surface,
295 CoreSurfaceBufferRole role,
296 void *destination,
297 int pitch,
298 const DFBRectangle *rect );
299
300 DFBResult dfb_surface_write_buffer ( CoreSurface *surface,
301 CoreSurfaceBufferRole role,
302 const void *source,
303 int pitch,
304 const DFBRectangle *rect );
305
306 DFBResult dfb_surface_dump_buffer ( CoreSurface *surface,
307 CoreSurfaceBufferRole role,
308 const char *path,
309 const char *prefix );
310
311 DFBResult dfb_surface_set_palette ( CoreSurface *surface,
312 CorePalette *palette );
313
314 DFBResult dfb_surface_set_field ( CoreSurface *surface,
315 int field );
316
317 DFBResult dfb_surface_set_alpha_ramp( CoreSurface *surface,
318 u8 a0,
319 u8 a1,
320 u8 a2,
321 u8 a3 );
322
323 DFBResult dfb_surface_clear_buffers ( CoreSurface *surface );
324
325
326 static inline DirectResult
dfb_surface_lock(CoreSurface * surface)327 dfb_surface_lock( CoreSurface *surface )
328 {
329 D_MAGIC_ASSERT( surface, CoreSurface );
330
331 return fusion_skirmish_prevail( &surface->lock );
332 }
333
334 static inline DirectResult
dfb_surface_trylock(CoreSurface * surface)335 dfb_surface_trylock( CoreSurface *surface )
336 {
337 D_MAGIC_ASSERT( surface, CoreSurface );
338
339 return fusion_skirmish_swoop( &surface->lock );
340 }
341
342 static inline DirectResult
dfb_surface_unlock(CoreSurface * surface)343 dfb_surface_unlock( CoreSurface *surface )
344 {
345 D_MAGIC_ASSERT( surface, CoreSurface );
346
347 return fusion_skirmish_dismiss( &surface->lock );
348 }
349
350 static inline CoreSurfaceBuffer *
dfb_surface_get_buffer(CoreSurface * surface,CoreSurfaceBufferRole role)351 dfb_surface_get_buffer( CoreSurface *surface,
352 CoreSurfaceBufferRole role )
353 {
354 D_MAGIC_ASSERT( surface, CoreSurface );
355 D_ASSERT( role == CSBR_FRONT || role == CSBR_BACK || role == CSBR_IDLE );
356
357 D_ASSERT( surface->num_buffers > 0 );
358
359 return surface->buffers[ surface->buffer_indices[(surface->flips + role) % surface->num_buffers] ];
360 }
361
362 static inline void *
dfb_surface_data_offset(const CoreSurface * surface,void * data,int pitch,int x,int y)363 dfb_surface_data_offset( const CoreSurface *surface,
364 void *data,
365 int pitch,
366 int x,
367 int y )
368 {
369 D_ASSERT( surface != NULL );
370 D_ASSERT( data != NULL );
371 D_ASSERT( pitch > 0 );
372 D_ASSERT( x >= 0 );
373 D_ASSERT( x < surface->config.size.w );
374 D_ASSERT( y >= 0 );
375 D_ASSERT( y < surface->config.size.h );
376
377 if (surface->config.caps & DSCAPS_SEPARATED) {
378 if (y & 1)
379 y += surface->config.size.h;
380
381 y >>= 1;
382 }
383
384 return (u8*)data + pitch * y + DFB_BYTES_PER_LINE( surface->config.format, x );
385 }
386
387 static inline void
dfb_surface_calc_buffer_size(CoreSurface * surface,int byte_align,int pixel_align,int * ret_pitch,int * ret_size)388 dfb_surface_calc_buffer_size( CoreSurface *surface,
389 int byte_align,
390 int pixel_align,
391 int *ret_pitch,
392 int *ret_size )
393 {
394 DFBSurfacePixelFormat format;
395 int width;
396 int pitch;
397
398 D_MAGIC_ASSERT( surface, CoreSurface );
399
400 format = surface->config.format;
401
402 width = direct_util_align( surface->config.size.w, pixel_align );
403 pitch = direct_util_align( DFB_BYTES_PER_LINE( format, width ), byte_align );
404
405 if (ret_pitch)
406 *ret_pitch = pitch;
407
408 if (ret_size)
409 *ret_size = pitch * DFB_PLANE_MULTIPLY( format, surface->config.size.h );
410 }
411
412 static inline void
dfb_surface_caps_apply_policy(CoreSurfacePolicy policy,DFBSurfaceCapabilities * caps)413 dfb_surface_caps_apply_policy( CoreSurfacePolicy policy,
414 DFBSurfaceCapabilities *caps )
415 {
416 switch (policy) {
417 case CSP_SYSTEMONLY:
418 *caps = (DFBSurfaceCapabilities)((*caps & ~DSCAPS_VIDEOONLY) | DSCAPS_SYSTEMONLY);
419 break;
420
421 case CSP_VIDEOONLY:
422 *caps = (DFBSurfaceCapabilities)((*caps & ~DSCAPS_SYSTEMONLY) | DSCAPS_VIDEOONLY);
423 break;
424
425 default:
426 *caps = (DFBSurfaceCapabilities)(*caps & ~(DSCAPS_SYSTEMONLY | DSCAPS_VIDEOONLY));
427 break;
428 }
429 }
430
431 static inline DFBResult
dfb_surface_resize(CoreSurface * surface,int width,int height)432 dfb_surface_resize( CoreSurface *surface,
433 int width,
434 int height )
435 {
436 CoreSurfaceConfig config;
437
438 D_MAGIC_ASSERT( surface, CoreSurface );
439 D_ASSERT( width > 0 );
440 D_ASSERT( height > 0 );
441
442 config.flags = CSCONF_SIZE;
443 config.size.w = width;
444 config.size.h = height;
445
446 return dfb_surface_reconfig( surface, &config );
447 }
448
449 static inline DFBResult
dfb_surface_reformat(CoreSurface * surface,int width,int height,DFBSurfacePixelFormat format)450 dfb_surface_reformat( CoreSurface *surface,
451 int width,
452 int height,
453 DFBSurfacePixelFormat format )
454 {
455 CoreSurfaceConfig config;
456
457 D_MAGIC_ASSERT( surface, CoreSurface );
458 D_ASSERT( width > 0 );
459 D_ASSERT( height > 0 );
460
461 config.flags = (CoreSurfaceConfigFlags)(CSCONF_SIZE | CSCONF_FORMAT);
462 config.size.w = width;
463 config.size.h = height;
464 config.format = format;
465
466 return dfb_surface_reconfig( surface, &config );
467 }
468
469 /* global reactions */
470 ReactionResult _dfb_surface_palette_listener( const void *msg_data,
471 void *ctx );
472
473 typedef enum {
474 DFB_LAYER_REGION_SURFACE_LISTENER,
475 DFB_WINDOWSTACK_BACKGROUND_IMAGE_LISTENER
476 } DFB_SURFACE_GLOBALS;
477
478 #endif
479
480