static DFBResult fbdevLock( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceAllocation *allocation, void *alloc_data, CoreSurfaceBufferLock *lock ) { CoreSurface *surface; FBDevAllocationData *alloc = alloc_data; FBDevShared *shared = dfb_fbdev->shared; D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_MAGIC_ASSERT( alloc, FBDevAllocationData ); D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock ); D_DEBUG_AT( FBDev_SurfLock, "%s( %p )\n", __FUNCTION__, lock->buffer ); surface = allocation->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if (surface->type & CSTF_LAYER && surface->resource_id == DLID_PRIMARY) { int index = dfb_surface_buffer_index( allocation->buffer ); D_DEBUG_AT( FBDev_Surfaces, " -> primary layer buffer (index %d)\n", index ); lock->pitch = shared->fix.line_length; lock->offset = index * surface->config.size.h * lock->pitch; #if D_DEBUG_ENABLED allocation->offset = lock->offset; #endif } else { D_MAGIC_ASSERT( alloc->chunk, Chunk ); lock->pitch = alloc->chunk->pitch; lock->offset = alloc->chunk->offset; } lock->addr = dfb_fbdev->framebuffer_base + lock->offset; lock->phys = dfb_fbdev->shared->fix.smem_start + lock->offset; D_DEBUG_AT( FBDev_SurfLock, " -> offset %lu, pitch %d, addr %p, phys 0x%08lx\n", lock->offset, lock->pitch, lock->addr, lock->phys ); return DFB_OK; }
static DFBResult osdAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { CoreSurface *surface; OSDPoolData *data = pool_data; OSDPoolLocalData *local = pool_local; OSDAllocationData *alloc = alloc_data; DavinciDeviceData *ddev = dfb_gfxcard_get_device_data(); D_DEBUG_AT( OSD_Surfaces, "%s( %p )\n", __FUNCTION__, buffer ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( data, OSDPoolData ); D_MAGIC_ASSERT( local, OSDPoolLocalData ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); (void) data; (void) local; surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if ((surface->type & CSTF_LAYER) && surface->resource_id == DLID_PRIMARY && surface->config.format == DSPF_RGB16) { int index = dfb_surface_buffer_index( buffer ); alloc->pitch = ddev->fix[OSD0].line_length; alloc->size = surface->config.size.h * alloc->pitch; alloc->offset = index * alloc->size; D_DEBUG_AT( OSD_Surfaces, " -> index %d, offset %d, pitch %d, size %d\n", index, alloc->offset, alloc->pitch, alloc->size ); allocation->size = alloc->size; allocation->offset = alloc->offset; D_MAGIC_SET( alloc, OSDAllocationData ); return DFB_OK; } return DFB_BUG; }
DFBResult dfb_surface_notify_display( CoreSurface *surface, CoreSurfaceBuffer *buffer ) { CoreSurfaceNotification notification; D_MAGIC_ASSERT( surface, CoreSurface ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); direct_serial_increase( &surface->serial ); notification.flags = CSNF_DISPLAY; notification.surface = surface; notification.index = dfb_surface_buffer_index( buffer ); return dfb_surface_dispatch( surface, ¬ification, dfb_surface_globals ); }
static DFBResult fbdevAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret; CoreSurface *surface; FBDevPoolData *data = pool_data; FBDevPoolLocalData *local = pool_local; FBDevAllocationData *alloc = alloc_data; D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( data, FBDevPoolData ); D_MAGIC_ASSERT( local, FBDevPoolLocalData ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if (surface->type & CSTF_LAYER && surface->resource_id == DLID_PRIMARY) { D_DEBUG_AT( FBDev_Surfaces, " -> primary layer buffer (index %d)\n", dfb_surface_buffer_index( buffer ) ); dfb_surface_calc_buffer_size( surface, 8, 1, NULL, &allocation->size ); } else { ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, allocation, &alloc->chunk ); if (ret) return ret; D_MAGIC_ASSERT( alloc->chunk, Chunk ); allocation->offset = alloc->chunk->offset; allocation->size = alloc->chunk->length; } D_MAGIC_SET( alloc, FBDevAllocationData ); return DFB_OK; }
static DFBResult fbdevAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret; CoreSurface *surface; FBDevPoolData *data = pool_data; FBDevPoolLocalData *local = pool_local; FBDevAllocationData *alloc = alloc_data; D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( data, FBDevPoolData ); D_MAGIC_ASSERT( local, FBDevPoolLocalData ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if ((surface->type & CSTF_LAYER) && surface->resource_id == DLID_PRIMARY) { FBDevShared *shared = dfb_fbdev->shared; int index = dfb_surface_buffer_index( buffer ); D_DEBUG_AT( FBDev_Surfaces, " -> primary layer buffer (index %d)\n", index ); if (( (surface->config.caps & DSCAPS_FLIPPING) && index == 1) || (!(surface->config.caps & DSCAPS_FLIPPING) && index == 0) ) { const VideoMode *highest; /* FIXME: this should use source.w/source.h from layer region config! */ unsigned int width = surface->config.size.w; unsigned int height = surface->config.size.h; D_INFO( "FBDev/Mode: Setting %dx%d %s\n", width, height, dfb_pixelformat_name(surface->config.format) ); highest = dfb_fbdev_find_mode( width, height ); if (!highest) return DFB_UNSUPPORTED; ret = dfb_fbdev_set_mode( highest, surface, 0, 0 ); if (ret) return ret; } alloc->pitch = shared->fix.line_length; alloc->size = surface->config.size.h * alloc->pitch; alloc->offset = index * alloc->size; D_INFO( "FBDev/Surface: Allocated %dx%d %d bit %s buffer (index %d) at offset %d and pitch %d.\n", surface->config.size.w, surface->config.size.h, shared->current_var.bits_per_pixel, dfb_pixelformat_name(buffer->format), index, alloc->offset, alloc->pitch ); } else { Chunk *chunk; ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, allocation, &chunk ); if (ret) return ret; D_MAGIC_ASSERT( chunk, Chunk ); alloc->offset = chunk->offset; alloc->pitch = chunk->pitch; alloc->size = chunk->length; alloc->chunk = chunk; } D_DEBUG_AT( FBDev_Surfaces, " -> offset %d, pitch %d, size %d\n", alloc->offset, alloc->pitch, alloc->size ); allocation->size = alloc->size; allocation->offset = alloc->offset; D_MAGIC_SET( alloc, FBDevAllocationData ); return DFB_OK; }
static DFBResult prealloc_transfer_readwrite( CoreSurface *surface, CoreSurfacePoolTransfer *transfer, CoreSurfaceAllocation *alloc, CoreSurfaceAccessFlags flags, CoreSlave *slave ) { DFBResult ret = DFB_OK; int index; int i, y; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( transfer != NULL ); CORE_SURFACE_ALLOCATION_ASSERT( alloc ); index = dfb_surface_buffer_index( alloc->buffer ); D_DEBUG_AT( PreAlloc_Bridge, "%s()\n", __FUNCTION__ ); D_DEBUG_AT( PreAlloc_Bridge, " ->Transfer read/write %s Fusion ID %lu (index %d)\n", (flags & CSAF_WRITE) ? "from" : "to", surface->object.identity, index ); for (i=0; i<transfer->num_rects; i++) { const DFBRectangle *rect = &transfer->rects[i]; int offset = DFB_BYTES_PER_LINE( surface->config.format, rect->x ); int length = DFB_BYTES_PER_LINE( surface->config.format, rect->w ); u8 *temp = alloca( length ); // FIXME for (y=0; y<rect->h; y++) { DFBRectangle lrect = { rect->x, rect->y + y, rect->w, 1 }; if (flags & CSAF_WRITE) { ret = CoreSlave_GetData( slave, surface->config.preallocated[index].addr + (rect->y + y) * surface->config.preallocated[index].pitch + offset, length, temp ); if (ret) break; ret = dfb_surface_pool_write( alloc->pool, alloc, temp, length, &lrect ); } else { ret = dfb_surface_pool_read( alloc->pool, alloc, temp, length, &lrect ); if (ret) break; ret = CoreSlave_PutData( slave, surface->config.preallocated[index].addr + (rect->y + y) * surface->config.preallocated[index].pitch + offset, length, temp ); } if (ret) break; } if (ret) break; } return ret; }
static DFBResult prealloc_transfer_locked( CoreSurface *surface, CoreSurfacePoolTransfer *transfer, CoreSurfaceAllocation *locked, CoreSurfaceAccessFlags flags, CoreSlave *slave ) { DFBResult ret; CoreSurfaceBufferLock lock; int index; int i, y; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( transfer != NULL ); CORE_SURFACE_ALLOCATION_ASSERT( locked ); index = dfb_surface_buffer_index( locked->buffer ); D_DEBUG_AT( PreAlloc_Bridge, "%s()\n", __FUNCTION__ ); D_DEBUG_AT( PreAlloc_Bridge, " -> Transfer locked %s Fusion ID %lu (index %d)\n", (flags & CSAF_WRITE) ? "from" : "to", surface->object.identity, index ); dfb_surface_buffer_lock_init( &lock, CSAID_CPU, flags ); ret = dfb_surface_pool_lock( locked->pool, locked, &lock ); if (ret) { dfb_surface_buffer_lock_deinit( &lock ); return ret; } for (i=0; i<transfer->num_rects; i++) { const DFBRectangle *rect = &transfer->rects[i]; int offset = DFB_BYTES_PER_LINE( surface->config.format, rect->x ); int length = DFB_BYTES_PER_LINE( surface->config.format, rect->w ); for (y=0; y<rect->h; y++) { if (flags & CSAF_WRITE) ret = CoreSlave_GetData( slave, surface->config.preallocated[index].addr + (rect->y + y) * surface->config.preallocated[index].pitch + offset, length, lock.addr + (rect->y + y) * lock.pitch + offset ); else ret = CoreSlave_PutData( slave, surface->config.preallocated[index].addr + (rect->y + y) * surface->config.preallocated[index].pitch + offset, length, lock.addr + (rect->y + y) * lock.pitch + offset ); if (ret) break; } if (ret) break; } dfb_surface_pool_unlock( locked->pool, locked, &lock ); dfb_surface_buffer_lock_deinit( &lock ); return ret; }
static DFBResult fbdevAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret; CoreSurface *surface; FBDevPoolData *data = pool_data; FBDevPoolLocalData *local = pool_local; FBDevAllocationData *alloc = alloc_data; D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( data, FBDevPoolData ); D_MAGIC_ASSERT( local, FBDevPoolLocalData ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if ((surface->type & CSTF_LAYER) && surface->resource_id == DLID_PRIMARY) { int i, index = dfb_surface_buffer_index( buffer ); /* HACK FIXME_SC_2 ALLOCATE/SETMODE TWIST */ for (i=0; i<surface->num_buffers; i++) { if (surface->buffers[i]->allocs.elements) break; } if (i == surface->num_buffers && dfb_fbdev->shared->test_mode) { ret = dfb_fbdev_set_mode( surface, dfb_fbdev->shared->test_mode, &dfb_fbdev->shared->test_config ); if (ret) return ret; dfb_fbdev->shared->test_mode = NULL; } /* /HACK FIXME_SC_2 ALLOCATE/SETMODE TWIST */ alloc->pitch = dfb_fbdev->shared->fix.line_length; alloc->size = surface->config.size.h * alloc->pitch; alloc->offset = index * alloc->size; D_INFO( "FBDev/Surface: Allocated %dx%d %dbit %s buffer at offset %d and pitch %d.\n", surface->config.size.w, surface->config.size.h, dfb_fbdev->shared->current_var.bits_per_pixel, dfb_pixelformat_name(buffer->format), alloc->offset, alloc->pitch ); } else { Chunk *chunk; ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, &chunk ); if (ret) return ret; D_MAGIC_ASSERT( chunk, Chunk ); alloc->offset = chunk->offset; alloc->pitch = chunk->pitch; alloc->size = chunk->length;// DFB_PLANE_MULTIPLY( buffer->format, surface->config.size.h ) * alloc->pitch; alloc->chunk = chunk; } D_DEBUG_AT( FBDev_Surfaces, " -> offset %d, pitch %d, size %d\n", alloc->offset, alloc->pitch, alloc->size ); allocation->size = alloc->size; allocation->offset = alloc->offset; D_MAGIC_SET( alloc, FBDevAllocationData ); return DFB_OK; }