GLContext * GLContextProviderWGL::GetGlobalContext(const ContextFlags aFlags) { LibType libToUse = WGLLibrary::SelectLibrary(aFlags); if (!sWGLLib[libToUse].EnsureInitialized(libToUse == WGLLibrary::MESA_LLVMPIPE_LIB)) { return nullptr; } static bool triedToCreateContext[WGLLibrary::LIBS_MAX] = {false, false}; if (!triedToCreateContext[libToUse] && !gGlobalContext[libToUse]) { triedToCreateContext[libToUse] = true; // conveniently, we already have what we need... gGlobalContext[libToUse] = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24), nullptr, sWGLLib[libToUse].GetWindowDC(), sWGLLib[libToUse].GetWindowGLContext(), libToUse); if (!gGlobalContext[libToUse]->Init()) { NS_WARNING("Global context GLContext initialization failed?"); gGlobalContext[libToUse] = nullptr; return false; } gGlobalContext[libToUse]->SetIsGlobalSharedContext(true); } return static_cast<GLContext*>(gGlobalContext[libToUse]); }
GLContext * GLContextProviderWGL::GetGlobalContext() { if (!sWGLLibrary.EnsureInitialized()) { return nsnull; } static bool triedToCreateContext = false; if (!triedToCreateContext && !gGlobalContext) { triedToCreateContext = true; // conveniently, we already have what we need... gGlobalContext = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24), nsnull, gSharedWindowDC, gSharedWindowGLContext); if (!gGlobalContext->Init()) { NS_WARNING("Global context GLContext initialization failed?"); gGlobalContext = nsnull; return false; } gGlobalContext->SetIsGlobalSharedContext(true); } return static_cast<GLContext*>(gGlobalContext); }
already_AddRefed<GLContext> GLContextProviderGLX::CreateForNativePixmapSurface(gfxASurface *aSurface) { if (!sGLXLibrary.EnsureInitialized()) { return nsnull; } if (aSurface->GetType() != gfxASurface::SurfaceTypeXlib) { NS_WARNING("GLContextProviderGLX::CreateForNativePixmapSurface called with non-Xlib surface"); return nsnull; } nsAutoTArray<int, 20> attribs; #define A1_(_x) do { attribs.AppendElement(_x); } while(0) #define A2_(_x,_y) do { \ attribs.AppendElement(_x); \ attribs.AppendElement(_y); \ } while(0) A2_(GLX_DOUBLEBUFFER, False); A2_(GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT); A1_(0); int numFormats; Display *display = DefaultXDisplay(); int xscreen = DefaultScreen(display); ScopedXFree<GLXFBConfig> cfg(sGLXLibrary.xChooseFBConfig(display, xscreen, attribs.Elements(), &numFormats)); if (!cfg) { return nsnull; } NS_ASSERTION(numFormats > 0, "glXChooseFBConfig() failed to match our requested format and violated its spec (!)"); gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(aSurface); GLXPixmap glxpixmap = sGLXLibrary.xCreatePixmap(display, cfg[0], xs->XDrawable(), NULL); nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(ContextFormat(ContextFormat::BasicRGB24), display, glxpixmap, cfg[0], NULL, NULL, PR_FALSE, xs); if (!glContext->Init()) { return nsnull; } return glContext.forget(); }
GLContext * GLContextProviderGLX::GetGlobalContext() { static bool triedToCreateContext = false; if (!triedToCreateContext && !gGlobalContext) { triedToCreateContext = true; gGlobalContext = CreateOffscreenPixmapContext(gfxIntSize(1, 1), ContextFormat(ContextFormat::BasicRGB24), PR_FALSE); if (gGlobalContext) gGlobalContext->SetIsGlobalSharedContext(PR_TRUE); } return gGlobalContext; }
already_AddRefed<GLContext> GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget) { if (!sWGLLibrary.EnsureInitialized()) { return nsnull; } /** * We need to make sure we call SetPixelFormat -after- calling * EnsureInitialized, otherwise it can load/unload the dll and * wglCreateContext will fail. */ HDC dc = (HDC)aWidget->GetNativeData(NS_NATIVE_GRAPHIC); SetPixelFormat(dc, gSharedWindowPixelFormat, NULL); HGLRC context = sWGLLibrary.fCreateContext(dc); if (!context) { return nsnull; } GLContextWGL *shareContext = GetGlobalContextWGL(); if (shareContext && !sWGLLibrary.fShareLists(shareContext->Context(), context)) { shareContext = nsnull; } nsRefPtr<GLContextWGL> glContext = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24), shareContext, dc, context); if (!glContext->Init()) { return nsnull; } return glContext.forget(); }
already_AddRefed<GLContext> GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget) { if (!sWGLLibrary.EnsureInitialized()) { return nsnull; } /** * We need to make sure we call SetPixelFormat -after- calling * EnsureInitialized, otherwise it can load/unload the dll and * wglCreateContext will fail. */ HDC dc = (HDC)aWidget->GetNativeData(NS_NATIVE_GRAPHIC); SetPixelFormat(dc, gSharedWindowPixelFormat, NULL); HGLRC context; GLContextWGL *shareContext = GetGlobalContextWGL(); if (sWGLLibrary.HasRobustness()) { int attribs[] = { LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB, LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, NULL }; context = sWGLLibrary.fCreateContextAttribs(dc, shareContext ? shareContext->Context() : nsnull, attribs); if (!context && shareContext) { context = sWGLLibrary.fCreateContextAttribs(dc, nsnull, attribs); if (context) { shareContext = nsnull; } } else { context = sWGLLibrary.fCreateContext(dc); if (context && shareContext && !sWGLLibrary.fShareLists(shareContext->Context(), context)) { shareContext = nsnull; } } } else { context = sWGLLibrary.fCreateContext(dc); if (context && shareContext && !sWGLLibrary.fShareLists(shareContext->Context(), context)) { shareContext = nsnull; } } if (!context) { return nsnull; } nsRefPtr<GLContextWGL> glContext = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24), shareContext, dc, context); if (!glContext->Init()) { return nsnull; } glContext->SetIsDoubleBuffered(gUseDoubleBufferedWindows); return glContext.forget(); }
already_AddRefed<GLContext> GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget) { if (!sGLXLibrary.EnsureInitialized()) { return nsnull; } // Currently, we take whatever Visual the window already has, and // try to create an fbconfig for that visual. This isn't // necessarily what we want in the long run; an fbconfig may not // be available for the existing visual, or if it is, the GL // performance might be suboptimal. But using the existing visual // is a relatively safe intermediate step. Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY); int xscreen = DefaultScreen(display); Window window = GET_NATIVE_WINDOW(aWidget); int numConfigs; ScopedXFree<GLXFBConfig> cfgs; if (gIsATI) { const int attribs[] = { GLX_DOUBLEBUFFER, False, 0 }; cfgs = sGLXLibrary.xChooseFBConfig(display, xscreen, attribs, &numConfigs); } else { cfgs = sGLXLibrary.xGetFBConfigs(display, xscreen, &numConfigs); } if (!cfgs) { NS_WARNING("[GLX] glXGetFBConfigs() failed"); return nsnull; } NS_ASSERTION(numConfigs > 0, "No FBConfigs found!"); // XXX the visual ID is almost certainly the GLX_FBCONFIG_ID, so // we could probably do this first and replace the glXGetFBConfigs // with glXChooseConfigs. Docs are sparklingly clear as always. XWindowAttributes widgetAttrs; if (!XGetWindowAttributes(display, window, &widgetAttrs)) { NS_WARNING("[GLX] XGetWindowAttributes() failed"); XFree(cfgs); return nsnull; } const VisualID widgetVisualID = XVisualIDFromVisual(widgetAttrs.visual); #ifdef DEBUG printf("[GLX] widget has VisualID 0x%lx\n", widgetVisualID); #endif ScopedXFree<XVisualInfo> vi; if (gIsATI) { XVisualInfo vinfo_template; int nvisuals; vinfo_template.visual = widgetAttrs.visual; vinfo_template.visualid = XVisualIDFromVisual(vinfo_template.visual); vinfo_template.depth = widgetAttrs.depth; vinfo_template.screen = xscreen; vi = XGetVisualInfo(display, VisualIDMask|VisualDepthMask|VisualScreenMask, &vinfo_template, &nvisuals); NS_ASSERTION(vi && nvisuals == 1, "Could not locate unique matching XVisualInfo for Visual"); } int matchIndex = -1; ScopedXFree<XVisualInfo> vinfo; for (int i = 0; i < numConfigs; i++) { vinfo = sGLXLibrary.xGetVisualFromFBConfig(display, cfgs[i]); if (!vinfo) { continue; } if (gIsATI) { if (AreCompatibleVisuals(vi, vinfo)) { matchIndex = i; break; } } else { if (widgetVisualID == vinfo->visualid) { matchIndex = i; break; } } } if (matchIndex == -1) { NS_WARNING("[GLX] Couldn't find a FBConfig matching widget visual"); return nsnull; } GLContextGLX *shareContext = GetGlobalContextGLX(); nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(ContextFormat(ContextFormat::BasicRGB24), display, window, cfgs[matchIndex], vinfo, shareContext, PR_FALSE); return glContext.forget(); }