Пример #1
0
DECLEXPORT(void) STATE_APIENTRY crStateLinkProgram(GLuint program)
{
    CRGLSLProgram *pProgram = crStateGetProgramObj(program);
    GLuint i;

    if (!pProgram)
    {
        crWarning("Unknown program %d", program);
        return;
    }

    pProgram->linked = GL_TRUE;

    /*Free program's active state*/
    if (pProgram->activeState.attachedShaders)
    {
        crHashtableWalk(pProgram->activeState.attachedShaders, crStateFakeDecRefCountCB, NULL);
        crFreeHashtable(pProgram->activeState.attachedShaders, crStateFreeGLSLShader);
        pProgram->activeState.attachedShaders = NULL;
    }
    for (i=0; i<pProgram->activeState.cAttribs; ++i)
    {
        crFree(pProgram->activeState.pAttribs[i].name);
    }
    if (pProgram->activeState.pAttribs) crFree(pProgram->activeState.pAttribs);

    /*copy current state to active state*/
    crMemcpy(&pProgram->activeState, &pProgram->currentState, sizeof(CRGLSLProgramState));

    pProgram->activeState.attachedShaders = crAllocHashtable();
    if (!pProgram->activeState.attachedShaders)
    {
        crWarning("crStateLinkProgram: Out of memory!");
        return;
    }
    crHashtableWalk(pProgram->currentState.attachedShaders, crStateCopyShaderCB, pProgram);

    /*that's not a bug, note the memcpy above*/
    if (pProgram->activeState.pAttribs)
    {
        pProgram->activeState.pAttribs = (CRGLSLAttrib *) crAlloc(pProgram->activeState.cAttribs * sizeof(CRGLSLAttrib));
    }

    for (i=0; i<pProgram->activeState.cAttribs; ++i)
    {
        crMemcpy(&pProgram->activeState.pAttribs[i], &pProgram->currentState.pAttribs[i], sizeof(CRGLSLAttrib));
        pProgram->activeState.pAttribs[i].name = crStrdup(pProgram->currentState.pAttribs[i].name);
    }

    crStateFreeProgramUniforms(pProgram);
}
Пример #2
0
static SPUFunctions *hiddenlineSPUInit( int id, SPU *child, SPU *self,
		unsigned int context_id,
		unsigned int num_contexts )
{

	(void) context_id;
	(void) num_contexts;

#ifdef CHROMIUM_THREADSAFE
	crDebug("Hiddenline SPU: thread-safe");
#endif

	hiddenline_spu.id = id;
	hiddenline_spu.has_child = 0;
	if (child)
	{
		crSPUInitDispatchTable( &(hiddenline_spu.child) );
		crSPUCopyDispatchTable( &(hiddenline_spu.child), &(child->dispatch_table) );
		hiddenline_spu.has_child = 1;
	}
	crSPUInitDispatchTable( &(hiddenline_spu.super) );
	crSPUCopyDispatchTable( &(hiddenline_spu.super), &(self->superSPU->dispatch_table) );
	hiddenlinespuGatherConfiguration( child );

	/* We need to track state so that the packer can deal with pixel data */
	crStateInit();

	hiddenlinespuCreateFunctions();

	hiddenline_spu.contextTable = crAllocHashtable();
#ifdef CHROMIUM_THREADSAFE
	crInitTSD(&_HiddenlineTSD);
#else
	hiddenline_spu.currentContext = NULL;
#endif
	crInitMutex(&(hiddenline_spu.mutex));

	return &hiddenline_functions;
}
Пример #3
0
/**
 * Vnc spu init function
 * \param id
 * \param child
 * \param self
 * \param context_id
 * \param num_contexts
 */
static SPUFunctions *
vncSPUInit( int id, SPU *child, SPU *self,
								 unsigned int context_id,
								 unsigned int num_contexts )
{

	(void) self;
	(void) context_id;
	(void) num_contexts;

	vnc_spu.id = id;
	vnc_spu.has_child = 0;
	vnc_spu.server = NULL;
	/* We should always have a child (next) SPU since we're derived from
	 * the Passthrough SPU which requires a child/next SPU.
	 */
	if (child)
	{
		crSPUInitDispatchTable( &(vnc_spu.child) );
		crSPUCopyDispatchTable( &(vnc_spu.child), &(child->dispatch_table) );
		vnc_spu.has_child = 1;
	}
	crSPUInitDispatchTable( &(vnc_spu.super) );
	crSPUCopyDispatchTable( &(vnc_spu.super), &(self->superSPU->dispatch_table) );
	vncspuGatherConfiguration();

	vnc_spu.windowTable = crAllocHashtable();

	vncspuNetLoggerInit();

	vncspuInitialize();

	vncspuStartServerThread();

	return &vnc_functions;
}
Пример #4
0
/**
 * Do CRServer initializations.  After this, we can begin servicing clients.
 */
void
crServerInit(int argc, char *argv[])
{
    int i;
    char *mothership = NULL;
    CRMuralInfo *defaultMural;

    for (i = 1 ; i < argc ; i++)
    {
        if (!crStrcmp( argv[i], "-mothership" ))
        {
            if (i == argc - 1)
            {
                crError( "-mothership requires an argument" );
            }
            mothership = argv[i+1];
            i++;
        }
        else if (!crStrcmp( argv[i], "-port" ))
        {
            /* This is the port on which we'll accept client connections */
            if (i == argc - 1)
            {
                crError( "-port requires an argument" );
            }
            cr_server.tcpip_port = crStrToInt(argv[i+1]);
            i++;
        }
        else if (!crStrcmp( argv[i], "-vncmode" ))
        {
            cr_server.vncMode = 1;
        }
        else if (!crStrcmp( argv[i], "-help" ))
        {
            crPrintHelp();
            exit(0);
        }
    }

    signal( SIGTERM, crServerCleanup );
    signal( SIGINT, crServerCleanup );
#ifndef WINDOWS
    signal( SIGPIPE, SIG_IGN );
#endif

#if DEBUG_FP_EXCEPTIONS
    {
        fpu_control_t mask;
        _FPU_GETCW(mask);
        mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
                  | _FPU_MASK_OM | _FPU_MASK_UM);
        _FPU_SETCW(mask);
    }
#endif

    cr_server.firstCallCreateContext = GL_TRUE;
    cr_server.firstCallMakeCurrent = GL_TRUE;

    /*
     * Create default mural info and hash table.
     */
    cr_server.muralTable = crAllocHashtable();
    defaultMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
    crHashtableAdd(cr_server.muralTable, 0, defaultMural);

    cr_server.programTable = crAllocHashtable();

    crNetInit(crServerRecv, crServerClose);
    crStateInit();

    crServerGatherConfiguration(mothership);

    crStateLimitsInit( &(cr_server.limits) );

    /*
     * Default context
     */
    cr_server.contextTable = crAllocHashtable();
    cr_server.DummyContext = crStateCreateContext( &cr_server.limits,
                             CR_RGB_BIT | CR_DEPTH_BIT, NULL );
    cr_server.curClient->currentCtx = cr_server.DummyContext;

    crServerInitDispatch();
    crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );

    crUnpackSetReturnPointer( &(cr_server.return_ptr) );
    crUnpackSetWritebackPointer( &(cr_server.writeback_ptr) );

    cr_server.barriers = crAllocHashtable();
    cr_server.semaphores = crAllocHashtable();
}
/**
 * This function creates and initializes a new display list
 * manager.  It returns a pointer to the manager, or NULL in
 * the case of insufficient memory.  The dispatch table pointer
 * is passed in to allow the utilities to muck with the table
 * to gain functional control when GL calls are made.
 */
CRDLM DLM_APIENTRY *crDLMNewDLM(unsigned int userConfigSize, const CRDLMConfig *userConfig)
{
    CRDLM *dlm;

    /* This is the default configuration.  We'll overwrite it later
     * with user-supplied configuration information.
     */
    CRDLMConfig config = {
	CRDLM_DEFAULT_BUFFERSIZE,
    };

    dlm = crAlloc(sizeof(*dlm));
    if (!dlm) {
	return NULL;
    }

    /* Start off by initializing all entries that require further
     * memory allocation, so we can free up all the memory if there's
     * a problem.
     */
    if (!(dlm->displayLists = crAllocHashtable())) {
	crFree(dlm);
	return NULL;
    }

    /* The creator counts as the first user. */
    dlm->userCount = 1;

#ifdef CHROMIUM_THREADSAFE
    /* This mutex ensures that only one thread is changing the displayLists
     * hash at a time.  Note that we may also need a mutex to guarantee that
     * the hash is not changed by one thread while another thread is
     * traversing it; this issue has not yet been resolved.
     */
    crInitMutex(&(dlm->dlMutex));

    /* Although the thread-specific data (TSD) functions will initialize
     * the thread key themselves when needed, those functions do not allow
     * us to specify a thread destructor.  Since a thread could potentially
     * exit with considerable memory allocated (e.g. if a thread exits 
     * after it has issued NewList but before EndList, and while there
     * are considerable content buffers allocated), I do the initialization
     * myself, in order to be able to reclaim those resources if a thread
     * exits.
     */
    crInitTSDF(&(dlm->tsdKey), threadDestructor);
    crInitTSD(&CRDLMTSDKey);
#endif

    /* Copy over any appropriate configuration values */
    if (userConfig != NULL) {
	/* Copy over as much configuration information as is provided.
	 * Note that if the CRDLMConfig structure strictly grows, this
	 * allows forward compatability - routines compiled with
	 * older versions of the structure will only initialize that
	 * section of the structure that they know about.
	 */
	crMemcpy((void *)&config, (void *) userConfig, 
		MIN(userConfigSize, sizeof(config)));
    }
    dlm->bufferSize = config.bufferSize;

    /* Return the pointer to the newly-allocated display list manager */
    return dlm;
}
Пример #6
0
/**
 * Init variables in the stub structure, install signal handler.
 */
static void stubInitVars(void)
{
    WindowInfo *defaultWin;

#ifdef CHROMIUM_THREADSAFE
    crInitMutex(&stub.mutex);
#endif

    /* At the very least we want CR_RGB_BIT. */
    stub.haveNativeOpenGL = GL_FALSE;
    stub.spu = NULL;
    stub.appDrawCursor = 0;
    stub.minChromiumWindowWidth = 0;
    stub.minChromiumWindowHeight = 0;
    stub.maxChromiumWindowWidth = 0;
    stub.maxChromiumWindowHeight = 0;
    stub.matchChromiumWindowCount = 0;
    stub.matchChromiumWindowID = NULL;
    stub.matchWindowTitle = NULL;
    stub.ignoreFreeglutMenus = 0;
    stub.threadSafe = GL_FALSE;
    stub.trackWindowSize = 0;
    stub.trackWindowPos = 0;
    stub.trackWindowVisibility = 0;
    stub.trackWindowVisibleRgn = 0;
    stub.mothershipPID = 0;
    stub.spu_dir = NULL;

    stub.freeContextNumber = MAGIC_CONTEXT_BASE;
    stub.contextTable = crAllocHashtable();
#ifndef RT_OS_WINDOWS
# ifdef CHROMIUM_THREADSAFE
    if (!g_stubIsCurrentContextTSDInited)
    {
        crInitTSDF(&g_stubCurrentContextTSD, stubThreadTlsDtor);
        g_stubIsCurrentContextTSDInited = true;
    }
# endif
#endif
    stubSetCurrentContext(NULL);

    stub.windowTable = crAllocHashtable();

#ifdef CR_NEWWINTRACK
    stub.bShutdownSyncThread = false;
    stub.hSyncThread = NIL_RTTHREAD;
#endif

    defaultWin = (WindowInfo *) crCalloc(sizeof(WindowInfo));
    defaultWin->type = CHROMIUM;
    defaultWin->spuWindow = 0;  /* window 0 always exists */
#ifdef WINDOWS
    defaultWin->hVisibleRegion = INVALID_HANDLE_VALUE;
#elif defined(GLX)
    defaultWin->pVisibleRegions = NULL;
    defaultWin->cVisibleRegions = 0;
#endif
    crHashtableAdd(stub.windowTable, 0, defaultWin);

#if 1
    atexit(stubExitHandler);
    signal(SIGTERM, stubSignalHandler);
    signal(SIGINT, stubSignalHandler);
#ifndef WINDOWS
    signal(SIGPIPE, SIG_IGN); /* the networking code should catch this */
#endif
#else
    (void) stubExitHandler;
    (void) stubSignalHandler;
#endif
}
Пример #7
0
/**
 * Do one-time initializations for the faker.
 * Returns TRUE on success, FALSE otherwise.
 */
static bool
stubInitLocked(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?
     */

    CRConnection *conn = NULL;
    char response[1024];
    char **spuchain;
    int num_spus;
    int *spu_ids;
    char **spu_names;
    const char *app_id;
    int i;
    int disable_sync = 0;

    stubInitVars();

    crGetProcName(response, 1024);
    crDebug("Stub launched for %s", response);

#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
     * as at the start compiz runs our code under XGrabServer.
     */
    if (!crStrcmp(response, "compiz") || !crStrcmp(response, "compiz_real") || !crStrcmp(response, "compiz.real")
	|| !crStrcmp(response, "compiz-bin"))
    {
        disable_sync = 1;
    }
#elif defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WDDM_MINIPORT_WITH_VISIBLE_RECTS)
    if (GetModuleHandle(VBOX_MODNAME_DISPD3D))
    {
        disable_sync = 1;
        crDebug("running with " VBOX_MODNAME_DISPD3D);
        stub.trackWindowVisibleRgn = 0;
        stub.bRunningUnderWDDM = true;
    }
#endif

    /* @todo check if it'd be of any use on other than guests, no use for windows */
    app_id = crGetenv( "CR_APPLICATION_ID_NUMBER" );

    crNetInit( NULL, NULL );

#ifndef WINDOWS
    {
        CRNetServer ns;

        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
                );
        if (!ns.conn)
        {
            crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM.");
            return false;
        }
        else
        {
            crNetFreeConnection(ns.conn);
        }
#if 0 && defined(CR_NEWWINTRACK)
        {
            Status st = XInitThreads();
            if (st==0)
            {
                crWarning("XInitThreads returned %i", (int)st);
            }
        }
#endif
    }
#endif

    strcpy(response, "2 0 feedback 1 pack");
    spuchain = crStrSplit( response, " " );
    num_spus = crStrToInt( spuchain[0] );
    spu_ids = (int *) crAlloc( num_spus * sizeof( *spu_ids ) );
    spu_names = (char **) crAlloc( num_spus * sizeof( *spu_names ) );
    for (i = 0 ; i < num_spus ; i++)
    {
        spu_ids[i] = crStrToInt( spuchain[2*i+1] );
        spu_names[i] = crStrdup( spuchain[2*i+2] );
        crDebug( "SPU %d/%d: (%d) \"%s\"", i+1, num_spus, spu_ids[i], spu_names[i] );
    }

    stubSetDefaultConfigurationOptions();

    stub.spu = crSPULoadChain( num_spus, spu_ids, spu_names, stub.spu_dir, NULL );

    crFree( spuchain );
    crFree( spu_ids );
    for (i = 0; i < num_spus; ++i)
        crFree(spu_names[i]);
    crFree( spu_names );

    // spu chain load failed somewhere
    if (!stub.spu) {
        return false;
    }

    crSPUInitDispatchTable( &glim );

    /* This is unlikely to change -- We still want to initialize our dispatch
     * table with the functions of the first SPU in the chain. */
    stubInitSPUDispatch( stub.spu );

    /* we need to plug one special stub function into the dispatch table */
    glim.GetChromiumParametervCR = stub_GetChromiumParametervCR;

#if !defined(VBOX_NO_NATIVEGL)
    /* Load pointers to native OpenGL functions into stub.nativeDispatch */
    stubInitNativeDispatch();
#endif

/*crDebug("stub init");
raise(SIGINT);*/

#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
    stubInstallWindowMessageHook();
# endif
#endif

#ifdef CR_NEWWINTRACK
    {
        int rc;

        RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);

        if (!disable_sync)
        {
            crDebug("Starting sync thread");

            rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync");
            if (RT_FAILURE(rc))
            {
                crError("Failed to start sync thread! (%x)", rc);
            }
            RTThreadUserWait(stub.hSyncThread, 60 * 1000);
            RTThreadUserReset(stub.hSyncThread);

            crDebug("Going on");
        }
    }
#endif

#ifdef GLX
    stub.xshmSI.shmid = -1;
    stub.bShmInitFailed = GL_FALSE;
    stub.pGLXPixmapsHash = crAllocHashtable();

    stub.bXExtensionsChecked = GL_FALSE;
    stub.bHaveXComposite = GL_FALSE;
    stub.bHaveXFixes = GL_FALSE;
#endif

    return true;
}
Пример #8
0
static SPUFunctions *
renderSPUInit( int id, SPU *child, SPU *self,
               unsigned int context_id, unsigned int num_contexts )
{
    int numFuncs, numSpecial;
    GLint defaultWin, defaultCtx;
    WindowInfo *windowInfo;
    const char * pcpwSetting;
    int rc;

    (void) child;
    (void) context_id;
    (void) num_contexts;

    self->privatePtr = (void *) &render_spu;

#ifdef CHROMIUM_THREADSAFE
    crDebug("Render SPU: thread-safe");
#endif

    crMemZero(&render_spu, sizeof(render_spu));

    render_spu.id = id;
    renderspuSetVBoxConfiguration(&render_spu);

    if (render_spu.swap_master_url)
        swapsyncConnect();


    /* Get our special functions. */
    numSpecial = renderspuCreateFunctions( _cr_render_table );

#ifdef RT_OS_WINDOWS
    /* Start thread to create windows and process window messages */
    crDebug("RenderSPU: Starting windows serving thread");
    render_spu.hWinThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!render_spu.hWinThreadReadyEvent)
    {
        crError("RenderSPU: Failed to create WinThreadReadyEvent! (%x)", GetLastError());
        return NULL;
    }

    if (!CreateThread(NULL, 0, renderSPUWindowThreadProc, 0, 0, &render_spu.dwWinThreadId))
    {
        crError("RenderSPU: Failed to start windows thread! (%x)", GetLastError());
        return NULL;
    }
    WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
#endif

    /* Get the OpenGL functions. */
    numFuncs = crLoadOpenGL( &render_spu.ws, _cr_render_table + numSpecial );
    if (numFuncs == 0) {
        crError("The render SPU was unable to load the native OpenGL library");
        return NULL;
    }

    numFuncs += numSpecial;

    render_spu.contextTable = crAllocHashtableEx(1, INT32_MAX);
    render_spu.windowTable = crAllocHashtableEx(1, INT32_MAX);

    render_spu.dummyWindowTable = crAllocHashtable();

    pcpwSetting = crGetenv("CR_RENDER_ENABLE_SINGLE_PRESENT_CONTEXT");
    if (pcpwSetting)
    {
        if (pcpwSetting[0] == '0')
            pcpwSetting = NULL;
    }

    if (pcpwSetting)
    {
        /* TODO: need proper blitter synchronization, do not use so far!
         * the problem is that rendering can be done in multiple thread: the main command (hgcm) thread and the redraw thread
         * we currently use per-window synchronization, while we'll need a per-blitter synchronization if one blitter is used for multiple windows
         * this is not done currently */
        crWarning("TODO: need proper blitter synchronization, do not use so far!");
        render_spu.blitterTable = crAllocHashtable();
        CRASSERT(render_spu.blitterTable);
    }
    else
        render_spu.blitterTable = NULL;

    CRASSERT(render_spu.default_visual & CR_RGB_BIT);
    
    rc = renderspu_SystemInit();
    if (!RT_SUCCESS(rc))
    {
        crError("renderspu_SystemInit failed rc %d", rc);
        return NULL;
    }
#ifdef USE_OSMESA
    if (render_spu.use_osmesa) {
        if (!crLoadOSMesa(&render_spu.OSMesaCreateContext,
                          &render_spu.OSMesaMakeCurrent,
                          &render_spu.OSMesaDestroyContext)) {
            crError("Unable to load OSMesa library");
        }
    }
#endif

#ifdef DARWIN
# ifdef VBOX_WITH_COCOA_QT
# else /* VBOX_WITH_COCOA_QT */
    render_spu.hRootVisibleRegion = 0;
    render_spu.currentBufferName = 1;
    render_spu.uiDockUpdateTS = 0;
    /* Create a mutex for synchronizing events from the main Qt thread & this
       thread */
    RTSemFastMutexCreate(&render_spu.syncMutex);
    /* Create our window groups */
    CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &render_spu.pMasterGroup);
    CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &render_spu.pParentGroup);
    /* Make the correct z-layering */
    SendWindowGroupBehind (render_spu.pParentGroup, render_spu.pMasterGroup);
    /* and set the gParentGroup as parent for gMasterGroup. */
    SetWindowGroupParent (render_spu.pMasterGroup, render_spu.pParentGroup);
    /* Install the event handlers */
    EventTypeSpec eventList[] =
    {
        {kEventClassVBox, kEventVBoxUpdateContext}, /* Update the context after show/size/move events */
        {kEventClassVBox, kEventVBoxBoundsChanged}  /* Clip/Pos the OpenGL windows when the main window is changed in pos/size */
    };
    /* We need to process events from our main window */
    render_spu.hParentEventHandler = NewEventHandlerUPP(windowEvtHndlr);
    InstallApplicationEventHandler (render_spu.hParentEventHandler,
                                    GetEventTypeCount(eventList), eventList,
                                    NULL, NULL);
    render_spu.fInit = true;
# endif /* VBOX_WITH_COCOA_QT */
#endif /* DARWIN */

    /*
     * Create the default window and context.  Their indexes are zero and
     * a client can use them without calling CreateContext or WindowCreate.
     */
    crDebug("Render SPU: Creating default window (visBits=0x%x, id=0)",
            render_spu.default_visual);
    defaultWin = renderspuWindowCreateEx( NULL, render_spu.default_visual, CR_RENDER_DEFAULT_WINDOW_ID );
    if (defaultWin != CR_RENDER_DEFAULT_WINDOW_ID) {
        crError("Render SPU: Couldn't get a double-buffered, RGB visual with Z!");
        return NULL;
    }
    crDebug( "Render SPU: WindowCreate returned %d (0=normal)", defaultWin );

    crDebug("Render SPU: Creating default context, visBits=0x%x",
            render_spu.default_visual );
    defaultCtx = renderspuCreateContextEx( NULL, render_spu.default_visual, CR_RENDER_DEFAULT_CONTEXT_ID, 0 );
    if (defaultCtx != CR_RENDER_DEFAULT_CONTEXT_ID) {
        crError("Render SPU: failed to create default context!");
        return NULL;
    }

    renderspuMakeCurrent( defaultWin, 0, defaultCtx );

    /* Get windowInfo for the default window */
    windowInfo = (WindowInfo *) crHashtableSearch(render_spu.windowTable, CR_RENDER_DEFAULT_WINDOW_ID);
    CRASSERT(windowInfo);
    windowInfo->mapPending = GL_TRUE;

    /*
     * Get the OpenGL extension functions.
     * SIGH -- we have to wait until the very bitter end to load the
     * extensions, because the context has to be bound before
     * wglGetProcAddress will work correctly.  No such issue with GLX though.
     */
    numFuncs += crLoadOpenGLExtensions( &render_spu.ws, _cr_render_table + numFuncs );
    CRASSERT(numFuncs < 1000);

#ifdef WINDOWS
    /*
     * Same problem as above, these are extensions so we need to
     * load them after a context has been bound. As they're WGL
     * extensions too, we can't simply tag them into the spu_loader.
     * So we do them here for now.
     * Grrr, NVIDIA driver uses EXT for GetExtensionsStringEXT,
     * but ARB for others. Need further testing here....
     */
    render_spu.ws.wglGetExtensionsStringEXT =
        (wglGetExtensionsStringEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetExtensionsStringEXT" );
    render_spu.ws.wglChoosePixelFormatEXT =
        (wglChoosePixelFormatEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglChoosePixelFormatARB" );
    render_spu.ws.wglGetPixelFormatAttribivEXT =
        (wglGetPixelFormatAttribivEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
    render_spu.ws.wglGetPixelFormatAttribfvEXT =
        (wglGetPixelFormatAttribfvEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribfvARB" );

    if (render_spu.ws.wglGetProcAddress("glCopyTexSubImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("CopyTexSubImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glCopyTexSubImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glCopyTexSubImage3D function");
    }

    if (render_spu.ws.wglGetProcAddress("glDrawRangeElements"))
    {
        _cr_render_table[numFuncs].name = crStrdup("DrawRangeElements");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glDrawRangeElements");
        ++numFuncs;
        crDebug("Render SPU: Found glDrawRangeElements function");
    }

    if (render_spu.ws.wglGetProcAddress("glTexSubImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("TexSubImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexSubImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glTexSubImage3D function");
    }

    if (render_spu.ws.wglGetProcAddress("glTexImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("TexImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glTexImage3D function");
    }

    if (render_spu.ws.wglGetExtensionsStringEXT) {
        crDebug("WGL - found wglGetExtensionsStringEXT\n");
    }
    if (render_spu.ws.wglChoosePixelFormatEXT) {
        crDebug("WGL - found wglChoosePixelFormatEXT\n");
    }
#endif

    render_spu.barrierHash = crAllocHashtable();

    render_spu.cursorX = 0;
    render_spu.cursorY = 0;
    render_spu.use_L2 = 0;

    render_spu.gather_conns = NULL;

    numFuncs = renderspu_SystemPostprocessFunctions(_cr_render_table, numFuncs, RT_ELEMENTS(_cr_render_table));

    crDebug("Render SPU: ---------- End of Init -------------");

    return &render_functions;
}
/**
 * Allocate a new ContextInfo object, initialize it, put it into the
 * context hash table.  If type==CHROMIUM, call the head SPU's
 * CreateContext() function too.
 */
    ContextInfo *
stubNewContext(char *dpyName, GLint visBits, ContextType type, unsigned long shareCtx
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        , struct VBOXUHGSMI *pHgsmi
#endif
    )
{
    GLint spuContext = -1, spuShareCtx = 0, spuConnection = 0;
    ContextInfo *context;

    if (shareCtx > 0) {
    /* translate shareCtx to a SPU context ID */
    context = (ContextInfo *)
        crHashtableSearch(stub.contextTable, shareCtx);
        if (context)
            spuShareCtx = context->spuContext;
    }

    if (type == CHROMIUM) {
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        if (pHgsmi)
        {
            spuConnection = stub.spu->dispatch_table.VBoxConCreate(pHgsmi);
            if (!spuConnection)
            {
                crWarning("VBoxConCreate failed");
                return NULL;
            }
        }
#endif
        spuContext
            = stub.spu->dispatch_table.VBoxCreateContext(spuConnection, dpyName, visBits, spuShareCtx);
        if (spuContext < 0)
        {
            crWarning("VBoxCreateContext failed");
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
            if (spuConnection)
                stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
#endif
            return NULL;
        }
    }

    context = crCalloc(sizeof(ContextInfo));
    if (!context) {
        stub.spu->dispatch_table.DestroyContext(spuContext);
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        if (spuConnection)
            stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
#endif
        return NULL;
    }

    if (!dpyName)
        dpyName = "";

    context->id = stub.freeContextNumber++;
    context->type = type;
    context->spuContext = spuContext;
    context->visBits = visBits;
    context->currentDrawable = NULL;
    crStrncpy(context->dpyName, dpyName, MAX_DPY_NAME);
    context->dpyName[MAX_DPY_NAME-1] = 0;

#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
    context->spuConnection = spuConnection;
    context->pHgsmi = pHgsmi;
#endif

#ifdef CHROMIUM_THREADSAFE
    VBoxTlsRefInit(context, stubContextDtor);
#endif

#if defined(GLX) || defined(DARWIN)
    context->share = (ContextInfo *)
        crHashtableSearch(stub.contextTable, (unsigned long) shareCtx);
#endif

#ifdef GLX
    context->pGLXPixmapsHash = crAllocHashtable();
    context->damageQueryFailed = GL_FALSE;
    context->damageEventsBase = 0;
#endif

    crHashtableAdd(stub.contextTable, context->id, (void *) context);

    return context;
}
/*
 * Begin compiling a list.
 */
void DLM_APIENTRY
crDLMNewList(GLuint listIdentifier, GLenum mode)
{
    DLMListInfo *listInfo;
    CRDLMContextState *listState = CURRENT_STATE();

    /* Error checks: 0 is not a valid identifier, and
     * we can't call NewList if NewList has been called
     * more recently than EndList.
     *
     * The caller is expected to check for an improper
     * mode parameter (GL_INVALID_ENUM), or for a NewList
     * within a glBegin/glEnd (GL_INVALID_OPERATION).
     */
    if (listState == NULL)
    {
	crWarning("DLM error: NewList(%d,%d) called with no current state (%s line %d)\n",
	    (int) listIdentifier, (int) mode, __FILE__, __LINE__);
	return;
    }

    if (listIdentifier == 0)
    {
	crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE,
	     "NewList called with a list identifier of 0");
	return;
    }

    if (listState->currentListInfo != NULL)
    {
	char msg[1000];
	sprintf(msg, "NewList called with display list %d while display list %d was already open",
	    (int) listIdentifier, (int) listState->currentListIdentifier);
	crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION, msg);
	return;
    }

    listInfo = (DLMListInfo *) crCalloc(sizeof(DLMListInfo));
    if (!(listInfo))
    {
	char msg[1000];
	sprintf(msg, "could not allocate %u bytes of memory in NewList",
	    (unsigned) sizeof(DLMListInfo));
	crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY, msg);									 
	return;
    }

    listInfo->first = listInfo->last = NULL;
    listInfo->stateFirst = listInfo->stateLast = NULL;
    listInfo->references = crAllocHashtable();
    if (!(listInfo->references))
    {
	crFree(listInfo);
	crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
	    "could not allocate memory in NewList");
	return;
    }
    listInfo->numInstances = 0;
    listInfo->listSent = GL_FALSE;
    listInfo->bbox.xmin = FLT_MAX;
    listInfo->bbox.xmax = -FLT_MAX;
    listInfo->bbox.ymin = FLT_MAX;
    listInfo->bbox.ymax = -FLT_MAX;
    listInfo->bbox.zmin = FLT_MAX;
    listInfo->bbox.zmax = -FLT_MAX;

    listState->currentListInfo = listInfo;
    listState->currentListIdentifier = listIdentifier;
    listState->currentListMode = mode;
}
Пример #11
0
/**
 * Do CRServer initializations.  After this, we can begin servicing clients.
 */
GLboolean crVBoxServerInit(void)
{
    CRMuralInfo *defaultMural;

#if DEBUG_FP_EXCEPTIONS
    {
        fpu_control_t mask;
        _FPU_GETCW(mask);
        mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
                            | _FPU_MASK_OM | _FPU_MASK_UM);
        _FPU_SETCW(mask);
    }
#endif

    crNetInit(crServerRecv, crServerClose);

    cr_server.firstCallCreateContext = GL_TRUE;
    cr_server.firstCallMakeCurrent = GL_TRUE;

    cr_server.bIsInLoadingState = GL_FALSE;
    cr_server.bIsInSavingState  = GL_FALSE;

    cr_server.pCleanupClient = NULL;

    /*
     * Create default mural info and hash table.
     */
    cr_server.muralTable = crAllocHashtable();
    defaultMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
    crHashtableAdd(cr_server.muralTable, 0, defaultMural);

    cr_server.programTable = crAllocHashtable();

    crStateInit();

    crStateLimitsInit( &(cr_server.limits) );

    cr_server.barriers = crAllocHashtable();
    cr_server.semaphores = crAllocHashtable();

    crUnpackSetReturnPointer( &(cr_server.return_ptr) );
    crUnpackSetWritebackPointer( &(cr_server.writeback_ptr) );

    /*
     * Default context
     */
    cr_server.contextTable = crAllocHashtable();
    cr_server.DummyContext = crStateCreateContext( &cr_server.limits,
                                                   CR_RGB_BIT | CR_DEPTH_BIT, NULL );
    cr_server.pContextCreateInfoTable = crAllocHashtable();
    cr_server.pWindowCreateInfoTable = crAllocHashtable();

    crServerSetVBoxConfigurationHGCM();

    if (!cr_server.head_spu)
        return GL_FALSE;

    crServerInitDispatch();
    crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );

    /*Check for PBO support*/
    if (crStateGetCurrent()->extensions.ARB_pixel_buffer_object)
    {
        cr_server.bUsePBOForReadback=GL_TRUE;
    }

    return GL_TRUE;
}
Пример #12
0
static SPUFunctions *
tilesortSPUInit( int id, SPU *child, SPU *self,
                 unsigned int context_id,
                 unsigned int num_contexts )
{
    ThreadInfo *thread0 = &(tilesort_spu.thread[0]);

    (void) context_id;
    (void) num_contexts;
    (void) child;
    (void) self;

#if DEBUG_FP_EXCEPTIONS
    {
        fpu_control_t mask;
        _FPU_GETCW(mask);
        mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
                  | _FPU_MASK_OM | _FPU_MASK_UM);
        _FPU_SETCW(mask);
    }
#endif

    crRandSeed(id);

    crMemZero( &tilesort_spu, sizeof(TileSortSPU) );

#ifdef CHROMIUM_THREADSAFE
    crInitTSD(&_ThreadTSD);
    crSetTSD(&_ThreadTSD, thread0);
    crInitMutex(&_TileSortMutex);
#endif

    thread0->state_server_index = -1;	 /* one-time init for thread */

    tilesortspuInitEvaluators();

    /* Init window, context hash tables */
    tilesort_spu.windowTable = crAllocHashtable();
    tilesort_spu.contextTable = crAllocHashtable();
    tilesort_spu.listTable = crAllocHashtable();

    tilesort_spu.id = id;
    tilesort_spu.glassesType = RED_BLUE;
    tilesortspuSetAnaglyphMask(&tilesort_spu);

    tilesortspuGatherConfiguration( child );
    tilesortspuConnectToServers(); /* set up thread0's server connection */

    tilesort_spu.geom_buffer_size = tilesort_spu.buffer_size;

    /* geom_buffer_mtu must fit in data's part of our buffers */
    tilesort_spu.geom_buffer_mtu = crPackMaxData(tilesort_spu.buffer_size)
                                   /* 24 is the size of the bounds info packet
                                    * END_FLUFF is the size of data of the extra End opcode if needed
                                    * 4 since BoundsInfo opcode may take a whole 4 bytes
                                    * and 4 to let room for extra End's opcode, if needed
                                    */
                                   - (24+END_FLUFF+4+4);

    /* the geometry must also fit in the mtu */
    if (tilesort_spu.geom_buffer_mtu >
            tilesort_spu.MTU - sizeof(CRMessageOpcodes) - (24+END_FLUFF+4+4))
        tilesort_spu.geom_buffer_mtu =
            tilesort_spu.MTU - sizeof(CRMessageOpcodes) - (24+END_FLUFF+4+4);

    tilesort_spu.swap = thread0->netServer[0].conn->swap;

    tilesortspuInitThreadPacking( thread0 );

    tilesortspuCreateFunctions();

    crStateInit();
    tilesortspuCreateDiffAPI();

    /* special dispatch tables for display lists */
    if (tilesort_spu.listTrack || tilesort_spu.lazySendDLists) {
        crMemZero((void *)&tilesort_spu.packerDispatch, sizeof tilesort_spu.packerDispatch);
        crSPUInitDispatchTable(&tilesort_spu.packerDispatch);
        tilesortspuLoadPackTable(&tilesort_spu.packerDispatch);

        crSPUInitDispatchTable(&tilesort_spu.stateDispatch);
        tilesortspuLoadStateTable(&tilesort_spu.stateDispatch);
    }

    if (tilesort_spu.useDMX) {
        /* load OpenGL */
        int n;
        crDebug("Tilesort SPU: Using DMX");
        n = crLoadOpenGL( &tilesort_spu.ws, NULL);
        if (!n) {
            crWarning("Tilesort SPU: Unable to load OpenGL, disabling DMX");
            tilesort_spu.useDMX = 0;
        }
    }
    else {
        crDebug("Tilesort SPU: Not using DMX");
    }

    crDebug("Tilesort SPU: ---------- End of Init -------------");

    return &tilesort_functions;
}