Exemplo n.º 1
0
GLboolean
stubMakeCurrent( WindowInfo *window, ContextInfo *context )
{
	GLboolean retVal;

	/*
	 * Get WindowInfo and ContextInfo pointers.
	 */

	if (!context || !window) {
		if (stub.currentContext)
			stub.currentContext->currentDrawable = NULL;
		if (context)
			context->currentDrawable = NULL;
		stub.currentContext = 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)) {
			/*
			 * Create a Chromium context.
			 */
#if defined(GLX) || defined(DARWIN)
			GLint spuShareCtx = context->share ? context->share->spuContext : 0;
#else
      GLint spuShareCtx = 0;
#endif

			CRASSERT(stub.spu);
			CRASSERT(stub.spu->dispatch_table.CreateContext);
			context->type = CHROMIUM;

			context->spuContext
				= stub.spu->dispatch_table.CreateContext( context->dpyName,
																									context->visBits,
																									spuShareCtx );
			if (window->spuWindow == -1)
				window->spuWindow = stub.spu->dispatch_table.WindowCreate( window->dpyName, context->visBits );
		}
		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)
			crWarning("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)
				window->spuWindow = stub.spu->dispatch_table.WindowCreate( window->dpyName, context->visBits );

			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;
	context->currentDrawable = window;
	stub.currentContext = 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 (stub.trackWindowSize)
			stub.spuDispatch.WindowSize( window->spuWindow, winW, winH );
		if (winW > 0 && winH > 0)
			stub.spu->dispatch_table.Viewport( 0, 0, winW, winH );
	}

	/* Update window mapping state.
	 * Basically, this lets us hide render SPU windows which correspond
	 * to unmapped application windows.  Without this, perfly (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) {
			stub.spu->dispatch_table.WindowShow(window->spuWindow, mapped);
			window->mapped = mapped;
		}
	}

	return retVal;
}
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;
}