renderspu_glx.c revision f6294c2ed1ec3872dec39315262f8850daffb3c3
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#if 00 /*TEMPORARY*/
#include <unistd.h>
#include "cr_rand.h"
#endif
#include <stdio.h>
#include "cr_environment.h"
#include "cr_error.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "cr_process.h"
#include "renderspu.h"
/*
* Stuff from MwmUtils.h
*/
typedef struct
{
unsigned long flags;
unsigned long functions;
unsigned long decorations;
long inputMode;
unsigned long status;
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
static Bool WindowExistsFlag;
static int
{
{
}
return 0;
}
static GLboolean
{
return WindowExistsFlag;
}
static GLboolean
{
}
return WindowExistsFlag;
}
#if 0
/*
* Garbage collection function.
* Loop over all known windows and check if corresponding X window still
* exists. If it doesn't, destroy the render SPU window.
* XXX seems to blow up with threadtest.conf tests.
*/
void
renderspu_GCWindow(void)
{
int i;
}
}
}
}
}
#endif
static Colormap
{
int a;
#if defined(__cplusplus) || defined(c_plusplus)
#else
#endif
if ( localclass != DirectColor )
{
crError( "No support for non-DirectColor visuals with LUTs" );
}
for (a=0; a<256; a++)
{
}
for (a=0; a<256; a++)
{
}
for (a=0; a<256; a++)
{
}
return cmap;
}
static Colormap
{
int i, numCmaps;
#if defined(__cplusplus) || defined(c_plusplus)
#else
#endif
if ( localclass != TrueColor )
{
crError( "No support for non-TrueColor visuals." );
}
if ( status == 1 )
{
if ( status == 1 )
{
for (i = 0 ; i < numCmaps ; i++)
{
{
return cmap;
}
}
}
}
return cmap;
}
static int
{
(void)display;
}
/**
* Return the X Visual ID of the given window
*/
static int
{
if (!k)
return -1;
}
/**
* Wrapper for glXGetConfig().
*/
static int
{
int value = 0;
return value;
}
/**
* Find a visual with the specified attributes. If we fail, turn off an
* attribute (like multisample or stereo) and try again.
*/
static XVisualInfo *
{
while (1) {
if (vis)
return vis;
if (visAttribs & CR_MULTISAMPLE_BIT)
else if (visAttribs & CR_OVERLAY_BIT)
visAttribs &= ~CR_OVERLAY_BIT;
else if (visAttribs & CR_STEREO_BIT)
visAttribs &= ~CR_STEREO_BIT;
else if (visAttribs & CR_ACCUM_BIT)
visAttribs &= ~CR_ACCUM_BIT;
else if (visAttribs & CR_ALPHA_BIT)
visAttribs &= ~CR_ALPHA_BIT;
else
return NULL;
}
}
/**
* Get an FBconfig for the specified attributes
*/
#ifdef GLX_VERSION_1_3
static GLXFBConfig
{
/* Make sure pbuffers are supported */
return 0;
}
if (visAttribs & CR_RGB_BIT) {
if (visAttribs & CR_ALPHA_BIT) {
}
}
if (visAttribs & CR_DEPTH_BIT) {
}
if (visAttribs & CR_DOUBLE_BIT) {
}
else {
/* don't care */
}
if (visAttribs & CR_STENCIL_BIT) {
}
if (visAttribs & CR_ACCUM_BIT) {
if (visAttribs & CR_ALPHA_BIT) {
}
}
if (visAttribs & CR_MULTISAMPLE_BIT) {
}
if (visAttribs & CR_STEREO_BIT) {
}
/* terminate */
if (!fbconfig || numConfigs == 0) {
/* no matches! */
return 0;
}
if (numConfigs == 1) {
/* one match */
return fbconfig[0];
}
else {
/* found several matches - try to find best one */
int i;
crDebug("Render SPU: glXChooseFBConfig found %d matches for visBits 0x%x",
* buffering. Possible add other tests in the future.
*/
for (i = 0; i < numConfigs; i++) {
GLX_DEPTH_SIZE, &zBits);
/* omit fbconfig with unneeded Z */
continue;
}
GLX_DOUBLEBUFFER, &db);
/* omit fbconfig with unneeded DB */
continue;
}
/* if we get here, use this config */
return fbconfig[i];
}
/* if we get here, we didn't find a better fbconfig */
return fbconfig[0];
}
}
#endif /* GLX_VERSION_1_3 */
static const char * renderspuGetDisplayName()
{
const char *dpyName;
if (render_spu.display_string[0])
else
{
crWarning("Render SPU: no display..");
}
return dpyName;
}
{
return VERR_NOT_IMPLEMENTED;
}
{
return VERR_NOT_IMPLEMENTED;
}
static int renderspuWinCmdInit()
{
const char * dpyName;
int rc = VERR_GENERAL_FAILURE;
{
return VERR_INVALID_STATE;
}
{
if (dpyName)
{
if (bRc)
{
bRc = renderspuWindowInitWithVisual(&render_spu.WinCmdWindow, &render_spu.WinCmdVisual, GL_FALSE, CR_RENDER_WINCMD_ID);
if (bRc)
{
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");
}
}
else
{
crError("crAllocHashtable failed");
}
return rc;
}
static void renderspuWinCmdTerm()
{
/* the window is not in the table, this will just ensure the key is freed */
/* we do not have visual destroy functionality
* @todo implement */
}
{
bool fExit = false;
/* process commands */
{
break;
break;
break;
fExit = true;
break;
break;
break;
default:
break;
}
return fExit;
}
{
int rc;
bool fExit = false;
rc = renderspuWinCmdInit();
/* notify the main cmd thread that we have started */
if (!RT_SUCCESS(rc))
{
return rc;
}
do
{
{
case ClientMessage:
{
{
{
}
}
break;
}
case Expose:
{
{
WindowInfo *pWindow = (WindowInfo*)crHashtableSearch(render_spu.pWinToInfoTable, event.xexpose.window);
if (pWindow)
{
struct VBOXVR_SCR_COMPOSITOR * pCompositor;
if (pCompositor)
{
}
}
}
break;
}
default:
break;
}
} while (!fExit);
return 0;
}
{
int rc;
status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, StructureNotifyMask, &event);
if (!status)
{
Assert(0);
crWarning("XSendEvent returned null");
return VERR_GENERAL_FAILURE;
}
if (!RT_SUCCESS(rc))
{
return 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 */
}
/* setup communication display connection */
if (!dpyName)
{
crWarning("no display name, aborting");
return VERR_GENERAL_FAILURE;
}
{
return VERR_GENERAL_FAILURE;
}
{
return VERR_GENERAL_FAILURE;
}
if (RT_SUCCESS(rc))
{
rc = RTThreadCreate(&render_spu.hWinCmdThread, renderspuWinCmdThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxCrWinCmd");
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
else
{
}
}
else
{
}
}
else
{
}
return rc;
}
int renderspu_SystemTerm()
{
if (!RT_SUCCESS(rc))
{
return rc;
}
return VINF_SUCCESS;
}
{
const char *dpyName;
int screen;
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
/* A dummy visual - being non null is enough. */
return GL_TRUE;
}
#endif
if (!dpyName)
{
crWarning("Render SPU: no display, aborting");
return GL_FALSE;
}
if (dpyName &&
/* Issue both debug and warning messages to make sure the
* message gets noticed!
*/
crDebug("Render SPU: display string looks like a proxy X server!");
crDebug("Render SPU: This is usually a problem!");
crWarning("Render SPU: display string looks like a proxy X server!");
crWarning("Render SPU: This is usually a problem!");
}
{
return GL_FALSE;
}
{
return GL_FALSE;
}
#ifdef GLX_VERSION_1_3
{
char s[1000];
crWarning( "Render SPU: Display %s doesn't have the necessary fbconfig: %s",
dpyName, s );
return GL_FALSE;
}
}
else
#endif /* GLX_VERSION_1_3 */
{
char s[1000];
crWarning("Render SPU: Display %s doesn't have the necessary visual: %s",
dpyName, s );
return GL_FALSE;
}
}
if ( render_spu.sync )
{
crDebug( "Render SPU: Turning on XSynchronize" );
}
crDebug( "Render SPU: Choose visual id=0x%x: RGBA=(%d,%d,%d,%d) Z=%d"
" stencil=%d double=%d stereo=%d accum=(%d,%d,%d,%d)",
);
}
int id;
GLX_FBCONFIG_ID, &id);
crDebug("Render SPU: Chose FBConfig 0x%x, visBits=0x%x",
}
return GL_TRUE;
}
/*
* Add a GLX window to a swap group for inter-machine SwapBuffer
* synchronization.
* Only supported on NVIDIA Quadro 3000G hardware.
*/
static void
{
const char *ext;
Bool b;
/*
* XXX maybe query glXGetClientString() instead???
*/
crWarning("Render SPU: nv_swap_group is set but GLX_NV_swap_group is not supported on this system!");
return;
}
&maxGroups, &maxBarriers);
if (!b)
crWarning("Render SPU: call to glXQueryMaxSwapGroupsNV() failed!");
crWarning("Render SPU: nv_swap_group too large (%d > %d)",
return;
}
crDebug("Render SPU: max swap groups = %d, max barriers = %d",
/* add this window to the swap group */
if (!b) {
crWarning("Render SPU: call to glXJoinSwapGroupNV() failed!");
return;
}
else {
crDebug("Render SPU: call to glXJoinSwapGroupNV() worked!");
}
/* ... and bind window to barrier of same ID */
if (!b) {
return;
}
else {
}
}
static GLboolean
{
XSizeHints hints = {0};
char *name;
unsigned long flags;
unsigned int vncWin;
window->nativeWindow = 0;
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
return GL_TRUE;
#endif
if ( render_spu.use_L2 )
{
crWarning( "Render SPU: Going fullscreen because we think we're using Lightning-2." );
}
/*
* Query screen size if we're going full-screen
*/
if ( render_spu.fullscreen )
{
/* disable the screensaver */
crDebug( "Render SPU: Just turned off the screensaver" );
/* Figure out how big the screen is, and make the window that size */
window->x = 0;
window->y = 0;
}
/* i've changed default window size to be 0,0 but X doesn't like it */
/*CRASSERT(window->BltInfo.width >= 1);
CRASSERT(window->BltInfo.height >= 1);*/
/*
* Get a colormap.
*/
if (render_spu.use_lut8)
else
if ( !cmap ) {
crError( "Render SPU: Unable to get a colormap!" );
return GL_FALSE;
}
/* destroy existing window if there is one */
}
/*
* Create the window
*
* POSSIBLE OPTIMIZATION:
* If we're using the render_to_app_window or render_to_crut_window option
* (or DMX) we may never actually use this X window. So we could perhaps
* delay its creation until glXMakeCurrent is called. With NVIDIA's OpenGL
* driver, creating a lot of GLX windows can eat up a lot of VRAM and lead
* to slow, software-fallback rendering. Apps that use render_to_app_window,
* etc should set the default window size very small to avoid this.
* See dmx.conf for example.
*/
swa.border_pixel = 0;
/*
* We pass the VNC's desktop windowID via an environment variable.
* If we don't find one, we're not on a 3D-capable vncviewer, or
* if we do find one, then create the renderspu subwindow as a
* child of the vncviewer's desktop window.
*
* This is purely for the replicateSPU.
*
* NOTE: This is crufty, and will do for now. FIXME.
*/
if (vncWin)
else
if (render_spu_parent_window_id>0)
{
}
else
{
/* This should happen only at the call from crVBoxServerInit. At this point we don't
* know render_spu_parent_window_id yet, nor we need it for default window which is hidden.
*/
}
crWarning( "Render SPU: unable to create window" );
return GL_FALSE;
}
crDebug( "Render SPU: Created window 0x%x on display %s, Xvisual 0x%x",
);
{
/* Disable border/decorations with an MWM property (observed by most
* modern window managers.
*/
/* setup the property */
/* get the atom for the property */
if (prop) {
/* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
32, /* format: 32-bit datums */
PropModeReplace, /* mode */
(unsigned char *) &motif_hints, /* data */
PROP_MOTIF_WM_HINTS_ELEMENTS /* nelements */
);
}
}
/* Make a clear cursor to get rid of the monitor cursor */
if ( render_spu.fullscreen )
{
char clearByte = 0;
/* AdB - Only bother to create a 1x1 cursor (byte) */
1, 1, 1, 0, 1);
if(!pixmap){
crWarning("Unable to create clear cursor pixmap");
return GL_FALSE;
}
if(!cursor){
crWarning("Unable to create clear cursor from zero byte pixmap");
return GL_FALSE;
}
}
if (render_spu.resizable)
else
/* New item! This is needed so that the sgimouse server can find
* the crDebug window.
*/
name = WINDOW_NAME;
/* Set window name, resource class */
class_hints = XAllocClassHint( );
XFree( class_hints );
if (showIt) {
}
/* NOTE:
* If this SPU creates N windows we don't want to gang the N windows
* together!
* By adding the window ID to the nvSwapGroup ID we can be sure each
* app window is in a separate swap group while all the back-end windows
* which form a mural are in the same swap group.
*/
}
/*
* End GLX code
*/
crDebug( "Render SPU: actual window x, y, width, height: %d, %d, %d, %d",
{
}
return GL_TRUE;
}
static GLboolean
{
window->x = 0;
window->y = 0;
window->nativeWindow = 0;
#ifdef GLX_VERSION_1_3
{
int attribs[100], i = 0, w, h;
attribs[i++] = GLX_PRESERVED_CONTENTS;
attribs[i++] = GLX_PBUFFER_WIDTH;
attribs[i++] = w;
attribs[i++] = GLX_PBUFFER_HEIGHT;
attribs[i++] = h;
attribs[i++] = 0; /* terminator */
crDebug("Render SPU: Allocated %d x %d pbuffer", w, h);
return GL_TRUE;
}
else {
crWarning("Render SPU: Failed to allocate %d x %d pbuffer", w, h);
return GL_FALSE;
}
}
#endif /* GLX_VERSION_1_3 */
return GL_FALSE;
}
{
}
else {
}
}
{
}
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
{
}
else
#endif
{
#ifdef GLX_VERSION_1_3
#endif
}
else {
/* The value window->nativeWindow will only be non-NULL if the
* render_to_app_window option is set to true. In this case, we
* don't want to do anything, since we're not responsible for this
* window. I know...personal responsibility and all...
*/
if (!window->nativeWindow) {
{
}
}
}
}
}
renderspu_SystemCreateContext( VisualInfo *visual, ContextInfo *context, ContextInfo *sharedContext )
{
if (sharedContext != NULL) {
}
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
return GL_TRUE;
else
return GL_FALSE;
}
#endif
#ifdef GLX_VERSION_1_3
}
else
#endif
{
}
crError( "Render SPU: Couldn't create rendering context" );
return GL_FALSE;
}
crDebug("Render SPU: Created %s context (%d) on display %s for visAttribs 0x%x",
visual->visAttribs);
{
crError( "Render SPU: Direct rendering not possible." );
return GL_FALSE;
}
return GL_TRUE;
}
#define USE_GLX_COPYCONTEXT 0
#if !USE_GLX_COPYCONTEXT
/**
* Unfortunately, glXCopyContext() is broken sometimes (NVIDIA 76.76 driver).
* This bit of code gets and sets GL state we need to copy between contexts.
*/
struct saved_state
{
/* XXX depending on the app, more state may be needed here */
};
static struct saved_state SavedState;
static void
get_state(struct saved_state *s)
{
int i;
for (i = 0; i < 8; i++) {
}
}
static void
set_state(const struct saved_state *s)
{
int i;
if (s->Lighting) {
}
else {
}
for (i = 0; i < 8; i++) {
if (s->LightEnabled[i]) {
}
else {
}
}
if (s->DepthTest)
else
}
#endif /* !USE_GLX_COPYCONTEXT */
/**
* Recreate the GLX context for ContextInfo. The new context will use the
* visual specified by newVisualID.
*/
static void
{
long templateFlags;
if (!vis)
return;
/* create new context */
/* copy old context state to new context */
crDebug("Render SPU: Done copying context state");
#endif
/* destroy old context */
}
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
{
}
else
#endif
{
#if 0
/* XXX disable for now - causes segfaults w/ NVIDIA's driver */
#endif
}
}
#ifdef USE_OSMESA
static void
{
* 4 * sizeof (GLubyte));
crDebug("Render SPU: dimensions changed to %d x %d", window->BltInfo.width, window->BltInfo.height);
}
}
#endif
void
{
Bool b;
/*crDebug("%s nativeWindow=0x%x", __FUNCTION__, (int) nativeWindow);*/
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
return;
}
#endif
nativeWindow = 0;
crDebug("Render SPU: MakeCurrent visual mismatch (win(%d) bits:0x%x != ctx(%d) bits:0x%x); remaking window.",
/*
* XXX have to revisit this issue!!!
*
* But for now we destroy the current window
* and re-create it with the context's visual abilities
*/
#ifndef SOLARIS_9_X_BUG
/*
I'm having some really weird issues if I destroy this window
when I'm using the version of sunX that comes with Solaris 9.
Subsiquent glX calls return GLXBadCurrentWindow error.
This is an issue even when running Linux version and using
the Solaris 9 sunX as a display.
-- jw
jw: we might have to call glXMakeCurrent(dpy, 0, 0) to unbind
the context from the window before destroying it. -Brian
*/
#endif
/*
crError("In renderspu_SystemMakeCurrent() window and context"
" weren't created with same visual!");
*/
}
#if 0
if (render_spu.render_to_crut_window) {
if (render_spu.crut_drawable == 0) {
/* We don't know the X drawable ID yet. Ask mothership for it. */
char response[8096];
if (!conn)
{
crError("Couldn't connect to the mothership to get CRUT drawable-- "
"I have no idea what to do!");
}
crDebug("Render SPU: using CRUT drawable: 0x%x",
if (!render_spu.crut_drawable) {
crDebug("Render SPU: Crut drawable 0 is invalid");
/* Continue with nativeWindow = 0; we'll render to the window that
* we (the Render SPU) previously created.
*/
}
}
}
#endif
&& nativeWindow)
{
/* We're about to bind the rendering context to a window that we
* (the Render SPU) did not create. The window was created by the
* application or the CRUT server.
* Make sure the window ID is valid and that the window's X visual is
* the same as the rendering context's.
*/
{
/* check that the window's visual and context's visual match */
"0x%x because of different X visuals (0x%x != 0x%x)!",
crWarning("Render SPU: Trying to recreate GLX context to match.");
/* Try to recreate the GLX context so that it uses the same
* GLX visual as the window.
*/
#if !USE_GLX_COPYCONTEXT
if (context->everCurrent) {
}
#endif
}
/* OK, this should work */
CRASSERT(b);
#if !USE_GLX_COPYCONTEXT
if (recreated) {
}
#endif
}
else
{
crWarning("Render SPU: render_to_app/crut_window option is set but "
"the window ID 0x%x is invalid on the display named %s",
(unsigned int) nativeWindow,
CRASSERT(b);
}
}
else
{
/* This is the normal case - rendering to the render SPU's own window */
#if 0
crDebug("calling glXMakecurrent(%p, 0x%x, 0x%x)",
#endif
if (!b) {
crWarning("glXMakeCurrent(%p, 0x%x, %p) failed! (winId %d, ctxId %d)",
}
/*CRASSERT(b);*/
}
/* XXX this is a total hack to work around an NVIDIA driver bug */
#if 0
GLfloat f[4];
crDebug("Render SPU: Resetting raster pos");
}
}
#endif
}
else
{
if (pCurCtx)
{
if (!b) {
}
}
}
#if 0
/* XXX disabled for now due to problem with threadtest.conf */
#endif
}
/**
* Set window (or pbuffer) size.
*/
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
return;
}
#endif
{
/* resizing a pbuffer */
/* size limit check */
crWarning("Render SPU: Request for %d x %d pbuffer is larger than "
"the configured size of %d x %d. ('pbuffer_size')",
return;
}
/*
* If the requested new pbuffer size is greater than 1/2 the size of
* the max pbuffer, just use the max pbuffer size. This helps avoid
* problems with VRAM memory fragmentation. If we run out of VRAM
* for pbuffers, some drivers revert to software rendering. We want
* to avoid that!
*/
/* increase the dimensions to the max pbuffer size now */
w = render_spu.pbufferWidth;
h = render_spu.pbufferHeight;
}
}
/* Only resize if the new dimensions really are different */
#ifdef CHROMIUM_THREADSAFE
#else
#endif
/* Can't resize pbuffers, so destroy it and make a new one */
crDebug("Render SPU: Creating new %d x %d PBuffer (id=%d)",
crWarning("Render SPU: Unable to create PBuffer (out of VRAM?)!");
}
/* Determine if we need to bind the current context to new pbuffer */
}
}
}
else {
if (!w || !h)
{
/* X can not handle zero sizes */
{
}
return;
}
/* Resize ordinary X window */
/*
* This is ugly, but it seems to be the only thing that works.
* Basically, XResizeWindow() doesn't seem to always take effect
* immediately.
* Even after an XSync(), the GetWindowAttributes() call will sometimes
* return the old window size. So, we use a loop to repeat the window
* resize until it seems to take effect.
*/
int attempt;
{
/* we have hidden the window instead of sizing it to (0;0) since X is unable to handle zero sizes */
{
return;
}
}
#if 0
/* Now, query the window size */
break;
/* sleep for a millisecond and try again */
crMsleep(1);
}
#endif
}
}
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
return;
}
#endif
{
*x = 0;
*y = 0;
}
else
{
&& window->nativeWindow) {
}
else {
}
/* translate x/y to screen coords */
}
*x = rx;
*y = ry;
*w = (int) width;
*h = (int) height;
}
}
void
{
int scrn;
#ifdef USE_OSMESA
if (render_spu.use_osmesa) {
*w = 2048;
*h = 2048;
return;
}
#endif
}
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
return;
#endif
{
}
}
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
return;
#endif
{
{
return;
}
if (cRects>0)
{
for (i=0; i<cRects; ++i)
{
}
}
else
{
pXRects[0].x = 0;
pXRects[0].y = 0;
cRects = 1;
}
crDebug("Render SPU: XShapeCombineRectangles (%x, %x, cRects=%i)", window->visual->dpy, window->window, cRects);
}
}
/* Either show or hide the render SPU's window. */
void
{
#ifdef USE_OSMESA
if (render_spu.use_osmesa)
return;
#endif
{
if (showIt)
{
{
}
}
else
{
}
}
}
void renderspu_SystemVBoxPresentComposition( WindowInfo *window, 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 */
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 */
if (RT_SUCCESS(rc))
{
}
else if (rc == VERR_SEM_BUSY)
#endif
{
status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, 0, &event);
if (!status)
{
Assert(0);
crWarning("XSendEvent returned null");
}
}
else
{
/* this is somewhat we do not expect */
}
#endif
}
static void
MarkWindow(WindowInfo *w)
{
if (!gc) {
/* Create a GC for drawing invisible lines */
}
}
void
{
CRASSERT(w);
#if 00 /*TEMPORARY - FOR TESTING SWAP LOCK*/
if (1) {
/* random delay */
static int first = 1;
if (first) {
first = 0;
}
usleep(k);
}
#endif
/* render_to_app_window:
* w->nativeWindow will only be non-zero if the
* render_spu.render_to_app_window option is true and
* MakeCurrent() recorded the nativeWindow handle in the WindowInfo
* structure.
*/
if (w->nativeWindow) {
#if 0
MarkWindow(w);
#else
(void) MarkWindow;
#endif
}
else {
}
}
{
}
{
}