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 //#define DIRECT_ENABLE_DEBUG
30
31 #include <config.h>
32
33 #include <direct/debug.h>
34 #include <direct/mem.h>
35
36 #include <core/surface_pool.h>
37
38 #include <gfx/convert.h>
39
40 #include "fbdev.h"
41 #include "surfacemanager.h"
42
43 extern FBDev *dfb_fbdev;
44
45 D_DEBUG_DOMAIN( FBDev_Surfaces, "FBDev/Surfaces", "FBDev Framebuffer Surface Pool" );
46 D_DEBUG_DOMAIN( FBDev_SurfLock, "FBDev/SurfLock", "FBDev Framebuffer Surface Pool Locks" );
47
48 /**********************************************************************************************************************/
49
50 typedef struct {
51 int magic;
52
53 SurfaceManager *manager;
54 } FBDevPoolData;
55
56 typedef struct {
57 int magic;
58
59 CoreDFB *core;
60 } FBDevPoolLocalData;
61
62 typedef struct {
63 int magic;
64
65 Chunk *chunk;
66 } FBDevAllocationData;
67
68 /**********************************************************************************************************************/
69
70 static int
fbdevPoolDataSize(void)71 fbdevPoolDataSize( void )
72 {
73 return sizeof(FBDevPoolData);
74 }
75
76 static int
fbdevPoolLocalDataSize(void)77 fbdevPoolLocalDataSize( void )
78 {
79 return sizeof(FBDevPoolLocalData);
80 }
81
82 static int
fbdevAllocationDataSize(void)83 fbdevAllocationDataSize( void )
84 {
85 return sizeof(FBDevAllocationData);
86 }
87
88 static DFBResult
fbdevInitPool(CoreDFB * core,CoreSurfacePool * pool,void * pool_data,void * pool_local,void * system_data,CoreSurfacePoolDescription * ret_desc)89 fbdevInitPool( CoreDFB *core,
90 CoreSurfacePool *pool,
91 void *pool_data,
92 void *pool_local,
93 void *system_data,
94 CoreSurfacePoolDescription *ret_desc )
95 {
96 DFBResult ret;
97 FBDevPoolData *data = pool_data;
98 FBDevPoolLocalData *local = pool_local;
99
100 D_DEBUG_AT( FBDev_Surfaces, "%s()\n", __FUNCTION__ );
101
102 D_ASSERT( core != NULL );
103 D_MAGIC_ASSERT( pool, CoreSurfacePool );
104 D_ASSERT( data != NULL );
105 D_ASSERT( local != NULL );
106 D_ASSERT( ret_desc != NULL );
107
108 ret = dfb_surfacemanager_create( core, dfb_fbdev->shared->fix.smem_len, &data->manager );
109 if (ret)
110 return ret;
111
112 ret_desc->caps = CSPCAPS_PHYSICAL | CSPCAPS_VIRTUAL;
113 ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
114 ret_desc->access[CSAID_GPU] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
115 ret_desc->types = CSTF_LAYER | CSTF_WINDOW | CSTF_CURSOR | CSTF_FONT | CSTF_SHARED | CSTF_EXTERNAL;
116 ret_desc->priority = CSPP_DEFAULT;
117
118 /* For hardware layers */
119 ret_desc->access[CSAID_LAYER0] = CSAF_READ;
120 ret_desc->access[CSAID_LAYER1] = CSAF_READ;
121 ret_desc->access[CSAID_LAYER2] = CSAF_READ;
122 ret_desc->access[CSAID_LAYER3] = CSAF_READ;
123 ret_desc->access[CSAID_LAYER4] = CSAF_READ;
124 ret_desc->access[CSAID_LAYER5] = CSAF_READ;
125 ret_desc->access[CSAID_LAYER6] = CSAF_READ;
126 ret_desc->access[CSAID_LAYER7] = CSAF_READ;
127 ret_desc->access[CSAID_LAYER8] = CSAF_READ;
128 ret_desc->access[CSAID_LAYER9] = CSAF_READ;
129 ret_desc->access[CSAID_LAYER10] = CSAF_READ;
130 ret_desc->access[CSAID_LAYER11] = CSAF_READ;
131 ret_desc->access[CSAID_LAYER12] = CSAF_READ;
132 ret_desc->access[CSAID_LAYER13] = CSAF_READ;
133 ret_desc->access[CSAID_LAYER14] = CSAF_READ;
134 ret_desc->access[CSAID_LAYER15] = CSAF_READ;
135
136 snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "Frame Buffer Memory" );
137
138 local->core = core;
139
140 D_MAGIC_SET( data, FBDevPoolData );
141 D_MAGIC_SET( local, FBDevPoolLocalData );
142
143
144 D_ASSERT( dfb_fbdev != NULL );
145 D_ASSERT( dfb_fbdev->shared != NULL );
146
147 dfb_fbdev->shared->manager = data->manager;
148
149 return DFB_OK;
150 }
151
152 static DFBResult
fbdevJoinPool(CoreDFB * core,CoreSurfacePool * pool,void * pool_data,void * pool_local,void * system_data)153 fbdevJoinPool( CoreDFB *core,
154 CoreSurfacePool *pool,
155 void *pool_data,
156 void *pool_local,
157 void *system_data )
158 {
159 FBDevPoolData *data = pool_data;
160 FBDevPoolLocalData *local = pool_local;
161
162 D_DEBUG_AT( FBDev_Surfaces, "%s()\n", __FUNCTION__ );
163
164 D_ASSERT( core != NULL );
165 D_MAGIC_ASSERT( pool, CoreSurfacePool );
166 D_MAGIC_ASSERT( data, FBDevPoolData );
167 D_ASSERT( local != NULL );
168
169 (void) data;
170
171 local->core = core;
172
173 D_MAGIC_SET( local, FBDevPoolLocalData );
174
175 return DFB_OK;
176 }
177
178 static DFBResult
fbdevDestroyPool(CoreSurfacePool * pool,void * pool_data,void * pool_local)179 fbdevDestroyPool( CoreSurfacePool *pool,
180 void *pool_data,
181 void *pool_local )
182 {
183 FBDevPoolData *data = pool_data;
184 FBDevPoolLocalData *local = pool_local;
185
186 D_DEBUG_AT( FBDev_Surfaces, "%s()\n", __FUNCTION__ );
187
188 D_MAGIC_ASSERT( pool, CoreSurfacePool );
189 D_MAGIC_ASSERT( data, FBDevPoolData );
190 D_MAGIC_ASSERT( local, FBDevPoolLocalData );
191
192 dfb_surfacemanager_destroy( data->manager );
193
194 D_MAGIC_CLEAR( data );
195 D_MAGIC_CLEAR( local );
196
197 return DFB_OK;
198 }
199
200 static DFBResult
fbdevLeavePool(CoreSurfacePool * pool,void * pool_data,void * pool_local)201 fbdevLeavePool( CoreSurfacePool *pool,
202 void *pool_data,
203 void *pool_local )
204 {
205 FBDevPoolData *data = pool_data;
206 FBDevPoolLocalData *local = pool_local;
207
208 D_DEBUG_AT( FBDev_Surfaces, "%s()\n", __FUNCTION__ );
209
210 D_MAGIC_ASSERT( pool, CoreSurfacePool );
211 D_MAGIC_ASSERT( data, FBDevPoolData );
212 D_MAGIC_ASSERT( local, FBDevPoolLocalData );
213
214 (void) data;
215
216 D_MAGIC_CLEAR( local );
217
218 return DFB_OK;
219 }
220
221 static DFBResult
fbdevTestConfig(CoreSurfacePool * pool,void * pool_data,void * pool_local,CoreSurfaceBuffer * buffer,const CoreSurfaceConfig * config)222 fbdevTestConfig( CoreSurfacePool *pool,
223 void *pool_data,
224 void *pool_local,
225 CoreSurfaceBuffer *buffer,
226 const CoreSurfaceConfig *config )
227 {
228 DFBResult ret;
229 CoreSurface *surface;
230 FBDevPoolData *data = pool_data;
231 FBDevPoolLocalData *local = pool_local;
232
233 D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
234
235 D_MAGIC_ASSERT( pool, CoreSurfacePool );
236 D_MAGIC_ASSERT( data, FBDevPoolData );
237 D_MAGIC_ASSERT( local, FBDevPoolLocalData );
238 D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
239
240 surface = buffer->surface;
241 D_MAGIC_ASSERT( surface, CoreSurface );
242
243 if ((surface->type & CSTF_LAYER) && surface->resource_id == DLID_PRIMARY)
244 return DFB_OK;
245
246 ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, NULL, NULL );
247
248 D_DEBUG_AT( FBDev_Surfaces, " -> %s\n", DirectFBErrorString(ret) );
249
250 return ret;
251 }
252
253 static DFBResult
fbdevAllocateBuffer(CoreSurfacePool * pool,void * pool_data,void * pool_local,CoreSurfaceBuffer * buffer,CoreSurfaceAllocation * allocation,void * alloc_data)254 fbdevAllocateBuffer( CoreSurfacePool *pool,
255 void *pool_data,
256 void *pool_local,
257 CoreSurfaceBuffer *buffer,
258 CoreSurfaceAllocation *allocation,
259 void *alloc_data )
260 {
261 DFBResult ret;
262 CoreSurface *surface;
263 FBDevPoolData *data = pool_data;
264 FBDevPoolLocalData *local = pool_local;
265 FBDevAllocationData *alloc = alloc_data;
266
267 D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
268
269 D_MAGIC_ASSERT( pool, CoreSurfacePool );
270 D_MAGIC_ASSERT( data, FBDevPoolData );
271 D_MAGIC_ASSERT( local, FBDevPoolLocalData );
272 D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
273
274 surface = buffer->surface;
275 D_MAGIC_ASSERT( surface, CoreSurface );
276
277 if (surface->type & CSTF_LAYER && surface->resource_id == DLID_PRIMARY) {
278 D_DEBUG_AT( FBDev_Surfaces, " -> primary layer buffer (index %d)\n", dfb_surface_buffer_index( buffer ) );
279
280 dfb_surface_calc_buffer_size( surface, 8, 1, NULL, &allocation->size );
281 }
282 else {
283 ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, allocation, &alloc->chunk );
284 if (ret)
285 return ret;
286
287 D_MAGIC_ASSERT( alloc->chunk, Chunk );
288
289 allocation->offset = alloc->chunk->offset;
290 allocation->size = alloc->chunk->length;
291 }
292
293 D_MAGIC_SET( alloc, FBDevAllocationData );
294
295 return DFB_OK;
296 }
297
298 static DFBResult
fbdevDeallocateBuffer(CoreSurfacePool * pool,void * pool_data,void * pool_local,CoreSurfaceBuffer * buffer,CoreSurfaceAllocation * allocation,void * alloc_data)299 fbdevDeallocateBuffer( CoreSurfacePool *pool,
300 void *pool_data,
301 void *pool_local,
302 CoreSurfaceBuffer *buffer,
303 CoreSurfaceAllocation *allocation,
304 void *alloc_data )
305 {
306 FBDevPoolData *data = pool_data;
307 FBDevAllocationData *alloc = alloc_data;
308
309 D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
310
311 D_MAGIC_ASSERT( pool, CoreSurfacePool );
312 D_MAGIC_ASSERT( data, FBDevPoolData );
313 D_MAGIC_ASSERT( alloc, FBDevAllocationData );
314
315 if (alloc->chunk)
316 dfb_surfacemanager_deallocate( data->manager, alloc->chunk );
317
318 D_MAGIC_CLEAR( alloc );
319
320 return DFB_OK;
321 }
322
323 static DFBResult
fbdevMuckOut(CoreSurfacePool * pool,void * pool_data,void * pool_local,CoreSurfaceBuffer * buffer)324 fbdevMuckOut( CoreSurfacePool *pool,
325 void *pool_data,
326 void *pool_local,
327 CoreSurfaceBuffer *buffer )
328 {
329 FBDevPoolData *data = pool_data;
330 FBDevPoolLocalData *local = pool_local;
331
332 D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
333
334 D_MAGIC_ASSERT( pool, CoreSurfacePool );
335 D_MAGIC_ASSERT( data, FBDevPoolData );
336 D_MAGIC_ASSERT( local, FBDevPoolLocalData );
337 D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
338
339 return dfb_surfacemanager_displace( local->core, data->manager, buffer );
340 }
341
342 static DFBResult
fbdevLock(CoreSurfacePool * pool,void * pool_data,void * pool_local,CoreSurfaceAllocation * allocation,void * alloc_data,CoreSurfaceBufferLock * lock)343 fbdevLock( CoreSurfacePool *pool,
344 void *pool_data,
345 void *pool_local,
346 CoreSurfaceAllocation *allocation,
347 void *alloc_data,
348 CoreSurfaceBufferLock *lock )
349 {
350 FBDevAllocationData *alloc = alloc_data;
351 FBDevShared *shared = dfb_fbdev->shared;
352
353 D_MAGIC_ASSERT( pool, CoreSurfacePool );
354 D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
355 D_MAGIC_ASSERT( alloc, FBDevAllocationData );
356 D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
357
358 D_DEBUG_AT( FBDev_SurfLock, "%s( %p )\n", __FUNCTION__, lock->buffer );
359
360 if (allocation->type & CSTF_LAYER && allocation->resource_id == DLID_PRIMARY) {
361 int index = dfb_surface_buffer_index( allocation->buffer );
362
363 D_DEBUG_AT( FBDev_Surfaces, " -> primary layer buffer (index %d)\n", index );
364
365 lock->pitch = shared->fix.line_length;
366 lock->offset = index * allocation->config.size.h * lock->pitch;
367 #if D_DEBUG_ENABLED
368 allocation->offset = lock->offset;
369 #endif
370 }
371 else {
372 D_MAGIC_ASSERT( alloc->chunk, Chunk );
373
374 lock->pitch = alloc->chunk->pitch;
375 lock->offset = alloc->chunk->offset;
376 }
377
378 lock->addr = dfb_fbdev->framebuffer_base + lock->offset;
379 lock->phys = dfb_fbdev->shared->fix.smem_start + lock->offset;
380
381 D_DEBUG_AT( FBDev_SurfLock, " -> offset %lu, pitch %d, addr %p, phys 0x%08lx\n",
382 lock->offset, lock->pitch, lock->addr, lock->phys );
383
384 return DFB_OK;
385 }
386
387 static DFBResult
fbdevUnlock(CoreSurfacePool * pool,void * pool_data,void * pool_local,CoreSurfaceAllocation * allocation,void * alloc_data,CoreSurfaceBufferLock * lock)388 fbdevUnlock( CoreSurfacePool *pool,
389 void *pool_data,
390 void *pool_local,
391 CoreSurfaceAllocation *allocation,
392 void *alloc_data,
393 CoreSurfaceBufferLock *lock )
394 {
395 FBDevAllocationData *alloc = alloc_data;
396
397 D_MAGIC_ASSERT( pool, CoreSurfacePool );
398 D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
399 D_MAGIC_ASSERT( alloc, FBDevAllocationData );
400 D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
401
402 D_DEBUG_AT( FBDev_SurfLock, "%s( %p )\n", __FUNCTION__, lock->buffer );
403
404 (void) alloc;
405
406 return DFB_OK;
407 }
408
409 const SurfacePoolFuncs fbdevSurfacePoolFuncs = {
410 .PoolDataSize = fbdevPoolDataSize,
411 .PoolLocalDataSize = fbdevPoolLocalDataSize,
412 .AllocationDataSize = fbdevAllocationDataSize,
413
414 .InitPool = fbdevInitPool,
415 .JoinPool = fbdevJoinPool,
416 .DestroyPool = fbdevDestroyPool,
417 .LeavePool = fbdevLeavePool,
418
419 .TestConfig = fbdevTestConfig,
420 .AllocateBuffer = fbdevAllocateBuffer,
421 .DeallocateBuffer = fbdevDeallocateBuffer,
422
423 .MuckOut = fbdevMuckOut,
424
425 .Lock = fbdevLock,
426 .Unlock = fbdevUnlock,
427 };
428
429