state_snapshot.c revision ad27e1d5e48ca41245120c331cc88b50464813ce
2271N/A * available from http://www.virtualbox.org. This file is free software;
2271N/A#include "state_internals.h"
4070N/A#include "state/cr_statetypes.h"
4070N/A#include "state/cr_texture.h"
2271N/A#include "cr_string.h"
4070N/A#include "cr_pixeldata.h"
3661N/A * On the bright side it's fast, though it's not really needed as it's not that often operation.
2271N/A * Second way would be to implement full dispatch api table and substitute diff_api during saving/loading.
4070N/A * Then if we implement that api in a similar way to packer/unpacker with a change to store/load
2271N/A * Restoring state in such case would look like unpacking commands from pSSM instead of network buffer.
2271N/A * This would be slower (who cares) but most likely will not require any code changes to support in future.
2271N/A * We will reduce amount of saved data as we'd save only changed state parts, but I doubt it'd be that much.
if (!*pBuffer)
return VERR_NO_MEMORY;
for (i = 0; i < CR_MAX_MIPMAP_LEVELS; i++) {
char *pImg;
if (!bound)
#ifdef DEBUG
#ifdef DEBUG
GLint w,h=0;
#ifdef DEBUG
return VINF_SUCCESS;
for (i = 0; i < CR_MAX_MIPMAP_LEVELS; i++) {
return VINF_SUCCESS;
return rc;
if (pTexture)
return VINF_SUCCESS;
static int32_t crStateLoadTextureObjPtr(CRTextureObj **pTexture, CRContext *pContext, GLenum target, PSSMHANDLE pSSM)
if (!*pTexture)
return VINF_SUCCESS;
if (texName)
switch (target)
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
#ifdef CR_OPENGL_VERSION_1_2
case GL_TEXTURE_3D:
#ifdef CR_ARB_texture_cube_map
case GL_TEXTURE_CUBE_MAP_ARB:
#ifdef CR_NV_texture_rectangle
case GL_TEXTURE_RECTANGLE_NV:
return rc;
#ifdef CR_ARB_texture_cube_map
#ifdef CR_NV_texture_rectangle
return rc;
static int32_t crStateLoadTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, CRContext *pContext, PSSMHANDLE pSSM)
#ifdef CR_ARB_texture_cube_map
rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureCubeMap, pContext, GL_TEXTURE_CUBE_MAP_ARB, pSSM);
#ifdef CR_NV_texture_rectangle
rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureRect, pContext, GL_TEXTURE_RECTANGLE_NV, pSSM);
return rc;
for (i=0; i<GLEVAL_TOT; ++i)
return VINF_SUCCESS;
for (i=0; i<GLEVAL_TOT; ++i)
rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat));
return VINF_SUCCESS;
for (i=0; i<GLEVAL_TOT; ++i)
if (bReallocMem)
return VINF_SUCCESS;
for (i=0; i<GLEVAL_TOT; ++i)
if (bReallocMem)
return VINF_SUCCESS;
int32_t i;
for (i=0; i<GLEVAL_TOT; ++i)
pDst[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff;
pDst[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff;
pDst[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff;
pDst[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff;
int32_t i;
for (i=0; i<GLEVAL_TOT; ++i)
pDst[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff;
pDst[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff;
pDst[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff;
pDst[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff;
/*We could get here even though retainBufferData is false on host side, in case when we're taking snapshot
unsigned long key;
if (*ppProgram)
return VINF_SUCCESS;
if (pStr)
if (len!=0)
return pStr;
if (sLen>0)
unsigned long key;
return pShader;
GLuint i;
if (activeUniforms>0)
if (!name)
for (i=0; i<activeUniforms; ++i)
if (activeUniforms>0)
for (i=0; i<activeUniforms; ++i)
if (!pIndexStr)
for (j=0; j<size; ++j)
#ifdef CR_EXT_compiled_vertex_array
return VINF_SUCCESS;
static int32_t crStateLoadClientPointer(CRVertexArrays *pArrays, int32_t index, CRContext *pContext, PSSMHANDLE pSSM)
cp->buffer = ui==0 ? pContext->bufferobject.nullBuffer : crHashtableSearch(pContext->shared->buffersTable, ui);
#ifdef CR_EXT_compiled_vertex_array
rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&cp->p, cp->stride*(pArrays->lockFirst+pArrays->lockCount));
return VINF_SUCCESS;
for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
#ifdef CR_NV_vertex_program
for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
return VINF_SUCCESS;
for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
#ifdef CR_NV_vertex_program
for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
#ifdef CR_NV_vertex_program
for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
return VINF_SUCCESS;
crWarning("Saving state with %d display lists, unsupported", crHashtableNumElements(pContext->shared->dlistTable));
for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
#ifdef CR_ARB_texture_cube_map
#ifdef CR_NV_texture_rectangle
if (bSaveShared)
if (ui32)
#ifdef CR_ARB_texture_cube_map
#ifdef CR_NV_texture_rectangle
for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
rc = SSMR3PutMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
#ifdef CR_ARB_vertex_buffer_object
if (bSaveShared)
#ifdef CR_ARB_pixel_buffer_object
for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
#ifdef CR_EXT_framebuffer_object
if (bSaveShared)
rc = SSMR3PutU32(pSSM, pContext->framebufferobject.drawFB?pContext->framebufferobject.drawFB->id:0);
rc = SSMR3PutU32(pSSM, pContext->framebufferobject.readFB?pContext->framebufferobject.readFB->id:0);
rc = SSMR3PutU32(pSSM, pContext->framebufferobject.renderbuffer?pContext->framebufferobject.renderbuffer->id:0);
#ifdef CR_OPENGL_VERSION_2_0
if (!pData)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
typedef struct _crFindSharedCtxParms {
(void) key;
unsigned long key;
if (!pTmpContext)
return VERR_NO_MEMORY;
for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
for (j=0; j<GLEVAL_TOT; ++j)
#ifdef CR_ARB_vertex_buffer_object
/*@todo, that should be removed probably as those should hold the offset values, so loading should be fine
#ifdef CR_EXT_compiled_vertex_array
for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
# ifdef CR_NV_vertex_program
for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
#ifdef CR_ARB_vertex_buffer_object
for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
# ifdef CR_NV_vertex_program
for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
#ifdef CR_ARB_texture_cube_map
#ifdef CR_NV_texture_rectangle
/* Don't have to worry about pContext->transform.current as it'd be set in crStateSetCurrent call */
/*SLC_COPYPTR(transform.currentStack);*/
for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
#ifdef CR_OPENGL_VERSION_2_0
for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
#ifdef CR_ARB_texture_cube_map
#ifdef CR_NV_texture_rectangle
if (bLoadShared)
for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
rc = SSMR3GetMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[k], pContext, pSSM);
#ifdef CR_ARB_vertex_buffer_object
if (key==0)
if (key!=0)
#define CRS_GET_BO(name) (((name)==0) ? (pContext->bufferobject.nullBuffer) : crHashtableSearch(pContext->shared->buffersTable, name))
#ifdef CR_ARB_pixel_buffer_object
for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
#ifdef CR_EXT_framebuffer_object
if (bLoadShared)
#ifdef CR_OPENGL_VERSION_2_0
for (k=0; k<numShaders; ++k)
crHashtableAdd(pProgram->currentState.attachedShaders, key, crHashtableSearch(pContext->glsl.shaders, key));
for (k=0; k<numShaders; ++k)
pProgram->currentState.pAttribs = (CRGLSLAttrib*) crAlloc(pProgram->currentState.cAttribs*sizeof(CRGLSLAttrib));
rc = SSMR3GetMem(pSSM, &pProgram->currentState.pAttribs[k].index, sizeof(pProgram->currentState.pAttribs[k].index));
pProgram->activeState.pAttribs = (CRGLSLAttrib*) crAlloc(pProgram->activeState.cAttribs*sizeof(CRGLSLAttrib));
rc = SSMR3GetMem(pSSM, &pProgram->activeState.pAttribs[k].index, sizeof(pProgram->activeState.pAttribs[k].index));
if (!pData)
return VERR_NO_MEMORY;
#ifdef CR_EXT_blend_color
#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
#if defined(CR_EXT_blend_func_separate)
#ifdef CR_ARB_vertex_buffer_object
# ifdef CR_ARB_pixel_buffer_object
for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
#ifdef CR_NV_vertex_program
for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
for (i=0; i<GLEVAL_TOT; i++)
#ifdef CR_NV_vertex_program
#ifdef CR_NV_fog_distance
#ifdef CR_EXT_fog_coord
#ifdef CR_EXT_clip_volume_hint
#ifdef CR_ARB_texture_compression
#ifdef CR_SGIS_generate_mipmap
for (i=0; i<CR_MAX_LIGHTS; ++i)
#ifdef CR_ARB_point_parameters
#ifdef CR_ARB_point_sprite
for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
for (i=0; i<CR_MAX_VERTEX_ATTRIBS; ++i)
for (i=0; i<CR_MAX_VERTEX_PROGRAM_ENV_PARAMS; ++i)
for (i=0; i<CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS; ++i)
for (i=0; i<CR_MAX_GENERAL_COMBINERS; ++i)
for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
return VINF_SUCCESS;