/** * We need to check if the GL_EXT_vertex/pixel_buffer_object extensions * are supported before calling any of the diff_api functions. * This flag indicates if the extensions is available (1), not available (0) * or needs to be tested for (-1). * If we don't do this, we can segfault inside OpenGL. * Ideally, the render SPU should no-op unsupported GL functions, but * that's a bit complicated. */ static GLboolean HaveBufferObjectExtension(void) { static GLint haveBufferObjectExt = -1; if (haveBufferObjectExt == -1) { const char *ext; /* XXX this check is temporary. We need to make the tilesort SPU plug * GetString into the diff'ing table in order for this to really work. */ if (!diff_api.GetString) { haveBufferObjectExt = 0; return 0; } CRASSERT(diff_api.GetString); ext = (const char *) diff_api.GetString(GL_EXTENSIONS); if (crStrstr(ext, "GL_ARB_vertex_buffer_object") || crStrstr(ext, "GL_ARB_pixel_buffer_object")) { haveBufferObjectExt = 1; } else { haveBufferObjectExt = 0; } } return haveBufferObjectExt; }
static int crBltInitOnMakeCurent(PCR_BLITTER pBlitter) { const char * pszExtension = (const char*)pBlitter->pDispatch->GetString(GL_EXTENSIONS); if (crStrstr(pszExtension, "GL_EXT_framebuffer_object")) { pBlitter->Flags.SupportsFBO = 1; pBlitter->pDispatch->GenFramebuffersEXT(1, &pBlitter->idFBO); Assert(pBlitter->idFBO); } else crWarning("GL_EXT_framebuffer_object not supported, blitter can only blit to window"); /* BlitFramebuffer seems to be buggy on Intel, * try always glDrawXxx for now */ if (!pBlitter->Flags.ForceDrawBlit && crStrstr(pszExtension, "GL_EXT_framebuffer_blit")) { pBlitter->pfnBlt = crBltBlitTexBufImplFbo; } else { // crWarning("GL_EXT_framebuffer_blit not supported, will use Draw functions for blitting, which might be less efficient"); pBlitter->pfnBlt = crBltBlitTexBufImplDraw2D; } /* defaults. but just in case */ pBlitter->pDispatch->MatrixMode(GL_TEXTURE); pBlitter->pDispatch->LoadIdentity(); pBlitter->pDispatch->MatrixMode(GL_MODELVIEW); pBlitter->pDispatch->LoadIdentity(); return VINF_SUCCESS; }
static int ParseVisString( const char *visString ) { int mask = 0; if (crStrlen(visString) > 0) { if (crStrstr(visString, "rgb")) mask |= CR_RGB_BIT; if (crStrstr(visString, "alpha")) mask |= CR_ALPHA_BIT; if (crStrstr(visString, "z") || crStrstr(visString, "depth")) mask |= CR_DEPTH_BIT; if (crStrstr(visString, "stencil")) mask |= CR_STENCIL_BIT; if (crStrstr(visString, "accum")) mask |= CR_ACCUM_BIT; if (crStrstr(visString, "stereo")) mask |= CR_STEREO_BIT; if (crStrstr(visString, "multisample")) mask |= CR_MULTISAMPLE_BIT; if (crStrstr(visString, "double")) mask |= CR_DOUBLE_BIT; if (crStrstr(visString, "pbuffer")) mask |= CR_PBUFFER_BIT; } return mask; }
GLboolean crServerSupportRedirMuralFBO(void) { const GLubyte* pExt = cr_server.head_spu->dispatch_table.GetString(GL_REAL_EXTENSIONS); return ( NULL!=crStrstr((const char*)pExt, "GL_ARB_framebuffer_object") || NULL!=crStrstr((const char*)pExt, "GL_EXT_framebuffer_object")) && NULL!=crStrstr((const char*)pExt, "GL_ARB_texture_non_power_of_two"); }
GLboolean crServerSupportRedirMuralFBO(void) { static GLboolean fInited = GL_FALSE; static GLboolean fSupported = GL_FALSE; if (!fInited) { const GLubyte* pExt = cr_server.head_spu->dispatch_table.GetString(GL_REAL_EXTENSIONS); fSupported = ( NULL!=crStrstr((const char*)pExt, "GL_ARB_framebuffer_object") || NULL!=crStrstr((const char*)pExt, "GL_EXT_framebuffer_object")) && NULL!=crStrstr((const char*)pExt, "GL_ARB_texture_non_power_of_two"); fInited = GL_TRUE; } return fSupported; }
static int validate_one_option( const SPUOptions *opt, const char *response, const char *min, const char *max ) { switch (opt->type) { case CR_BOOL: return validate_int( response, "0", "1" ); case CR_INT: return validate_int( response, min, max ); case CR_FLOAT: return validate_float( response, min, max ); case CR_ENUM: /* Make sure response string is present in the min string. * For enums, the min string is a comma-separated list of valid values. */ CRASSERT(opt->numValues == 1); /* an enum limitation for now */ { const char *p = crStrstr(min, response); if (!p) return 0; /* invalid value! */ if (p[-1] != '\'') return 0; /* right substring */ if (p[crStrlen(response)] != '\'') return 0; /* left substring */ return 1; } default: return 0; } }
/** * Search str for pattern. Pattern may include leading and trailing * wildcard (*) characters. * \return pointer to match in s, or NULL. */ char * crStrPatternMatch(const char *s, const char *pattern) { const int patLen = crStrlen(pattern); const int leadingWildcard = pattern[0] == '*'; const int trailingWildcard = pattern[patLen-1] == '*'; if (!leadingWildcard) { if (!trailingWildcard) { /* total match */ return crStrstr(s, pattern); } else { /* match at head */ char *p = crStrstr(s, pattern); if (p == s) return p; else return NULL; } } else { if (!trailingWildcard) { /* match at tail */ const char *pPtr = pattern + patLen - 1; const char *sPtr = s + crStrlen(s) - 1; while (pPtr >= pattern && sPtr >= s) { if (*pPtr == *sPtr) { pPtr--; sPtr--; } else { break; } } if (pPtr == pattern && sPtr >= s) return (char *) sPtr; else return NULL; } else { /* match anywhere */ return crStrstr(s, pattern); } } }
static int __numOccurrences( const char *str, const char *substr ) { int ret = 0; char *temp = (char *) str; while ((temp = crStrstr( temp, substr )) != NULL ) { temp += crStrlen(substr); ret++; } return ret; }
void SERVER_DISPATCH_APIENTRY crServerDispatchLoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *string) { if (target == GL_VERTEX_PROGRAM_NV && cr_server.vpProjectionMatrixVariable != NULL) { /* scan the program string looking for 'vertprog_projection' * If the program was generated by Cg, the info we want will look * something like this: * #var float4x4 ModelViewProj : : c[0], 4 : 1 : 1 */ CRServerProgram *prog = LookupProgram(id); CRASSERT(prog); if (prog) { const char *varPos, *paramPos; varPos = crStrstr((const char *) string, cr_server.vpProjectionMatrixVariable); if (varPos) { paramPos = crStrstr(varPos, "c["); if (paramPos) { char number[10]; int i = 0; paramPos += 2; /* skip "c[" */ while (crIsDigit(paramPos[i])) { number[i] = paramPos[i]; i++; } number[i] = 0; prog->projParamStart = crStrToInt(number); } } else { crWarning("Didn't find %s parameter in vertex program string", cr_server.vpProjectionMatrixVariable); } } } /* pass through */ crStateLoadProgramNV(&cr_server.StateTracker, target, id, len, string); cr_server.head_spu->dispatch_table.LoadProgramNV(target, id, len, string); }
GLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id ) { crMemset(window, 0, sizeof (*window)); RTCritSectInit(&window->CompositorLock); window->fCompositorPresentEmpty = GL_FALSE; window->pCompositor = NULL; window->BltInfo.Base.id = id; window->x = render_spu.defaultX; window->y = render_spu.defaultY; window->BltInfo.width = render_spu.defaultWidth; window->BltInfo.height = render_spu.defaultHeight; /* Set window->title, replacing %i with the window ID number */ { const char *s = crStrstr(render_spu.window_title, "%i"); if (s) { int i, j, k; window->title = crAlloc(crStrlen(render_spu.window_title) + 10); for (i = 0; render_spu.window_title[i] != '%'; i++) window->title[i] = render_spu.window_title[i]; k = sprintf(window->title + i, "%d", window->BltInfo.Base.id); CRASSERT(k < 10); i++; /* skip the 'i' after the '%' */ j = i + k; for (; (window->title[j] = s[i]) != 0; i++, j++) ; } else { window->title = crStrdup(render_spu.window_title); } } window->BltInfo.Base.visualBits = visual->visAttribs; /* crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id); */ /* Have GLX/WGL/AGL create the window */ if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window )) { crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" ); return GL_FALSE; } window->visible = !!showIt; CRASSERT(window->visual == visual); return GL_TRUE; }
static GLboolean hasExtension(const char *haystack, const char *needle) { const int needleLen = crStrlen(needle); const char *s; while (1) { s = crStrstr(haystack, needle); if (!s) return GL_FALSE; if (s && (s[needleLen] == ' ' || s[needleLen] == 0)) return GL_TRUE; haystack += needleLen; } }
static void set_default_visual( RenderSPU *render_spu, const char *response ) { if (crStrlen(response) > 0) { if (crStrstr(response, "rgb")) render_spu->default_visual |= CR_RGB_BIT; if (crStrstr(response, "alpha")) render_spu->default_visual |= CR_ALPHA_BIT; if (crStrstr(response, "z") || crStrstr(response, "depth")) render_spu->default_visual |= CR_DEPTH_BIT; if (crStrstr(response, "stencil")) render_spu->default_visual |= CR_STENCIL_BIT; if (crStrstr(response, "accum")) render_spu->default_visual |= CR_ACCUM_BIT; if (crStrstr(response, "stereo")) render_spu->default_visual |= CR_STEREO_BIT; if (crStrstr(response, "multisample")) render_spu->default_visual |= CR_MULTISAMPLE_BIT; if (crStrstr(response, "double")) render_spu->default_visual |= CR_DOUBLE_BIT; if (crStrstr(response, "pbuffer")) render_spu->default_visual |= CR_PBUFFER_BIT; } }
static void renderSPUSelfDispatch(SPUDispatchTable *self) { crSPUInitDispatchTable( &(render_spu.self) ); crSPUCopyDispatchTable( &(render_spu.self), self ); render_spu.server = (CRServer *)(self->server); { GLfloat version; version = crStrToFloat((const char *) render_spu.ws.glGetString(GL_VERSION)); if (version>=2.f || crStrstr((const char*)render_spu.ws.glGetString(GL_EXTENSIONS), "GL_ARB_vertex_shader")) { GLint mu=0; render_spu.self.GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &mu); crInfo("Render SPU: GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB=%i", mu); } } }
void CRUT_APIENTRY crutGetWindowParams( CRUTAPI *crut_api) { char response[8096]; if (!crut_api->mothershipConn) crError("Checking for Window Params but no connection!"); crMothershipGetCRUTServerParam( crut_api->mothershipConn, response, "window_geometry" ); crDebug("CRUTserver window geometry is %s", response); if (response[0] == '[') sscanf( response, "[ %i, %i, %i, %i ]", &crut_api->winX, &crut_api->winY, &crut_api->winWidth, &crut_api->winHeight ); else if (crStrchr(response, ',')) sscanf( response, "%i, %i, %i, %i", &crut_api->winX, &crut_api->winY, &crut_api->winWidth, &crut_api->winHeight ); else sscanf( response, "%i %i %i %i", &crut_api->winX, &crut_api->winY, &crut_api->winWidth, &crut_api->winHeight ); crDebug("CRUTserver window geometry is %s", response); crMothershipGetCRUTServerParam( crut_api->mothershipConn, response, "composite_mode" ); crut_api->compositeAlpha = crStrstr(response, "alpha") ? 1 : 0; crut_api->compositeDepth = crStrcmp(response, "depth") ? 1 : 0; }
void RENDER_APIENTRY renderspuMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx) { WindowInfo *window; ContextInfo *context; /* crDebug("%s win=%d native=0x%x ctx=%d", __FUNCTION__, crWindow, (int) nativeWindow, ctx); */ window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, crWindow); context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx); if (window && context) { #ifdef CHROMIUM_THREADSAFE crSetTSD(&_RenderTSD, context); #else render_spu.currentContext = context; #endif context->currentWindow = window; if (!window) { crDebug("Render SPU: MakeCurrent invalid window id: %d", crWindow); return; } if (!context) { crDebug("Render SPU: MakeCurrent invalid context id: %d", ctx); return; } renderspu_SystemMakeCurrent( window, nativeWindow, context ); if (!context->everCurrent) { /* print OpenGL info */ const char *extString = (const char *) render_spu.ws.glGetString( GL_EXTENSIONS ); /* crDebug( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) ); */ crInfo( "Render SPU: GL_VENDOR: %s", render_spu.ws.glGetString( GL_VENDOR ) ); crInfo( "Render SPU: GL_RENDERER: %s", render_spu.ws.glGetString( GL_RENDERER ) ); crInfo( "Render SPU: GL_VERSION: %s", render_spu.ws.glGetString( GL_VERSION ) ); crInfo( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) ); if (crStrstr(extString, "GL_ARB_window_pos")) context->haveWindowPosARB = GL_TRUE; else context->haveWindowPosARB = GL_FALSE; context->everCurrent = GL_TRUE; } if (crWindow == CR_RENDER_DEFAULT_WINDOW_ID && window->mapPending && !render_spu.render_to_app_window && !render_spu.render_to_crut_window) { /* Window[CR_RENDER_DEFAULT_CONTEXT_ID] is special, it's the default window and normally hidden. * If the mapPending flag is set, then we should now make the window * visible. */ /*renderspu_SystemShowWindow( window, GL_TRUE );*/ window->mapPending = GL_FALSE; } window->everCurrent = GL_TRUE; } else if (!crWindow && !ctx) { renderspu_SystemMakeCurrent( NULL, 0, NULL ); #ifdef CHROMIUM_THREADSAFE crSetTSD(&_RenderTSD, NULL); #else render_spu.currentContext = NULL; #endif } else { crError("renderspuMakeCurrent invalid ids: crWindow(%d), ctx(%d)", crWindow, ctx); } }
/** * This function is called by MakeCurrent() and determines whether or * not a new rendering context should be bound to Chromium or the native * OpenGL. * \return GL_FALSE if native OpenGL should be used, or GL_TRUE if Chromium * should be used. */ static GLboolean stubCheckUseChromium( WindowInfo *window ) { int x, y; unsigned int w, h; /* If the provided window is CHROMIUM, we're clearly intended * to create a CHROMIUM context. */ if (window->type == CHROMIUM) return GL_TRUE; if (stub.ignoreFreeglutMenus) { const char *glutMenuTitle = "freeglut menu"; char title[1000]; GetWindowTitle(window, title); if (crStrcmp(title, glutMenuTitle) == 0) { crDebug("GL faker: Ignoring freeglut menu window"); return GL_FALSE; } } /* If the user's specified a window count for Chromium, see if * this window satisfies that criterium. */ stub.matchChromiumWindowCounter++; if (stub.matchChromiumWindowCount > 0) { if (stub.matchChromiumWindowCounter != stub.matchChromiumWindowCount) { crDebug("Using native GL, app window doesn't meet match_window_count"); return GL_FALSE; } } /* If the user's specified a window list to ignore, see if this * window satisfies that criterium. */ if (stub.matchChromiumWindowID) { GLuint i; for (i = 0; i <= stub.numIgnoreWindowID; i++) { if (stub.matchChromiumWindowID[i] == stub.matchChromiumWindowCounter) { crDebug("Ignore window ID %d, using native GL", stub.matchChromiumWindowID[i]); return GL_FALSE; } } } /* If the user's specified a minimum window size for Chromium, see if * this window satisfies that criterium. */ if (stub.minChromiumWindowWidth > 0 && stub.minChromiumWindowHeight > 0) { stubGetWindowGeometry( window, &x, &y, &w, &h ); if (w >= stub.minChromiumWindowWidth && h >= stub.minChromiumWindowHeight) { /* Check for maximum sized window now too */ if (stub.maxChromiumWindowWidth && stub.maxChromiumWindowHeight) { if (w < stub.maxChromiumWindowWidth && h < stub.maxChromiumWindowHeight) return GL_TRUE; else return GL_FALSE; } return GL_TRUE; } crDebug("Using native GL, app window doesn't meet minimum_window_size"); return GL_FALSE; } else if (stub.matchWindowTitle) { /* If the user's specified a window title for Chromium, see if this * window satisfies that criterium. */ GLboolean wildcard = GL_FALSE; char title[1000]; char *titlePattern; int len; /* check for leading '*' wildcard */ if (stub.matchWindowTitle[0] == '*') { titlePattern = crStrdup( stub.matchWindowTitle + 1 ); wildcard = GL_TRUE; } else { titlePattern = crStrdup( stub.matchWindowTitle ); } /* check for trailing '*' wildcard */ len = crStrlen(titlePattern); if (len > 0 && titlePattern[len - 1] == '*') { titlePattern[len - 1] = '\0'; /* terminate here */ wildcard = GL_TRUE; } GetWindowTitle( window, title ); if (title[0]) { if (wildcard) { if (crStrstr(title, titlePattern)) { crFree(titlePattern); return GL_TRUE; } } else if (crStrcmp(title, titlePattern) == 0) { crFree(titlePattern); return GL_TRUE; } } crFree(titlePattern); crDebug("Using native GL, app window title doesn't match match_window_title string (\"%s\" != \"%s\")", title, stub.matchWindowTitle); return GL_FALSE; } /* Window title and size don't matter */ CRASSERT(stub.minChromiumWindowWidth == 0); CRASSERT(stub.minChromiumWindowHeight == 0); CRASSERT(stub.matchWindowTitle == NULL); /* User hasn't specified a width/height or window title. * We'll use chromium for this window (and context) if no other is. */ return GL_TRUE; /* use Chromium! */ }
GLint RENDER_APIENTRY renderspuWindowCreate( const char *dpyName, GLint visBits ) { WindowInfo *window; VisualInfo *visual; GLboolean showIt; if (!dpyName || crStrlen(render_spu.display_string) > 0) dpyName = render_spu.display_string; visual = renderspuFindVisual( dpyName, visBits ); if (!visual) { crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" ); return -1; } /* Allocate WindowInfo */ window = (WindowInfo *) crCalloc(sizeof(WindowInfo)); if (!window) { crWarning( "Render SPU: Couldn't create a window" ); return -1; } crHashtableAdd(render_spu.windowTable, render_spu.window_id, window); window->id = render_spu.window_id; render_spu.window_id++; window->x = render_spu.defaultX; window->y = render_spu.defaultY; window->width = render_spu.defaultWidth; window->height = render_spu.defaultHeight; if ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")) showIt = 0; else showIt = window->id > 0; /* Set window->title, replacing %i with the window ID number */ { const char *s = crStrstr(render_spu.window_title, "%i"); if (s) { int i, j, k; window->title = crAlloc(crStrlen(render_spu.window_title) + 10); for (i = 0; render_spu.window_title[i] != '%'; i++) window->title[i] = render_spu.window_title[i]; k = sprintf(window->title + i, "%d", window->id); CRASSERT(k < 10); i++; /* skip the 'i' after the '%' */ j = i + k; for (; (window->title[j] = s[i]) != 0; i++, j++) ; } else { window->title = crStrdup(render_spu.window_title); } } /* crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->id); */ /* Have GLX/WGL/AGL create the window */ if (!renderspu_SystemCreateWindow( visual, showIt, window )) { crFree(window); crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" ); return -1; } CRASSERT(window->visual == visual); return window->id; }