Index: trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c	(revision 16939)
+++ trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c	(revision 16969)
@@ -23,4 +23,5 @@
 #include "state.h"
 #include "state/cr_statetypes.h"
+#include "state/cr_texture.h"
 #include "cr_mem.h"
 
@@ -84,4 +85,26 @@
                 AssertRCReturn(rc, rc);
             }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+            /* Note, this is not a bug. 
+             * Even with CR_STATE_NO_TEXTURE_IMAGE_STORE defined, it's possible that ptl->img!=NULL.
+             * For ex. we're saving snapshot right after it was loaded
+             * and some context hasn't been used by the guest application yet
+             * (pContext->texture.bResyncNeeded==GL_TRUE).
+             */
+            else if (ptl->bytes)
+            {
+                char *pImg;
+
+                pImg = crAlloc(ptl->bytes);
+                if (!pImg) return VERR_NO_MEMORY;
+
+                diff_api.BindTexture(pTexture->target, pTexture->name);
+                diff_api.GetTexImage(pTexture->target, i, ptl->format, ptl->type, pImg);
+
+                rc = SSMR3PutMem(pSSM, pImg, ptl->bytes);
+                crFree(pImg);
+                AssertRCReturn(rc, rc);
+            }
+#endif
         }
     }
@@ -115,4 +138,15 @@
                 AssertRCReturn(rc, rc);
             }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+            /* Same story as in crStateSaveTextureObjData */
+            else if (ptl->bytes)
+            {
+                ptl->img = crAlloc(ptl->bytes);
+                if (!ptl->img) return VERR_NO_MEMORY;
+
+                rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
+                AssertRCReturn(rc, rc);
+            }
+#endif
             crStateTextureInitTextureFormat(ptl, ptl->internalFormat);
 
@@ -557,4 +591,24 @@
     crHashtableWalk(pContext->shared->textureTable, crStateSaveSharedTextureCB, pSSM);
 
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+	/* Restore previous texture bindings via diff_api */
+	if (ui32)
+    {
+        CRTextureUnit *pTexUnit;
+
+        pTexUnit = &pContext->texture.unit[pContext->texture.curTextureUnit];
+
+	    diff_api.BindTexture(GL_TEXTURE_1D, pTexUnit->currentTexture1D->name);
+	    diff_api.BindTexture(GL_TEXTURE_2D, pTexUnit->currentTexture2D->name);
+	    diff_api.BindTexture(GL_TEXTURE_3D, pTexUnit->currentTexture3D->name);
+#ifdef CR_ARB_texture_cube_map
+    	diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, pTexUnit->currentTextureCubeMap->name);
+#endif
+#ifdef CR_NV_texture_rectangle
+    	diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, pTexUnit->currentTextureRect->name);
+#endif
+    }
+#endif
+
     /* Save current texture pointers */
     for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
Index: trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c	(revision 16939)
+++ trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c	(revision 16969)
@@ -594,6 +594,6 @@
 void
 crStateTextureObjectDiff(CRContext *fromCtx,
-                                                 const CRbitvalue *bitID, const CRbitvalue *nbitID,
-                                                 CRTextureObj *tobj, GLboolean alwaysDirty)
+                         const CRbitvalue *bitID, const CRbitvalue *nbitID,
+                         CRTextureObj *tobj, GLboolean alwaysDirty)
 {
     CRTextureState *from = &(fromCtx->texture);
@@ -684,6 +684,6 @@
                         if (tl->compressed) {
                             diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
-                                                                                             tl->internalFormat, tl->width,
-                                                                                             tl->border, tl->bytes, tl->img);
+                                                             tl->internalFormat, tl->width,
+                                                             tl->border, tl->bytes, tl->img);
                         }
                         else {
@@ -697,10 +697,19 @@
                             }
                             diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
-                                                                    tl->internalFormat,
-                                                                    tl->width, tl->border,
-                                                                    tl->format, tl->type, tl->img);
+                                                tl->internalFormat,
+                                                tl->width, tl->border,
+                                                tl->format, tl->type, tl->img);
                         }
                         if (!alwaysDirty)
+                        {
                             CLEARDIRTY(tl->dirty, nbitID);
+                        }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+                        else
+                        {
+                            crFree(tl->img);
+                            tl->img = NULL;
+                        }
+#endif
                     }
                 }
@@ -715,9 +724,10 @@
                             diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
                         }
+
                         if (tl->compressed) {
                             diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
-                                                                                             tl->internalFormat, tl->width,
-                                                                                             tl->height, tl->border,
-                                                                                             tl->bytes, tl->img);
+                                     tl->internalFormat, tl->width,
+                                     tl->height, tl->border,
+                                     tl->bytes, tl->img);
                         }
                         else {
@@ -728,10 +738,20 @@
                             diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
                             diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
-                                                                    tl->internalFormat,
-                                                                    tl->width, tl->height, tl->border,
-                                                                    tl->format, tl->type, tl->img);
-                        }
+                                                tl->internalFormat,
+                                                tl->width, tl->height, tl->border,
+                                                tl->format, tl->type, tl->img);
+                        }
+
                         if (!alwaysDirty)
+                        {
                             CLEARDIRTY(tl->dirty, nbitID);
+                        }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+                        else
+                        {
+                            crFree(tl->img);
+                            tl->img = NULL;
+                        }
+#endif
                     }
                 }
@@ -749,7 +769,7 @@
                         if (tl->compressed) {
                             diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
-                                                                                             tl->internalFormat, tl->width,
-                                                                                             tl->height, tl->depth,
-                                                                                             tl->border, tl->bytes, tl->img);
+                                                             tl->internalFormat, tl->width,
+                                                             tl->height, tl->depth,
+                                                             tl->border, tl->bytes, tl->img);
                         }
                         else {
@@ -760,11 +780,20 @@
                             diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
                             diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
-                                                                    tl->internalFormat,
-                                                                    tl->width, tl->height, tl->depth,
-                                                                    tl->border, tl->format,
-                                                                    tl->type, tl->img);
+                                                tl->internalFormat,
+                                                tl->width, tl->height, tl->depth,
+                                                tl->border, tl->format,
+                                                tl->type, tl->img);
                         }
                         if (!alwaysDirty)
+                        {
                             CLEARDIRTY(tl->dirty, nbitID);
+                        }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+                        else
+                        {
+                            crFree(tl->img);
+                            tl->img = NULL;
+                        }
+#endif
                     }
                 }
@@ -781,7 +810,7 @@
                         if (tl->compressed) {
                             diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
-                                                                                             tl->internalFormat, tl->width,
-                                                                                             tl->height, tl->border,
-                                                                                             tl->bytes, tl->img);
+                                                             tl->internalFormat, tl->width,
+                                                             tl->height, tl->border,
+                                                             tl->bytes, tl->img);
                         }
                         else {
@@ -792,10 +821,19 @@
                             diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
                             diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
-                                                                    tl->internalFormat,
-                                                                    tl->width, tl->height, tl->border,
-                                                                    tl->format, tl->type, tl->img);
+                                                tl->internalFormat,
+                                                tl->width, tl->height, tl->border,
+                                                tl->format, tl->type, tl->img);
                         }
                         if (!alwaysDirty)
+                        {
                             CLEARDIRTY(tl->dirty, nbitID);
+                        }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+                        else
+                        {
+                            crFree(tl->img);
+                            tl->img = NULL;
+                        }
+#endif
                     }
                 }
@@ -814,11 +852,11 @@
                             if (tl->generateMipmap) {
                                 diff_api.TexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
-                                                                             GL_GENERATE_MIPMAP_SGIS, 1);
+                                                       GL_GENERATE_MIPMAP_SGIS, 1);
                             }
                             if (tl->compressed) {
                                 diff_api.CompressedTexImage2DARB(target,
-                                                                                                 lvl, tl->internalFormat,
-                                                                                                 tl->width, tl->height,
-                                                                                                 tl->border, tl->bytes, tl->img);
+                                                                 lvl, tl->internalFormat,
+                                                                 tl->width, tl->height,
+                                                                 tl->border, tl->bytes, tl->img);
                             }
                             else {
@@ -829,10 +867,19 @@
                                 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
                                 diff_api.TexImage2D(target, lvl,
-                                                                        tl->internalFormat,
-                                                                        tl->width, tl->height, tl->border,
-                                                                        tl->format, tl->type, tl->img);
+                                                    tl->internalFormat,
+                                                    tl->width, tl->height, tl->border,
+                                                    tl->format, tl->type, tl->img);
                             }
                             if (!alwaysDirty)
+                            {
                                 CLEARDIRTY(tl->dirty, nbitID);
+                            }
+#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
+                            else
+                            {
+                                crFree(tl->img);
+                                tl->img = NULL;
+                            }
+#endif
                         }
                     } /* for lvl */
Index: trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_teximage.c
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_teximage.c	(revision 16939)
+++ trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_teximage.c	(revision 16969)
@@ -544,4 +544,5 @@
         tl->bytes = crImageSize(format, type, width, 1);
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     if (tl->bytes)
     {
@@ -553,11 +554,12 @@
         {
             crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
-                                     "glTexImage1D out of memory");
+                         "glTexImage1D out of memory");
             return;
         }
         if (pixels)
             crPixelCopy1D((GLvoid *) tl->img, format, type,
-                                        pixels, format, type, width, &(c->unpack));
-    }
+                          pixels, format, type, width, &(c->unpack));
+    }
+#endif
 
     tl->width = width;
@@ -594,6 +596,6 @@
 void STATE_APIENTRY
 crStateTexImage2D(GLenum target, GLint level, GLint internalFormat,
-                                    GLsizei width, GLsizei height, GLint border,
-                                    GLenum format, GLenum type, const GLvoid * pixels)
+                  GLsizei width, GLsizei height, GLint border,
+                  GLenum format, GLenum type, const GLvoid * pixels)
 {
     CRContext *g = GetCurrentContext();
@@ -639,4 +641,5 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     /* allocate the image buffer and fill it */
     if (tl->bytes)
@@ -649,5 +652,5 @@
         {
             crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
-                                     "glTexImage2D out of memory");
+                         "glTexImage2D out of memory");
             return;
         }
@@ -661,9 +664,10 @@
             {
                 crPixelCopy2D(width, height,
-                                            (GLvoid *) tl->img, format, type, NULL, /* dst */
-                                            pixels, format, type, &(c->unpack));    /* src */
+                              (GLvoid *) tl->img, format, type, NULL, /* dst */
+                              pixels, format, type, &(c->unpack));    /* src */
             }
         }
     }
+#endif
 
     tl->width = width;
@@ -741,4 +745,5 @@
         tl->bytes = crTextureSize(format, type, width, height, depth);
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     if (tl->bytes)
     {
@@ -750,11 +755,12 @@
         {
             crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
-                                     "glTexImage3D out of memory");
+                         "glTexImage3D out of memory");
             return;
         }
         if (pixels)
             crPixelCopy3D(width, height, depth, (GLvoid *) (tl->img), format, type,
-                                        NULL, pixels, format, type, &(c->unpack));
-    }
+                          NULL, pixels, format, type, &(c->unpack));
+    }
+#endif
 
     tl->internalFormat = internalFormat;
@@ -820,9 +826,11 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     xoffset += tl->border;
 
     crPixelCopy1D((void *) (tl->img + xoffset * tl->bytesPerPixel),
-                                tl->format, tl->type,
-                                pixels, format, type, width, &(c->unpack));
+                  tl->format, tl->type,
+                  pixels, format, type, width, &(c->unpack));
+#endif
 
 #ifdef CR_SGIS_generate_mipmap
@@ -844,6 +852,6 @@
 void STATE_APIENTRY
 crStateTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                         GLsizei width, GLsizei height,
-                                         GLenum format, GLenum type, const GLvoid * pixels)
+                     GLsizei width, GLsizei height,
+                     GLenum format, GLenum type, const GLvoid * pixels)
 {
     CRContext *g = GetCurrentContext();
@@ -855,6 +863,8 @@
     GLubyte *subimg = NULL;
     GLubyte *img = NULL;
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     GLubyte *src;
     int i;
+#endif
 
     FLUSH();
@@ -869,12 +879,12 @@
     CRASSERT(tl);
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     xoffset += tl->border;
     yoffset += tl->border;
 
-    subimg =
-        (GLubyte *) crAlloc(crImageSize(tl->format, tl->type, width, height));
+    subimg = (GLubyte *) crAlloc(crImageSize(tl->format, tl->type, width, height));
 
     crPixelCopy2D(width, height, subimg, tl->format, tl->type, NULL,    /* dst */
-                                pixels, format, type, &(c->unpack));    /* src */
+                  pixels, format, type, &(c->unpack));                  /* src */
 
     img = tl->img +
@@ -892,4 +902,5 @@
 
     crFree(subimg);
+#endif
 
 #ifdef CR_SGIS_generate_mipmap
@@ -925,6 +936,8 @@
     GLubyte *subimg = NULL;
     GLubyte *img = NULL;
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     GLubyte *src;
     int i;
+#endif
 
     FLUSH();
@@ -935,4 +948,5 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     xoffset += tl->border;
     yoffset += tl->border;
@@ -944,5 +958,5 @@
 
     crPixelCopy3D(width, height, depth, subimg, tl->format, tl->type, NULL,
-                                pixels, format, type, &(c->unpack));
+                  pixels, format, type, &(c->unpack));
 
     img = tl->img + xoffset * tl->bytesPerPixel +
@@ -961,4 +975,5 @@
 
     crFree(subimg);
+#endif
 
 #ifdef CR_SGIS_generate_mipmap
@@ -1014,4 +1029,5 @@
         tl->bytes = imageSize;
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     if (tl->bytes)
     {
@@ -1023,5 +1039,5 @@
         {
             crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
-                                     "glTexImage1D out of memory");
+                         "glTexImage1D out of memory");
             return;
         }
@@ -1029,4 +1045,5 @@
             crMemcpy(tl->img, data, imageSize);
     }
+#endif
 
     tl->width = width;
@@ -1059,7 +1076,7 @@
 void STATE_APIENTRY
 crStateCompressedTexImage2DARB(GLenum target, GLint level,
-                                                             GLenum internalFormat, GLsizei width,
-                                                             GLsizei height, GLint border,
-                                                             GLsizei imageSize, const GLvoid * data)
+                               GLenum internalFormat, GLsizei width,
+                               GLsizei height, GLint border,
+                               GLsizei imageSize, const GLvoid * data)
 {
     CRContext *g = GetCurrentContext();
@@ -1092,4 +1109,5 @@
         tl->bytes = imageSize;
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     if (tl->bytes)
     {
@@ -1101,5 +1119,5 @@
         {
             crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
-                                     "glTexImage2D out of memory");
+                         "glTexImage2D out of memory");
             return;
         }
@@ -1107,4 +1125,5 @@
             crMemcpy(tl->img, data, imageSize);
     }
+#endif
 
     tl->width = width;
@@ -1171,4 +1190,5 @@
         tl->bytes = imageSize;
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     if (tl->bytes)
     {
@@ -1180,5 +1200,5 @@
         {
             crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
-                                     "glCompressedTexImage3D out of memory");
+                         "glCompressedTexImage3D out of memory");
             return;
         }
@@ -1186,4 +1206,5 @@
             crMemcpy(tl->img, data, imageSize);
     }
+#endif
 
     tl->width = width;
@@ -1234,4 +1255,5 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     xoffset += tl->border;
 
@@ -1242,5 +1264,7 @@
     else {
         /* XXX this depends on the exact compression method */
-    }
+        crWarning("Not implemented part crStateCompressedTexSubImage1DARB");
+    }
+#endif
 
 #ifdef CR_SGIS_generate_mipmap
@@ -1281,9 +1305,11 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     xoffset += tl->border;
     yoffset += tl->border;
 
-    if (xoffset == 0 && width == tl->width &&
-            yoffset == 0 && height == tl->height) {
+    if (xoffset == 0 && width == tl->width 
+        && yoffset == 0 && height == tl->height) 
+    {
         /* just memcpy */
         crMemcpy(tl->img, data, imageSize);
@@ -1291,5 +1317,7 @@
     else {
         /* XXX this depends on the exact compression method */
-    }
+        crWarning("Not implemented part crStateCompressedTexSubImage2DARB");
+    }
+#endif
 
 #ifdef CR_SGIS_generate_mipmap
@@ -1331,4 +1359,5 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     xoffset += tl->border;
     yoffset += tl->border;
@@ -1336,6 +1365,6 @@
 
     if (xoffset == 0 && width == tl->width &&
-            yoffset == 0 && height == tl->height &&
-            zoffset == 0 && depth == tl->depth) {
+        yoffset == 0 && height == tl->height &&
+        zoffset == 0 && depth == tl->depth) {
         /* just memcpy */
         crMemcpy(tl->img, data, imageSize);
@@ -1343,5 +1372,7 @@
     else {
         /* XXX this depends on the exact compression method */
-    }
+        crWarning("Not implemented part crStateCompressedTexSubImage3DARB");
+    }
+#endif
 
 #ifdef CR_SGIS_generate_mipmap
@@ -1388,5 +1419,9 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
     crMemcpy(img, tl->img, tl->bytes);
+#else
+    diff_api.GetCompressedTexImageARB(target, level, img);
+#endif
 }
 
@@ -1394,5 +1429,5 @@
 void STATE_APIENTRY
 crStateGetTexImage(GLenum target, GLint level, GLenum format,
-                                     GLenum type, GLvoid * pixels)
+                   GLenum type, GLvoid * pixels)
 {
     CRContext *g = GetCurrentContext();
@@ -1453,16 +1488,20 @@
     }
 
+#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
 #ifdef CR_OPENGL_VERSION_1_2
     if (target == GL_TEXTURE_3D)
     {
         crPixelCopy3D(tl->width, tl->height, tl->depth, (GLvoid *) pixels, format,
-                                    type, NULL, (tl->img), format, type, &(c->pack));
+                      type, NULL, (tl->img), format, type, &(c->pack));
     }
     else
 #endif
-    if ((target == GL_TEXTURE_2D) || (target == GL_TEXTURE_1D))
+    if ((target == GL_TEXTURE_1D) || (target == GL_TEXTURE_2D))
     {
         crPixelCopy2D(tl->width, tl->height, (GLvoid *) pixels, format, type, NULL, /* dst */
-                                    (tl->img), format, type, &(c->pack));   /* src */
-    }
-}
+                      tl->img, format, type, &(c->pack));                           /* src */
+    }
+#else
+    diff_api.GetTexImage(target, level, format, type, pixels);
+#endif
+}
