VirtualBox

Changeset 44290 in vbox for trunk/src


Ignore:
Timestamp:
Jan 14, 2013 9:49:11 PM (12 years ago)
Author:
vboxsync
Message:

crOpenGL: saved state fixes & improvements

Location:
trunk/src/VBox
Files:
1 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h

    r44196 r44290  
    5858# define CR_STATE_SHAREDOBJ_USAGE_INIT(_pObj) (crMemset((_pObj)->ctxUsage, 0, sizeof ((_pObj)->ctxUsage)))
    5959# define CR_STATE_SHAREDOBJ_USAGE_SET(_pObj, _pCtx) (ASMBitSet((_pObj)->ctxUsage, (_pCtx)->id))
     60# define CR_STATE_SHAREDOBJ_USAGE_IS_SET(_pObj, _pCtx) (ASMBitTest((_pObj)->ctxUsage, (_pCtx)->id))
    6061# define CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(_pObj, _i) (ASMBitClear((_pObj)->ctxUsage, (_i)))
    6162# define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) (CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX((_pObj), (_pCtx)->id))
     
    6667# define CR_STATE_SHAREDOBJ_USAGE_INIT(_pObj) do {} while (0)
    6768# define CR_STATE_SHAREDOBJ_USAGE_SET(_pObj, _pCtx) do {} while (0)
     69# define CR_STATE_SHAREDOBJ_USAGE_IS_SET(_pObj, _pCtx) (false)
    6870# define CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(_pObj, _i) do {} while (0)
    6971# define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) do {} while (0)
     
    244246DECLEXPORT(void) crStateSwitchContext( CRContext *from, CRContext *to );
    245247DECLEXPORT(void) crStateApplyFBImage(CRContext *to);
     248DECLEXPORT(int) crStateAcquireFBImage(CRContext *to);
     249DECLEXPORT(void) crStateFreeFBImage(CRContext *to);
     250
     251DECLEXPORT(void) crStateGetTextureObjectAndImage(CRContext *g, GLenum texTarget, GLint level,
     252                                     CRTextureObj **obj, CRTextureLevel **img);
     253
    246254
    247255#ifndef IN_GUEST
     
    251259DECLEXPORT(int32_t) crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PFNCRSTATE_CONTEXT_GET pfnCtxGet, PSSMHANDLE pSSM, uint32_t u32Version);
    252260DECLEXPORT(void) crStateFreeShared(CRContext *pContext, CRSharedState *s);
     261
     262DECLEXPORT(int32_t) crStateLoadGlobals(PSSMHANDLE pSSM, uint32_t u32Version);
     263DECLEXPORT(int32_t) crStateSaveGlobals(PSSMHANDLE pSSM);
    253264#endif
    254265
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_hash.h

    r44127 r44290  
    1616#endif
    1717
     18typedef struct CRHashIdPool CRHashIdPool;
    1819typedef struct CRHashTable CRHashTable;
    1920
     
    2223/* Callback function used for walking through table entries */
    2324typedef void (*CRHashtableWalkCallback)(unsigned long key, void *data1, void *data2);
     25
     26DECLEXPORT(CRHashIdPool *) crAllocHashIdPool( void );
     27DECLEXPORT(void) crFreeHashIdPool( CRHashIdPool *pool );
     28DECLEXPORT(GLboolean) crHashIdPoolIsIdFree( const CRHashIdPool *pool, GLuint id );
     29DECLEXPORT(GLuint) crHashIdPoolAllocBlock( CRHashIdPool *pool, GLuint count );
     30DECLEXPORT(void) crHashIdPoolFreeBlock( CRHashIdPool *pool, GLuint first, GLuint count );
     31DECLEXPORT(GLboolean) crHashIdPoolAllocId( CRHashIdPool *pool, GLuint id );
    2432
    2533DECLEXPORT(CRHashTable *) crAllocHashtable( void );
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r43980 r44290  
    123123    GLuint fboWidth, fboHeight;
    124124    GLuint idPBO;
     125
     126    /* bitfield representing contexts the mural has been ever current with
     127     * we just reuse CR_STATE_SHAREDOBJ_USAGE_XXX API here for simplicity */
     128    CRbitvalue             ctxUsage[CR_MAX_BITARRAY];
    125129} CRMuralInfo;
    126130
     
    129133    int SpuContext;
    130134    CRCreateInfo_t CreateInfo;
     135    CRMuralInfo * currentMural;
    131136} CRContextInfo;
    132137
     
    375380/* */
    376381
     382/* helpers */
     383
     384void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData);
     385void* CrHlpGetTexImage(CRContext *pCurCtx, PCR_BLITTER_TEXTURE pTexture, GLuint idPBO);
     386
     387/* */
    377388
    378389typedef struct {
     
    403414    int client_spu_id;
    404415
    405     CRServerFreeIDsPool_t idsPool;
    406 
    407416    int mtu;
    408417    int buffer_size;
     
    423432    CRHashTable *programTable;  /**< for vertex programs */
    424433    GLuint currentProgram;
     434
     435    /* visBits -> dummy mural association */
     436    CRHashTable *dummyMuralTable;
    425437
    426438    /** configuration options */
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h

    r44196 r44290  
    1616/* version with invalid glGetError state */
    1717#define SHCROGL_SSM_VERSION_WITH_INVALID_ERROR_STATE   30
    18 #define SHCROGL_SSM_VERSION                            31
     18/* the saved state has incorrect front and back buffer image data */
     19#define SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA   31
     20#define SHCROGL_SSM_VERSION_WITH_STATE_BITS            33
     21#define SHCROGL_SSM_VERSION_WITH_WINDOW_CTX_USAGE      33
     22#define SHCROGL_SSM_VERSION                            33
    1923
    2024/* These define the Chromium release number.
  • trunk/src/VBox/GuestHost/OpenGL/include/state/cr_bufferobject.h

    r44125 r44290  
    6060DECLEXPORT(CRBufferObject *) crStateGetBoundBufferObject(GLenum target, CRBufferObjectState *b);
    6161DECLEXPORT(GLboolean) crStateIsBufferBound(GLenum target);
     62struct CRContext;
     63DECLEXPORT(GLboolean) crStateIsBufferBoundForCtx(struct CRContext *g, GLenum target);
    6264
    6365DECLEXPORT(GLuint) STATE_APIENTRY crStateBufferHWIDtoID(GLuint hwid);
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h

    r44126 r44290  
    4747
    4848extern CRContext *g_pAvailableContexts[CR_MAX_CONTEXTS];
     49extern uint32_t g_cContexts;
    4950
    5051extern void crStateTextureInitTextureObj (CRContext *ctx, CRTextureObj *tobj, GLuint name, GLenum target);
     
    7071void crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,   CRContext *from, CRContext *to);
    7172
    72 void crStateGetTextureObjectAndImage(CRContext *g, GLenum texTarget, GLint level,
    73                                      CRTextureObj **obj, CRTextureLevel **img);
    74 
    7573void crStateFreeBufferObject(void *data);
    7674void crStateFreeFBO(void *data);
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c

    r44125 r44290  
    4242}
    4343
    44 GLboolean crStateIsBufferBound(GLenum target)
    45 {
    46     CRContext *g = GetCurrentContext();
     44GLboolean crStateIsBufferBoundForCtx(CRContext *g, GLenum target)
     45{
    4746    CRBufferObjectState *b = &(g->bufferobject);
    4847
     
    6261            return GL_FALSE;
    6362    }
     63}
     64
     65GLboolean crStateIsBufferBound(GLenum target)
     66{
     67    CRContext *g = GetCurrentContext();
     68    return crStateIsBufferBoundForCtx(g, target);
    6469}
    6570
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c

    r44196 r44290  
    99#include "cr_mem.h"
    1010#include "cr_pixeldata.h"
     11#include <iprt/err.h>
    1112
    1213void crStateDiffContext( CRContext *from, CRContext *to )
     
    120121                crStateCurrentDiff( &(sb->current), bitID, from, to );
    121122        }
     123}
     124
     125void crStateFreeFBImage(CRContext *to)
     126{
     127    if (to->buffer.pFrontImg)
     128    {
     129        crFree(to->buffer.pFrontImg);
     130        to->buffer.pFrontImg = NULL;
     131    }
     132    if (to->buffer.pBackImg)
     133    {
     134        crFree(to->buffer.pBackImg);
     135        to->buffer.pBackImg = NULL;
     136    }
     137
     138    to->buffer.storedWidth = 0;
     139    to->buffer.storedHeight = 0;
     140}
     141
     142int crStateAcquireFBImage(CRContext *to)
     143{
     144    CRBufferState *pBuf = &to->buffer;
     145    CRPixelPackState packing = to->client.pack;
     146    GLint cbData;
     147    void *pFbData, *pBbData;
     148
     149    crStateFreeFBImage(to);
     150
     151    if (!to->buffer.width || !to->buffer.height)
     152        return VINF_SUCCESS;
     153
     154    cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->width * pBuf->height;
     155    pFbData = crAlloc(cbData);
     156    if (!pFbData)
     157        return VERR_NO_MEMORY;
     158    pBbData = crAlloc(cbData);
     159    if (!pBbData)
     160    {
     161        crFree(pFbData);
     162        return VERR_NO_MEMORY;
     163    }
     164
     165    diff_api.PixelStorei(GL_PACK_SKIP_ROWS, 0);
     166    diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, 0);
     167    diff_api.PixelStorei(GL_PACK_ALIGNMENT, 1);
     168    diff_api.PixelStorei(GL_PACK_ROW_LENGTH, 0);
     169    diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
     170    diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, 0);
     171    diff_api.PixelStorei(GL_PACK_SWAP_BYTES, 0);
     172    diff_api.PixelStorei(GL_PACK_LSB_FIRST, 0);
     173
     174    if (to->framebufferobject.readFB)
     175    {
     176        diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
     177    }
     178    if (to->bufferobject.packBuffer->hwid>0)
     179    {
     180        diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
     181    }
     182
     183    pBuf->storedWidth = pBuf->width;
     184    pBuf->storedHeight = pBuf->height;
     185    diff_api.ReadBuffer(GL_FRONT);
     186    diff_api.ReadPixels(0, 0, pBuf->width, pBuf->height, GL_RGBA, GL_UNSIGNED_BYTE, pFbData);
     187    to->buffer.pFrontImg = pFbData;
     188
     189    diff_api.ReadBuffer(GL_BACK);
     190    diff_api.ReadPixels(0, 0, pBuf->width, pBuf->height, GL_RGBA, GL_UNSIGNED_BYTE, pBbData);
     191    to->buffer.pBackImg = pBbData;
     192
     193    if (to->bufferobject.packBuffer->hwid>0)
     194    {
     195        diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, to->bufferobject.packBuffer->hwid);
     196    }
     197    if (to->framebufferobject.readFB)
     198    {
     199        diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB->hwid);
     200    }
     201    diff_api.ReadBuffer(to->framebufferobject.readFB ?
     202                        to->framebufferobject.readFB->readbuffer : to->buffer.readBuffer);
     203
     204    diff_api.PixelStorei(GL_PACK_SKIP_ROWS, packing.skipRows);
     205    diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, packing.skipPixels);
     206    diff_api.PixelStorei(GL_PACK_ALIGNMENT, packing.alignment);
     207    diff_api.PixelStorei(GL_PACK_ROW_LENGTH, packing.rowLength);
     208    diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, packing.imageHeight);
     209    diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, packing.skipImages);
     210    diff_api.PixelStorei(GL_PACK_SWAP_BYTES, packing.swapBytes);
     211    diff_api.PixelStorei(GL_PACK_LSB_FIRST, packing.psLSBFirst);
     212    return VINF_SUCCESS;
    122213}
    123214
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c

    r44105 r44290  
    1919CRStateBits *__currentBits = NULL;
    2020CRContext *g_pAvailableContexts[CR_MAX_CONTEXTS];
     21uint32_t g_cContexts = 0;
    2122
    2223static CRSharedState *gSharedState=NULL;
     
    237238    }
    238239    g_pAvailableContexts[i] = ctx;
     240    ++g_cContexts;
     241    CRASSERT(g_cContexts < RT_ELEMENTS(g_pAvailableContexts));
    239242    ctx->id = i;
    240243#ifdef CHROMIUM_THREADSAFE
     
    346349    CRASSERT(g_pAvailableContexts[ctx->id] == ctx);
    347350    if (ctx->id || ctx == defaultContext)
     351    {
    348352        g_pAvailableContexts[ctx->id] = NULL;
     353        --g_cContexts;
     354        CRASSERT(g_cContexts < RT_ELEMENTS(g_pAvailableContexts));
     355    }
    349356
    350357    crStateClientDestroy( ctx );
     
    432439    CRASSERT(g_pAvailableContexts[0] == NULL);
    433440    defaultContext = crStateCreateContextId(0, NULL, CR_RGB_BIT, NULL);
    434     g_pAvailableContexts[0] = defaultContext; /* in use forever */
    435 
     441    CRASSERT(g_pAvailableContexts[0] == defaultContext);
     442    CRASSERT(g_cContexts == 1);
    436443#ifdef CHROMIUM_THREADSAFE
    437444    SetCurrentContext(defaultContext);
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c

    r44196 r44290  
    15971597#endif
    15981598
    1599     if (pContext->buffer.storedWidth && pContext->buffer.storedHeight)
    1600     {
    1601         CRBufferState *pBuf = &pContext->buffer;
    1602         CRPixelPackState packing = pContext->client.pack;
    1603         GLint cbData;
    1604         void *pData;
    1605 
    1606         cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->storedWidth * pBuf->storedHeight;
    1607         pData = crAlloc(cbData);
    1608 
    1609         if (!pData)
    1610         {
    1611             return VERR_NO_MEMORY;
    1612         }
    1613 
    1614         diff_api.PixelStorei(GL_PACK_SKIP_ROWS, 0);
    1615         diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, 0);
    1616         diff_api.PixelStorei(GL_PACK_ALIGNMENT, 1);
    1617         diff_api.PixelStorei(GL_PACK_ROW_LENGTH, 0);
    1618         diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
    1619         diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, 0);
    1620         diff_api.PixelStorei(GL_PACK_SWAP_BYTES, 0);
    1621         diff_api.PixelStorei(GL_PACK_LSB_FIRST, 0);
    1622 
    1623         if (pContext->framebufferobject.readFB)
    1624         {
    1625             diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
    1626         }
    1627         if (pContext->bufferobject.packBuffer->hwid>0)
    1628         {
    1629             diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    1630         }
    1631 
    1632         diff_api.ReadBuffer(GL_FRONT);
    1633         diff_api.ReadPixels(0, 0, pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);
    1634         rc = SSMR3PutMem(pSSM, pData, cbData);
    1635         AssertRCReturn(rc, rc);
    1636 
    1637         diff_api.ReadBuffer(GL_BACK);
    1638         diff_api.ReadPixels(0, 0, pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);
    1639         rc = SSMR3PutMem(pSSM, pData, cbData);
    1640         AssertRCReturn(rc, rc);
    1641 
    1642         if (pContext->bufferobject.packBuffer->hwid>0)
    1643         {
    1644             diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pContext->bufferobject.packBuffer->hwid);
    1645         }
    1646         if (pContext->framebufferobject.readFB)
    1647         {
    1648             diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, pContext->framebufferobject.readFB->hwid);
    1649         }
    1650         diff_api.ReadBuffer(pContext->framebufferobject.readFB ?
    1651                             pContext->framebufferobject.readFB->readbuffer : pContext->buffer.readBuffer);
    1652 
    1653         diff_api.PixelStorei(GL_PACK_SKIP_ROWS, packing.skipRows);
    1654         diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, packing.skipPixels);
    1655         diff_api.PixelStorei(GL_PACK_ALIGNMENT, packing.alignment);
    1656         diff_api.PixelStorei(GL_PACK_ROW_LENGTH, packing.rowLength);
    1657         diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, packing.imageHeight);
    1658         diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, packing.skipImages);
    1659         diff_api.PixelStorei(GL_PACK_SWAP_BYTES, packing.swapBytes);
    1660         diff_api.PixelStorei(GL_PACK_LSB_FIRST, packing.psLSBFirst);
    1661 
    1662         crFree(pData);
    1663     }
    1664 
    16651599    return VINF_SUCCESS;
    16661600}
     
    16821616    }
    16831617}
     1618
     1619int32_t crStateSaveGlobals(PSSMHANDLE pSSM)
     1620{
     1621    CRStateBits *pBits;
     1622    int rc;
     1623
     1624    CRASSERT(g_cContexts >= 1);
     1625    if (g_cContexts <= 1)
     1626        return VINF_SUCCESS;
     1627
     1628    pBits = GetCurrentBits();
     1629#define CRSTATE_BITS_OP(_var, _size) \
     1630        rc = SSMR3PutMem(pSSM, (pBits->_var), _size); \
     1631        AssertRCReturn(rc, rc);
     1632#include "state_bits_globalop.h"
     1633#undef CRSTATE_BITS_OP
     1634    return VINF_SUCCESS;
     1635}
     1636
     1637int32_t crStateLoadGlobals(PSSMHANDLE pSSM, uint32_t u32Version)
     1638{
     1639    CRStateBits *pBits;
     1640    int rc;
     1641    CRASSERT(g_cContexts >= 1);
     1642    if (g_cContexts <= 1)
     1643        return VINF_SUCCESS;
     1644
     1645    pBits = GetCurrentBits();
     1646
     1647    if (u32Version >= SHCROGL_SSM_VERSION_WITH_STATE_BITS)
     1648    {
     1649#define CRSTATE_BITS_OP(_var, _size) \
     1650            rc = SSMR3GetMem(pSSM, (pBits->_var), _size); \
     1651            AssertRCReturn(rc, rc);
     1652#include "state_bits_globalop.h"
     1653#undef CRSTATE_BITS_OP
     1654        return VINF_SUCCESS;
     1655    }
     1656
     1657#define CRSTATE_BITS_OP(_var, _size) FILLDIRTY(pBits->_var);
     1658#include "state_bits_globalop.h"
     1659#undef CRSTATE_BITS_OP
     1660    return VINF_SUCCESS;
     1661}
     1662
    16841663
    16851664#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
     
    24252404#endif
    24262405
    2427 
    2428     /*Restore front/back buffer images*/
    2429     if (pContext->buffer.storedWidth && pContext->buffer.storedHeight)
    2430     {
    2431         CRBufferState *pBuf = &pContext->buffer;
    2432         GLint cbData;
    2433         void *pData;
    2434 
    2435         cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->storedWidth * pBuf->storedHeight;
    2436 
    2437         pData = crAlloc(cbData);
    2438         if (!pData)
    2439         {
    2440             pBuf->pFrontImg = NULL;
    2441             pBuf->pBackImg = NULL;
    2442             return VERR_NO_MEMORY;
    2443         }
    2444 
    2445         rc = SSMR3GetMem(pSSM, pData, cbData);
    2446         AssertRCReturn(rc, rc);
    2447 
    2448         pBuf->pFrontImg = pData;
    2449 
    2450         pData = crAlloc(cbData);
    2451         if (!pData)
    2452         {
    2453             pBuf->pBackImg = NULL;
    2454             return VERR_NO_MEMORY;
    2455         }
    2456 
    2457         rc = SSMR3GetMem(pSSM, pData, cbData);
    2458         AssertRCReturn(rc, rc);
    2459 
    2460         pBuf->pBackImg = pData;
    2461     }
    2462 
    24632406    if (pContext->error != err)
    24642407    {
     
    24682411    }
    24692412
    2470     /*Mark all as dirty to make sure we'd restore correct context state*/
    2471     {
    2472         CRStateBits *pBits = GetCurrentBits();
    2473 
    2474         FILLDIRTY(pBits->attrib.dirty);
    2475 
    2476         FILLDIRTY(pBits->buffer.dirty);
    2477         FILLDIRTY(pBits->buffer.enable);
    2478         FILLDIRTY(pBits->buffer.alphaFunc);
    2479         FILLDIRTY(pBits->buffer.depthFunc);
    2480         FILLDIRTY(pBits->buffer.blendFunc);
    2481         FILLDIRTY(pBits->buffer.logicOp);
    2482         FILLDIRTY(pBits->buffer.indexLogicOp);
    2483         FILLDIRTY(pBits->buffer.drawBuffer);
    2484         FILLDIRTY(pBits->buffer.readBuffer);
    2485         FILLDIRTY(pBits->buffer.indexMask);
    2486         FILLDIRTY(pBits->buffer.colorWriteMask);
    2487         FILLDIRTY(pBits->buffer.clearColor);
    2488         FILLDIRTY(pBits->buffer.clearIndex);
    2489         FILLDIRTY(pBits->buffer.clearDepth);
    2490         FILLDIRTY(pBits->buffer.clearAccum);
    2491         FILLDIRTY(pBits->buffer.depthMask);
    2492 #ifdef CR_EXT_blend_color
    2493         FILLDIRTY(pBits->buffer.blendColor);
    2494 #endif
    2495 #if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
    2496         FILLDIRTY(pBits->buffer.blendEquation);
    2497 #endif
    2498 #if defined(CR_EXT_blend_func_separate)
    2499         FILLDIRTY(pBits->buffer.blendFuncSeparate);
    2500 #endif
    2501 
    2502 #ifdef CR_ARB_vertex_buffer_object
    2503         FILLDIRTY(pBits->bufferobject.dirty);
    2504         FILLDIRTY(pBits->bufferobject.arrayBinding);
    2505         FILLDIRTY(pBits->bufferobject.elementsBinding);
    2506 # ifdef CR_ARB_pixel_buffer_object
    2507         FILLDIRTY(pBits->bufferobject.packBinding);
    2508         FILLDIRTY(pBits->bufferobject.unpackBinding);
    2509 # endif
    2510 #endif
    2511 
    2512         FILLDIRTY(pBits->client.dirty);
    2513         FILLDIRTY(pBits->client.pack);
    2514         FILLDIRTY(pBits->client.unpack);
    2515         FILLDIRTY(pBits->client.enableClientState);
    2516         FILLDIRTY(pBits->client.clientPointer);
    2517         FILLDIRTY(pBits->client.v);
    2518         FILLDIRTY(pBits->client.n);
    2519         FILLDIRTY(pBits->client.c);
    2520         FILLDIRTY(pBits->client.i);
    2521         FILLDIRTY(pBits->client.e);
    2522         FILLDIRTY(pBits->client.s);
    2523         FILLDIRTY(pBits->client.f);
    2524         for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
    2525         {
    2526             FILLDIRTY(pBits->client.t[i]);
    2527         }
    2528 #ifdef CR_NV_vertex_program
    2529         for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
    2530         {
    2531             FILLDIRTY(pBits->client.a[i]);
    2532         }
    2533 #endif
    2534 
    2535         FILLDIRTY(pBits->current.dirty);
    2536         for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
    2537         {
    2538             FILLDIRTY(pBits->current.vertexAttrib[i]);
    2539         }
    2540         FILLDIRTY(pBits->current.edgeFlag);
    2541         FILLDIRTY(pBits->current.colorIndex);
    2542         FILLDIRTY(pBits->current.rasterPos);
    2543 
    2544 
    2545         FILLDIRTY(pBits->eval.dirty);
    2546         for (i=0; i<GLEVAL_TOT; i++)
    2547         {
    2548             FILLDIRTY(pBits->eval.eval1D[i]);
    2549             FILLDIRTY(pBits->eval.eval2D[i]);
    2550             FILLDIRTY(pBits->eval.enable1D[i]);
    2551             FILLDIRTY(pBits->eval.enable2D[i]);
    2552         }
    2553         FILLDIRTY(pBits->eval.enable);
    2554         FILLDIRTY(pBits->eval.grid1D);
    2555         FILLDIRTY(pBits->eval.grid2D);
    2556 #ifdef CR_NV_vertex_program
    2557         /*@todo Those seems to be unused?
    2558         FILLDIRTY(pBits->eval.enableAttrib1D);
    2559         FILLDIRTY(pBits->eval.enableAttrib2D);
    2560         */
    2561 #endif
    2562 
    2563         FILLDIRTY(pBits->feedback.dirty);
    2564         FILLDIRTY(pBits->selection.dirty);
    2565 
    2566         FILLDIRTY(pBits->fog.dirty);
    2567         FILLDIRTY(pBits->fog.color);
    2568         FILLDIRTY(pBits->fog.index);
    2569         FILLDIRTY(pBits->fog.density);
    2570         FILLDIRTY(pBits->fog.start);
    2571         FILLDIRTY(pBits->fog.end);
    2572         FILLDIRTY(pBits->fog.mode);
    2573         FILLDIRTY(pBits->fog.enable);
    2574 #ifdef CR_NV_fog_distance
    2575         FILLDIRTY(pBits->fog.fogDistanceMode);
    2576 #endif
    2577 #ifdef CR_EXT_fog_coord
    2578         FILLDIRTY(pBits->fog.fogCoordinateSource);
    2579 #endif
    2580 
    2581         FILLDIRTY(pBits->hint.dirty);
    2582         FILLDIRTY(pBits->hint.perspectiveCorrection);
    2583         FILLDIRTY(pBits->hint.pointSmooth);
    2584         FILLDIRTY(pBits->hint.lineSmooth);
    2585         FILLDIRTY(pBits->hint.polygonSmooth);
    2586         FILLDIRTY(pBits->hint.fog);
    2587 #ifdef CR_EXT_clip_volume_hint
    2588         FILLDIRTY(pBits->hint.clipVolumeClipping);
    2589 
    2590 #endif
    2591 #ifdef CR_ARB_texture_compression
    2592         FILLDIRTY(pBits->hint.textureCompression);
    2593 #endif
    2594 #ifdef CR_SGIS_generate_mipmap
    2595         FILLDIRTY(pBits->hint.generateMipmap);
    2596 #endif
    2597 
    2598         FILLDIRTY(pBits->lighting.dirty);
    2599         FILLDIRTY(pBits->lighting.shadeModel);
    2600         FILLDIRTY(pBits->lighting.colorMaterial);
    2601         FILLDIRTY(pBits->lighting.lightModel);
    2602         FILLDIRTY(pBits->lighting.material);
    2603         FILLDIRTY(pBits->lighting.enable);
    2604         for (i=0; i<CR_MAX_LIGHTS; ++i)
    2605         {
    2606             FILLDIRTY(pBits->lighting.light[i].dirty);
    2607             FILLDIRTY(pBits->lighting.light[i].enable);
    2608             FILLDIRTY(pBits->lighting.light[i].ambient);
    2609             FILLDIRTY(pBits->lighting.light[i].diffuse);
    2610             FILLDIRTY(pBits->lighting.light[i].specular);
    2611             FILLDIRTY(pBits->lighting.light[i].position);
    2612             FILLDIRTY(pBits->lighting.light[i].attenuation);
    2613             FILLDIRTY(pBits->lighting.light[i].spot);
    2614         }
    2615 
    2616         FILLDIRTY(pBits->line.dirty);
    2617         FILLDIRTY(pBits->line.enable);
    2618         FILLDIRTY(pBits->line.width);
    2619         FILLDIRTY(pBits->line.stipple);
    2620 
    2621         FILLDIRTY(pBits->lists.dirty);
    2622         FILLDIRTY(pBits->lists.base);
    2623 
    2624         FILLDIRTY(pBits->multisample.dirty);
    2625         FILLDIRTY(pBits->multisample.enable);
    2626         FILLDIRTY(pBits->multisample.sampleAlphaToCoverage);
    2627         FILLDIRTY(pBits->multisample.sampleAlphaToOne);
    2628         FILLDIRTY(pBits->multisample.sampleCoverage);
    2629         FILLDIRTY(pBits->multisample.sampleCoverageValue);
    2630 
    2631 #if CR_ARB_occlusion_query
    2632         FILLDIRTY(pBits->occlusion.dirty);
    2633 #endif
    2634 
    2635         FILLDIRTY(pBits->pixel.dirty);
    2636         FILLDIRTY(pBits->pixel.transfer);
    2637         FILLDIRTY(pBits->pixel.zoom);
    2638         FILLDIRTY(pBits->pixel.maps);
    2639 
    2640         FILLDIRTY(pBits->point.dirty);
    2641         FILLDIRTY(pBits->point.enableSmooth);
    2642         FILLDIRTY(pBits->point.size);
    2643 #ifdef CR_ARB_point_parameters
    2644         FILLDIRTY(pBits->point.minSize);
    2645         FILLDIRTY(pBits->point.maxSize);
    2646         FILLDIRTY(pBits->point.fadeThresholdSize);
    2647         FILLDIRTY(pBits->point.distanceAttenuation);
    2648 #endif
    2649 #ifdef CR_ARB_point_sprite
    2650         FILLDIRTY(pBits->point.enableSprite);
    2651         for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
    2652         {
    2653             FILLDIRTY(pBits->point.coordReplacement[i]);
    2654         }
    2655 #endif
    2656 
    2657         FILLDIRTY(pBits->polygon.dirty);
    2658         FILLDIRTY(pBits->polygon.enable);
    2659         FILLDIRTY(pBits->polygon.offset);
    2660         FILLDIRTY(pBits->polygon.mode);
    2661         FILLDIRTY(pBits->polygon.stipple);
    2662 
    2663         FILLDIRTY(pBits->program.dirty);
    2664         FILLDIRTY(pBits->program.vpEnable);
    2665         FILLDIRTY(pBits->program.fpEnable);
    2666         FILLDIRTY(pBits->program.vpBinding);
    2667         FILLDIRTY(pBits->program.fpBinding);
    2668         for (i=0; i<CR_MAX_VERTEX_ATTRIBS; ++i)
    2669         {
    2670             FILLDIRTY(pBits->program.vertexAttribArrayEnable[i]);
    2671             FILLDIRTY(pBits->program.map1AttribArrayEnable[i]);
    2672             FILLDIRTY(pBits->program.map2AttribArrayEnable[i]);
    2673         }
    2674         for (i=0; i<CR_MAX_VERTEX_PROGRAM_ENV_PARAMS; ++i)
    2675         {
    2676             FILLDIRTY(pBits->program.vertexEnvParameter[i]);
    2677         }
    2678         for (i=0; i<CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS; ++i)
    2679         {
    2680             FILLDIRTY(pBits->program.fragmentEnvParameter[i]);
    2681         }
    2682         FILLDIRTY(pBits->program.vertexEnvParameters);
    2683         FILLDIRTY(pBits->program.fragmentEnvParameters);
    2684         for (i=0; i<CR_MAX_VERTEX_PROGRAM_ENV_PARAMS/4; ++i)
    2685         {
    2686             FILLDIRTY(pBits->program.trackMatrix[i]);
    2687         }
    2688 
    2689         FILLDIRTY(pBits->regcombiner.dirty);
    2690         FILLDIRTY(pBits->regcombiner.enable);
    2691         FILLDIRTY(pBits->regcombiner.regCombinerVars);
    2692         FILLDIRTY(pBits->regcombiner.regCombinerColor0);
    2693         FILLDIRTY(pBits->regcombiner.regCombinerColor1);
    2694         for (i=0; i<CR_MAX_GENERAL_COMBINERS; ++i)
    2695         {
    2696             FILLDIRTY(pBits->regcombiner.regCombinerStageColor0[i]);
    2697             FILLDIRTY(pBits->regcombiner.regCombinerStageColor1[i]);
    2698             FILLDIRTY(pBits->regcombiner.regCombinerInput[i]);
    2699             FILLDIRTY(pBits->regcombiner.regCombinerOutput[i]);
    2700         }
    2701         FILLDIRTY(pBits->regcombiner.regCombinerFinalInput);
    2702 
    2703         FILLDIRTY(pBits->stencil.dirty);
    2704         FILLDIRTY(pBits->stencil.enable);
    2705         FILLDIRTY(pBits->stencil.func);
    2706         FILLDIRTY(pBits->stencil.op);
    2707         FILLDIRTY(pBits->stencil.clearValue);
    2708         FILLDIRTY(pBits->stencil.writeMask);
    2709 
    2710         FILLDIRTY(pBits->texture.dirty);
    2711         for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
    2712         {
    2713             FILLDIRTY(pBits->texture.enable[i]);
    2714             FILLDIRTY(pBits->texture.current[i]);
    2715             FILLDIRTY(pBits->texture.objGen[i]);
    2716             FILLDIRTY(pBits->texture.eyeGen[i]);
    2717             FILLDIRTY(pBits->texture.genMode[i]);
    2718             FILLDIRTY(pBits->texture.envBit[i]);
    2719         }
    2720 
    2721         FILLDIRTY(pBits->transform.dirty);
    2722         FILLDIRTY(pBits->transform.matrixMode);
    2723         FILLDIRTY(pBits->transform.modelviewMatrix);
    2724         FILLDIRTY(pBits->transform.projectionMatrix);
    2725         FILLDIRTY(pBits->transform.colorMatrix);
    2726         FILLDIRTY(pBits->transform.textureMatrix);
    2727         FILLDIRTY(pBits->transform.programMatrix);
    2728         FILLDIRTY(pBits->transform.clipPlane);
    2729         FILLDIRTY(pBits->transform.enable);
    2730         FILLDIRTY(pBits->transform.base);
    2731 
    2732         FILLDIRTY(pBits->viewport.dirty);
    2733         FILLDIRTY(pBits->viewport.v_dims);
    2734         FILLDIRTY(pBits->viewport.s_dims);
    2735         FILLDIRTY(pBits->viewport.enable);
    2736         FILLDIRTY(pBits->viewport.depth);
    2737     }
    2738 
    27392413    return VINF_SUCCESS;
    27402414}
  • trunk/src/VBox/GuestHost/OpenGL/util/hash.c

    r44193 r44290  
    2424} FreeElem;
    2525
    26 typedef struct CRHashIdPoolRec {
     26typedef struct CRHashIdPool {
    2727    RTLISTNODE freeList;
    2828} CRHashIdPool;
     
    4444
    4545
    46 static CRHashIdPool *crAllocHashIdPool( void )
     46CRHashIdPool *crAllocHashIdPool( void )
    4747{
    4848    CRHashIdPool *pool = (CRHashIdPool *) crCalloc(sizeof(CRHashIdPool));
     
    5555}
    5656
    57 static void crFreeHashIdPool( CRHashIdPool *pool )
     57void crFreeHashIdPool( CRHashIdPool *pool )
    5858{
    5959    FreeElem *i, *next;
     
    6565    crFree(pool);
    6666}
    67 
    68 static GLboolean crHashIdPoolIsIdFree( const CRHashIdPool *pool, GLuint id );
    6967
    7068#ifdef DEBUG_misha
     
    122120 * Return 0 if we fail.
    123121 */
    124 static GLuint crHashIdPoolAllocBlock( CRHashIdPool *pool, GLuint count )
     122GLuint crHashIdPoolAllocBlock( CRHashIdPool *pool, GLuint count )
    125123{
    126124    FreeElem *f, *next;
     
    157155 * Free a block of <count> IDs starting at <first>.
    158156 */
    159 static void crHashIdPoolFreeBlock( CRHashIdPool *pool, GLuint first, GLuint count )
     157void crHashIdPoolFreeBlock( CRHashIdPool *pool, GLuint first, GLuint count )
    160158{
    161159    FreeElem *f;
     
    249247 * Mark the given Id as being allocated.
    250248 */
    251 static GLboolean crHashIdPoolAllocId( CRHashIdPool *pool, GLuint id )
     249GLboolean crHashIdPoolAllocId( CRHashIdPool *pool, GLuint id )
    252250{
    253251    FreeElem *f, *next;
     
    315313 * Determine if the given id is free.  Return GL_TRUE if so.
    316314 */
    317 static GLboolean crHashIdPoolIsIdFree( const CRHashIdPool *pool, GLuint id )
     315GLboolean crHashIdPoolIsIdFree( const CRHashIdPool *pool, GLuint id )
    318316{
    319317    FreeElem *f;
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r43980 r44290  
    149149PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen);
    150150
     151void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo );
     152
    151153RT_C_DECLS_END
    152154
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c

    r43945 r44290  
    5050
    5151    cr_server.uniqueWindows = 0;
    52 
    53     cr_server.idsPool.freeWindowID = 1;
    54     cr_server.idsPool.freeContextID = 1;
    55     cr_server.idsPool.freeClientID = 1;
    5652
    5753    cr_server.screenCount = 0;
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c

    r44196 r44290  
    4040    }
    4141
     42    pContextInfo->currentMural = NULL;
     43
    4244    pContextInfo->CreateInfo.visualBits = visualBits;
    4345
     
    121123        crStateSetCurrentPointers( newCtx, &(cr_server.current) );
    122124        crStateResetCurrentPointers(&(cr_server.current));
    123         retVal = preloadCtxID<0 ? crServerGenerateID(&cr_server.idsPool.freeContextID) : preloadCtxID;
     125        retVal = preloadCtxID<0 ? (GLint)crHashtableAllocKeys( cr_server.contextTable, 1 ) : preloadCtxID;
    124126
    125127        pContextInfo->pContext = newCtx;
     
    161163}
    162164
     165static void crServerCleanupMuralCtxUsageCB(unsigned long key, void *data1, void *data2)
     166{
     167    CRMuralInfo *mural = (CRMuralInfo *) data1;
     168    CRContext *ctx = (CRContext *) data2;
     169
     170    CR_STATE_SHAREDOBJ_USAGE_CLEAR(mural, ctx);
     171}
     172
    163173void SERVER_DISPATCH_APIENTRY
    164174crServerDispatchDestroyContext( GLint ctx )
     
    180190    crDebug("CRServer: DestroyContext context %d", ctx);
    181191
     192    crHashtableWalk(cr_server.muralTable, crServerCleanupMuralCtxUsageCB, crCtx);
     193    crCtxInfo->currentMural = NULL;
    182194    crHashtableDelete(cr_server.contextTable, ctx, NULL);
    183195    crStateDestroyContext( crCtx );
     
    256268}
    257269
    258 void SERVER_DISPATCH_APIENTRY
    259 crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
    260 {
    261     CRMuralInfo *mural, *oldMural;
    262     CRContextInfo *ctxInfo = NULL;
     270void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo )
     271{
     272    CRMuralInfo *oldMural;
    263273    CRContext *ctx, *oldCtx = NULL;
    264274    GLuint idDrawFBO, idReadFBO;
    265 
    266     if (context >= 0 && window >= 0) {
    267         mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
    268         if (!mural)
    269         {
    270             crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window);
    271             return;
    272         }
    273 
    274         /* Update the state tracker's current context */
    275         ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context);
    276         if (!ctxInfo) {
    277             crWarning("CRserver: NULL context in MakeCurrent %d", context);
    278             return;
    279         }
    280     }
    281     else {
    282 #if 0
    283         oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);
    284         if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO())
    285         {
    286             if (!crStateGetCurrent()->framebufferobject.drawFB)
    287             {
    288                 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
    289             }
    290             if (!crStateGetCurrent()->framebufferobject.readFB)
    291             {
    292                 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
    293             }
    294         }
    295 
    296         ctxInfo = &cr_server.MainContextInfo;
    297         window = -1;
    298         mural = NULL;
    299 #endif
    300         cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
    301         return;
    302     }
     275    GLint context = ctxInfo->CreateInfo.externalID;
     276    GLint window = mural->CreateInfo.externalID;
    303277
    304278    cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE;
     
    374348         */
    375349        cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow,
    376                                                         nativeWindow,
     350                                                        0,
    377351                                                        ctxInfo->SpuContext >= 0
    378352                                                            ? ctxInfo->SpuContext
    379353                                                              : cr_server.MainContextInfo.SpuContext);
     354
     355        CR_STATE_SHAREDOBJ_USAGE_SET(mural, ctx);
     356        if (cr_server.currentCtxInfo)
     357            cr_server.currentCtxInfo->currentMural = NULL;
     358        ctxInfo->currentMural = mural;
     359
    380360        cr_server.firstCallMakeCurrent = GL_FALSE;
    381361        cr_server.currentCtxInfo = ctxInfo;
    382362        cr_server.currentWindow = window;
    383         cr_server.currentNativeWindow = nativeWindow;
     363        cr_server.currentNativeWindow = 0;
    384364        cr_server.currentMural = mural;
    385365    }
     
    430410}
    431411
     412
     413void SERVER_DISPATCH_APIENTRY
     414crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
     415{
     416    CRMuralInfo *mural;
     417    CRContextInfo *ctxInfo = NULL;
     418
     419    if (context >= 0 && window >= 0) {
     420        mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
     421        if (!mural)
     422        {
     423            crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window);
     424            return;
     425        }
     426
     427        /* Update the state tracker's current context */
     428        ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context);
     429        if (!ctxInfo) {
     430            crWarning("CRserver: NULL context in MakeCurrent %d", context);
     431            return;
     432        }
     433    }
     434    else {
     435#if 0
     436        oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);
     437        if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO())
     438        {
     439            if (!crStateGetCurrent()->framebufferobject.drawFB)
     440            {
     441                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
     442            }
     443            if (!crStateGetCurrent()->framebufferobject.readFB)
     444            {
     445                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
     446            }
     447        }
     448
     449        ctxInfo = &cr_server.MainContextInfo;
     450        window = -1;
     451        mural = NULL;
     452#endif
     453        cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
     454        return;
     455    }
     456
     457    crServerPerformMakeCurrent( mural, ctxInfo );
     458}
     459
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r44196 r44290  
    1414#include "cr_hash.h"
    1515#include "cr_environment.h"
     16#include "cr_pixeldata.h"
    1617#include "server_dispatch.h"
    1718#include "state/cr_texture.h"
     
    119120}
    120121
     122static void deleteMuralInfoCallback( void *data )
     123{
     124    CRMuralInfo *m = (CRMuralInfo *) data;
     125    if (m->spuWindow) /* <- do not do term for default mural as it does not contain any info to be freed,
     126                       * and renderspu will destroy it up itself*/
     127    {
     128        crServerMuralTerm(m);
     129    }
     130    crFree(m);
     131}
    121132
    122133static void crServerTearDown( void )
     
    152163    /* Free vertex programs */
    153164    crFreeHashtable(cr_server.programTable, crFree);
     165
     166    /* Free dummy murals */
     167    crFreeHashtable(cr_server.dummyMuralTable, deleteMuralInfoCallback);
     168
     169    /* Free murals */
     170    crFreeHashtable(cr_server.muralTable, deleteMuralInfoCallback);
    154171
    155172    for (i = 0; i < cr_server.numClients; i++) {
     
    309326    cr_server.curClient->currentCtxInfo = &cr_server.MainContextInfo;
    310327
     328    cr_server.dummyMuralTable = crAllocHashtable();
     329
    311330    crServerInitDispatch();
    312331    crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );
     
    383402     */
    384403    cr_server.contextTable = crAllocHashtable();
     404
     405    cr_server.dummyMuralTable = crAllocHashtable();
    385406
    386407    crServerSetVBoxConfigurationHGCM();
     
    693714        rc = SSMR3PutMem(pSSM, pMI->pVisibleRects, 4*sizeof(GLint)*pMI->cVisibleRects);
    694715    }
     716
     717    rc = SSMR3PutMem(pSSM, pMI->ctxUsage, sizeof (pMI->ctxUsage));
     718    CRASSERT(rc == VINF_SUCCESS);
    695719}
    696720
     
    745769}
    746770
     771typedef struct CRVBOX_SAVE_STATE_GLOBAL
     772{
     773    /* context id -> mural association
     774     * on context data save, each context will be made current with the corresponding mural from this table
     775     * thus saving the mural front & back buffer data */
     776    CRHashTable *contextMuralTable;
     777    /* mural id -> context info
     778     * for murals that do not have associated context in contextMuralTable
     779     * we still need to save*/
     780    CRHashTable *additionalMuralContextTable;
     781
     782    PSSMHANDLE pSSM;
     783
     784    int rc;
     785} CRVBOX_SAVE_STATE_GLOBAL, *PCRVBOX_SAVE_STATE_GLOBAL;
     786
     787
     788typedef struct CRVBOX_CTXWND_CTXWALKER_CB
     789{
     790    PCRVBOX_SAVE_STATE_GLOBAL pGlobal;
     791    CRHashTable *usedMuralTable;
     792    GLuint cAdditionalMurals;
     793} CRVBOX_CTXWND_CTXWALKER_CB, *PCRVBOX_CTXWND_CTXWALKER_CB;
     794
     795static void crVBoxServerBuildAdditionalWindowContextMapCB(unsigned long key, void *data1, void *data2)
     796{
     797    CRMuralInfo * pMural = (CRMuralInfo *) data1;
     798    PCRVBOX_CTXWND_CTXWALKER_CB pData = (PCRVBOX_CTXWND_CTXWALKER_CB)data2;
     799    CRContextInfo *pContextInfo = NULL;
     800
     801    if (!pMural->CreateInfo.externalID)
     802        return;
     803
     804    if (crHashtableSearch(pData->usedMuralTable, pMural->CreateInfo.externalID))
     805    {
     806        Assert(crHashtableGetDataKey(pData->pGlobal->contextMuralTable, pMural, NULL));
     807        return;
     808    }
     809
     810    Assert(!crHashtableGetDataKey(pData->pGlobal->contextMuralTable, pMural, NULL));
     811
     812    if (cr_server.MainContextInfo.CreateInfo.visualBits == pMural->CreateInfo.visualBits)
     813    {
     814        pContextInfo = &cr_server.MainContextInfo;
     815    }
     816    else
     817    {
     818        crWarning("different visual bits not implemented!");
     819        pContextInfo = &cr_server.MainContextInfo;
     820    }
     821
     822    crHashtableAdd(pData->pGlobal->additionalMuralContextTable, pMural->CreateInfo.externalID, pContextInfo);
     823}
     824
     825
     826typedef struct CRVBOX_CTXWND_WNDWALKER_CB
     827{
     828    PCRVBOX_SAVE_STATE_GLOBAL pGlobal;
     829    CRHashTable *usedMuralTable;
     830    CRContextInfo *pContextInfo;
     831    CRMuralInfo * pMural;
     832} CRVBOX_CTXWND_WNDWALKER_CB, *PCRVBOX_CTXWND_WNDWALKER_CB;
     833
     834static void crVBoxServerBuildContextWindowMapWindowWalkerCB(unsigned long key, void *data1, void *data2)
     835{
     836    CRMuralInfo * pMural = (CRMuralInfo *) data1;
     837    PCRVBOX_CTXWND_WNDWALKER_CB pData = (PCRVBOX_CTXWND_WNDWALKER_CB)data2;
     838
     839    Assert(pData->pMural != pMural);
     840    Assert(pData->pContextInfo);
     841
     842    if (pData->pMural)
     843        return;
     844
     845    if (!pMural->CreateInfo.externalID)
     846        return;
     847
     848    if (!CR_STATE_SHAREDOBJ_USAGE_IS_SET(pMural, pData->pContextInfo->pContext))
     849        return;
     850
     851    if (crHashtableSearch(pData->usedMuralTable, pMural->CreateInfo.externalID))
     852        return;
     853
     854    CRASSERT(pMural->CreateInfo.visualBits == pData->pContextInfo->CreateInfo.visualBits);
     855    pData->pMural = pMural;
     856}
     857
     858static void crVBoxServerBuildContextUsedWindowMapCB(unsigned long key, void *data1, void *data2)
     859{
     860    CRContextInfo *pContextInfo = (CRContextInfo *)data1;
     861    PCRVBOX_CTXWND_CTXWALKER_CB pData = (PCRVBOX_CTXWND_CTXWALKER_CB)data2;
     862
     863    if (!pContextInfo->currentMural)
     864        return;
     865
     866    crHashtableAdd(pData->pGlobal->contextMuralTable, pContextInfo->CreateInfo.externalID, pContextInfo->currentMural);
     867    crHashtableAdd(pData->usedMuralTable, pContextInfo->currentMural->CreateInfo.externalID, pContextInfo->currentMural);
     868}
     869
     870CRMuralInfo * crServerGetDummyMural(GLint visualBits)
     871{
     872    CRMuralInfo * pMural = (CRMuralInfo *)crHashtableSearch(cr_server.dummyMuralTable, visualBits);
     873    if (!pMural)
     874    {
     875        GLint id;
     876        pMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
     877        if (!pMural)
     878        {
     879            crWarning("crCalloc failed!");
     880            return NULL;
     881        }
     882        id = crServerMuralInit(pMural, "", visualBits, -1);
     883        if (id < 0)
     884        {
     885            crWarning("crServerMuralInit failed!");
     886            crFree(pMural);
     887            return NULL;
     888        }
     889
     890        crHashtableAdd(cr_server.dummyMuralTable, visualBits, pMural);
     891    }
     892
     893    return pMural;
     894}
     895
     896static void crVBoxServerBuildContextUnusedWindowMapCB(unsigned long key, void *data1, void *data2)
     897{
     898    CRContextInfo *pContextInfo = (CRContextInfo *)data1;
     899    PCRVBOX_CTXWND_CTXWALKER_CB pData = (PCRVBOX_CTXWND_CTXWALKER_CB)data2;
     900    CRMuralInfo * pMural = NULL;
     901
     902    if (pContextInfo->currentMural)
     903        return;
     904
     905    Assert(crHashtableNumElements(pData->pGlobal->contextMuralTable) <= crHashtableNumElements(cr_server.muralTable) - 1);
     906    if (crHashtableNumElements(pData->pGlobal->contextMuralTable) < crHashtableNumElements(cr_server.muralTable) - 1)
     907    {
     908        CRVBOX_CTXWND_WNDWALKER_CB MuralData;
     909        MuralData.pGlobal = pData->pGlobal;
     910        MuralData.usedMuralTable = pData->usedMuralTable;
     911        MuralData.pContextInfo = pContextInfo;
     912        MuralData.pMural = NULL;
     913
     914        crHashtableWalk(cr_server.muralTable, crVBoxServerBuildContextWindowMapWindowWalkerCB, &MuralData);
     915
     916        pMural = MuralData.pMural;
     917
     918    }
     919
     920    if (!pMural)
     921    {
     922        pMural = crServerGetDummyMural(pContextInfo->CreateInfo.visualBits);
     923        if (!pMural)
     924        {
     925            crWarning("crServerGetDummyMural failed");
     926            return;
     927        }
     928    }
     929    else
     930    {
     931        crHashtableAdd(pData->usedMuralTable, pMural->CreateInfo.externalID, pMural);
     932        ++pData->cAdditionalMurals;
     933    }
     934
     935    crHashtableAdd(pData->pGlobal->contextMuralTable, pContextInfo->CreateInfo.externalID, pMural);
     936}
     937
     938static void crVBoxServerBuildSaveStateGlobal(PCRVBOX_SAVE_STATE_GLOBAL pGlobal)
     939{
     940    CRVBOX_CTXWND_CTXWALKER_CB Data;
     941    GLuint cMurals;
     942    pGlobal->contextMuralTable = crAllocHashtable();
     943    pGlobal->additionalMuralContextTable = crAllocHashtable();
     944    /* 1. go through all contexts and match all having currentMural set */
     945    Data.pGlobal = pGlobal;
     946    Data.usedMuralTable = crAllocHashtable();
     947    Data.cAdditionalMurals = 0;
     948    crHashtableWalk(cr_server.contextTable, crVBoxServerBuildContextUsedWindowMapCB, &Data);
     949
     950    cMurals = crHashtableNumElements(pGlobal->contextMuralTable);
     951    CRASSERT(cMurals <= crHashtableNumElements(cr_server.contextTable));
     952    CRASSERT(cMurals <= crHashtableNumElements(cr_server.muralTable) - 1);
     953    CRASSERT(cMurals == crHashtableNumElements(Data.usedMuralTable));
     954    if (cMurals < crHashtableNumElements(cr_server.contextTable))
     955    {
     956        Data.cAdditionalMurals = 0;
     957        crHashtableWalk(cr_server.contextTable, crVBoxServerBuildContextUnusedWindowMapCB, &Data);
     958    }
     959
     960    CRASSERT(crHashtableNumElements(pGlobal->contextMuralTable) == crHashtableNumElements(cr_server.contextTable));
     961    CRASSERT(cMurals + Data.cAdditionalMurals <= crHashtableNumElements(cr_server.muralTable) - 1);
     962    if (cMurals + Data.cAdditionalMurals < crHashtableNumElements(cr_server.muralTable) - 1)
     963    {
     964        crHashtableWalk(cr_server.muralTable, crVBoxServerBuildAdditionalWindowContextMapCB, &Data);
     965        CRASSERT(cMurals + Data.cAdditionalMurals + crHashtableNumElements(pGlobal->additionalMuralContextTable) == crHashtableNumElements(cr_server.muralTable) - 1);
     966    }
     967}
     968
     969static int crVBoxServerSaveFBImage(PSSMHANDLE pSSM)
     970{
     971    int32_t rc;
     972    CRContext *pContext;
     973    CRMuralInfo *pMural;
     974    GLint cbData;
     975
     976    CRASSERT(cr_server.currentCtxInfo);
     977    CRASSERT(cr_server.currentCtxInfo->currentMural);
     978
     979    pContext = cr_server.currentCtxInfo->pContext;
     980    pMural = cr_server.currentCtxInfo->currentMural;
     981    /* do crStateAcquireFBImage no matter whether offscreen drawing is used or not
     982     * in the former case this would just free pContext->buffer.pFrontImg and pContext->buffer.pFrontImg
     983     */
     984    rc = crStateAcquireFBImage(pContext);
     985    AssertRCReturn(rc, rc);
     986
     987    if (!pMural->width || !pMural->height)
     988        return VINF_SUCCESS;
     989
     990
     991    cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pMural->width * pMural->height;
     992
     993    if (!pMural->fUseFBO)
     994    {
     995        CRASSERT(pMural->width == pContext->buffer.storedWidth);
     996        CRASSERT(pMural->width == pContext->buffer.width);
     997        CRASSERT(pMural->height == pContext->buffer.storedHeight);
     998        CRASSERT(pMural->height == pContext->buffer.height);
     999
     1000        rc = SSMR3PutMem(pSSM, pContext->buffer.pFrontImg, cbData);
     1001        AssertRCReturn(rc, rc);
     1002        rc = SSMR3PutMem(pSSM, pContext->buffer.pBackImg, cbData);
     1003        AssertRCReturn(rc, rc);
     1004
     1005        crStateFreeFBImage(pContext);
     1006    }
     1007    else
     1008    {
     1009        CR_BLITTER_TEXTURE Tex;
     1010        void *pvData;
     1011        GLuint idPBO = cr_server.bUsePBOForReadback ? pMural->idPBO : 0;
     1012
     1013        if (idPBO)
     1014        {
     1015            CRASSERT(pMural->fboWidth == pMural->width);
     1016            CRASSERT(pMural->fboHeight == pMural->height);
     1017        }
     1018
     1019        Tex.width = pMural->width;
     1020        Tex.height = pMural->height;
     1021        Tex.target = GL_TEXTURE_2D;
     1022        Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_FB_IDX(pMural)];
     1023
     1024        CRASSERT(Tex.hwid);
     1025
     1026        pvData = CrHlpGetTexImage(pContext, &Tex, idPBO);
     1027        if (!pvData)
     1028        {
     1029            crWarning("CrHlpGetTexImage failed for frontbuffer");
     1030            return VERR_NO_MEMORY;
     1031        }
     1032
     1033        rc = SSMR3PutMem(pSSM, pvData, cbData);
     1034
     1035        CrHlpFreeTexImage(pContext, idPBO, pvData);
     1036
     1037        AssertRCReturn(rc, rc);
     1038
     1039        Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_BB_IDX(pMural)];
     1040
     1041        CRASSERT(Tex.hwid);
     1042
     1043        pvData = CrHlpGetTexImage(pContext, &Tex, idPBO);
     1044        if (!pvData)
     1045        {
     1046            crWarning("CrHlpGetTexImage failed for backbuffer");
     1047            return VERR_NO_MEMORY;
     1048        }
     1049
     1050        rc = SSMR3PutMem(pSSM, pvData, cbData);
     1051
     1052        CrHlpFreeTexImage(pContext, idPBO, pvData);
     1053
     1054        AssertRCReturn(rc, rc);
     1055    }
     1056
     1057    return VINF_SUCCESS;
     1058}
     1059
     1060#define CRSERVER_ASSERTRC_RETURN_VOID(_rc) do { \
     1061        if(!RT_SUCCESS((_rc))) { \
     1062            AssertFailed(); \
     1063            return; \
     1064        } \
     1065    } while (0)
     1066
     1067static void crVBoxServerSaveAdditionalMuralsCB(unsigned long key, void *data1, void *data2)
     1068{
     1069    CRContextInfo *pContextInfo = (CRContextInfo *) data1;
     1070    PCRVBOX_SAVE_STATE_GLOBAL pData = (PCRVBOX_SAVE_STATE_GLOBAL)data2;
     1071    CRMuralInfo *pMural = (CRMuralInfo*)crHashtableSearch(cr_server.muralTable, key);
     1072    PSSMHANDLE pSSM = pData->pSSM;
     1073    CRbitvalue initialCtxUsage[CR_MAX_BITARRAY];
     1074    CRMuralInfo *pInitialCurMural = pContextInfo->currentMural;
     1075
     1076    crMemcpy(initialCtxUsage, pMural->ctxUsage, sizeof (initialCtxUsage));
     1077
     1078    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1079
     1080    pData->rc = SSMR3PutMem(pSSM, &key, sizeof(key));
     1081    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1082
     1083    pData->rc = SSMR3PutMem(pSSM, &pContextInfo->CreateInfo.externalID, sizeof(pContextInfo->CreateInfo.externalID));
     1084    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1085
     1086    crServerPerformMakeCurrent(pMural, pContextInfo);
     1087
     1088    pData->rc = crVBoxServerSaveFBImage(pSSM);
     1089
     1090    /* restore the reference data, we synchronize it with the HW state in a later crServerPerformMakeCurrent call */
     1091    crMemcpy(pMural->ctxUsage, initialCtxUsage, sizeof (initialCtxUsage));
     1092    pContextInfo->currentMural = pInitialCurMural;
     1093
     1094    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1095}
     1096
    7471097static void crVBoxServerSaveContextStateCB(unsigned long key, void *data1, void *data2)
    7481098{
    7491099    CRContextInfo *pContextInfo = (CRContextInfo *) data1;
    7501100    CRContext *pContext = pContextInfo->pContext;
    751     PSSMHANDLE pSSM = (PSSMHANDLE) data2;
    752     int32_t rc;
     1101    PCRVBOX_SAVE_STATE_GLOBAL pData = (PCRVBOX_SAVE_STATE_GLOBAL)data2;
     1102    PSSMHANDLE pSSM = pData->pSSM;
     1103    CRMuralInfo *pMural = (CRMuralInfo*)crHashtableSearch(pData->contextMuralTable, key);
     1104    CRMuralInfo *pContextCurrentMural = pContextInfo->currentMural;
     1105    const int32_t i32Dummy = 0;
     1106
     1107    AssertCompile(sizeof (i32Dummy) == sizeof (pMural->CreateInfo.externalID));
     1108    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
    7531109
    7541110    CRASSERT(pContext && pSSM);
     1111    CRASSERT(pMural);
    7551112
    7561113    /* We could have skipped saving the key and use similar callback to load context states back,
    7571114     * but there's no guarantee we'd traverse hashtable in same order after loading.
    7581115     */
    759     rc = SSMR3PutMem(pSSM, &key, sizeof(key));
    760     CRASSERT(rc == VINF_SUCCESS);
    761 
    762 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    763     CRASSERT(cr_server.curClient);
    764     if (cr_server.curClient)
    765     {
    766 # ifdef DEBUG_misha
    767         {
     1116    pData->rc = SSMR3PutMem(pSSM, &key, sizeof(key));
     1117    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1118
     1119#ifdef DEBUG_misha
     1120    {
    7681121            unsigned long id;
    7691122            if (!crHashtableGetDataKey(cr_server.contextTable, pContextInfo, &id))
    770                 crWarning("No client id for server ctx %d", pContext->id);
     1123                crWarning("No client id for server ctx %d", pContextInfo->CreateInfo.externalID);
    7711124            else
    7721125                CRASSERT(id == key);
    773         }
    774 # endif
    775         crServerDispatchMakeCurrent(cr_server.curClient->currentWindow, 0, key);
    776     }
    777 #endif
    778 
    779     rc = crStateSaveContext(pContext, pSSM);
    780     CRASSERT(rc == VINF_SUCCESS);
     1126    }
     1127#endif
     1128
     1129#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
     1130    if (pContextInfo->currentMural || crHashtableSearch(cr_server.muralTable, key))
     1131    {
     1132        CRASSERT(pMural->CreateInfo.externalID);
     1133        pData->rc = SSMR3PutMem(pSSM, &pMural->CreateInfo.externalID, sizeof(pMural->CreateInfo.externalID));
     1134    }
     1135    else
     1136    {
     1137        CRASSERT(!pMural->width);
     1138        CRASSERT(!pMural->height);
     1139        CRASSERT(crHashtableSearch(cr_server.dummyMuralTable, key));
     1140        pData->rc = SSMR3PutMem(pSSM, &i32Dummy, sizeof(pMural->CreateInfo.externalID));
     1141    }
     1142    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1143
     1144    CRASSERT(CR_STATE_SHAREDOBJ_USAGE_IS_SET(pMural, pContext));
     1145    CRASSERT(pContextInfo->currentMural == pMural || !pContextInfo->currentMural);
     1146    CRASSERT(cr_server.curClient);
     1147
     1148    crServerPerformMakeCurrent(pMural, pContextInfo);
     1149#endif
     1150
     1151    pData->rc = crStateSaveContext(pContext, pSSM);
     1152    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1153
     1154    pData->rc = crVBoxServerSaveFBImage(pSSM);
     1155    CRSERVER_ASSERTRC_RETURN_VOID(pData->rc);
     1156
     1157    /* restore the initial current mural */
     1158    pContextInfo->currentMural = pContextCurrentMural;
    7811159}
    7821160
     
    9101288    GLenum err;
    9111289#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    912     unsigned long ctxID=-1, winID=-1;
    913 #endif
     1290    CRClient *curClient;
     1291    CRMuralInfo *curMural = NULL;
     1292    CRContextInfo *curCtxInfo = NULL;
     1293#endif
     1294    CRVBOX_SAVE_STATE_GLOBAL Data = {0};
    9141295
    9151296#if 0
     
    9501331
    9511332#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
     1333    curClient = cr_server.curClient;
    9521334    /* Save current win and ctx IDs, as we'd rebind contexts when saving textures */
    953     if (cr_server.curClient)
    954     {
    955         ctxID = cr_server.curClient->currentContextNumber;
    956         winID = cr_server.curClient->currentWindow;
    957     }
    958 #endif
    959 
    960     /* Save contexts state tracker data */
    961     /* @todo For now just some blind data dumps,
    962      * but I've a feeling those should be saved/restored in a very strict sequence to
    963      * allow diff_api to work correctly.
    964      * Should be tested more with multiply guest opengl apps working when saving VM snapshot.
    965      */
    966     crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, pSSM);
    967 
    968 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    969     /* Restore original win and ctx IDs*/
    970     if (cr_server.curClient)
    971     {
    972         crServerDispatchMakeCurrent(winID, 0, ctxID);
    973     }
    974 #endif
    975 
     1335    if (curClient)
     1336    {
     1337        curCtxInfo = cr_server.curClient->currentCtxInfo;
     1338        curMural = cr_server.curClient->currentMural;
     1339    }
     1340    else if (cr_server.numClients)
     1341    {
     1342        cr_server.curClient = cr_server.clients[0];
     1343    }
     1344#endif
     1345
     1346    /* first save windows info */
    9761347    /* Save windows creation info */
    9771348    ui32 = crHashtableNumElements(cr_server.muralTable);
     
    9891360    crHashtableWalk(cr_server.muralTable, crVBoxServerSaveMuralCB, pSSM);
    9901361
    991     /* Save starting free context and window IDs */
    992     rc = SSMR3PutMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
     1362    /* we need to save front & backbuffer data for each mural first create a context -> mural association */
     1363    crVBoxServerBuildSaveStateGlobal(&Data);
     1364
     1365    rc = crStateSaveGlobals(pSSM);
    9931366    AssertRCReturn(rc, rc);
     1367
     1368    Data.pSSM = pSSM;
     1369    /* Save contexts state tracker data */
     1370    /* @todo For now just some blind data dumps,
     1371     * but I've a feeling those should be saved/restored in a very strict sequence to
     1372     * allow diff_api to work correctly.
     1373     * Should be tested more with multiply guest opengl apps working when saving VM snapshot.
     1374     */
     1375    crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, &Data);
     1376    AssertRCReturn(Data.rc, Data.rc);
     1377
     1378    ui32 = crHashtableNumElements(Data.additionalMuralContextTable);
     1379    rc = SSMR3PutU32(pSSM, (uint32_t) ui32);
     1380    AssertRCReturn(rc, rc);
     1381
     1382    crHashtableWalk(Data.additionalMuralContextTable, crVBoxServerSaveAdditionalMuralsCB, &Data);
     1383    AssertRCReturn(Data.rc, Data.rc);
     1384
     1385#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
     1386    cr_server.curClient = curClient;
     1387    /* Restore original win and ctx IDs*/
     1388    if (curClient && curMural && curCtxInfo)
     1389    {
     1390        crServerPerformMakeCurrent(curMural, curCtxInfo);
     1391    }
     1392    else
     1393    {
     1394        cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
     1395    }
     1396#endif
    9941397
    9951398    /* Save clients info */
     
    10481451}
    10491452
     1453static int32_t crVBoxServerLoadMurals(PSSMHANDLE pSSM, uint32_t version)
     1454{
     1455    unsigned long key;
     1456    uint32_t ui, uiNumElems;
     1457    /* Load windows */
     1458    int32_t rc = SSMR3GetU32(pSSM, &uiNumElems);
     1459    AssertRCReturn(rc, rc);
     1460    for (ui=0; ui<uiNumElems; ++ui)
     1461    {
     1462        CRCreateInfo_t createInfo;
     1463        char psz[200];
     1464        GLint winID;
     1465        unsigned long key;
     1466
     1467        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
     1468        AssertRCReturn(rc, rc);
     1469        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
     1470        AssertRCReturn(rc, rc);
     1471
     1472        if (createInfo.pszDpyName)
     1473        {
     1474            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
     1475            AssertRCReturn(rc, rc);
     1476            createInfo.pszDpyName = psz;
     1477        }
     1478
     1479        winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key);
     1480        CRASSERT((int64_t)winID == (int64_t)key);
     1481    }
     1482
     1483    /* Load cr_server.muralTable */
     1484    rc = SSMR3GetU32(pSSM, &uiNumElems);
     1485    AssertRCReturn(rc, rc);
     1486    for (ui=0; ui<uiNumElems; ++ui)
     1487    {
     1488        CRMuralInfo muralInfo;
     1489
     1490        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
     1491        AssertRCReturn(rc, rc);
     1492        rc = SSMR3GetMem(pSSM, &muralInfo, RT_OFFSETOF(CRMuralInfo, CreateInfo));
     1493        AssertRCReturn(rc, rc);
     1494
     1495        if (version <= SHCROGL_SSM_VERSION_BEFORE_FRONT_DRAW_TRACKING)
     1496            muralInfo.bFbDraw = GL_TRUE;
     1497
     1498        if (muralInfo.pVisibleRects)
     1499        {
     1500            muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects);
     1501            if (!muralInfo.pVisibleRects)
     1502            {
     1503                return VERR_NO_MEMORY;
     1504            }
     1505
     1506            rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects);
     1507            AssertRCReturn(rc, rc);
     1508        }
     1509
     1510        if (version >= SHCROGL_SSM_VERSION_WITH_WINDOW_CTX_USAGE)
     1511        {
     1512            CRMuralInfo *pActualMural = (CRMuralInfo *)crHashtableSearch(cr_server.muralTable, key);;
     1513            CRASSERT(pActualMural);
     1514            rc = SSMR3GetMem(pSSM, pActualMural->ctxUsage, sizeof (pActualMural->ctxUsage));
     1515            CRASSERT(rc == VINF_SUCCESS);
     1516        }
     1517
     1518        /* Restore windows geometry info */
     1519        crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
     1520        crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
     1521        /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
     1522        if (muralInfo.bReceivedRects)
     1523        {
     1524            crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
     1525        }
     1526        crServerDispatchWindowShow(key, muralInfo.bVisible);
     1527
     1528        if (muralInfo.pVisibleRects)
     1529        {
     1530            crFree(muralInfo.pVisibleRects);
     1531        }
     1532    }
     1533
     1534    CRASSERT(RT_SUCCESS(rc));
     1535    return VINF_SUCCESS;
     1536}
     1537
     1538static int crVBoxServerLoadFBImage(PSSMHANDLE pSSM, uint32_t version,
     1539        CRContextInfo* pContextInfo, CRMuralInfo *pMural)
     1540{
     1541    CRContext *pContext = pContextInfo->pContext;
     1542    GLint storedWidth, storedHeight;
     1543    int32_t rc = VINF_SUCCESS;
     1544
     1545    if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1546    {
     1547        CRASSERT(cr_server.currentCtxInfo == pContextInfo);
     1548        CRASSERT(cr_server.currentMural = pMural);
     1549        storedWidth = pMural->width;
     1550        storedHeight = pMural->height;
     1551        CRASSERT(pContext->buffer.storedWidth == storedWidth);
     1552        CRASSERT(pContext->buffer.storedHeight == storedHeight);
     1553    }
     1554    else
     1555    {
     1556        storedWidth = pContext->buffer.storedWidth;
     1557        storedHeight = pContext->buffer.storedHeight;
     1558    }
     1559
     1560    if (storedWidth && storedHeight)
     1561    {
     1562        CRBufferState *pBuf = &pContext->buffer;
     1563        GLint cbData;
     1564        void *pData;
     1565
     1566        cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * storedWidth * storedHeight;
     1567
     1568        pData = crAlloc(cbData);
     1569        if (!pData)
     1570        {
     1571            crWarning("crAlloc failed trying to allocate %d of fb data", cbData);
     1572            pBuf->pFrontImg = NULL;
     1573            pBuf->pBackImg = NULL;
     1574            return VERR_NO_MEMORY;
     1575        }
     1576
     1577        rc = SSMR3GetMem(pSSM, pData, cbData);
     1578        AssertRCReturn(rc, rc);
     1579
     1580        pBuf->pFrontImg = pData;
     1581
     1582        pData = crAlloc(cbData);
     1583        if (!pData)
     1584        {
     1585            crWarning("crAlloc failed trying to allocate %d of bb data", cbData);
     1586            pBuf->pBackImg = NULL;
     1587            return VERR_NO_MEMORY;
     1588        }
     1589
     1590        rc = SSMR3GetMem(pSSM, pData, cbData);
     1591        AssertRCReturn(rc, rc);
     1592
     1593        pBuf->pBackImg = pData;
     1594
     1595        if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1596        {
     1597            /* can apply the data right away */
     1598            crStateApplyFBImage(pContext);
     1599            CRASSERT(!pBuf->pFrontImg);
     1600            CRASSERT(!pBuf->pBackImg);
     1601        }
     1602    }
     1603
     1604    CRASSERT(RT_SUCCESS(rc));
     1605    return VINF_SUCCESS;
     1606}
     1607
    10501608DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
    10511609{
     
    11111669    }
    11121670
     1671    if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1672    {
     1673        /* we have a mural data here */
     1674        rc = crVBoxServerLoadMurals(pSSM, version);
     1675        AssertRCReturn(rc, rc);
     1676    }
     1677
     1678    if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA && uiNumElems)
     1679    {
     1680        /* set the current client to allow doing crServerPerformMakeCurrent later */
     1681        CRASSERT(cr_server.numClients);
     1682        cr_server.curClient = cr_server.clients[0];
     1683    }
     1684
     1685    rc = crStateLoadGlobals(pSSM, version);
     1686    AssertRCReturn(rc, rc);
     1687
    11131688    /* Restore context state data */
    11141689    for (ui=0; ui<uiNumElems; ++ui)
     
    11161691        CRContextInfo* pContextInfo;
    11171692        CRContext *pContext;
     1693        CRMuralInfo *pMural = NULL;
     1694        int32_t winId = 0;
    11181695
    11191696        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
     
    11251702        pContext = pContextInfo->pContext;
    11261703
     1704        if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1705        {
     1706            rc = SSMR3GetMem(pSSM, &winId, sizeof(winId));
     1707            AssertRCReturn(rc, rc);
     1708
     1709            if (winId)
     1710            {
     1711                pMural = (CRMuralInfo*)crHashtableSearch(cr_server.muralTable, winId);
     1712                CRASSERT(pMural);
     1713            }
     1714            else
     1715            {
     1716                /* null winId means a dummy mural, get it */
     1717                pMural = crServerGetDummyMural(pContextInfo->CreateInfo.visualBits);
     1718                CRASSERT(pMural);
     1719            }
     1720
     1721            crServerPerformMakeCurrent(pMural, pContextInfo);
     1722        }
     1723
    11271724        rc = crStateLoadContext(pContext, cr_server.contextTable, crVBoxServerGetContextCB, pSSM, version);
    11281725        AssertRCReturn(rc, rc);
    1129     }
    1130 
    1131     /* Load windows */
    1132     rc = SSMR3GetU32(pSSM, &uiNumElems);
    1133     AssertRCReturn(rc, rc);
    1134     for (ui=0; ui<uiNumElems; ++ui)
    1135     {
    1136         CRCreateInfo_t createInfo;
    1137         char psz[200];
    1138         GLint winID;
    1139         unsigned long key;
    1140 
    1141         rc = SSMR3GetMem(pSSM, &key, sizeof(key));
     1726
     1727        /*Restore front/back buffer images*/
     1728        rc = crVBoxServerLoadFBImage(pSSM, version, pContextInfo, pMural);
    11421729        AssertRCReturn(rc, rc);
    1143         rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
     1730    }
     1731
     1732    if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1733    {
     1734        CRContextInfo *pContextInfo;
     1735        CRMuralInfo *pMural;
     1736        GLint ctxId;
     1737
     1738        rc = SSMR3GetU32(pSSM, &uiNumElems);
    11441739        AssertRCReturn(rc, rc);
    1145 
    1146         if (createInfo.pszDpyName)
    1147         {
    1148             rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
     1740        for (ui=0; ui<uiNumElems; ++ui)
     1741        {
     1742            CRbitvalue initialCtxUsage[CR_MAX_BITARRAY];
     1743            CRMuralInfo *pInitialCurMural;
     1744
     1745            rc = SSMR3GetMem(pSSM, &key, sizeof(key));
    11491746            AssertRCReturn(rc, rc);
    1150             createInfo.pszDpyName = psz;
    1151         }
    1152 
    1153         winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key);
    1154         CRASSERT((int64_t)winID == (int64_t)key);
    1155     }
    1156 
    1157     /* Load cr_server.muralTable */
    1158     rc = SSMR3GetU32(pSSM, &uiNumElems);
    1159     AssertRCReturn(rc, rc);
    1160     for (ui=0; ui<uiNumElems; ++ui)
    1161     {
    1162         CRMuralInfo muralInfo;
    1163 
    1164         rc = SSMR3GetMem(pSSM, &key, sizeof(key));
     1747
     1748            rc = SSMR3GetMem(pSSM, &ctxId, sizeof(ctxId));
     1749            AssertRCReturn(rc, rc);
     1750
     1751            pMural = (CRMuralInfo*)crHashtableSearch(cr_server.muralTable, key);
     1752            CRASSERT(pMural);
     1753            if (ctxId)
     1754            {
     1755                pContextInfo = (CRContextInfo *)crHashtableSearch(cr_server.contextTable, ctxId);
     1756                CRASSERT(pContextInfo);
     1757            }
     1758            else
     1759                pContextInfo =  &cr_server.MainContextInfo;
     1760
     1761            crMemcpy(initialCtxUsage, pMural->ctxUsage, sizeof (initialCtxUsage));
     1762            pInitialCurMural = pContextInfo->currentMural;
     1763
     1764            crServerPerformMakeCurrent(pMural, pContextInfo);
     1765
     1766            rc = crVBoxServerLoadFBImage(pSSM, version, pContextInfo, pMural);
     1767            AssertRCReturn(rc, rc);
     1768
     1769            /* restore the reference data, we synchronize it with the HW state in a later crServerPerformMakeCurrent call */
     1770            crMemcpy(pMural->ctxUsage, initialCtxUsage, sizeof (initialCtxUsage));
     1771            pContextInfo->currentMural = pInitialCurMural;
     1772        }
     1773
     1774        if (cr_server.currentCtxInfo != &cr_server.MainContextInfo)
     1775        {
     1776            /* most ogl data gets loaded to hw on chromium 3D state switch, i.e. inside crStateMakeCurrent -> crStateSwitchContext
     1777             * to force the crStateSwitchContext being called later, we need to  set the current context to our dummy one */
     1778            pMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.visualBits);
     1779            CRASSERT(pMural);
     1780            crServerPerformMakeCurrent(pMural, &cr_server.MainContextInfo);
     1781        }
     1782
     1783        cr_server.curClient = NULL;
     1784        cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
     1785    }
     1786    else
     1787    {
     1788        CRServerFreeIDsPool_t dummyIdsPool;
     1789
     1790        /* we have a mural data here */
     1791        rc = crVBoxServerLoadMurals(pSSM, version);
    11651792        AssertRCReturn(rc, rc);
    1166         rc = SSMR3GetMem(pSSM, &muralInfo, RT_OFFSETOF(CRMuralInfo, CreateInfo));
    1167         AssertRCReturn(rc, rc);
    1168 
    1169         if (version <= SHCROGL_SSM_VERSION_BEFORE_FRONT_DRAW_TRACKING)
    1170             muralInfo.bFbDraw = GL_TRUE;
    1171 
    1172         if (muralInfo.pVisibleRects)
    1173         {
    1174             muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects);
    1175             if (!muralInfo.pVisibleRects)
    1176             {
    1177                 return VERR_NO_MEMORY;
    1178             }
    1179 
    1180             rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects);
    1181             AssertRCReturn(rc, rc);
    1182         }
    1183 
    1184         /* Restore windows geometry info */
    1185         crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
    1186         crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
    1187         /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
    1188         if (muralInfo.bReceivedRects)
    1189         {
    1190             crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
    1191         }
    1192         crServerDispatchWindowShow(key, muralInfo.bVisible);
    1193 
    1194         if (muralInfo.pVisibleRects)
    1195         {
    1196             crFree(muralInfo.pVisibleRects);
    1197         }
    1198     }
    1199 
    1200     /* Load starting free context and window IDs */
    1201     rc = SSMR3GetMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
    1202     CRASSERT(rc == VINF_SUCCESS);
     1793
     1794        /* not used any more, just read it out and ignore */
     1795        rc = SSMR3GetMem(pSSM, &dummyIdsPool, sizeof(dummyIdsPool));
     1796        CRASSERT(rc == VINF_SUCCESS);
     1797    }
    12031798
    12041799    /* Load clients info */
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c

    r44026 r44290  
    508508{
    509509    char *pixels=NULL, *tmppixels;
    510     GLuint uid;
    511510    int i, j;
    512511    CRrecti rect, rectwr, sectr;
    513     GLboolean bUsePBO;
     512    GLuint idPBO;
    514513    CRContext *ctx = crStateGetCurrent();
     514    CR_BLITTER_TEXTURE Tex;
    515515
    516516    CRASSERT(mural->fUseFBO);
     
    526526        return;
    527527    }
     528
     529    Tex.width = mural->width;
     530    Tex.height = mural->height;
     531    Tex.target = GL_TEXTURE_2D;
     532    Tex.hwid = mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)];
     533    CRASSERT(Tex.hwid);
    528534
    529535    if (mural->fUseFBO == CR_SERVER_REDIR_FBO_BLT)
     
    547553        if (RT_SUCCESS(rc))
    548554        {
    549             CR_BLITTER_TEXTURE Tex;
    550555            RTRECT Rect;
    551             Tex.width = mural->width;
    552             Tex.height = mural->height;
    553             Tex.target = GL_TEXTURE_2D;
    554             Tex.hwid = mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)];
    555556            Rect.xLeft = 0;
    556557            Rect.yTop = 0;
     
    576577    }
    577578
    578     bUsePBO = cr_server.bUsePBOForReadback && mural->idPBO;
    579 
    580     cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    581 
    582     if (bUsePBO)
    583     {
    584         CRASSERT(mural->idPBO);
    585         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
    586     }
    587     else
    588     {
    589         if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
    590         {
    591             cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    592         }
    593 
    594         pixels = crAlloc(4*mural->fboWidth*mural->fboHeight);
    595         if (!pixels)
    596         {
    597             crWarning("Out of memory in crServerPresentFBO");
    598             return;
    599         }
    600     }
    601 
    602     /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/   
    603     cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
    604 
    605     /*restore gl state*/
    606     uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
    607     cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, uid);
    608 
    609     if (bUsePBO)
    610     {
    611         pixels = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
    612         if (!pixels)
    613         {
    614             crWarning("Failed to MapBuffer in crServerPresentFBO");
    615             return;
    616         }
     579    idPBO = cr_server.bUsePBOForReadback ? mural->idPBO : 0;
     580    if (idPBO)
     581    {
     582        CRASSERT(mural->fboWidth == mural->width);
     583        CRASSERT(mural->fboHeight == mural->height);
     584    }
     585
     586    pixels = CrHlpGetTexImage(ctx, &Tex, idPBO);
     587    if (!pixels)
     588    {
     589        crWarning("CrHlpGetTexImage failed in crServerPresentFBO");
     590        return;
    617591    }
    618592
     
    676650    }
    677651
    678     if (bUsePBO)
    679     {
    680         cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
    681         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
    682     }
    683     else
    684     {
    685         crFree(pixels);
    686         if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
    687         {
    688             cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
    689         }
    690     }
     652    CrHlpFreeTexImage(ctx, idPBO, pixels);
    691653}
    692654
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp

    r43932 r44290  
    810810}
    811811
     812void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData)
     813{
     814    if (idPBO)
     815    {
     816        cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
     817        if (pCurCtx)
     818            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
     819        else
     820            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, NULL);
     821    }
     822    else
     823    {
     824        crFree(pvData);
     825        if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
     826            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
     827    }
     828}
     829
     830void* CrHlpGetTexImage(CRContext *pCurCtx, PCR_BLITTER_TEXTURE pTexture, GLuint idPBO)
     831{
     832    void *pvData = NULL;
     833    cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);
     834
     835    if (idPBO)
     836    {
     837        cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, idPBO);
     838    }
     839    else
     840    {
     841        if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
     842        {
     843            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
     844        }
     845
     846        pvData = crAlloc(4*pTexture->width*pTexture->height);
     847        if (!pvData)
     848        {
     849            crWarning("Out of memory in CrHlpGetTexImage");
     850            return NULL;
     851        }
     852    }
     853
     854    /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
     855    cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvData);
     856
     857    /*restore gl state*/
     858    if (pCurCtx)
     859    {
     860        CRTextureObj *pTObj;
     861        CRTextureLevel *pTImg;
     862        crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);
     863
     864        GLuint uid = pTObj->hwid;
     865        cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);
     866    }
     867    else
     868    {
     869        cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);
     870    }
     871
     872    if (idPBO)
     873    {
     874        pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
     875        if (!pvData)
     876        {
     877            crWarning("Failed to MapBuffer in CrHlpGetTexImage");
     878            return NULL;
     879        }
     880    }
     881
     882    CRASSERT(pvData);
     883    return pvData;
     884}
     885
    812886void SERVER_DISPATCH_APIENTRY
    813887crServerDispatchTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, GLint *pRects)
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c

    r41258 r44290  
    8585    /* give this client a unique number if needed */
    8686    if (!client->number) {
    87         client->number = crServerGenerateID(&cr_server.idsPool.freeClientID);
     87        client->number = client->conn->u32ClientID;
    8888    }
    8989
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r43932 r44290  
    5656        windowID = spuWindow;
    5757    else
    58         windowID = preloadWinID<0 ? crServerGenerateID(&cr_server.idsPool.freeWindowID) : preloadWinID;
     58        windowID = preloadWinID<0 ? (GLint)crHashtableAllocKeys( cr_server.muralTable, 1 ) : preloadWinID;
    5959
    6060    mural->CreateInfo.visualBits = visBits;
    6161    mural->CreateInfo.externalID = windowID;
    6262    mural->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
     63
     64    CR_STATE_SHAREDOBJ_USAGE_INIT(mural);
    6365
    6466    crServerSetupOutputRedirect(mural);
     
    172174        crFree(mural->pVisibleRects);
    173175    }
     176
     177    if (mural->CreateInfo.pszDpyName)
     178        crFree(mural->CreateInfo.pszDpyName);
     179}
     180
     181static void crServerCleanupCtxMuralRefsCB(unsigned long key, void *data1, void *data2)
     182{
     183    CRContextInfo *ctxInfo = (CRContextInfo *) data1;
     184    CRMuralInfo *mural = (CRMuralInfo *) data2;
     185
     186    if (ctxInfo->currentMural == mural)
     187        ctxInfo->currentMural = NULL;
    174188}
    175189
     
    195209
    196210    crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
     211
     212    crHashtableWalk(cr_server.contextTable, crServerCleanupCtxMuralRefsCB, mural);
    197213
    198214    crServerMuralTerm(mural);
     
    268284    }
    269285
    270     if (mural->CreateInfo.pszDpyName)
    271         crFree(mural->CreateInfo.pszDpyName);
    272 
    273286    crHashtableDelete(cr_server.muralTable, window, crFree);
    274287}
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c

    r43748 r44290  
    177177    CRASSERT(ctx);
    178178
     179    if (ctx == 0)
     180    {
     181        crWarning("request to destroy a default context, ignoring");
     182        return;
     183    }
     184
    179185    context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
    180186    CRASSERT(context);
     
    352358    {
    353359        renderspuMakeCurrent(0, 0, pCtx->id);
     360        pCtx->currentWindow=0;
    354361    }
    355362}
     
    362369
    363370    CRASSERT(win >= 0);
     371    if (win == 0)
     372    {
     373        crWarning("request to destroy a default mural, ignoring");
     374        return;
     375    }
    364376    window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
    365377    if (window) {
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c

    r43285 r44290  
    12541254    }
    12551255
    1256     sharedContext->currentWindow = window;
    1257 
    12581256    return GL_TRUE;
    12591257}
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