From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/src/core/layers.c | 640 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 640 insertions(+) create mode 100755 Source/DirectFB/src/core/layers.c (limited to 'Source/DirectFB/src/core/layers.c') diff --git a/Source/DirectFB/src/core/layers.c b/Source/DirectFB/src/core/layers.c new file mode 100755 index 0000000..29c0de8 --- /dev/null +++ b/Source/DirectFB/src/core/layers.c @@ -0,0 +1,640 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + + +D_DEBUG_DOMAIN( Core_Layer, "Core/Layer", "DirectFB Display Layer Core" ); + +/**********************************************************************************************************************/ + +typedef struct { + int magic; + + int num; + CoreLayerShared *layers[MAX_LAYERS]; +} DFBLayerCoreShared; + +struct __DFB_DFBLayerCore { + int magic; + + CoreDFB *core; + + DFBLayerCoreShared *shared; +}; + + +DFB_CORE_PART( layer_core, LayerCore ); + +/**********************************************************************************************************************/ + +static int dfb_num_layers; +static CoreLayer *dfb_layers[MAX_LAYERS]; + +/** FIXME: Add proper error paths! **/ + +static DFBResult +dfb_layer_core_initialize( CoreDFB *core, + DFBLayerCore *data, + DFBLayerCoreShared *shared ) +{ + int i; + DFBResult ret; + FusionSHMPoolShared *pool; + + D_DEBUG_AT( Core_Layer, "dfb_layer_core_initialize( %p, %p, %p )\n", core, data, shared ); + + D_ASSERT( data != NULL ); + D_ASSERT( shared != NULL ); + + data->core = core; + data->shared = shared; + + + pool = dfb_core_shmpool( core ); + + /* Initialize all registered layers. */ + for (i=0; ifuncs; + + /* Allocate shared data. */ + lshared = SHCALLOC( pool, 1, sizeof(CoreLayerShared) ); + + /* Assign ID (zero based index). */ + lshared->layer_id = i; + lshared->shmpool = pool; + + snprintf( buf, sizeof(buf), "Display Layer %d", i ); + + /* Initialize the lock. */ + ret = fusion_skirmish_init( &lshared->lock, buf, dfb_core_world(core) ); + if (ret) + return ret; + + /* Allocate driver's layer data. */ + if (funcs->LayerDataSize) { + int size = funcs->LayerDataSize(); + + if (size > 0) { + lshared->layer_data = SHCALLOC( pool, 1, size ); + if (!lshared->layer_data) + return D_OOSHM(); + } + } + + /* Initialize the layer, get the layer description, + the default configuration and default color adjustment. */ + ret = funcs->InitLayer( layer, + layer->driver_data, + lshared->layer_data, + &lshared->description, + &lshared->default_config, + &lshared->default_adjustment ); + if (ret) { + D_DERROR( ret, "DirectFB/Core/layers: " + "Failed to initialize layer %d!\n", lshared->layer_id ); + return ret; + } + + if (lshared->description.caps & DLCAPS_SOURCES) { + int n; + + lshared->sources = SHCALLOC( pool, lshared->description.sources, sizeof(CoreLayerSource) ); + if (!lshared->sources) + return D_OOSHM(); + + for (n=0; ndescription.sources; n++) { + CoreLayerSource *source = &lshared->sources[n]; + + source->index = n; + + ret = funcs->InitSource( layer, layer->driver_data, + lshared->layer_data, n, &source->description ); + if (ret) { + D_DERROR( ret, "DirectFB/Core/layers: Failed to initialize source %d " + "of layer %d!\n", n, lshared->layer_id ); + return ret; + } + } + } + + if (D_FLAGS_IS_SET( lshared->description.caps, DLCAPS_SCREEN_LOCATION )) + D_FLAGS_SET( lshared->description.caps, DLCAPS_SCREEN_POSITION | DLCAPS_SCREEN_SIZE ); + + if (D_FLAGS_ARE_SET( lshared->description.caps, + DLCAPS_SCREEN_POSITION | DLCAPS_SCREEN_SIZE )) + D_FLAGS_SET( lshared->description.caps, DLCAPS_SCREEN_LOCATION ); + + /* Initialize the vector for the contexts. */ + fusion_vector_init( &lshared->contexts.stack, 4, pool ); + + /* Initialize the vector for realized (added) regions. */ + fusion_vector_init( &lshared->added_regions, 4, pool ); + + /* No active context by default. */ + lshared->contexts.active = -1; + + /* Store layer data. */ + layer->layer_data = lshared->layer_data; + + /* Store pointer to shared data and core. */ + layer->shared = lshared; + layer->core = core; + + /* Add the layer to the shared list. */ + shared->layers[ shared->num++ ] = lshared; + } + + + D_MAGIC_SET( data, DFBLayerCore ); + D_MAGIC_SET( shared, DFBLayerCoreShared ); + + return DFB_OK; +} + +static DFBResult +dfb_layer_core_join( CoreDFB *core, + DFBLayerCore *data, + DFBLayerCoreShared *shared ) +{ + int i; + + D_DEBUG_AT( Core_Layer, "dfb_layer_core_join( %p, %p, %p )\n", core, data, shared ); + + D_ASSERT( data != NULL ); + D_MAGIC_ASSERT( shared, DFBLayerCoreShared ); + + data->core = core; + data->shared = shared; + + + if (dfb_num_layers != shared->num) { + D_ERROR("DirectFB/core/layers: Number of layers does not match!\n"); + return DFB_BUG; + } + + for (i=0; ilayers[i]; + + /* make a copy for faster access */ + layer->layer_data = lshared->layer_data; + + /* store pointer to shared data and core */ + layer->shared = lshared; + layer->core = core; + } + + + D_MAGIC_SET( data, DFBLayerCore ); + + return DFB_OK; +} + +static DFBResult +dfb_layer_core_shutdown( DFBLayerCore *data, + bool emergency ) +{ + int i; + DFBResult ret; + DFBLayerCoreShared *shared; + + D_DEBUG_AT( Core_Layer, "dfb_layer_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " ); + + D_MAGIC_ASSERT( data, DFBLayerCore ); + D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared ); + + shared = data->shared; + + + /* Begin with the most recently added layer. */ + for (i=dfb_num_layers-1; i>=0; i--) { + CoreLayer *layer = dfb_layers[i]; + CoreLayerShared *shared = layer->shared; + const DisplayLayerFuncs *funcs = layer->funcs; + + D_ASSUME( emergency || fusion_vector_is_empty( &shared->added_regions ) ); + + /* Remove all regions during emergency shutdown. */ + if (emergency && funcs->RemoveRegion) { + int n; + CoreLayerRegion *region; + + fusion_vector_foreach( region, n, shared->added_regions ) { + D_DEBUG_AT( Core_Layer, "Removing region (%d, %d - %dx%d) from '%s'.\n", + DFB_RECTANGLE_VALS( ®ion->config.dest ), + shared->description.name ); + + ret = funcs->RemoveRegion( layer, layer->driver_data, + layer->layer_data, region->region_data ); + if (ret) + D_DERROR( ret, "Core/Layers: Could not remove region!\n" ); + } + } + + /* Deinitialize the lock. */ + fusion_skirmish_destroy( &shared->lock ); + + /* Deinitialize the state for window stack repaints. */ + dfb_state_destroy( &layer->state ); + + /* Deinitialize the vector for the contexts. */ + fusion_vector_destroy( &shared->contexts.stack ); + + /* Deinitialize the vector for the realized (added) regions. */ + fusion_vector_destroy( &shared->added_regions ); + + /* Free the driver's layer data. */ + if (shared->layer_data) + SHFREE( shared->shmpool, shared->layer_data ); + + /* Free the shared layer data. */ + SHFREE( shared->shmpool, shared ); + + /* Free the local layer data. */ + D_FREE( layer ); + } + + dfb_num_layers = 0; + + + D_MAGIC_CLEAR( data ); + D_MAGIC_CLEAR( shared ); + + return DFB_OK; +} + +static DFBResult +dfb_layer_core_leave( DFBLayerCore *data, + bool emergency ) +{ + int i; + DFBLayerCoreShared *shared; + + D_DEBUG_AT( Core_Layer, "dfb_layer_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " ); + + D_MAGIC_ASSERT( data, DFBLayerCore ); + D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared ); + + shared = data->shared; + + + /* Deinitialize all local stuff. */ + for (i=0; istate ); + + /* Free local layer data. */ + D_FREE( layer ); + } + + dfb_num_layers = 0; + + + D_MAGIC_CLEAR( data ); + + return DFB_OK; +} + +static DFBResult +dfb_layer_core_suspend( DFBLayerCore *data ) +{ + int i; + DFBLayerCoreShared *shared; + + D_DEBUG_AT( Core_Layer, "dfb_layer_core_suspend( %p )\n", data ); + + D_MAGIC_ASSERT( data, DFBLayerCore ); + D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared ); + + shared = data->shared; + + for (i=dfb_num_layers-1; i>=0; i--) + dfb_layer_suspend( dfb_layers[i] ); + + return DFB_OK; +} + +static DFBResult +dfb_layer_core_resume( DFBLayerCore *data ) +{ + int i; + DFBLayerCoreShared *shared; + + D_DEBUG_AT( Core_Layer, "dfb_layer_core_resume( %p )\n", data ); + + D_MAGIC_ASSERT( data, DFBLayerCore ); + D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared ); + + shared = data->shared; + + for (i=0; idevice = screen->device; + layer->screen = screen; + layer->driver_data = driver_data; + layer->funcs = funcs; + + /* Initialize the state for window stack repaints */ + dfb_state_init( &layer->state, NULL ); + + /* add it to the local list */ + dfb_layers[dfb_num_layers++] = layer; + + return layer; +} + +typedef void (*AnyFunc)( void ); + +CoreLayer * +dfb_layers_hook_primary( CoreGraphicsDevice *device, + void *driver_data, + DisplayLayerFuncs *funcs, + DisplayLayerFuncs *primary_funcs, + void **primary_driver_data ) +{ + int i; + int entries; + CoreLayer *primary = dfb_layers[0]; + + D_ASSERT( primary != NULL ); + D_ASSERT( device != NULL ); + D_ASSERT( funcs != NULL ); + + /* copy content of original function table */ + if (primary_funcs) + direct_memcpy( primary_funcs, primary->funcs, sizeof(DisplayLayerFuncs) ); + + /* copy pointer to original driver data */ + if (primary_driver_data) + *primary_driver_data = primary->driver_data; + + /* replace all entries in the old table that aren't NULL in the new one */ + entries = sizeof(DisplayLayerFuncs) / sizeof(void(*)( void )); + for (i=0; ifuncs; + + if (newfuncs[i]) + oldfuncs[i] = newfuncs[i]; + } + + /* replace device and driver data pointer */ + primary->device = device; + primary->driver_data = driver_data; + + return primary; +} + +CoreLayer * +dfb_layers_replace_primary( CoreGraphicsDevice *device, + void *driver_data, + DisplayLayerFuncs *funcs ) +{ + CoreLayer *primary = dfb_layers[0]; + + D_ASSERT( primary != NULL ); + D_ASSERT( device != NULL ); + D_ASSERT( funcs != NULL ); + + /* replace device, function table and driver data pointer */ + primary->device = device; + primary->funcs = funcs; + primary->driver_data = driver_data; + + return primary; +} + +void +dfb_layers_enumerate( DisplayLayerCallback callback, + void *ctx ) +{ + int i; + + D_ASSERT( callback != NULL ); + + for (i=0; i= 0); + D_ASSERT( id < dfb_num_layers); + + return dfb_layers[id]; +} + +CoreLayer * +dfb_layer_at_translated( DFBDisplayLayerID id ) +{ + D_ASSERT( id >= 0); + D_ASSERT( id < dfb_num_layers); + D_ASSERT( dfb_config != NULL ); + + if (dfb_config->primary_layer > 0 && + dfb_config->primary_layer < dfb_num_layers) + { + if (id == DLID_PRIMARY) + return dfb_layer_at( dfb_config->primary_layer ); + + if (id == dfb_config->primary_layer) + return dfb_layer_at( DLID_PRIMARY ); + } + + return dfb_layer_at( id ); +} + +void +dfb_layer_get_description( const CoreLayer *layer, + DFBDisplayLayerDescription *desc ) +{ + D_ASSERT( layer != NULL ); + D_ASSERT( layer->shared != NULL ); + D_ASSERT( desc != NULL ); + + *desc = layer->shared->description; +} + +CoreScreen * +dfb_layer_screen( const CoreLayer *layer ) +{ + D_ASSERT( layer != NULL ); + + return layer->screen; +} + +CardState * +dfb_layer_state( CoreLayer *layer ) +{ + D_ASSERT( layer != NULL ); + + return &layer->state; +} + +DFBDisplayLayerID +dfb_layer_id( const CoreLayer *layer ) +{ + D_ASSERT( layer != NULL ); + D_ASSERT( layer->shared != NULL ); + + return layer->shared->layer_id; +} + +DFBDisplayLayerID +dfb_layer_id_translated( const CoreLayer *layer ) +{ + CoreLayerShared *shared; + + D_ASSERT( layer != NULL ); + D_ASSERT( layer->shared != NULL ); + D_ASSERT( dfb_config != NULL ); + + shared = layer->shared; + + if (dfb_config->primary_layer > 0 && + dfb_config->primary_layer < dfb_num_layers) + { + if (shared->layer_id == DLID_PRIMARY) + return dfb_config->primary_layer; + + if (shared->layer_id == dfb_config->primary_layer) + return DLID_PRIMARY; + } + + return shared->layer_id; +} + +DFBSurfacePixelFormat +dfb_primary_layer_pixelformat( void ) +{ + CoreLayerShared *shared; + CoreLayerContext *context; + CoreLayer *layer = dfb_layer_at_translated(DLID_PRIMARY); + DFBSurfacePixelFormat format = DSPF_UNKNOWN; + + D_ASSERT( layer != NULL ); + D_ASSERT( layer->shared != NULL ); + + shared = layer->shared; + + /* If no context is active, return the default format. */ + if (dfb_layer_get_active_context( layer, &context ) != DFB_OK) + return shared->default_config.pixelformat; + + /* Use the format from the current configuration. */ + format = context->config.pixelformat; + + /* Decrease the context's reference counter. */ + dfb_layer_context_unref( context ); + + return format; +} + -- cgit