summaryrefslogtreecommitdiff
path: root/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c')
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c332
1 files changed, 292 insertions, 40 deletions
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
index d46a9561..c8e616d2 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
@@ -8,6 +8,8 @@
#include "cr_error.h"
#include "cr_mem.h"
#include "cr_pixeldata.h"
+#include <iprt/err.h>
+#include <stdio.h>
void crStateDiffContext( CRContext *from, CRContext *to )
{
@@ -121,12 +123,165 @@ void crStateDiffContext( CRContext *from, CRContext *to )
}
}
-void crStateApplyFBImage(CRContext *to)
+void crStateFreeFBImageLegacy(CRContext *to)
+{
+ if (to->buffer.pFrontImg)
+ {
+ crFree(to->buffer.pFrontImg);
+ to->buffer.pFrontImg = NULL;
+ }
+ if (to->buffer.pBackImg)
+ {
+ crFree(to->buffer.pBackImg);
+ to->buffer.pBackImg = NULL;
+ }
+
+ to->buffer.storedWidth = 0;
+ to->buffer.storedHeight = 0;
+}
+
+int crStateAcquireFBImage(CRContext *to, CRFBData *data)
+{
+ CRBufferState *pBuf = &to->buffer;
+ CRPixelPackState packing = to->client.pack;
+ uint32_t i;
+
+ diff_api.PixelStorei(GL_PACK_SKIP_ROWS, 0);
+ diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ diff_api.PixelStorei(GL_PACK_ALIGNMENT, 1);
+ diff_api.PixelStorei(GL_PACK_ROW_LENGTH, 0);
+ diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
+ diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, 0);
+ diff_api.PixelStorei(GL_PACK_SWAP_BYTES, 0);
+ diff_api.PixelStorei(GL_PACK_LSB_FIRST, 0);
+
+ if (to->bufferobject.packBuffer->hwid>0)
+ {
+ diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+ }
+
+ for (i = 0; i < data->cElements; ++i)
+ {
+ CRFBDataElement *el = &data->aElements[i];
+
+ if (el->enmFormat == GL_DEPTH_COMPONENT || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ if (!to->buffer.depthTest)
+ {
+ diff_api.Enable(GL_DEPTH_TEST);
+ }
+ if (to->pixel.depthScale != 1.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_SCALE, 1.0f);
+ }
+ if (to->pixel.depthBias != 0.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_BIAS, 0.0f);
+ }
+ }
+ if (el->enmFormat == GL_STENCIL_INDEX || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ if (!to->stencil.stencilTest)
+ {
+ diff_api.Enable(GL_STENCIL_TEST);
+ }
+ if (to->pixel.mapStencil)
+ {
+ diff_api.PixelTransferi (GL_MAP_STENCIL, GL_FALSE);
+ }
+ if (to->pixel.indexOffset)
+ {
+ diff_api.PixelTransferi (GL_INDEX_OFFSET, 0);
+ }
+ if (to->pixel.indexShift)
+ {
+ diff_api.PixelTransferi (GL_INDEX_SHIFT, 0);
+ }
+ }
+
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, el->idFBO);
+
+ if (el->enmBuffer)
+ diff_api.ReadBuffer(el->enmBuffer);
+
+ diff_api.ReadPixels(el->posX, el->posY, el->width, el->height, el->enmFormat, el->enmType, el->pvData);
+ crDebug("Acquired %d;%d;%d;%d;%d;0x%p fb image", el->enmBuffer, el->width, el->height, el->enmFormat, el->enmType, el->pvData);
+
+ if (el->enmFormat == GL_DEPTH_COMPONENT || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ if (to->pixel.depthScale != 1.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_SCALE, to->pixel.depthScale);
+ }
+ if (to->pixel.depthBias != 0.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_BIAS, to->pixel.depthBias);
+ }
+ if (!to->buffer.depthTest)
+ {
+ diff_api.Disable(GL_DEPTH_TEST);
+ }
+ }
+ if (el->enmFormat == GL_STENCIL_INDEX || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ if (to->pixel.indexOffset)
+ {
+ diff_api.PixelTransferi (GL_INDEX_OFFSET, to->pixel.indexOffset);
+ }
+ if (to->pixel.indexShift)
+ {
+ diff_api.PixelTransferi (GL_INDEX_SHIFT, to->pixel.indexShift);
+ }
+ if (to->pixel.mapStencil)
+ {
+ diff_api.PixelTransferi (GL_MAP_STENCIL, GL_TRUE);
+ }
+ if (!to->stencil.stencilTest)
+ {
+ diff_api.Disable(GL_STENCIL_TEST);
+ }
+ }
+ }
+
+ if (to->bufferobject.packBuffer->hwid>0)
+ {
+ diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, to->bufferobject.packBuffer->hwid);
+ }
+ if (to->framebufferobject.readFB)
+ {
+ CRASSERT(to->framebufferobject.readFB->hwid);
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, to->framebufferobject.readFB->hwid);
+ diff_api.ReadBuffer(to->framebufferobject.readFB->readbuffer);
+
+ }
+ else if (data->idOverrrideFBO)
+ {
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, data->idOverrrideFBO);
+ diff_api.ReadBuffer(GL_COLOR_ATTACHMENT0);
+ }
+ else
+ {
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
+ diff_api.ReadBuffer(to->buffer.readBuffer);
+ }
+
+ diff_api.PixelStorei(GL_PACK_SKIP_ROWS, packing.skipRows);
+ diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, packing.skipPixels);
+ diff_api.PixelStorei(GL_PACK_ALIGNMENT, packing.alignment);
+ diff_api.PixelStorei(GL_PACK_ROW_LENGTH, packing.rowLength);
+ diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, packing.imageHeight);
+ diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, packing.skipImages);
+ diff_api.PixelStorei(GL_PACK_SWAP_BYTES, packing.swapBytes);
+ diff_api.PixelStorei(GL_PACK_LSB_FIRST, packing.psLSBFirst);
+ return VINF_SUCCESS;
+}
+
+void crStateApplyFBImage(CRContext *to, CRFBData *data)
{
- if (to->buffer.pFrontImg || to->buffer.pBackImg)
{
CRBufferState *pBuf = &to->buffer;
CRPixelPackState unpack = to->client.unpack;
+ uint32_t i;
diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
@@ -137,11 +292,6 @@ void crStateApplyFBImage(CRContext *to)
diff_api.PixelStorei(GL_UNPACK_SWAP_BYTES, 0);
diff_api.PixelStorei(GL_UNPACK_LSB_FIRST, 0);
- if (to->framebufferobject.drawFB)
- {
- diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
- }
-
if (to->bufferobject.unpackBuffer->hwid>0)
{
diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
@@ -151,25 +301,84 @@ void crStateApplyFBImage(CRContext *to)
diff_api.Disable(GL_SCISSOR_TEST);
diff_api.Disable(GL_BLEND);
diff_api.Disable(GL_COLOR_LOGIC_OP);
+ diff_api.Disable(GL_DEPTH_TEST);
+ diff_api.Disable(GL_STENCIL_TEST);
- if (pBuf->pFrontImg)
+ for (i = 0; i < data->cElements; ++i)
{
- diff_api.DrawBuffer(GL_FRONT);
- diff_api.WindowPos2iARB(0, 0);
- diff_api.DrawPixels(pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBuf->pFrontImg);
- crDebug("Applied %ix%i fb image", pBuf->storedWidth, pBuf->storedHeight);
- crFree(pBuf->pFrontImg);
- pBuf->pFrontImg = NULL;
- }
+ CRFBDataElement *el = &data->aElements[i];
+#if 0
+ char fname[200];
+ sprintf(fname, "./img_apply_%p_%d_%d.tga", to, i, el->enmFormat);
+ crDumpNamedTGA(fname, el->width, el->height, el->pvData);
+#endif
- if (pBuf->pBackImg)
- {
- diff_api.DrawBuffer(GL_BACK);
- diff_api.WindowPos2iARB(0, 0);
- diff_api.DrawPixels(pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBuf->pBackImg);
- crDebug("Applied %ix%i bb image", pBuf->storedWidth, pBuf->storedHeight);
- crFree(pBuf->pBackImg);
- pBuf->pBackImg = NULL;
+ if (el->enmFormat == GL_DEPTH_COMPONENT || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ diff_api.Enable(GL_DEPTH_TEST);
+ if (to->pixel.depthScale != 1.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_SCALE, 1.0f);
+ }
+ if (to->pixel.depthBias != 0.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_BIAS, 0.0f);
+ }
+ }
+ if (el->enmFormat == GL_STENCIL_INDEX || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ diff_api.Enable(GL_STENCIL_TEST);
+ if (to->pixel.mapStencil)
+ {
+ diff_api.PixelTransferi (GL_MAP_STENCIL, GL_FALSE);
+ }
+ if (to->pixel.indexOffset)
+ {
+ diff_api.PixelTransferi (GL_INDEX_OFFSET, 0);
+ }
+ if (to->pixel.indexShift)
+ {
+ diff_api.PixelTransferi (GL_INDEX_SHIFT, 0);
+ }
+ }
+
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, el->idFBO);
+
+ if (el->enmBuffer)
+ diff_api.DrawBuffer(el->enmBuffer);
+
+ diff_api.WindowPos2iARB(el->posX, el->posY);
+ diff_api.DrawPixels(el->width, el->height, el->enmFormat, el->enmType, el->pvData);
+ crDebug("Applied %d;%d;%d;%d;%d;0x%p fb image", el->enmBuffer, el->width, el->height, el->enmFormat, el->enmType, el->pvData);
+
+ if (el->enmFormat == GL_DEPTH_COMPONENT || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ if (to->pixel.depthScale != 1.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_SCALE, to->pixel.depthScale);
+ }
+ if (to->pixel.depthBias != 0.0f)
+ {
+ diff_api.PixelTransferf (GL_DEPTH_BIAS, to->pixel.depthBias);
+ }
+ diff_api.Disable(GL_DEPTH_TEST);
+ }
+ if (el->enmFormat == GL_STENCIL_INDEX || el->enmFormat == GL_DEPTH_STENCIL)
+ {
+ if (to->pixel.indexOffset)
+ {
+ diff_api.PixelTransferi (GL_INDEX_OFFSET, to->pixel.indexOffset);
+ }
+ if (to->pixel.indexShift)
+ {
+ diff_api.PixelTransferi (GL_INDEX_SHIFT, to->pixel.indexShift);
+ }
+ if (to->pixel.mapStencil)
+ {
+ diff_api.PixelTransferi (GL_MAP_STENCIL, GL_TRUE);
+ }
+ diff_api.Disable(GL_STENCIL_TEST);
+ }
}
diff_api.WindowPos3fvARB(to->current.rasterAttrib[VERT_ATTRIB_POS]);
@@ -179,10 +388,20 @@ void crStateApplyFBImage(CRContext *to)
}
if (to->framebufferobject.drawFB)
{
+ CRASSERT(to->framebufferobject.drawFB->hwid);
diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, to->framebufferobject.drawFB->hwid);
+ diff_api.DrawBuffer(to->framebufferobject.drawFB->drawbuffer[0]);
+ }
+ else if (data->idOverrrideFBO)
+ {
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, data->idOverrrideFBO);
+ diff_api.DrawBuffer(GL_COLOR_ATTACHMENT0);
+ }
+ else
+ {
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+ diff_api.DrawBuffer(to->buffer.drawBuffer);
}
- diff_api.DrawBuffer(to->framebufferobject.drawFB ?
- to->framebufferobject.drawFB->drawbuffer[0] : to->buffer.drawBuffer);
if (to->buffer.alphaTest)
{
diff_api.Enable(GL_ALPHA_TEST);
@@ -199,6 +418,14 @@ void crStateApplyFBImage(CRContext *to)
{
diff_api.Enable(GL_COLOR_LOGIC_OP);
}
+ if (to->buffer.depthTest)
+ {
+ diff_api.Enable(GL_DEPTH_TEST);
+ }
+ if (to->stencil.stencilTest)
+ {
+ diff_api.Enable(GL_STENCIL_TEST);
+ }
diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, unpack.skipRows);
diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, unpack.skipPixels);
@@ -341,34 +568,59 @@ void crStateSwitchContext( CRContext *from, CRContext *to )
}
#ifdef WINDOWS
- crStateApplyFBImage(to);
+ if (to->buffer.pFrontImg)
+ {
+ CRFBData *pLazyData = (CRFBData *)to->buffer.pFrontImg;
+ crStateApplyFBImage(to, pLazyData);
+ crStateFreeFBImageLegacy(to);
+ }
#endif
}
-CRContext * crStateSwichPrepare(CRContext *toCtx, GLboolean fMultipleContexts, GLuint idFBO)
+void crStateSyncHWErrorState(CRContext *ctx)
{
- CRContext *fromCtx = GetCurrentContext();
-
- if (!fMultipleContexts)
+ GLenum err;
+ while ((err = diff_api.GetError()) != GL_NO_ERROR)
{
+ if (ctx->error != GL_NO_ERROR)
+ ctx->error = err;
+ }
+}
+
+void crStateSwitchPrepare(CRContext *toCtx, CRContext *fromCtx, GLuint idDrawFBO, GLuint idReadFBO)
+{
+ if (!fromCtx)
+ return;
+
+ if (g_bVBoxEnableDiffOnMakeCurrent && toCtx && toCtx != fromCtx)
+ crStateSyncHWErrorState(fromCtx);
+
#ifdef CR_EXT_framebuffer_object
- if (fromCtx)
- crStateFramebufferObjectDisableHW(fromCtx, idFBO);
+ crStateFramebufferObjectDisableHW(fromCtx, idDrawFBO, idReadFBO);
#endif
- }
- return fromCtx;
}
-void crStateSwichPostprocess(CRContext *fromCtx, GLboolean fMultipleContexts, GLuint idFBO)
+void crStateSwitchPostprocess(CRContext *toCtx, CRContext *fromCtx, GLuint idDrawFBO, GLuint idReadFBO)
{
- CRContext *toCtx = GetCurrentContext();;
- if (!fromCtx || !toCtx)
+ if (!toCtx)
return;
- if (!fMultipleContexts)
+ if (g_bVBoxEnableDiffOnMakeCurrent && fromCtx && toCtx != fromCtx)
{
-#ifdef CR_EXT_framebuffer_object
- crStateFramebufferObjectReenableHW(fromCtx, toCtx, idFBO);
+ GLenum err;
+ while ((err = diff_api.GetError()) != GL_NO_ERROR)
+ {
+ static int cErrPrints = 0;
+#ifndef DEBUG_misha
+ if (cErrPrints < 5)
#endif
+ {
+ ++cErrPrints;
+ crWarning("gl error (0x%x) after context switch, ignoring.. (%d out of 5) ..", err, cErrPrints);
+ }
+ }
}
+#ifdef CR_EXT_framebuffer_object
+ crStateFramebufferObjectReenableHW(fromCtx, toCtx, idDrawFBO, idReadFBO);
+#endif
}