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/lib/voodoo/manager_c.cpp | 553 +++++++++++++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100755 Source/DirectFB/lib/voodoo/manager_c.cpp (limited to 'Source/DirectFB/lib/voodoo/manager_c.cpp') diff --git a/Source/DirectFB/lib/voodoo/manager_c.cpp b/Source/DirectFB/lib/voodoo/manager_c.cpp new file mode 100755 index 0000000..7019da8 --- /dev/null +++ b/Source/DirectFB/lib/voodoo/manager_c.cpp @@ -0,0 +1,553 @@ +/* + (c) Copyright 2001-2011 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. +*/ + +//#define DIRECT_ENABLE_DEBUG + +#include + +#include + +#include + +extern "C" { +#include +#include +#include + +#include +#include +} + +#include + + +D_DEBUG_DOMAIN( Voodoo_Manager, "Voodoo/Manager", "Voodoo Manager" ); + +/**********************************************************************************************************************/ + + +#define VOODOO_MANAGER_MESSAGE_BLOCKS_MAX 20 + +static __inline__ int +calc_blocks( va_list args, + VoodooMessageBlock *ret_blocks, size_t *ret_num ) +{ + int size = 4; /* for the terminating VMBT_NONE */ + size_t num = 0; + VoodooMessageBlockType type; + + /* Fetch first block type. */ + type = (VoodooMessageBlockType) va_arg( args, int ); + + while (type != VMBT_NONE) { + if (num == VOODOO_MANAGER_MESSAGE_BLOCKS_MAX) { + // FIXME: support more blocks? + D_UNIMPLEMENTED(); + break; + } + + /* Set message block type. */ + ret_blocks[num].type = type; + + switch (type) { + case VMBT_ID: + ret_blocks[num].len = 4; + ret_blocks[num].ptr = NULL; + ret_blocks[num].val = va_arg( args, u32 ); + + D_DEBUG( "Voodoo/Message: + ID %u\n", ret_blocks[num].val ); + break; + + case VMBT_INT: + ret_blocks[num].len = 4; + ret_blocks[num].ptr = NULL; + ret_blocks[num].val = va_arg( args, s32 ); + + D_DEBUG( "Voodoo/Message: + INT %d\n", ret_blocks[num].val ); + break; + + case VMBT_UINT: + ret_blocks[num].len = 4; + ret_blocks[num].ptr = NULL; + ret_blocks[num].val = va_arg( args, u32 ); + + D_DEBUG( "Voodoo/Message: + UINT %u\n", ret_blocks[num].val ); + break; + + case VMBT_DATA: + ret_blocks[num].len = va_arg( args, int ); + ret_blocks[num].ptr = va_arg( args, void * ); + +// D_ASSERT( ret_blocks[num].len > 0 ); + D_ASSERT( ret_blocks[num].ptr != NULL ); + + D_DEBUG( "Voodoo/Message: + DATA at %p with length %d\n", ret_blocks[num].ptr, ret_blocks[num].len ); + break; + + case VMBT_ODATA: + ret_blocks[num].len = va_arg( args, int ); + ret_blocks[num].ptr = va_arg( args, void * ); + + D_ASSERT( ret_blocks[num].len > 0 ); + + D_DEBUG( "Voodoo/Message: + ODATA at %p with length %d\n", ret_blocks[num].ptr, ret_blocks[num].len ); + + if (!ret_blocks[num].ptr) + ret_blocks[num].len = 0; + break; + + case VMBT_STRING: + ret_blocks[num].ptr = va_arg( args, char * ); + ret_blocks[num].len = strlen( (const char*) ret_blocks[num].ptr ) + 1; + + D_ASSERT( ret_blocks[num].ptr != NULL ); + + D_DEBUG( "Voodoo/Message: + STRING '%s' at %p with length %d\n", (char*) ret_blocks[num].ptr, ret_blocks[num].ptr, ret_blocks[num].len ); + break; + + default: + D_BREAK( "unknown message block type" ); + } + + /* Fetch next block type. */ + type = (VoodooMessageBlockType) va_arg( args, int ); + + size += 8 + VOODOO_MSG_ALIGN(ret_blocks[num].len); + + num++; + } + + *ret_num = num; + + return size; +} + + +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/* Old C API + */ + +/* + + +register add refs proxy +unregister releases proxy + +proxy destruct releases real + +*/ + +class VoodooInstanceInterface : public VoodooInstance { +public: + VoodooManager *manager; + VoodooInstance *super; + IAny *proxy; + IAny *real; + VoodooDispatch dispatch; + + + static std::list interfaces; + + +public: + VoodooInstanceInterface( VoodooManager *manager, + VoodooInstance *super, + IAny *proxy, + IAny *real, + VoodooDispatch dispatch ) + : + manager( manager ), + super( super ), + proxy( proxy ), + real( real ), + dispatch( dispatch ) + { + D_DEBUG_AT( Voodoo_Manager, "VoodooInstanceInterface::%s( %p, manager %p, super %p, proxy %p, real %p, dispatch %p )\n", + __func__, this, manager, super, proxy, real, dispatch ); + + if (super) + super->AddRef(); + + interfaces.push_back( this ); + } + +protected: + virtual ~VoodooInstanceInterface() + { + D_DEBUG_AT( Voodoo_Manager, "VoodooInstanceInterface::%s( %p )\n", __func__, this ); + + D_MAGIC_ASSERT( this, VoodooInstance ); + + if (proxy) { + D_DEBUG_AT( Voodoo_Manager, " -> releasing proxy interface\n" ); + + proxy->Release( proxy ); + } + + + if (super) { + D_DEBUG_AT( Voodoo_Manager, " -> releasing super instance\n" ); + + super->Release(); + } + + interfaces.remove( this ); + } + +public: + virtual DirectResult + Dispatch( VoodooManager *manager, + VoodooRequestMessage *msg ) + { + D_DEBUG_AT( Voodoo_Manager, "VoodooInstanceInterface::%s( %p, manager %p, msg %p )\n", __func__, this, manager, msg ); + + D_MAGIC_ASSERT( this, VoodooInstance ); + + D_ASSERT( dispatch != NULL ); + + return dispatch( proxy, real, manager, msg ); + } +}; + +std::list VoodooInstanceInterface::interfaces; + +/**********************************************************************************************************************/ + +class VoodooContextClassic : public VoodooContext { +private: + VoodooServer *server; + +public: + VoodooContextClassic( VoodooServer *server ) + : + server( server ) + { + } + + virtual DirectResult + HandleSuper( VoodooManager *manager, const char *name, VoodooInstanceID *ret_instance ) + { + return voodoo_server_construct( server, manager, name, ret_instance ); + } +}; + +DirectResult +voodoo_manager_create( VoodooLink *link, + VoodooClient *client, + VoodooServer *server, + VoodooManager **ret_manager ) +{ + D_ASSERT( ret_manager != NULL ); + + *ret_manager = new VoodooManager( link, new VoodooContextClassic( server ) ); // FIXME: leak + + return DR_OK; +} + +DirectResult +voodoo_manager_quit( VoodooManager *manager ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + manager->quit(); + + return DR_OK; +} + +DirectResult +voodoo_manager_destroy( VoodooManager *manager ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + delete manager; + + for (std::list::const_iterator iter = VoodooInstanceInterface::interfaces.begin(); + iter != VoodooInstanceInterface::interfaces.end(); iter++) + { + VoodooInstanceInterface *instance = *iter; + + if (instance->manager == manager) + D_INFO( "Zombie: Instance %p, proxy %p, real %p, super %p\n", instance, instance->proxy, instance->real, instance->super ); + } + + return DR_OK; +} + +bool +voodoo_manager_is_closed( const VoodooManager *manager ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + return manager->is_quit; +} + +/**************************************************************************************************/ + +DirectResult +voodoo_manager_super( VoodooManager *manager, + const char *name, + VoodooInstanceID *ret_instance ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + return manager->do_super( name, ret_instance ); +} + +DirectResult +voodoo_manager_request( VoodooManager *manager, + VoodooInstanceID instance, + VoodooMethodID method, + VoodooRequestFlags flags, + VoodooResponseMessage **ret_response, ... ) +{ + DirectResult ret; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + va_list ap; + + va_start( ap, ret_response ); + + + VoodooMessageBlock blocks[VOODOO_MANAGER_MESSAGE_BLOCKS_MAX]; + size_t num_blocks; + size_t data_size; + + data_size = calc_blocks( ap, blocks, &num_blocks ); + + + ret = manager->do_request( instance, method, flags, ret_response, blocks, num_blocks, data_size ); + + va_end( ap ); + + return ret; +} + +DirectResult +voodoo_manager_next_response( VoodooManager *manager, + VoodooResponseMessage *response, + VoodooResponseMessage **ret_response ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + return manager->next_response( response, ret_response ); +} + +DirectResult +voodoo_manager_finish_request( VoodooManager *manager, + VoodooResponseMessage *response ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + return manager->finish_request( response ); +} + +DirectResult +voodoo_manager_respond( VoodooManager *manager, + bool flush, + VoodooMessageSerial request, + DirectResult result, + VoodooInstanceID instance, ... ) +{ + DirectResult ret; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + va_list ap; + + va_start( ap, instance ); + + + VoodooMessageBlock blocks[VOODOO_MANAGER_MESSAGE_BLOCKS_MAX]; + size_t num_blocks; + size_t data_size; + + data_size = calc_blocks( ap, blocks, &num_blocks ); + + + ret = manager->do_respond( flush, request, result, instance, blocks, num_blocks, data_size ); + + va_end( ap ); + + return ret; +} + +DirectResult +voodoo_manager_register_local( VoodooManager *manager, + VoodooInstanceID super, + void *dispatcher, + void *real, + VoodooDispatch dispatch, + VoodooInstanceID *ret_instance ) +{ + DirectResult ret; + VoodooInstance *super_instance = NULL; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + if (super != VOODOO_INSTANCE_NONE) { + ret = manager->lookup_local( super, &super_instance ); + if (ret) { + D_DERROR( ret, "Voodoo/Manager: Could not lookup super instance %u!\n", super ); + return ret; + } + } + + + VoodooInstanceInterface *instance = new VoodooInstanceInterface( manager, super_instance, (IAny*) dispatcher, (IAny*) real, dispatch ); + + ret = manager->register_local( instance, ret_instance ); + + instance->Release(); + + return ret; +} + +DirectResult +voodoo_manager_unregister_local( VoodooManager *manager, + VoodooInstanceID instance_id ) +{ + D_MAGIC_ASSERT( manager, VoodooManager ); + + return manager->unregister_local( instance_id ); +} + +DirectResult +voodoo_manager_lookup_local( VoodooManager *manager, + VoodooInstanceID instance_id, + void **ret_dispatcher, + void **ret_real ) +{ + DirectResult ret; + VoodooInstance *instance; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + ret = manager->lookup_local( instance_id, &instance ); + if (ret) + return ret; + + if (ret_dispatcher) + *ret_dispatcher = ((VoodooInstanceInterface*) instance)->proxy; + + if (ret_real) + *ret_real = ((VoodooInstanceInterface*) instance)->real; + + return DR_OK; +} + +DirectResult +voodoo_manager_register_remote( VoodooManager *manager, + bool super, + void *requestor, + VoodooInstanceID instance_id ) +{ + DirectResult ret; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + VoodooInstanceInterface *instance = new VoodooInstanceInterface( manager, NULL, (IAny*) requestor, NULL, NULL); + + ret = manager->register_remote( instance, instance_id ); + + instance->Release(); + + return ret; +} + + +DirectResult +voodoo_manager_lookup_remote( VoodooManager *manager, + VoodooInstanceID instance_id, + void **ret_requestor ) +{ + DirectResult ret; + VoodooInstance *instance; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + ret = manager->lookup_remote( instance_id, &instance ); + if (ret) + return ret; + + if (ret_requestor) + *ret_requestor = ((VoodooInstanceInterface*) instance)->proxy; + + return DR_OK; +} + +DirectResult +voodoo_manager_check_allocation( VoodooManager *manager, + unsigned int amount ) +{ +#ifndef WIN32 + FILE *f; + char buf[2000]; + int size; + char *p; + size_t bytes; + + D_MAGIC_ASSERT( manager, VoodooManager ); + + if (!voodoo_config->memory_max) + return DR_OK; + + direct_snprintf( buf, sizeof(buf), "/proc/%d/status", direct_getpid() ); + + f = fopen( buf, "r" ); + if (!f) { + D_ERROR( "Could not open '%s'!\n", buf ); + return DR_FAILURE; + } + + bytes = fread( buf, 1, sizeof(buf)-1, f ); + + fclose( f ); + + if (bytes) { + buf[bytes] = 0; + + p = strstr( buf, "VmRSS:" ); + if (!p) { + D_ERROR( "Could not find memory information!\n" ); + return DR_FAILURE; + } + + sscanf( p + 6, " %u", &size ); + + D_INFO( "SIZE: %u kB (+%u kB)\n", size, amount / 1024 ); + + if (size * 1024 + amount > voodoo_config->memory_max) + return DR_LIMITEXCEEDED; + } +#endif + return DR_OK; +} + -- cgit