server_main.c revision dea65cada3ff5e4b07cfacd85d96b389cdfdff05
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "server.h"
#include "cr_net.h"
#include "cr_unpack.h"
#include "cr_error.h"
#include "cr_glstate.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "cr_hash.h"
#include "server_dispatch.h"
#include "state/cr_texture.h"
#include "render/renderspu.h"
#include <signal.h>
#include <stdlib.h>
#define DEBUG_FP_EXCEPTIONS 0
#include <fpu_control.h>
#include <math.h>
#endif
#ifdef VBOXCR_LOGFPS
#endif
/**
* \mainpage CrServerLib
*
* \section CrServerLibIntroduction Introduction
*
* Chromium consists of all the top-level files in the cr
* directory. The core module basically takes care of API dispatch,
* and OpenGL state management.
*/
/**
* CRServer global data
*/
int tearingdown = 0; /* can't be static */
/**
* Return pointer to server's first SPU.
*/
SPU*
crServerHeadSPU(void)
{
}
static void DeleteBarrierCallback( void *data )
{
}
static void deleteContextCallback( void *data )
{
}
static void crServerTearDown( void )
{
GLint i;
/* avoid a race condition */
if (tearingdown)
return;
tearingdown = 1;
/* Deallocate all semaphores */
/* Deallocate all barriers */
/* Free all context info */
/* Free vertex programs */
for (i = 0; i < cr_server.numClients; i++) {
}
}
cr_server.numClients = 0;
while (pNode)
{
}
#if 1
/* disable these two lines if trying to get stack traces with valgrind */
#endif
}
static void crServerClose( unsigned int id )
{
crError( "Client disconnected!" );
(void) id;
}
static void crServerCleanup( int sigio )
{
tearingdown = 0;
}
void
crServerSetPort(int port)
{
}
static void
crPrintHelp(void)
{
printf("Usage: crserver [OPTIONS]\n");
printf("Options:\n");
printf(" -mothership URL Specifies URL for contacting the mothership.\n");
printf(" URL is of the form [protocol://]hostname[:port]\n");
printf(" -port N Specifies the port number this server will listen to.\n");
printf(" -help Prints this information.\n");
}
/**
* Do CRServer initializations. After this, we can begin servicing clients.
*/
void
{
int i;
char *mothership = NULL;
for (i = 1 ; i < argc ; i++)
{
{
if (i == argc - 1)
{
crError( "-mothership requires an argument" );
}
i++;
}
{
/* This is the port on which we'll accept client connections */
if (i == argc - 1)
{
crError( "-port requires an argument" );
}
i++;
}
{
}
{
crPrintHelp();
exit(0);
}
}
#ifndef WINDOWS
#endif
{
| _FPU_MASK_OM | _FPU_MASK_UM);
}
#endif
/*
* Create default mural info and hash table.
*/
crStateInit();
/*
* Default context
*/
}
void crVBoxServerTearDown(void)
{
}
/**
* Do CRServer initializations. After this, we can begin servicing clients.
*/
GLboolean crVBoxServerInit(void)
{
{
| _FPU_MASK_OM | _FPU_MASK_UM);
}
#endif
/*
* Create default mural info and hash table.
*/
crStateInit();
/*
* Default context
*/
return GL_FALSE;
/*Check for PBO support*/
{
}
return GL_TRUE;
}
{
{
return VERR_MAX_THRDS_REACHED;
}
return VINF_SUCCESS;
}
{
int32_t i;
for (i = 0; i < cr_server.numClients; i++)
{
{
break;
}
}
//if (!pClient) return VERR_INVALID_PARAMETER;
if (!pClient)
{
return;
}
/* Disconnect the client */
/* Let server clear client from the queue */
}
{
int32_t i;
#ifdef VBOXCR_LOGFPS
#endif
/*crDebug("=>crServer: ClientWrite u32ClientID=%d", u32ClientID);*/
for (i = 0; i < cr_server.numClients; i++)
{
{
break;
}
}
if (!pClient) return VERR_INVALID_PARAMETER;
#ifdef VBOXCR_LOGFPS
tstart = RTTimeNanoTS();
#endif
/* This should never fire unless we start to multithread */
/* Check if there's a blocker in queue and it's not this client */
{
}
else
{
}
crNetRecv();
#if 0
if (pClient->currentMural) {
}
#endif
#ifdef VBOXCR_LOGFPS
tend = RTTimeNanoTS();
#endif
/*crDebug("<=crServer: ClientWrite u32ClientID=%d", u32ClientID);*/
return VINF_SUCCESS;
}
{
int32_t i;
//crDebug("crServer: [%x] ClientRead u32ClientID=%d", crThreadID(), u32ClientID);
for (i = 0; i < cr_server.numClients; i++)
{
{
break;
}
}
if (!pClient) return VERR_INVALID_PARAMETER;
{
crDebug("crServer: [%lx] ClientRead u32ClientID=%d FAIL, host buffer too small %d of %d",
/* Return the size of needed buffer */
return VERR_BUFFER_OVERFLOW;
}
if (*pcbBuffer)
{
}
return VINF_SUCCESS;
}
{
int32_t i;
for (i = 0; i < cr_server.numClients; i++)
{
{
break;
}
}
if (!pClient) return VERR_INVALID_PARAMETER;
if (vMajor != CR_PROTOCOL_VERSION_MAJOR
|| vMinor != CR_PROTOCOL_VERSION_MINOR)
{
return VERR_NOT_SUPPORTED;
}
else return VINF_SUCCESS;
}
{
int32_t i;
for (i = 0; i < cr_server.numClients; i++)
{
{
break;
}
}
if (!pClient) return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
}
int
{
tearingdown = 0;
return 0;
}
{
/* Don't store default mural */
if (!key) return;
if (pMI->pVisibleRects)
{
}
}
/* @todo add hashtable walker with result info and intermediate abort */
{
if (pCreateInfo->pszDpyName)
{
}
}
{
}
{
/* We could have skipped saving the key and use similar callback to load context states back,
* but there's no guarantee we'd traverse hashtable in same order after loading.
*/
{
unsigned long id;
{
}
else
{
}
}
#endif
}
static uint32_t g_hackVBoxServerSaveLoadCallsLeft = 0;
{
GLboolean b;
unsigned long key;
#endif
/* We shouldn't be called if there's no clients at all*/
/* @todo it's hack atm */
/* We want to be called only once to save server state but atm we're being called from svcSaveState
* for every connected client (e.g. guest opengl application)
*/
{
/* Store number of clients */
}
/* Do nothing until we're being called last time */
{
return VINF_SUCCESS;
}
/* Save rendering contexts creation info */
/* Save current win and ctx IDs, as we'd rebind contexts when saving textures */
{
}
#endif
/* Save contexts state tracker data */
/* @todo For now just some blind data dumps,
* allow diff_api to work correctly.
* Should be tested more with multiply guest opengl apps working when saving VM snapshot.
*/
/* Restore original win and ctx IDs*/
{
}
#endif
/* Save windows creation info */
/* Save cr_server.muralTable
* @todo we don't need it all, just geometry info actually
*/
/* There should be default mural always */
/* Save starting free context and window IDs */
/* Save clients info */
for (i = 0; i < cr_server.numClients; i++)
{
{
{
CRASSERT(b);
}
{
CRASSERT(b);
}
}
}
return VINF_SUCCESS;
}
{
unsigned long key;
if (!cr_server.bIsInLoadingState)
{
/* AssertRCReturn(...) will leave us in loading state, but it doesn't matter as we'd be failing anyway */
/* Read number of clients */
}
/* Do nothing until we're being called last time */
{
return VINF_SUCCESS;
}
if (version!=SHCROGL_SSM_VERSION)
{
}
/* Load and recreate rendering contexts */
{
char psz[200];
if (createInfo.pszDpyName)
{
}
ctxID = crServerDispatchCreateContextEx(createInfo.pszDpyName, createInfo.visualBits, 0, key, createInfo.internalID);
}
/* Restore context state data */
{
}
/* Load windows */
{
char psz[200];
unsigned long key;
if (createInfo.pszDpyName)
{
}
}
/* Load cr_server.muralTable */
{
if (muralInfo.pVisibleRects)
{
if (!muralInfo.pVisibleRects)
{
return VERR_NO_MEMORY;
}
}
/* Restore windows geometry info */
/* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
if (muralInfo.bReceivedRects)
{
}
if (muralInfo.pVisibleRects)
{
}
}
/* Load starting free context and window IDs */
/* Load clients info */
for (i = 0; i < cr_server.numClients; i++)
{
{
/* If this assert fires, then we should search correct client in the list first*/
if (version>=4)
{
}
/* We can't reassign client number, as we'd get wrong results in TranslateTextureID
* and fail to bind old textures.
*/
/*client.number = pClient->number;*/
{
//pClient->currentCtx = client.currentCtx;
//pClient->currentContextNumber = ctxID;
}
{
//pClient->currentMural = client.currentMural;
//pClient->currentWindow = winID;
}
/* Restore client active context and window */
if (0)
{
crHashtableWalk(client.currentCtx->shared->textureTable, crVBoxServerSyncTextureCB, client.currentCtx);
crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base1D, GL_TRUE);
crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base2D, GL_TRUE);
crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base3D, GL_TRUE);
#ifdef CR_ARB_texture_cube_map
crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseCubeMap, GL_TRUE);
#endif
#ifdef CR_NV_texture_rectangle
//@todo this doesn't work as expected
//crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseRect, GL_TRUE);
#endif
/*cr_server.head_spu->dispatch_table.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
cr_server.head_spu->dispatch_table.LightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
cr_server.head_spu->dispatch_table.Lightfv(GL_LIGHT1, GL_DIFFUSE, one);
cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
cr_server.head_spu->dispatch_table.Enable(GL_LIGHT0);
cr_server.head_spu->dispatch_table.Enable(GL_LIGHT1);
cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);*/
//crStateViewport( 0, 0, 600, 600 );
//pClient->currentMural->viewportValidated = GL_FALSE;
//cr_server.head_spu->dispatch_table.Viewport( 0, 0, 600, 600 );
//crStateMatrixMode(GL_PROJECTION);
//cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
//crStateLoadIdentity();
//cr_server.head_spu->dispatch_table.LoadIdentity();
//crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
//cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
//crStateMatrixMode(GL_MODELVIEW);
//cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
//crServerDispatchLoadIdentity();
//crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
//cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
//crServerDispatchLoadIdentity();
/*createInfo = (CRCreateInfo_t *) crHashtableSearch(cr_server.pContextCreateInfoTable, ctxID);
CRASSERT(createInfo);
tmpCtx = crStateCreateContext(NULL, createInfo->visualBits, NULL);
CRASSERT(tmpCtx);
crStateDiffContext(tmpCtx, client.currentCtx);
crStateDestroyContext(tmpCtx);*/
}
}
}
//crServerDispatchMakeCurrent(-1, 0, -1);
{
if (err != GL_NO_ERROR)
{
}
}
return VINF_SUCCESS;
}
{
{
}
}
{
(void) data2;
}
{
int i;
return VERR_INVALID_PARAMETER;
/*Shouldn't happen yet, but to be safe in future*/
for (i=0; i<cr_server.screenCount; ++i)
{
crWarning("Screen count is changing, but screen[%i] is still mapped", i);
return VERR_NOT_IMPLEMENTED;
}
for (i=0; i<sCount; ++i)
{
}
return VINF_SUCCESS;
}
{
return VERR_INVALID_PARAMETER;
{
}
return VINF_SUCCESS;
}
DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID)
{
return VERR_INVALID_PARAMETER;
{
}
#ifndef WINDOWS
/*Restore FB content for clients, which have current window on a screen being remapped*/
{
GLint i;
for (i = 0; i < cr_server.numClients; i++)
{
{
{
}
}
}
}
#endif
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
}
{
}
{
{
return VINF_SUCCESS;
}
if (value && !crServerSupportRedirMuralFBO())
{
return VERR_NOT_SUPPORTED;
}
return VINF_SUCCESS;
}