summaryrefslogtreecommitdiff
path: root/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c')
-rw-r--r--src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c519
1 files changed, 460 insertions, 59 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c
index eceb96f3..9bdcf293 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c
@@ -85,6 +85,7 @@ renderDestroyWindow( Display *dpy, Window w )
return WindowExistsFlag;
}
+#if 0
/*
* Garbage collection function.
* Loop over all known windows and check if corresponding X window still
@@ -109,6 +110,7 @@ renderspu_GCWindow(void)
}
}
}
+#endif
static Colormap
GetLUTColormap( Display *dpy, XVisualInfo *vi )
@@ -401,6 +403,314 @@ chooseFBConfig( Display *dpy, int screen, GLbitfield visAttribs )
}
#endif /* GLX_VERSION_1_3 */
+static const char * renderspuGetDisplayName()
+{
+ const char *dpyName;
+
+ if (render_spu.display_string[0])
+ dpyName = render_spu.display_string;
+ else
+ {
+ crWarning("Render SPU: no display..");
+ dpyName = NULL;
+ }
+ return dpyName;
+}
+
+static int renderspuWinCmdWinCreate(WindowInfo *pWindow)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+static int renderspuWinCmdWinDestroy(WindowInfo *pWindow)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+static int renderspuWinCmdInit()
+{
+ const char * dpyName;
+ int rc = VERR_GENERAL_FAILURE;
+
+ if (!crHashtableAllocRegisterKey(render_spu.windowTable, CR_RENDER_WINCMD_ID))
+ {
+ crError("CR_RENDER_WINCMD_ID %d is occupied already", CR_RENDER_WINCMD_ID);
+ return VERR_INVALID_STATE;
+ }
+
+ render_spu.pWinToInfoTable = crAllocHashtable();
+ if (render_spu.pWinToInfoTable)
+ {
+ dpyName = renderspuGetDisplayName();
+ if (dpyName)
+ {
+ GLboolean bRc = renderspuInitVisual(&render_spu.WinCmdVisual, dpyName, render_spu.default_visual);
+ if (bRc)
+ {
+ bRc = renderspuWindowInitWithVisual(&render_spu.WinCmdWindow, &render_spu.WinCmdVisual, GL_FALSE, CR_RENDER_WINCMD_ID);
+ if (bRc)
+ {
+ XSelectInput(render_spu.WinCmdVisual.dpy, render_spu.WinCmdWindow.window, StructureNotifyMask);
+ render_spu.WinCmdAtom = XInternAtom(render_spu.WinCmdVisual.dpy, "VBoxWinCmd", False);
+ CRASSERT(render_spu.WinCmdAtom != None);
+ return VINF_SUCCESS;
+ }
+ else
+ {
+ crError("renderspuWindowInitWithVisual failed");
+ }
+ /* there is no visual destroy impl currently
+ * @todo: implement */
+ }
+ else
+ {
+ crError("renderspuInitVisual failed");
+ }
+ }
+ else
+ {
+ crError("Render SPU: no display, aborting");
+ }
+ crFreeHashtable(render_spu.pWinToInfoTable, NULL);
+ render_spu.pWinToInfoTable = NULL;
+ }
+ else
+ {
+ crError("crAllocHashtable failed");
+ }
+ return rc;
+}
+
+static void renderspuWinCmdTerm()
+{
+ /* the window is not in the table, this will just ensure the key is freed */
+ crHashtableDelete(render_spu.windowTable, CR_RENDER_WINCMD_ID, NULL);
+ renderspuWindowTerm(&render_spu.WinCmdWindow);
+ crFreeHashtable(render_spu.pWinToInfoTable, NULL);
+ /* we do not have visual destroy functionality
+ * @todo implement */
+}
+
+
+static bool renderspuWinCmdProcess(CR_RENDER_WINCMD* pWinCmd)
+{
+ bool fExit = false;
+ /* process commands */
+ switch (pWinCmd->enmCmd)
+ {
+ case CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE:
+ crHashtableAdd(render_spu.pWinToInfoTable, pWinCmd->pWindow->window, pWinCmd->pWindow);
+ XSelectInput(render_spu.WinCmdVisual.dpy, pWinCmd->pWindow->window, ExposureMask);
+ pWinCmd->rc = VINF_SUCCESS;
+ break;
+ case CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY:
+ crHashtableDelete(render_spu.pWinToInfoTable, pWinCmd->pWindow->window, NULL);
+ pWinCmd->rc = VINF_SUCCESS;
+ break;
+ case CR_RENDER_WINCMD_TYPE_NOP:
+ pWinCmd->rc = VINF_SUCCESS;
+ break;
+ case CR_RENDER_WINCMD_TYPE_EXIT:
+ renderspuWinCmdTerm();
+ pWinCmd->rc = VINF_SUCCESS;
+ fExit = true;
+ pWinCmd->rc = VINF_SUCCESS;
+ break;
+ case CR_RENDER_WINCMD_TYPE_WIN_CREATE:
+ pWinCmd->rc = renderspuWinCmdWinCreate(pWinCmd->pWindow);
+ break;
+ case CR_RENDER_WINCMD_TYPE_WIN_DESTROY:
+ pWinCmd->rc = renderspuWinCmdWinDestroy(pWinCmd->pWindow);
+ break;
+ default:
+ crError("unknown WinCmd command! %d", pWinCmd->enmCmd);
+ pWinCmd->rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+
+ RTSemEventSignal(render_spu.hWinCmdCompleteEvent);
+ return fExit;
+}
+
+static DECLCALLBACK(int) renderspuWinCmdThreadProc(RTTHREAD ThreadSelf, void *pvUser)
+{
+ int rc;
+ bool fExit = false;
+ crDebug("RenderSPU: Window thread started (%x)", crThreadID());
+
+ rc = renderspuWinCmdInit();
+
+ /* notify the main cmd thread that we have started */
+ RTSemEventSignal(render_spu.hWinCmdCompleteEvent);
+
+ if (!RT_SUCCESS(rc))
+ {
+ CRASSERT(!render_spu.pWinToInfoTable);
+ return rc;
+ }
+
+ do
+ {
+ XEvent event;
+ XNextEvent(render_spu.WinCmdVisual.dpy, &event);
+
+ switch (event.type)
+ {
+ case ClientMessage:
+ {
+ CRASSERT(event.xclient.window == render_spu.WinCmdWindow.window);
+ if (event.xclient.window == render_spu.WinCmdWindow.window)
+ {
+ if (render_spu.WinCmdAtom == event.xclient.message_type)
+ {
+ CR_RENDER_WINCMD *pWinCmd;
+ memcpy(&pWinCmd, event.xclient.data.b, sizeof (pWinCmd));
+ fExit = renderspuWinCmdProcess(pWinCmd);
+ }
+ }
+
+ break;
+ }
+ case Expose:
+ {
+ if (!event.xexpose.count)
+ {
+ WindowInfo *pWindow = (WindowInfo*)crHashtableSearch(render_spu.pWinToInfoTable, event.xexpose.window);
+ if (pWindow)
+ {
+ const struct VBOXVR_SCR_COMPOSITOR * pCompositor;
+
+ pCompositor = renderspuVBoxCompositorAcquire(pWindow);
+ if (pCompositor)
+ {
+ renderspuVBoxPresentCompositionGeneric(pWindow, pCompositor, NULL, 0);
+ renderspuVBoxCompositorRelease(pWindow);
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!fExit);
+
+ return 0;
+}
+
+static int renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE enmCmd, WindowInfo *pWindow)
+{
+ Status status;
+ XEvent event;
+ CR_RENDER_WINCMD WinCmd, *pWinCmd;
+ int rc;
+
+ pWinCmd = &WinCmd;
+ pWinCmd->enmCmd = enmCmd;
+ pWinCmd->rc = VERR_GENERAL_FAILURE;
+ pWinCmd->pWindow = pWindow;
+
+ memset(&event, 0, sizeof (event));
+ event.type = ClientMessage;
+ event.xclient.window = render_spu.WinCmdWindow.window;
+ event.xclient.message_type = render_spu.WinCmdAtom;
+ event.xclient.format = 8;
+ memcpy(event.xclient.data.b, &pWinCmd, sizeof (pWinCmd));
+
+ status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, StructureNotifyMask, &event);
+ if (!status)
+ {
+ Assert(0);
+ crWarning("XSendEvent returned null");
+ return VERR_GENERAL_FAILURE;
+ }
+
+ XFlush(render_spu.pCommunicationDisplay);
+ rc = RTSemEventWaitNoResume(render_spu.hWinCmdCompleteEvent, RT_INDEFINITE_WAIT);
+ if (!RT_SUCCESS(rc))
+ {
+ crWarning("RTSemEventWaitNoResume failed rc %d", rc);
+ return rc;
+ }
+ return pWinCmd->rc;
+}
+
+int renderspu_SystemInit()
+{
+ const char * dpyName;
+ int rc = VERR_GENERAL_FAILURE;
+
+ if (!render_spu.use_glxchoosevisual) {
+ /* sometimes want to set this option with ATI drivers */
+ render_spu.ws.glXChooseVisual = NULL;
+ }
+
+ /* setup communication display connection */
+ dpyName = renderspuGetDisplayName();
+ if (!dpyName)
+ {
+ crWarning("no display name, aborting");
+ return VERR_GENERAL_FAILURE;
+ }
+
+ render_spu.pCommunicationDisplay = XOpenDisplay(dpyName);
+ if (!render_spu.pCommunicationDisplay)
+ {
+ crWarning( "Couldn't open X display named '%s'", dpyName );
+ return VERR_GENERAL_FAILURE;
+ }
+
+ if ( !render_spu.ws.glXQueryExtension( render_spu.pCommunicationDisplay, NULL, NULL ) )
+ {
+ crWarning( "Render SPU: Display %s doesn't support GLX", dpyName );
+ return VERR_GENERAL_FAILURE;
+ }
+
+ rc = RTSemEventCreate(&render_spu.hWinCmdCompleteEvent);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTThreadCreate(&render_spu.hWinCmdThread, renderspuWinCmdThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxCrWinCmd");
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTSemEventWait(render_spu.hWinCmdCompleteEvent, RT_INDEFINITE_WAIT);
+ if (RT_SUCCESS(rc))
+ {
+ return VINF_SUCCESS;
+ }
+ else
+ {
+ crWarning("RTSemEventWait failed rc %d", rc);
+ }
+
+ RTThreadWait(render_spu.hWinCmdThread, RT_INDEFINITE_WAIT, NULL);
+ }
+ else
+ {
+ crWarning("RTThreadCreate failed rc %d", rc);
+ }
+ RTSemEventDestroy(render_spu.hWinCmdCompleteEvent);
+ }
+ else
+ {
+ crWarning("RTSemEventCreate failed rc %d", rc);
+ }
+
+ return rc;
+}
+
+int renderspu_SystemTerm()
+{
+ int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_EXIT, NULL);
+ if (!RT_SUCCESS(rc))
+ {
+ crWarning("renderspuWinCmdSubmit EXIT failed rc %d", rc);
+ return rc;
+ }
+
+ RTThreadWait(render_spu.hWinCmdThread, RT_INDEFINITE_WAIT, NULL);
+ RTSemEventDestroy(render_spu.hWinCmdCompleteEvent);
+ return VINF_SUCCESS;
+}
GLboolean
renderspu_SystemInitVisual( VisualInfo *visual )
@@ -418,20 +728,15 @@ renderspu_SystemInitVisual( VisualInfo *visual )
}
#endif
- if (render_spu.display_string[0])
- dpyName = render_spu.display_string;
- else if (visual->displayName[0])
- dpyName = visual->displayName;
- else
- dpyName = NULL;
-
+ dpyName = renderspuGetDisplayName();
if (!dpyName)
{
crWarning("Render SPU: no display, aborting");
return GL_FALSE;
}
- crDebug("Render SPU: Opening display %s", dpyName);
+
+ crInfo("Render SPU: Opening display %s", dpyName);
if (dpyName &&
(crStrncmp(dpyName, "localhost:11", 12) == 0 ||
@@ -640,15 +945,15 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
window->x = 0;
window->y = 0;
- window->width = xwa.width;
- window->height = xwa.height;
+ window->BltInfo.width = xwa.width;
+ window->BltInfo.height = xwa.height;
}
/* i've changed default window size to be 0,0 but X doesn't like it */
- /*CRASSERT(window->width >= 1);
- CRASSERT(window->height >= 1);*/
- if (window->width < 1) window->width = 1;
- if (window->height < 1) window->height = 1;
+ /*CRASSERT(window->BltInfo.width >= 1);
+ CRASSERT(window->BltInfo.height >= 1);*/
+ if (window->BltInfo.width < 1) window->BltInfo.width = 1;
+ if (window->BltInfo.height < 1) window->BltInfo.height = 1;
/*
* Get a colormap.
@@ -707,7 +1012,7 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
crDebug("Render SPU: VBox parent window_id is: %x", render_spu_parent_window_id);
window->window = XCreateWindow(dpy, render_spu_parent_window_id,
window->x, window->y,
- window->width, window->height,
+ window->BltInfo.width, window->BltInfo.height,
0, visual->visual->depth, InputOutput,
visual->visual->visual, flags, &swa);
}
@@ -720,7 +1025,7 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
crDebug("Render SPU: Creating global window, parent: %x", RootWindow(dpy, visual->visual->screen));
window->window = XCreateWindow(dpy, RootWindow(dpy, visual->visual->screen),
window->x, window->y,
- window->width, window->height,
+ window->BltInfo.width, window->BltInfo.height,
0, visual->visual->depth, InputOutput,
visual->visual->visual, flags, &swa);
}
@@ -790,8 +1095,8 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
hints.x = window->x;
hints.y = window->y;
- hints.width = window->width;
- hints.height = window->height;
+ hints.width = window->BltInfo.width;
+ hints.height = window->BltInfo.height;
hints.min_width = hints.width;
hints.min_height = hints.height;
hints.max_width = hints.width;
@@ -825,7 +1130,6 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
XIfEvent( dpy, &event, WaitForMapNotify,
(char *) window->window );
}
- window->visible = showIt;
if ((window->visual->visAttribs & CR_DOUBLE_BIT) && render_spu.nvSwapGroup) {
/* NOTE:
@@ -835,7 +1139,7 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
* app window is in a separate swap group while all the back-end windows
* which form a mural are in the same swap group.
*/
- GLuint group = 0; /*render_spu.nvSwapGroup + window->id;*/
+ GLuint group = 0; /*render_spu.nvSwapGroup + window->BltInfo.Base.id;*/
GLuint barrier = 0;
JoinSwapGroup(dpy, visual->visual->screen, window->window, group, barrier);
}
@@ -844,9 +1148,15 @@ createWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
* End GLX code
*/
crDebug( "Render SPU: actual window x, y, width, height: %d, %d, %d, %d",
- window->x, window->y, window->width, window->height );
+ window->x, window->y, window->BltInfo.width, window->BltInfo.height );
XSync(dpy, 0);
+
+ if (window->BltInfo.Base.id != CR_RENDER_WINCMD_ID)
+ {
+ int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE, window);
+ AssertRC(rc);
+ }
return GL_TRUE;
}
@@ -860,15 +1170,15 @@ createPBuffer( VisualInfo *visual, WindowInfo *window )
window->y = 0;
window->nativeWindow = 0;
- CRASSERT(window->width > 0);
- CRASSERT(window->height > 0);
+ CRASSERT(window->BltInfo.width > 0);
+ CRASSERT(window->BltInfo.height > 0);
#ifdef GLX_VERSION_1_3
{
int attribs[100], i = 0, w, h;
CRASSERT(visual->fbconfig);
- w = window->width;
- h = window->height;
+ w = window->BltInfo.width;
+ h = window->BltInfo.height;
attribs[i++] = GLX_PRESERVED_CONTENTS;
attribs[i++] = True;
attribs[i++] = GLX_PBUFFER_WIDTH;
@@ -896,8 +1206,8 @@ GLboolean
renderspu_SystemCreateWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
{
if (visual->visAttribs & CR_PBUFFER_BIT) {
- window->width = render_spu.defaultWidth;
- window->height = render_spu.defaultHeight;
+ window->BltInfo.width = render_spu.defaultWidth;
+ window->BltInfo.height = render_spu.defaultHeight;
return createPBuffer(visual, window);
}
else {
@@ -938,6 +1248,11 @@ renderspu_SystemDestroyWindow( WindowInfo *window )
* window. I know...personal responsibility and all...
*/
if (!window->nativeWindow) {
+ if (window->BltInfo.Base.id != CR_RENDER_WINCMD_ID)
+ {
+ int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY, window);
+ AssertRC(rc);
+ }
XDestroyWindow(window->visual->dpy, window->window);
XSync(window->visual->dpy, 0);
}
@@ -1000,7 +1315,7 @@ renderspu_SystemCreateContext( VisualInfo *visual, ContextInfo *context, Context
if (visual->visual)
crDebug("Render SPU: Created %s context (%d) on display %s for visAttribs 0x%x",
is_direct ? "DIRECT" : "INDIRECT",
- context->id,
+ context->BltInfo.Base.id,
DisplayString(visual->dpy),
visual->visAttribs);
@@ -1152,18 +1467,18 @@ renderspu_SystemDestroyContext( ContextInfo *context )
static void
check_buffer_size( WindowInfo *window )
{
- if (window->width != window->in_buffer_width
- || window->height != window->in_buffer_height
+ if (window->BltInfo.width != window->in_buffer_width
+ || window->BltInfo.height != window->in_buffer_height
|| ! window->buffer) {
crFree(window->buffer);
- window->buffer = crCalloc(window->width * window->height
+ window->buffer = crCalloc(window->BltInfo.width * window->BltInfo.height
* 4 * sizeof (GLubyte));
- window->in_buffer_width = window->width;
- window->in_buffer_height = window->height;
+ window->in_buffer_width = window->BltInfo.width;
+ window->in_buffer_height = window->BltInfo.height;
- crDebug("Render SPU: dimensions changed to %d x %d", window->width, window->height);
+ crDebug("Render SPU: dimensions changed to %d x %d", window->BltInfo.width, window->BltInfo.height);
}
}
#endif
@@ -1176,7 +1491,6 @@ renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow,
Bool b;
CRASSERT(render_spu.ws.glXMakeCurrent);
- window->appWindow = nativeWindow;
/*crDebug("%s nativeWindow=0x%x", __FUNCTION__, (int) nativeWindow);*/
@@ -1185,16 +1499,20 @@ renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow,
check_buffer_size(window);
render_spu.OSMesaMakeCurrent( (OSMesaContext) context->context,
window->buffer, GL_UNSIGNED_BYTE,
- window->width, window->height);
+ window->BltInfo.width, window->BltInfo.height);
return;
}
#endif
+ nativeWindow = 0;
+
if (window && context) {
+ window->appWindow = nativeWindow;
+
if (window->visual != context->visual) {
crDebug("Render SPU: MakeCurrent visual mismatch (win(%d) bits:0x%x != ctx(%d) bits:0x%x); remaking window.",
- window->id, window->visual->visAttribs,
- context->id, context->visual->visAttribs);
+ window->BltInfo.Base.id, window->visual->visAttribs,
+ context->BltInfo.Base.id, context->visual->visAttribs);
/*
* XXX have to revisit this issue!!!
*
@@ -1273,7 +1591,7 @@ renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow,
if (vid != (int) context->visual->visual->visualid) {
crWarning("Render SPU: Can't bind context %d to CRUT/native window "
"0x%x because of different X visuals (0x%x != 0x%x)!",
- context->id, (int) nativeWindow,
+ context->BltInfo.Base.id, (int) nativeWindow,
vid, (int) context->visual->visual->visualid);
crWarning("Render SPU: Trying to recreate GLX context to match.");
/* Try to recreate the GLX context so that it uses the same
@@ -1327,7 +1645,7 @@ renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow,
crWarning("glXMakeCurrent(%p, 0x%x, %p) failed! (winId %d, ctxId %d)",
window->visual->dpy,
(int) window->window, (void *) context->context,
- window->id, context->id );
+ window->BltInfo.Base.id, context->BltInfo.Base.id );
}
/*CRASSERT(b);*/
}
@@ -1344,6 +1662,18 @@ renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow,
}
#endif
}
+ else
+ {
+ GET_CONTEXT(pCurCtx);
+ if (pCurCtx)
+ {
+ b = render_spu.ws.glXMakeCurrent( pCurCtx->currentWindow->visual->dpy, None, NULL);
+ if (!b) {
+ crWarning("glXMakeCurrent(%p, None, NULL) failed!", pCurCtx->currentWindow->visual->dpy);
+ }
+ }
+
+ }
#if 0
/* XXX disabled for now due to problem with threadtest.conf */
@@ -1360,8 +1690,8 @@ renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
- window->width = w;
- window->height = h;
+ window->BltInfo.width = w;
+ window->BltInfo.height = h;
check_buffer_size(window);
return;
}
@@ -1394,7 +1724,7 @@ renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
}
}
- if (window->width != w || window->height != h) {
+ if (window->BltInfo.width != w || window->BltInfo.height != h) {
/* Only resize if the new dimensions really are different */
#ifdef CHROMIUM_THREADSAFE
ContextInfo *currentContext = (ContextInfo *) crGetTSD(&_RenderTSD);
@@ -1403,10 +1733,10 @@ renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
#endif
/* Can't resize pbuffers, so destroy it and make a new one */
render_spu.ws.glXDestroyPbuffer(window->visual->dpy, window->window);
- window->width = w;
- window->height = h;
+ window->BltInfo.width = w;
+ window->BltInfo.height = h;
crDebug("Render SPU: Creating new %d x %d PBuffer (id=%d)",
- w, h, window->id);
+ w, h, window->BltInfo.Base.id);
if (!createPBuffer(window->visual, window)) {
crWarning("Render SPU: Unable to create PBuffer (out of VRAM?)!");
}
@@ -1419,6 +1749,15 @@ renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
}
}
else {
+ if (!w || !h)
+ {
+ /* X can not handle zero sizes */
+ if (window->visible)
+ {
+ renderspu_SystemShowWindow( window, GL_FALSE );
+ }
+ return;
+ }
/* Resize ordinary X window */
/*
* This is ugly, but it seems to be the only thing that works.
@@ -1432,6 +1771,16 @@ renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
crDebug("Render SPU: XResizeWindow (%x, %x, %d, %d)", window->visual->dpy, window->window, w, h);
XResizeWindow(window->visual->dpy, window->window, w, h);
XSync(window->visual->dpy, 0);
+
+ if (!window->BltInfo.width || !window->BltInfo.height)
+ {
+ /* we have hidden the window instead of sizing it to (0;0) since X is unable to handle zero sizes */
+ if (window->visible)
+ {
+ renderspu_SystemShowWindow( window, GL_TRUE );
+ return;
+ }
+ }
#if 0
for (attempt = 0; attempt < 3; attempt++) { /* try three times max */
XWindowAttributes attribs;
@@ -1444,10 +1793,6 @@ renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
}
#endif
}
-
- /* finally, save the new size */
- window->width = w;
- window->height = h;
}
@@ -1457,8 +1802,8 @@ renderspu_SystemGetWindowGeometry( WindowInfo *window,
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
- *w = window->width;
- *h = window->height;
+ *w = window->BltInfo.width;
+ *h = window->BltInfo.height;
return;
}
#endif
@@ -1470,8 +1815,8 @@ renderspu_SystemGetWindowGeometry( WindowInfo *window,
{
*x = 0;
*y = 0;
- *w = window->width;
- *h = window->height;
+ *w = window->BltInfo.width;
+ *h = window->BltInfo.height;
}
else
{
@@ -1544,7 +1889,7 @@ renderspu_SystemWindowPosition( WindowInfo *window, GLint x, GLint y )
}
void
-renderspu_SystemWindowVisibleRegion( WindowInfo *window, GLint cRects, GLint *pRects )
+renderspu_SystemWindowVisibleRegion( WindowInfo *window, GLint cRects, const GLint *pRects )
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
@@ -1609,18 +1954,64 @@ renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt )
{
if (showIt)
{
- XMapWindow( window->visual->dpy, window->window );
- XSync(window->visual->dpy, 0);
+ if (window->BltInfo.width && window->BltInfo.height)
+ {
+ XMapWindow( window->visual->dpy, window->window );
+ XSync(window->visual->dpy, 0);
+ }
}
else
{
XUnmapWindow( window->visual->dpy, window->window );
XSync(window->visual->dpy, 0);
}
- window->visible = showIt;
}
}
+void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
+{
+ /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
+ * here it forces rendering in WinCmd thread rather than a Main thread.
+ * it is used for debugging only in any way actually.
+ * @todo: change to some more generic macro name */
+#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
+ const struct VBOXVR_SCR_COMPOSITOR *pCompositor;
+ /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
+ int rc = renderspuVBoxCompositorTryAcquire(window, &pCompositor);
+ if (RT_SUCCESS(rc))
+ {
+ renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry, 0);
+ renderspuVBoxCompositorRelease(window);
+ }
+ else if (rc == VERR_SEM_BUSY)
+#endif
+ {
+ Status status;
+ XEvent event;
+ render_spu.self.Flush();
+ renderspuVBoxPresentBlitterEnsureCreated(window, 0);
+
+ crMemset(&event, 0, sizeof (event));
+ event.type = Expose;
+ event.xexpose.window = window->window;
+ event.xexpose.width = window->BltInfo.width;
+ event.xexpose.height = window->BltInfo.height;
+ status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, 0, &event);
+ if (!status)
+ {
+ Assert(0);
+ crWarning("XSendEvent returned null");
+ }
+ XFlush(render_spu.pCommunicationDisplay);
+ }
+#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
+ else
+ {
+ /* this is somewhat we do not expect */
+ crWarning("renderspuVBoxCompositorTryAcquire failed rc %d", rc);
+ }
+#endif
+}
static void
MarkWindow(WindowInfo *w)
@@ -1632,7 +2023,7 @@ MarkWindow(WindowInfo *w)
gcValues.function = GXnoop;
gc = XCreateGC(w->visual->dpy, w->nativeWindow, GCFunction, &gcValues);
}
- XDrawLine(w->visual->dpy, w->nativeWindow, gc, 0, 0, w->width, w->height);
+ XDrawLine(w->visual->dpy, w->nativeWindow, gc, 0, 0, w->BltInfo.width, w->BltInfo.height);
}
@@ -1683,3 +2074,13 @@ void renderspu_SystemReparentWindow(WindowInfo *window)
XReparentWindow(window->visual->dpy, window->window, parent, window->x, window->y);
XSync(window->visual->dpy, False);
}
+
+void renderspu_SystemDefaultSharedContextChanged(ContextInfo *fromContext, ContextInfo *toContext)
+{
+
+}
+
+uint32_t renderspu_SystemPostprocessFunctions(SPUNamedFunctionTable *aFunctions, uint32_t cFunctions, uint32_t cTable)
+{
+ return cFunctions;
+}