void
stubDestroyContext( unsigned long contextId )
{
    ContextInfo *context;

    if (!stub.contextTable) {
        return;
    }

    /* the lock order is windowTable->contextTable (see wglMakeCurrent_prox, glXMakeCurrent)
     * this is why we need to take a windowTable lock since we will later do stub.windowTable access & locking */
    crHashtableLock(stub.windowTable);
    crHashtableLock(stub.contextTable);

    context = (ContextInfo *) crHashtableSearch(stub.contextTable, contextId);
    if (context)
        stubDestroyContextLocked(context);
    else
        crError("No context.");

#ifdef CHROMIUM_THREADSAFE
    if (stubGetCurrentContext() == context) {
        stubSetCurrentContext(NULL);
    }

    VBoxTlsRefMarkDestroy(context);
    VBoxTlsRefRelease(context);
#else
    if (stubGetCurrentContext() == context) {
        stubSetCurrentContext(NULL);
    }
    stubContextFree(context);
#endif
    crHashtableUnlock(stub.contextTable);
    crHashtableUnlock(stub.windowTable);
}
Пример #2
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
}
Пример #3
0
/* Windows crap */
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
    (void) lpvReserved;

    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        CRNetServer ns;

#ifdef CHROMIUM_THREADSAFE
        crInitTSD(&g_stubCurrentContextTSD);
#endif

        crInitMutex(&stub_init_mutex);

#ifdef VDBG_VEHANDLER
        vboxVDbgVEHandlerRegister();
#endif

        crNetInit(NULL, NULL);
        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
);
        if (!ns.conn)
        {
            crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
#ifdef VDBG_VEHANDLER
            vboxVDbgVEHandlerUnregister();
#endif
            return FALSE;
        }
        else
            crNetFreeConnection(ns.conn);

        break;
    }

    case DLL_PROCESS_DETACH:
    {
        /* do exactly the same thing as for DLL_THREAD_DETACH since
         * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }

        stubSPUSafeTearDown();

#ifdef CHROMIUM_THREADSAFE
        crFreeTSD(&g_stubCurrentContextTSD);
#endif

#ifdef VDBG_VEHANDLER
        vboxVDbgVEHandlerUnregister();
#endif
        break;
    }

    case DLL_THREAD_ATTACH:
    {
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxAttachThread();
        }
        break;
    }

    case DLL_THREAD_DETACH:
    {
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }
        break;
    }

    default:
        break;
    }

    return TRUE;
}
GLboolean
stubMakeCurrent( WindowInfo *window, ContextInfo *context )
{
    GLboolean retVal;

    /*
     * Get WindowInfo and ContextInfo pointers.
     */

    if (!context || !window) {
        ContextInfo * currentContext = stubGetCurrentContext();
        if (currentContext)
            currentContext->currentDrawable = NULL;
        if (context)
            context->currentDrawable = NULL;
        stubSetCurrentContext(NULL);
        return GL_TRUE;  /* OK */
    }

#ifdef CHROMIUM_THREADSAFE
    stubCheckMultithread();
#endif

    if (context->type == UNDECIDED) {
        /* Here's where we really create contexts */
#ifdef CHROMIUM_THREADSAFE
        crLockMutex(&stub.mutex);
#endif

        if (stubCheckUseChromium(window)) {
            GLint spuConnection = 0;

            if (!stubCtxCreate(context))
            {
                crWarning("stubCtxCreate failed");
                return GL_FALSE;
            }

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

            if (window->spuWindow == -1)
            {
                /*crDebug("(1)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/
                window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(spuConnection, window->dpyName, context->visBits );
#ifdef CR_NEWWINTRACK
                window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(spuConnection);
#endif
            }
        }
        else {
            /*
             * Create a native OpenGL context.
             */
            if (!InstantiateNativeContext(window, context))
            {
#ifdef CHROMIUM_THREADSAFE
                crUnlockMutex(&stub.mutex);
#endif
                return 0; /* false */
            }
            context->type = NATIVE;
        }

#ifdef CHROMIUM_THREADSAFE
        crUnlockMutex(&stub.mutex);
#endif
    }


    if (context->type == NATIVE) {
        /*
         * Native OpenGL MakeCurrent().
         */
#ifdef WINDOWS
        retVal = (GLboolean) stub.wsInterface.wglMakeCurrent( window->drawable, context->hglrc );
#elif defined(Darwin)
        // XXX \todo We need to differentiate between these two..
        retVal = ( stub.wsInterface.CGLSetSurface(context->cglc, window->connection, window->drawable, window->surface) == noErr );
        retVal = ( stub.wsInterface.CGLSetCurrentContext(context->cglc) == noErr );
#elif defined(GLX)
        retVal = (GLboolean) stub.wsInterface.glXMakeCurrent( window->dpy, window->drawable, context->glxContext );
#endif
    }
    else {
        /*
         * SPU chain MakeCurrent().
         */
        CRASSERT(context->type == CHROMIUM);
        CRASSERT(context->spuContext >= 0);

        /*if (context->currentDrawable && context->currentDrawable != window)
            crDebug("Rebinding context %p to a different window", context);*/

        if (window->type == NATIVE) {
            crWarning("Can't rebind a chromium context to a native window\n");
            retVal = 0;
        }
        else {
            if (window->spuWindow == -1)
            {
                /*crDebug("(2)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/
                window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                        context->spuConnection,
#else
                        0,
#endif
                        window->dpyName, context->visBits );
#ifdef CR_NEWWINTRACK
                window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(
# if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                        context->spuConnection
# else
                        0
# endif
                        );
#endif
                if (context->currentDrawable && context->currentDrawable->type==CHROMIUM 
                    && context->currentDrawable->pOwner==context)
                {
#ifdef WINDOWS
                        if (context->currentDrawable->hWnd!=WindowFromDC(context->currentDrawable->drawable))
                        {
                            stubDestroyWindow(CR_CTX_CON(context), (GLint)context->currentDrawable->hWnd);
                        }
#else
                        Window root;
                        int x, y;
                        unsigned int border, depth, w, h;

                        XLOCK(context->currentDrawable->dpy);
                        if (!XGetGeometry(context->currentDrawable->dpy, context->currentDrawable->drawable, &root, &x, &y, &w, &h, &border, &depth))
                        {
                            stubDestroyWindow(CR_CTX_CON(context), (GLint)context->currentDrawable->drawable);
                        }
                        XUNLOCK(context->currentDrawable->dpy);
#endif
                    
                }
            }

            if (window->spuWindow != (GLint)window->drawable)
                 stub.spu->dispatch_table.MakeCurrent( window->spuWindow, (GLint) window->drawable, context->spuContext );
            else
                 stub.spu->dispatch_table.MakeCurrent( window->spuWindow, 0, /* native window handle */ context->spuContext );

            retVal = 1;
        }
    }

    window->type = context->type;
    window->pOwner = context;
    context->currentDrawable = window;
    stubSetCurrentContext(context);

    if (retVal) {
        /* Now, if we've transitions from Chromium to native rendering, or
         * vice versa, we have to change all the OpenGL entrypoint pointers.
         */
        if (context->type == NATIVE) {
            /* Switch to native API */
            /*printf("  Switching to native API\n");*/
            stubSetDispatch(&stub.nativeDispatch);
        }
        else if (context->type == CHROMIUM) {
            /* Switch to stub (SPU) API */
            /*printf("  Switching to spu API\n");*/
            stubSetDispatch(&stub.spuDispatch);
        }
        else {
            /* no API switch needed */
        }
    }

    if (!window->width && window->type == CHROMIUM) {
        /* One time window setup */
        int x, y;
        unsigned int winW, winH;

        stubGetWindowGeometry( window, &x, &y, &winW, &winH );

        /* If we're not using GLX/WGL (no app window) we'll always get
         * a width and height of zero here.  In that case, skip the viewport
         * call since we're probably using a tilesort SPU with fake_window_dims
         * which the tilesort SPU will use for the viewport.
         */
        window->width = winW;
        window->height = winH;
#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
        if (stubIsWindowVisible(window))
#endif
        {
            if (stub.trackWindowSize)
                stub.spuDispatch.WindowSize( window->spuWindow, winW, winH );
            if (stub.trackWindowPos)
                stub.spuDispatch.WindowPosition(window->spuWindow, x, y);
            if (winW > 0 && winH > 0)
                stub.spu->dispatch_table.Viewport( 0, 0, winW, winH );
        }
#ifdef VBOX_WITH_WDDM
        if (stub.trackWindowVisibleRgn)
            stub.spu->dispatch_table.WindowVisibleRegion(window->spuWindow, 0, NULL);
#endif
    }

    /* Update window mapping state.
     * Basically, this lets us hide render SPU windows which correspond
     * to unmapped application windows.  Without this, "pertly" (for example)
     * opens *lots* of temporary windows which otherwise clutter the screen.
     */
    if (stub.trackWindowVisibility && window->type == CHROMIUM && window->drawable) {
        const int mapped = stubIsWindowVisible(window);
        if (mapped != window->mapped) {
            crDebug("Dispatched: WindowShow(%i, %i)", window->spuWindow, mapped);
            stub.spu->dispatch_table.WindowShow(window->spuWindow, mapped);
            window->mapped = mapped;
        }
    }

    return retVal;
}
Пример #5
0
/* Windows crap */
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
    (void) lpvReserved;

    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        CRNetServer ns;
        const char * env;
#if defined(DEBUG_misha)
        HMODULE hCrUtil;
        char aName[MAX_PATH];

        GetModuleFileNameA(hDLLInst, aName, RT_ELEMENTS(aName));
        crDbgCmdSymLoadPrint(aName, hDLLInst);

        hCrUtil = GetModuleHandleA("VBoxOGLcrutil.dll");
        Assert(hCrUtil);
        crDbgCmdSymLoadPrint("VBoxOGLcrutil.dll", hCrUtil);
#endif
#ifdef CHROMIUM_THREADSAFE
        crInitTSD(&g_stubCurrentContextTSD);
#endif

        crInitMutex(&stub_init_mutex);

#ifdef VDBG_VEHANDLER
        env = crGetenv("CR_DBG_VEH_ENABLE");
        g_VBoxVehEnable = crStrParseI32(env,
# ifdef DEBUG_misha
                1
# else
                0
# endif
                );

        if (g_VBoxVehEnable)
        {
            char procName[1024];
            size_t cProcName;
            size_t cChars;

            env = crGetenv("CR_DBG_VEH_FLAGS");
            g_VBoxVehFlags = crStrParseI32(env,
                    0
# ifdef DEBUG_misha
                    | VBOXVEH_F_BREAK
# else
                    | VBOXVEH_F_DUMP
# endif
                    );

            env = crGetenv("CR_DBG_VEH_DUMP_DIR");
            if (!env)
                env = VBOXMD_DUMP_DIR_DEFAULT;

            g_cVBoxMdFilePrefixLen = strlen(env);

            if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) <= g_cVBoxMdFilePrefixLen + 26 + (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR))
            {
                g_cVBoxMdFilePrefixLen = 0;
                env = "";
            }

            mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix, g_cVBoxMdFilePrefixLen + 1, env, _TRUNCATE);

            Assert(cChars == g_cVBoxMdFilePrefixLen + 1);

            g_cVBoxMdFilePrefixLen = cChars - 1;

            if (g_cVBoxMdFilePrefixLen && g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen - 1] != L'\\')
                g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'\\';

            memcpy(g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, VBOXMD_DUMP_NAME_PREFIX_W, sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR));
            g_cVBoxMdFilePrefixLen += (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR);

            crGetProcName(procName, RT_ELEMENTS(procName));
            cProcName = strlen(procName);

            if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) > g_cVBoxMdFilePrefixLen + cProcName + 1 + 26)
            {
                mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, cProcName + 1, procName, _TRUNCATE);
                Assert(cChars == cProcName + 1);
                g_cVBoxMdFilePrefixLen += cChars - 1;
                g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'_';
            }

            /* sanity */
            g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen] = L'\0';

            env = crGetenv("CR_DBG_VEH_DUMP_TYPE");

            g_enmVBoxMdDumpType = crStrParseI32(env,
                    MiniDumpNormal
                    | MiniDumpWithDataSegs
                    | MiniDumpWithFullMemory
                    | MiniDumpWithHandleData
            ////        | MiniDumpFilterMemory
            ////        | MiniDumpScanMemory
            //        | MiniDumpWithUnloadedModules
            ////        | MiniDumpWithIndirectlyReferencedMemory
            ////        | MiniDumpFilterModulePaths
            //        | MiniDumpWithProcessThreadData
            //        | MiniDumpWithPrivateReadWriteMemory
            ////        | MiniDumpWithoutOptionalData
            //        | MiniDumpWithFullMemoryInfo
            //        | MiniDumpWithThreadInfo
            //        | MiniDumpWithCodeSegs
            //        | MiniDumpWithFullAuxiliaryState
            //        | MiniDumpWithPrivateWriteCopyMemory
            //        | MiniDumpIgnoreInaccessibleMemory
            //        | MiniDumpWithTokenInformation
            ////        | MiniDumpWithModuleHeaders
            ////        | MiniDumpFilterTriage
                    );

            vboxVDbgVEHandlerRegister();
        }
#endif

        crNetInit(NULL, NULL);
        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
);
        if (!ns.conn)
        {
            crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
#ifdef VDBG_VEHANDLER
            if (g_VBoxVehEnable)
                vboxVDbgVEHandlerUnregister();
#endif
            return FALSE;
        }
        else
        {
            crNetFreeConnection(ns.conn);
        }

#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        VBoxCrHgsmiInit();
#endif
        break;
    }

    case DLL_PROCESS_DETACH:
    {
        /* do exactly the same thing as for DLL_THREAD_DETACH since
         * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }

        
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        VBoxCrHgsmiTerm();
#endif

        stubSPUSafeTearDown();

#ifdef CHROMIUM_THREADSAFE
        crFreeTSD(&g_stubCurrentContextTSD);
#endif

#ifdef VDBG_VEHANDLER
        if (g_VBoxVehEnable)
            vboxVDbgVEHandlerUnregister();
#endif
        break;
    }

    case DLL_THREAD_ATTACH:
    {
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxAttachThread();
        }
        break;
    }

    case DLL_THREAD_DETACH:
    {
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }
        break;
    }

    default:
        break;
    }

    return TRUE;
}