load.c revision 63bd3e50e47875b211cb97a76c9f18298f68df39
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "cr_spu.h"
#include "cr_net.h"
#include "cr_error.h"
#include "cr_mem.h"
#include "cr_string.h"
#include "cr_net.h"
#include "cr_environment.h"
#include "cr_process.h"
#include "cr_rand.h"
#include "cr_netserver.h"
#include "stub.h"
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <iprt/initterm.h>
#ifndef WINDOWS
# include <unistd.h>
#endif
#ifdef CHROMIUM_THREADSAFE
#include "cr_threads.h"
#endif
#ifdef VBOX_WITH_WDDM
#include <d3d9types.h>
#include <D3dumddi.h>
#include "../../WINNT/Graphics/Miniport/wddm/VBoxVideoIf.h"
#include "../../WINNT/Graphics/Display/wddm/vboxdispmp.h"
#endif
/**
* If you change this, see the comments in tilesortspu_context.c
*/
#define MAGIC_CONTEXT_BASE 500
#define CONFIG_LOOKUP_FILE ".crconfigs"
#ifdef WINDOWS
#define PYTHON_EXE "python.exe"
#else
#define PYTHON_EXE "python"
#endif
#ifdef WINDOWS
#endif
static int stub_initialized = 0;
/* NOTE: 'SPUDispatchTable glim' is declared in NULLfuncs.py now */
/* NOTE: 'SPUDispatchTable stubThreadsafeDispatch' is declared in tsfuncs.c */
static void stubInitNativeDispatch( void )
{
#define MAX_FUNCS 1000
int numFuncs;
/* XXX call this after context binding */
}
/** Pointer to the SPU's real glClear and glViewport functions */
static ClearFunc_t origClear;
static ViewportFunc_t origViewport;
static SwapBuffersFunc_t origSwapBuffers;
static DrawBufferFunc_t origDrawBuffer;
static ScissorFunc_t origScissor;
{
bool bForceUpdate = false;
bool bChanged = false;
#ifdef WINDOWS
/* @todo install hook and track for WM_DISPLAYCHANGE */
{
{
crDebug("Resolution changed(%d,%d), forcing window Pos/Size update", devMode.dmPelsWidth, devMode.dmPelsHeight);
bForceUpdate = true;
}
}
#endif
{
}
#endif
bChanged = true;
}
}
if (bFlushOnChange && bChanged)
{
}
}
{
#ifdef WINDOWS
{
return false;
}
#else
int x, y;
{
return false;
}
#endif
return true;
}
{
{
return;
}
if (!stubSystemWindowExist(pWindow))
{
#ifdef WINDOWS
#else
#endif
return;
}
}
static void stubCheckWindowsState(void)
{
if (!stub.currentContext)
return;
#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
#endif
#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
#endif
}
/**
* Override the head SPU's glClear function.
* We're basically trapping this function so that we can poll the
* application window size at a regular interval.
*/
{
/* call the original SPU glClear function */
}
/**
* As above, but for glViewport. Most apps call glViewport before
* glClear when a window is resized.
*/
{
/* call the original SPU glViewport function */
if (!stub.viewportHack)
{
origViewport(x, y, w, h);
}
else
{
}
}
{
}
{
}
{
}
/**
* Use the GL function pointers in <spu> to initialize the static glim
* dispatch table.
*/
{
if (stub.viewportHack)
/*stub.spuDispatch.SwapBuffers = trapSwapBuffers;
stub.spuDispatch.DrawBuffer = trapDrawBuffer;*/
}
}
// Callback function, used to destroy all created contexts
{
}
/**
* This is called when we exit.
* We call all the SPU's cleanup functions.
*/
static void stubSPUTearDown(void)
{
crDebug("stubSPUTearDown");
if (!stub_initialized) return;
stub_initialized = 0;
#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
# endif
#endif
#ifdef CR_NEWWINTRACK
#endif
//delete all created contexts
/* shutdown, now trap any calls to a NULL dispatcher */
#ifndef Linux
#endif
#ifdef GLX
{
}
#endif
}
static void stubSPUSafeTearDown(void)
{
#ifdef CHROMIUM_THREADSAFE
#endif
if (!stub_initialized) return;
stub_initialized = 0;
#ifdef CHROMIUM_THREADSAFE
#endif
crDebug("stubSPUSafeTearDown");
#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
# endif
#endif
#if defined(CR_NEWWINTRACK)
# if defined(WINDOWS)
{
{
}
else
{
crDebug("Sync thread killed before DLL_PROCESS_DETACH");
}
}
#else
{
/*RTThreadWait might return too early, which cause our code being unloaded while RT thread wrapper is still running*/
if (!rc)
{
}
}
#endif
#endif
#ifdef CHROMIUM_THREADSAFE
#endif
}
static void stubExitHandler(void)
{
}
/**
* Called when we receive a SIGTERM signal.
*/
static void stubSignalHandler(int signo)
{
exit(0); /* this causes stubExitHandler() to be called */
}
/**
* Init variables in the stub structure, install signal handler.
*/
static void stubInitVars(void)
{
#ifdef CHROMIUM_THREADSAFE
#endif
/* At the very least we want CR_RGB_BIT. */
stub.appDrawCursor = 0;
stub.ignoreFreeglutMenus = 0;
stub.trackWindowSize = 0;
stub.trackWindowPos = 0;
stub.mothershipPID = 0;
#ifdef CR_NEWWINTRACK
stub.bShutdownSyncThread = false;
#endif
#ifdef WINDOWS
defaultWin->cVisibleRegions = 0;
#endif
#if 1
#ifndef WINDOWS
#endif
#else
(void) stubExitHandler;
(void) stubSignalHandler;
#endif
}
/**
* Return a free port number for the mothership to use, or -1 if we
* can't find one.
*/
static int
GenerateMothershipPort(void)
{
const int MAX_PORT = 10100;
unsigned short port;
/* generate initial port number randomly */
#ifdef WINDOWS
/* XXX should implement a free port check here */
return port;
#else
/*
* See if this port number really is free, try another if needed.
*/
{
struct sockaddr_in servaddr;
int so_reuseaddr = 1;
int sock, k;
/* create socket */
(char *) &so_reuseaddr, sizeof(so_reuseaddr));
CRASSERT(k == 0);
/* initialize the servaddr struct */
/* Bind to the given port number, return -1 if we fail */
if (k) {
/* failed to create port. try next one. */
port++;
}
else {
return port;
}
}
}
#endif /* WINDOWS */
return -1;
}
/**
* Try to determine which mothership configuration to use for this program.
*/
static char **
LookupMothershipConfig(const char *procName)
{
FILE *f;
const char *home;
char configPath[1000];
/* first, check if the CR_CONFIG env var is set */
{
}
/* second, look up config name from config file */
if (home)
else
/* Check if the CR_CONFIG_PATH env var is set. */
{
if (conf)
}
if (!f) {
return NULL;
}
while (!feof(f)) {
char line[1000];
char **args;
{
crWarning("Using Chromium configuration for %s from %s",
return args;
}
}
fclose(f);
return NULL;
}
static int Mothership_Awake = 0;
/**
* Signal handler to determine when mothership is ready.
*/
static void
MothershipPhoneHome(int signo)
{
Mothership_Awake = 1;
}
void stubSetDefaultConfigurationOptions(void)
{
unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
stub.appDrawCursor = 0;
stub.numIgnoreWindowID = 0;
stub.ignoreFreeglutMenus = 0;
crNetSetRank(0);
stub.force_pbuffers = 0;
stub.viewportHack = 0;
#ifdef WINDOWS
{
char name[1000];
int i;
/* Apply viewport hack only if we're running under wine */
{
for (i=0; gsViewportHackApps[i]; ++i)
{
{
break;
}
}
}
}
#endif
}
#ifdef CR_NEWWINTRACK
# ifdef VBOX_WITH_WDDM
{
if (lpRgnData)
{
crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, lpRgnData->rdh.nCount);
stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, lpRgnData->rdh.nCount, (GLint*) lpRgnData->Buffer);
}
else crWarning("GetRegionData failed, VisibleRegions update failed");
}
{
uint32_t i;
{
return INVALID_HANDLE_VALUE;
}
hRgn = CreateRectRgn(0, 0, 0, 0);
{
}
return hRgn;
}
{
bool bChanged = false;
{
return;
}
{
bChanged = true;
}
{
{
bChanged = true;
}
{
bChanged = true;
}
}
else
{
}
if (hNewRgn!=INVALID_HANDLE_VALUE)
{
{
{
bChanged = true;
}
else
{
}
}
else
{
{
bChanged = true;
}
}
}
if (bChanged)
{
}
}
# endif
{
(void) data2;
{
return;
}
if (!stubSystemWindowExist(pWindow))
{
#ifdef WINDOWS
#else
#endif
/*No need to flush here as crWindowDestroy does it*/
return;
}
}
{
#ifdef WINDOWS
# ifdef VBOX_WITH_WDDM
# endif
#endif
(void) pvUser;
crDebug("Sync thread started");
#ifdef WINDOWS
# ifdef VBOX_WITH_WDDM
{
pfnVBoxDispMpGetCallbacks = (PFNVBOXDISPMP_GETCALLBACKS)GetProcAddress(hVBoxD3D, TEXT("VBoxDispMpGetCallbacks"));
{
{
{
crWarning("VBoxDispMpTstCallbacks.pfnEnableEvents failed");
}
else
{
crDebug("running with VBoxDispD3D");
}
}
else
{
crWarning("VBoxDispMpGetCallbacks failed");
}
}
}
# endif
#endif
while(!stub.bShutdownSyncThread)
{
#ifdef WINDOWS
{
# ifdef VBOX_WITH_WDDM
{
{
# if 0
uint32_t i;
{
crDebug("Rect(%d): left(%d), top(%d), right(%d), bottom(%d)", i, pRect->left, pRect->top, pRect->right, pRect->bottom);
}
crDebug("<<<<<");
# endif
/*hacky way to make sure window wouldn't be deleted in another thread as we hold hashtable lock here*/
}
else
{
if (WAIT_TIMEOUT!=hr)
{
}
}
}
else
# endif
{
RTThreadSleep(50);
}
}
else
{
{
crDebug("Sync thread got WM_QUIT");
break;
}
else
{
}
}
#else
RTThreadSleep(50);
#endif
}
#ifdef VBOX_WITH_WDDM
{
}
if (hVBoxD3D)
{
}
#endif
crDebug("Sync thread stopped");
return 0;
}
#endif
/**
* Do one-time initializations for the faker.
* Returns TRUE on success, FALSE otherwise.
*/
bool
stubInit(void)
{
/* Here is where we contact the mothership to find out what we're supposed
* to be doing. Networking code in a DLL initializer. I sure hope this
* works :)
*
* HOW can I pass the mothership address to this if I already know it?
*/
char response[1024];
char **spuchain;
int num_spus;
int *spu_ids;
char **spu_names;
const char *app_id;
int i;
int disable_sync = 0;
if (stub_initialized)
return true;
stubInitVars();
#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
/*@todo when vm boots with compiz turned on, new code causes hang in xcb_wait_for_reply in the sync thread*/
{
disable_sync = 1;
}
#endif
/* @todo check if it'd be of any use on other than guests, no use for windows */
#ifndef WINDOWS
{
{
crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM.");
return false;
}
else
{
}
#if 0 && defined(CR_NEWWINTRACK)
{
if (st==0)
{
}
}
#endif
}
#endif
for (i = 0 ; i < num_spus ; i++)
{
}
for (i = 0; i < num_spus; ++i)
// spu chain load failed somewhere
return false;
}
/* This is unlikely to change -- We still want to initialize our dispatch
* table with the functions of the first SPU in the chain. */
/* we need to plug one special stub function into the dispatch table */
#if !defined(VBOX_NO_NATIVEGL)
/* Load pointers to native OpenGL functions into stub.nativeDispatch */
#endif
/*crDebug("stub init");
raise(SIGINT);*/
#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
# endif
#endif
#ifdef CR_NEWWINTRACK
{
int rc;
RTR3Init();
if (!disable_sync)
{
crDebug("Starting sync thread");
rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync");
if (RT_FAILURE(rc))
{
}
crDebug("Going on");
}
}
#endif
#ifdef GLX
#endif
stub_initialized = 1;
return true;
}
/* Sigh -- we can't do initialization at load time, since Windows forbids
* the loading of other libraries from DLLMain. */
#ifdef LINUX
/* GCC crap
*void (*stub_init_ptr)(void) __attribute__((section(".ctors"))) = __stubInit; */
#endif
#ifdef WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* Windows crap */
{
(void) lpvReserved;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
{
crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
return FALSE;
}
else
break;
}
case DLL_PROCESS_DETACH:
{
break;
}
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return TRUE;
}
#endif