VirtualBox

Changeset 44860 in vbox for trunk/src/VBox/HostServices


Ignore:
Timestamp:
Feb 28, 2013 10:48:15 AM (12 years ago)
Author:
vboxsync
Message:

crOpenGL: redraw impl for X11/glx hosts; enable offscreen rendering for X11/glx hosts

Location:
trunk/src/VBox/HostServices/SharedOpenGL
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c

    r44766 r44860  
    167167            crWarning("invalid redir option %c", redir);
    168168    }
    169 #if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
     169#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    170170    else
    171171    {
     
    309309            crWarning("invalid redir option %c", redir);
    310310    }
    311 #if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
     311#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    312312    else
    313313    {
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c

    r44390 r44860  
    2828    GLboolean fFirst = GL_FALSE;
    2929
     30    dpyName = "";
     31
    3032    if (shareCtx > 0) {
    3133        crWarning("CRServer: context sharing not implemented.");
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r44818 r44860  
    9090    CRMuralInfo *mural;
    9191    GLint windowID = -1;
     92
     93    dpyName = "";
    9294
    9395    if (cr_server.sharedWindows) {
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c

    r44813 r44860  
    8080}
    8181
     82GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs)
     83{
     84    pVisInfo->displayName = crStrdup(displayName);
     85    pVisInfo->visAttribs = visAttribs;
     86    return renderspu_SystemInitVisual(pVisInfo);
     87}
    8288
    8389/*
     
    117123    /* create a new visual */
    118124    i = render_spu.numVisuals;
    119     render_spu.visuals[i].displayName = crStrdup(displayName);
    120     render_spu.visuals[i].visAttribs = visAttribs;
    121     if (renderspu_SystemInitVisual(&(render_spu.visuals[i]))) {
     125    if (renderspuInitVisual(&(render_spu.visuals[i]), displayName, visAttribs)) {
    122126        render_spu.numVisuals++;
    123127        return &(render_spu.visuals[i]);
     
    315319}
    316320
    317 
    318 /*
    319  * Window functions
    320  */
    321 
    322 GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
    323 {
    324     WindowInfo *window;
    325     VisualInfo *visual;
    326     GLboolean showIt;
    327 
    328     if (id <= 0)
    329     {
    330         id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
    331         if (id <= 0)
    332         {
    333             crWarning("failed to allocate window id");
    334             return -1;
    335         }
    336     }
    337     else
    338     {
    339         if (crHashtableIsKeyUsed(render_spu.windowTable, id))
    340         {
    341             crWarning("the specified window key %d is in use", id);
    342             return -1;
    343         }
    344     }
    345 
    346 
    347     if (!dpyName || crStrlen(render_spu.display_string) > 0)
    348         dpyName = render_spu.display_string;
    349 
    350     visual = renderspuFindVisual( dpyName, visBits );
    351     if (!visual)
    352     {
    353         crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
    354         return -1;
    355     }
    356 
    357     /* Allocate WindowInfo */
    358     window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
    359     if (!window)
    360     {
    361         crWarning( "Render SPU: Couldn't create a window" );
    362         return -1;
    363     }
    364 
     321GLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id )
     322{
    365323    RTCritSectInit(&window->CompositorLock);
    366324    window->pCompositor = NULL;
    367325
    368     crHashtableAdd(render_spu.windowTable, id, window);
    369326    window->BltInfo.Base.id = id;
    370327
     
    373330    window->BltInfo.width  = render_spu.defaultWidth;
    374331    window->BltInfo.height = render_spu.defaultHeight;
    375 
    376     if (render_spu.force_hidden_wdn_create
    377             || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
    378         showIt = 0;
    379     else
    380         showIt = window->BltInfo.Base.id != CR_RENDER_DEFAULT_WINDOW_ID;
    381332
    382333    /* Set window->title, replacing %i with the window ID number */
     
    399350        }
    400351    }
    401 
     352       
     353    window->BltInfo.Base.visualBits = visual->visAttribs;
     354   
     355   
    402356    /*
    403357    crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
     
    406360    if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window ))
    407361    {
     362        crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
     363        return GL_FALSE;
     364    }
     365
     366    CRASSERT(window->visual == visual);
     367    return GL_TRUE;
     368}
     369
     370/*
     371 * Window functions
     372 */
     373
     374GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
     375{
     376    WindowInfo *window;
     377    VisualInfo *visual;
     378    GLboolean showIt;
     379
     380    if (id <= 0)
     381    {
     382        id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
     383        if (id <= 0)
     384        {
     385            crWarning("failed to allocate window id");
     386            return -1;
     387        }
     388    }
     389    else
     390    {
     391        if (crHashtableIsKeyUsed(render_spu.windowTable, id))
     392        {
     393            crWarning("the specified window key %d is in use", id);
     394            return -1;
     395        }
     396    }
     397
     398
     399    if (!dpyName || crStrlen(render_spu.display_string) > 0)
     400        dpyName = render_spu.display_string;
     401
     402    visual = renderspuFindVisual( dpyName, visBits );
     403    if (!visual)
     404    {
     405        crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
     406        return -1;
     407    }
     408
     409    /* Allocate WindowInfo */
     410    window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
     411    if (!window)
     412    {
     413        crWarning( "Render SPU: Couldn't create a window" );
     414        return -1;
     415    }
     416   
     417    crHashtableAdd(render_spu.windowTable, id, window);
     418
     419    if (render_spu.force_hidden_wdn_create
     420            || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
     421        showIt = 0;
     422    else
     423        showIt = window->BltInfo.Base.id != CR_RENDER_DEFAULT_WINDOW_ID;
     424
     425
     426    /*
     427    crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
     428    */
     429    /* Have GLX/WGL/AGL create the window */
     430    if (!renderspuWindowInit( window, visual, showIt, id ))
     431    {
    408432        crFree(window);
    409433        crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
    410434        return -1;
    411435    }
    412 
    413     CRASSERT(window->visual == visual);
    414 
    415     window->BltInfo.Base.visualBits = visual->visAttribs;
    416 
     436   
    417437    return window->BltInfo.Base.id;
    418438}
     
    437457}
    438458
     459void renderspuWindowTerm( WindowInfo *window )
     460{
     461    GET_CONTEXT(pOldCtx);
     462    /* ensure no concurrent draws can take place */
     463    renderspuVBoxCompositorSet(window, NULL);
     464    renderspu_SystemDestroyWindow( window );
     465    RTCritSectDelete(&window->CompositorLock);
     466    /* check if this window is bound to some ctx. Note: window pointer is already freed here */
     467    crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
     468    /* restore current context */
     469    {
     470        GET_CONTEXT(pNewCtx);
     471        if (pNewCtx!=pOldCtx)
     472        {
     473            renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0,
     474                                     pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID);
     475        }
     476    }
     477}
     478
    439479void
    440480RENDER_APIENTRY renderspuWindowDestroy( GLint win )
    441481{
    442482    WindowInfo *window;
    443     GET_CONTEXT(pOldCtx);
    444483
    445484    CRASSERT(win >= 0);
     
    452491    if (window) {
    453492        crDebug("Render SPU: Destroy window (%d)", win);
    454         renderspu_SystemDestroyWindow( window );
    455 
    456         RTCritSectDelete(&window->CompositorLock);
    457         window->pCompositor = NULL;
     493        renderspuWindowTerm( window );
    458494
    459495        /* remove window info from hash table, and free it */
    460496        crHashtableDelete(render_spu.windowTable, win, crFree);
    461497
    462         /* check if this window is bound to some ctx. Note: window pointer is already freed here */
    463         crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
    464 
    465         /* restore current context */
    466         {
    467             GET_CONTEXT(pNewCtx);
    468             if (pNewCtx!=pOldCtx)
    469             {
    470                 renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0,
    471                                      pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID);
    472             }
    473         }
    474498    }
    475499    else {
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.h

    r44784 r44860  
    3232#include <iprt/cdefs.h>
    3333#include <iprt/critsect.h>
     34#if defined(GLX) /* @todo: unify windows and glx thread creation code */
     35#include <iprt/thread.h>
     36#include <iprt/semaphore.h>
     37
     38/* special window id used for representing the command window CRWindowInfo */
     39#define CR_RENDER_WINCMD_ID (INT32_MAX-2)
     40AssertCompile(CR_RENDER_WINCMD_ID != CR_RENDER_DEFAULT_WINDOW_ID);
     41/* CRHashTable is using unsigned long keys, we use it to trore X Window -> CRWindowInfo association */
     42AssertCompile(sizeof (Window) == sizeof (unsigned long));
     43#endif
     44
    3445
    3546#define MAX_VISUALS 32
     
    167178} Barrier;
    168179
     180#ifdef GLX
     181typedef enum
     182{
     183        CR_RENDER_WINCMD_TYPE_UNDEFINED = 0,
     184        /* create the window (not used for now) */
     185        CR_RENDER_WINCMD_TYPE_WIN_CREATE,
     186        /* destroy the window (not used for now) */
     187        CR_RENDER_WINCMD_TYPE_WIN_DESTROY,
     188        /* notify the WinCmd thread about window creation */
     189        CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE,
     190        /* notify the WinCmd thread about window destroy */
     191        CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY,
     192        /* nop used to synchronize with the WinCmd thread */
     193        CR_RENDER_WINCMD_TYPE_NOP,
     194        /* exit Win Cmd thread */
     195        CR_RENDER_WINCMD_TYPE_EXIT,
     196} CR_RENDER_WINCMD_TYPE;
     197
     198typedef struct CR_RENDER_WINCMD
     199{
     200    /* command type */
     201        CR_RENDER_WINCMD_TYPE enmCmd;
     202        /* command result */
     203        int rc;
     204        /* valid for WIN_CREATE & WIN_DESTROY only */
     205        WindowInfo *pWindow;
     206} CR_RENDER_WINCMD, *PCR_RENDER_WINCMD;
     207#endif
     208
    169209/**
    170210 * Renderspu state info
     
    243283                     GLsizei height );
    244284    void (*OSMesaDestroyContext)( OSMesaContext ctx );
     285#endif
     286
     287#if defined(GLX)
     288    RTTHREAD hWinCmdThread;
     289    VisualInfo WinCmdVisual;
     290    WindowInfo WinCmdWindow;
     291    RTSEMEVENT hWinCmdCompleteEvent;
     292    /* display connection used to send data to the WinCmd thread */
     293    Display *pCommunicationDisplay;
     294    Atom WinCmdAtom;
     295    /* X Window -> CRWindowInfo table */
     296    CRHashTable *pWinToInfoTable;
    245297#endif
    246298
     
    328380extern void renderspu_SystemSetRootVisibleRegion(GLint cRects, GLint *pRects);
    329381#endif
     382
     383#ifdef GLX
     384extern int renderspu_SystemInit();
     385extern int renderspu_SystemTerm();
     386#endif
    330387extern void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt );
    331388extern void renderspu_SystemMakeCurrent( WindowInfo *window, GLint windowInfor, ContextInfo *context );
     
    344401extern PCR_BLITTER renderspuVBoxPresentBlitterGetAndEnter( WindowInfo *window );
    345402extern PCR_BLITTER renderspuVBoxPresentBlitterEnsureCreated( WindowInfo *window );
     403extern void renderspuWindowTerm( WindowInfo *window );
     404extern GLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id );
     405extern GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs);
    346406extern void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter);
    347407extern void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY);
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c

    r44768 r44860  
    404404#endif /* GLX_VERSION_1_3 */
    405405
     406static const char * renderspuGetDisplayName()
     407{
     408    const char *dpyName;
     409
     410    if (render_spu.display_string[0])
     411        dpyName = render_spu.display_string;
     412    else
     413    {
     414        crWarning("Render SPU: no display..");
     415        dpyName = NULL;
     416    }
     417    return dpyName;
     418}
     419
     420static int renderspuWinCmdWinCreate(WindowInfo *pWindow)
     421{
     422    return VERR_NOT_IMPLEMENTED;
     423}
     424
     425static int renderspuWinCmdWinDestroy(WindowInfo *pWindow)
     426{
     427    return VERR_NOT_IMPLEMENTED;
     428}
     429
     430static int renderspuWinCmdInit()
     431{
     432    const char * dpyName;
     433    int rc = VERR_GENERAL_FAILURE;
     434   
     435    if (!crHashtableAllocRegisterKey(render_spu.windowTable, CR_RENDER_WINCMD_ID))
     436    {
     437        crError("CR_RENDER_WINCMD_ID %d is occupied already", CR_RENDER_WINCMD_ID);
     438        return VERR_INVALID_STATE;
     439    }
     440   
     441    render_spu.pWinToInfoTable = crAllocHashtable();
     442    if (render_spu.pWinToInfoTable)
     443    {
     444        dpyName = renderspuGetDisplayName();
     445        if (dpyName)
     446        {
     447            GLboolean bRc = renderspuInitVisual(&render_spu.WinCmdVisual, dpyName, render_spu.default_visual);
     448            if (bRc)
     449            {
     450                bRc = renderspuWindowInit(&render_spu.WinCmdWindow, &render_spu.WinCmdVisual, GL_FALSE, CR_RENDER_WINCMD_ID);
     451                if (bRc)
     452                {
     453                    XSelectInput(render_spu.WinCmdVisual.dpy, render_spu.WinCmdWindow.window, StructureNotifyMask);
     454                    render_spu.WinCmdAtom = XInternAtom(render_spu.WinCmdVisual.dpy, "VBoxWinCmd", False);
     455                    CRASSERT(render_spu.WinCmdAtom != None);
     456                    return VINF_SUCCESS;
     457                }
     458                else
     459                {
     460                    crError("renderspuWindowInit failed");
     461                }
     462                /* there is no visual destroy impl currently
     463                 * @todo: implement */
     464            }
     465            else
     466            {
     467                crError("renderspuInitVisual failed");
     468            }
     469        }
     470        else
     471        {
     472            crError("Render SPU: no display, aborting");
     473        }
     474        crFreeHashtable(render_spu.pWinToInfoTable, NULL);
     475        render_spu.pWinToInfoTable = NULL;
     476    }
     477    else
     478    {
     479        crError("crAllocHashtable failed");
     480    }
     481    return rc;
     482}
     483
     484static void renderspuWinCmdTerm()
     485{
     486    /* the window is not in the table, this will just ensure the key is freed */
     487    crHashtableDelete(render_spu.windowTable, CR_RENDER_WINCMD_ID, NULL);
     488    renderspuWindowTerm(&render_spu.WinCmdWindow);
     489    crFreeHashtable(render_spu.pWinToInfoTable, NULL);
     490    /* we do not have visual destroy functionality
     491     * @todo implement */
     492}
     493
     494
     495static bool renderspuWinCmdProcess(CR_RENDER_WINCMD* pWinCmd)
     496{
     497    bool fExit = false;
     498    /* process commands */
     499    switch (pWinCmd->enmCmd)
     500    {
     501        case CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE:
     502            crHashtableAdd(render_spu.pWinToInfoTable, pWinCmd->pWindow->window, pWinCmd->pWindow);
     503            XSelectInput(render_spu.WinCmdVisual.dpy, pWinCmd->pWindow->window, ExposureMask);
     504            pWinCmd->rc = VINF_SUCCESS;
     505            break;
     506        case CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY:
     507            crHashtableDelete(render_spu.pWinToInfoTable, pWinCmd->pWindow->window, NULL);
     508            pWinCmd->rc = VINF_SUCCESS;
     509            break;
     510        case CR_RENDER_WINCMD_TYPE_NOP:
     511            pWinCmd->rc = VINF_SUCCESS;
     512            break;
     513        case CR_RENDER_WINCMD_TYPE_EXIT:
     514            renderspuWinCmdTerm();
     515            pWinCmd->rc = VINF_SUCCESS;
     516            fExit = true;
     517            pWinCmd->rc = VINF_SUCCESS;
     518            break;
     519        case CR_RENDER_WINCMD_TYPE_WIN_CREATE:
     520            pWinCmd->rc = renderspuWinCmdWinCreate(pWinCmd->pWindow);
     521            break; 
     522        case CR_RENDER_WINCMD_TYPE_WIN_DESTROY:
     523            pWinCmd->rc = renderspuWinCmdWinDestroy(pWinCmd->pWindow);
     524            break;
     525        default:
     526            crError("unknown WinCmd command! %d", pWinCmd->enmCmd);
     527            pWinCmd->rc = VERR_INVALID_PARAMETER;
     528            break;
     529    }
     530
     531    RTSemEventSignal(render_spu.hWinCmdCompleteEvent);
     532    return fExit;
     533}
     534
     535static DECLCALLBACK(int) renderspuWinCmdThreadProc(RTTHREAD ThreadSelf, void *pvUser)
     536{
     537    int rc;
     538    bool fExit = false;
     539    crDebug("RenderSPU: Window thread started (%x)", crThreadID());
     540   
     541    rc = renderspuWinCmdInit();
     542
     543    /* notify the main cmd thread that we have started */
     544    RTSemEventSignal(render_spu.hWinCmdCompleteEvent);
     545   
     546    if (!RT_SUCCESS(rc))
     547    {
     548        CRASSERT(!render_spu.pWinToInfoTable);
     549        return rc;
     550    }
     551
     552    do
     553    {
     554        XEvent event;
     555        XNextEvent(render_spu.WinCmdVisual.dpy, &event);
     556       
     557        switch (event.type)
     558        {
     559            case ClientMessage:
     560            {
     561                CRASSERT(event.xclient.window == render_spu.WinCmdWindow.window);
     562                if (event.xclient.window == render_spu.WinCmdWindow.window)
     563                {
     564                    if (render_spu.WinCmdAtom == event.xclient.message_type)
     565                    {
     566                        CR_RENDER_WINCMD *pWinCmd;
     567                        memcpy(&pWinCmd, event.xclient.data.b, sizeof (pWinCmd));
     568                        fExit = renderspuWinCmdProcess(pWinCmd);
     569                    }
     570                }
     571               
     572                break;
     573            }
     574            case Expose:
     575            {
     576                if (!event.xexpose.count)
     577                {   
     578                    WindowInfo *pWindow = (WindowInfo*)crHashtableSearch(render_spu.pWinToInfoTable, event.xexpose.window);
     579                    if (pWindow)
     580                    {
     581                        struct VBOXVR_SCR_COMPOSITOR * pCompositor;
     582
     583                        pCompositor = renderspuVBoxCompositorAcquire(pWindow);
     584                        if (pCompositor)
     585                        {
     586                            renderspuVBoxPresentCompositionGeneric(pWindow, pCompositor, NULL);
     587                            renderspuVBoxCompositorRelease(pWindow);
     588                        }
     589                    }
     590                }
     591                break;
     592            }
     593            default:
     594                break;
     595        }
     596    } while (!fExit);
     597
     598    return 0;
     599}
     600
     601static int renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE enmCmd, WindowInfo *pWindow)
     602{
     603    Status status;
     604    XEvent event;
     605    CR_RENDER_WINCMD WinCmd, *pWinCmd;
     606    int rc;
     607   
     608    pWinCmd = &WinCmd;
     609    pWinCmd->enmCmd = enmCmd;
     610    pWinCmd->rc = VERR_GENERAL_FAILURE;
     611    pWinCmd->pWindow = pWindow;
     612   
     613    memset(&event, 0, sizeof (event));
     614    event.type = ClientMessage;
     615    event.xclient.window = render_spu.WinCmdWindow.window;
     616    event.xclient.message_type = render_spu.WinCmdAtom;
     617    event.xclient.format = 8;
     618    memcpy(event.xclient.data.b, &pWinCmd, sizeof (pWinCmd));
     619   
     620    status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, StructureNotifyMask, &event);
     621    if (!status)
     622    {
     623        Assert(0);
     624        crWarning("XSendEvent returned null");
     625        return VERR_GENERAL_FAILURE;
     626    }
     627   
     628    XFlush(render_spu.pCommunicationDisplay);
     629    rc = RTSemEventWaitNoResume(render_spu.hWinCmdCompleteEvent, RT_INDEFINITE_WAIT);
     630    if (!RT_SUCCESS(rc))
     631    {
     632        crWarning("RTSemEventWaitNoResume failed rc %d", rc);
     633        return rc;
     634    }
     635    return pWinCmd->rc;
     636}
     637
     638int renderspu_SystemInit()
     639{
     640    const char * dpyName;
     641    int rc = VERR_GENERAL_FAILURE;
     642   
     643    if (!render_spu.use_glxchoosevisual) {
     644        /* sometimes want to set this option with ATI drivers */
     645        render_spu.ws.glXChooseVisual = NULL;
     646    }
     647
     648    /* enable multi-threading */
     649    XInitThreads();
     650
     651    /* setup communication display connection */
     652    dpyName = renderspuGetDisplayName();
     653    if (!dpyName)
     654    {
     655        crWarning("no display name, aborting");
     656        return VERR_GENERAL_FAILURE;
     657    }
     658   
     659    render_spu.pCommunicationDisplay = XOpenDisplay(dpyName);
     660    if (!render_spu.pCommunicationDisplay)
     661    {
     662        crWarning( "Couldn't open X display named '%s'", dpyName );
     663        return VERR_GENERAL_FAILURE;
     664    }
     665
     666    if ( !render_spu.ws.glXQueryExtension( render_spu.pCommunicationDisplay, NULL, NULL ) )
     667    {
     668        crWarning( "Render SPU: Display %s doesn't support GLX", dpyName );
     669        return VERR_GENERAL_FAILURE;
     670    }
     671
     672    rc = RTSemEventCreate(&render_spu.hWinCmdCompleteEvent);
     673    if (RT_SUCCESS(rc))
     674    {
     675        rc = RTThreadCreate(&render_spu.hWinCmdThread, renderspuWinCmdThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxCrWinCmd");
     676        if (RT_SUCCESS(rc))
     677        {
     678            rc = RTSemEventWait(render_spu.hWinCmdCompleteEvent, RT_INDEFINITE_WAIT);
     679            if (RT_SUCCESS(rc))
     680            {
     681                return VINF_SUCCESS;
     682            }
     683            else
     684            {
     685                crWarning("RTSemEventWait failed rc %d", rc);
     686            }
     687
     688            RTThreadWait(render_spu.hWinCmdThread, RT_INDEFINITE_WAIT, NULL);
     689        }
     690        else
     691        {
     692            crWarning("RTThreadCreate failed rc %d", rc);
     693        }
     694        RTSemEventDestroy(render_spu.hWinCmdCompleteEvent);
     695    }
     696    else
     697    {
     698        crWarning("RTSemEventCreate failed rc %d", rc);
     699    }
     700   
     701    return rc;
     702}
     703
     704int renderspu_SystemTerm()
     705{
     706        int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_EXIT, NULL);
     707        if (!RT_SUCCESS(rc))
     708        {
     709            crWarning("renderspuWinCmdSubmit EXIT failed rc %d", rc);
     710            return rc;
     711        }
     712
     713        RTThreadWait(render_spu.hWinCmdThread, RT_INDEFINITE_WAIT, NULL);
     714        RTSemEventDestroy(render_spu.hWinCmdCompleteEvent);
     715        return VINF_SUCCESS;
     716}
    406717
    407718GLboolean
     
    421732#endif
    422733   
    423     if (render_spu.display_string[0])
    424         dpyName = render_spu.display_string;
    425     else if (visual->displayName[0])
    426         dpyName = visual->displayName;
    427     else
    428         dpyName = NULL;
    429 
     734    dpyName = renderspuGetDisplayName();
    430735    if (!dpyName)
    431736    {
     
    433738        return GL_FALSE;
    434739    }
     740
    435741
    436742    crInfo("Render SPU: Opening display %s", dpyName);
     
    8501156
    8511157    XSync(dpy, 0);
     1158   
     1159    if (window->BltInfo.Base.id != CR_RENDER_WINCMD_ID)
     1160    {
     1161        int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE, window);
     1162        AssertRC(rc);
     1163    }
    8521164
    8531165    return GL_TRUE;
     
    9411253             */
    9421254            if (!window->nativeWindow) {
     1255                if (window->BltInfo.Base.id != CR_RENDER_WINCMD_ID)
     1256                {
     1257                    int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY, window);
     1258                    AssertRC(rc);
     1259                }
    9431260                XDestroyWindow(window->visual->dpy, window->window);
    9441261                XSync(window->visual->dpy, 0);
     
    16391956void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    16401957{
    1641     renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry);
     1958    /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
     1959     * here it forces rendering in WinCmd thread rather than a Main thread.
     1960     * it is used for debugging only in any way actually.
     1961     * @todo: change to some more generic macro name */
     1962#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
     1963    struct VBOXVR_SCR_COMPOSITOR *pCurCompositor;
     1964    /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
     1965    int rc = renderspuVBoxCompositorTryAcquire(window, &pCurCompositor);
     1966    if (RT_SUCCESS(rc))
     1967    {
     1968        Assert(pCurCompositor == pCompositor);
     1969        renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry);
     1970        renderspuVBoxCompositorRelease(window);
     1971    }
     1972    else if (rc == VERR_SEM_BUSY)
     1973#endif
     1974    {
     1975        Status status;
     1976        XEvent event;
     1977        render_spu.self.Flush();
     1978        renderspuVBoxPresentBlitterEnsureCreated(window);
     1979
     1980        crMemset(&event, 0, sizeof (event));
     1981        event.type = Expose;
     1982        event.xexpose.window = window->window;
     1983        event.xexpose.width = window->BltInfo.width;
     1984        event.xexpose.height = window->BltInfo.height;
     1985        status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, 0, &event);
     1986        if (!status)
     1987        {
     1988            Assert(0);
     1989            crWarning("XSendEvent returned null");
     1990        }
     1991        XFlush(render_spu.pCommunicationDisplay);
     1992    }
     1993#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
     1994    else
     1995    {
     1996        /* this is somewhat we do not expect */
     1997        crWarning("renderspuVBoxCompositorTryAcquire failed rc %d", rc);
     1998    }
     1999#endif
    16422000}
    16432001
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c

    r44766 r44860  
    192192    numFuncs += numSpecial;
    193193
    194 #ifdef GLX
    195     if (!render_spu.use_glxchoosevisual) {
    196         /* sometimes want to set this option with ATI drivers */
    197         render_spu.ws.glXChooseVisual = NULL;
    198     }
    199 #endif
    200 
    201194    render_spu.contextTable = crAllocHashtableEx(1, INT32_MAX);
    202195    render_spu.windowTable = crAllocHashtableEx(1, INT32_MAX);
     
    227220
    228221    CRASSERT(render_spu.default_visual & CR_RGB_BIT);
     222   
     223#ifdef GLX
     224    {
     225        int rc = renderspu_SystemInit();
     226        if (!RT_SUCCESS(rc))
     227        {
     228            crError("renderspu_SystemInit failed rc %d", rc);
     229            return NULL;
     230        }
     231    }
     232#endif
    229233
    230234#ifdef USE_OSMESA
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c

    r44813 r44860  
    12471247void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    12481248{
     1249    /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
     1250     * here it forces rendering in WinCmd thread rather than a Main thread.
     1251     * it is used for debugging only in any way actually.
     1252     * @todo: change to some more generic macro name */
     1253#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
    12491254    struct VBOXVR_SCR_COMPOSITOR *pCurCompositor;
    12501255    /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
     
    12571262    }
    12581263    else if (rc == VERR_SEM_BUSY)
     1264#endif
    12591265    {
    12601266        render_spu.self.Flush();
     
    12621268        RedrawWindow(window->hWnd, NULL, NULL, RDW_INTERNALPAINT);
    12631269    }
     1270#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
    12641271    else
    12651272    {
     
    12671274        crWarning("renderspuVBoxCompositorTryAcquire failed rc %d", rc);
    12681275    }
     1276#endif
    12691277}
    12701278
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette