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(); }
static already_AddRefed<GLContextGLX> CreateOffscreenPixmapContext(CreateContextFlags flags, const IntSize& size, const SurfaceCaps& minCaps, nsACString* const out_failureId, ContextProfile profile = ContextProfile::OpenGLCompatibility) { GLXLibrary* glx = &sGLXLibrary; if (!glx->EnsureInitialized()) return nullptr; Display* display = DefaultXDisplay(); int screen = DefaultScreen(display); ScopedXFree<GLXFBConfig> scopedConfigArr; GLXFBConfig config; int visid; if (!ChooseConfig(glx, display, screen, minCaps, &scopedConfigArr, &config, &visid)) { NS_WARNING("Failed to find a compatible config."); return nullptr; } Visual* visual; int depth; FindVisualAndDepth(display, visid, &visual, &depth); ScopedXErrorHandler xErrorHandler; bool error = false; // Must be declared before goto: Drawable drawable; GLXPixmap pixmap; gfx::IntSize dummySize(16, 16); RefPtr<gfxXlibSurface> surface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display), visual, dummySize); if (surface->CairoStatus() != 0) { error = true; goto DONE_CREATING_PIXMAP; } // Handle slightly different signature between glXCreatePixmap and // its pre-GLX-1.3 extension equivalent (though given the ABI, we // might not need to). drawable = surface->XDrawable(); if (glx->GLXVersionCheck(1, 3)) { pixmap = glx->xCreatePixmap(display, config, drawable, nullptr); } else { pixmap = glx->xCreateGLXPixmapWithConfig(display, config, drawable); } if (pixmap == 0) { error = true; } DONE_CREATING_PIXMAP: bool serverError = xErrorHandler.SyncAndGetError(display); if (error || serverError) return nullptr; GLContextGLX* shareContext = GetGlobalContextGLX(); return GLContextGLX::CreateGLContext(flags, minCaps, shareContext, true, display, pixmap, config, true, surface, profile); }
static already_AddRefed<GLContextGLX> CreateOffscreenPixmapContext(const gfxIntSize& aSize, const ContextFormat& aFormat, PRBool aShare) { if (!sGLXLibrary.EnsureInitialized()) { return nsnull; } Display *display = DefaultXDisplay(); int xscreen = DefaultScreen(display); int attribs[] = { GLX_DOUBLEBUFFER, False, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_X_RENDERABLE, True, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 0, GLX_DEPTH_SIZE, 0, 0 }; int numConfigs = 0; ScopedXFree<GLXFBConfig> cfgs; cfgs = sGLXLibrary.xChooseFBConfig(display, xscreen, attribs, &numConfigs); if (!cfgs) { return nsnull; } NS_ASSERTION(numConfigs > 0, "glXChooseFBConfig() failed to match our requested format and violated its spec (!)"); ScopedXFree<XVisualInfo> vinfo; int chosenIndex; for (int i = 0; i < numConfigs; ++i) { int dtype, visid; if (sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], GLX_DRAWABLE_TYPE, &dtype) != Success || !(dtype & GLX_PIXMAP_BIT)) { continue; } if (sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &visid) != Success || visid == 0) { continue; } vinfo = sGLXLibrary.xGetVisualFromFBConfig(display, cfgs[i]); if (vinfo) { chosenIndex = i; break; } } if (!vinfo) { NS_WARNING("glXChooseFBConfig() didn't give us any configs with visuals!"); return nsnull; } nsRefPtr<gfxXlibSurface> xsurface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display), vinfo->visual, gfxIntSize(16, 16)); if (xsurface->CairoStatus() != 0) { return nsnull; } GLXPixmap glxpixmap = sGLXLibrary.xCreatePixmap(display, cfgs[chosenIndex], xsurface->XDrawable(), NULL); if (glxpixmap == 0) { return nsnull; } GLContextGLX *shareContext = aShare ? GetGlobalContextGLX() : nsnull; nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(aFormat, display, glxpixmap, cfgs[chosenIndex], vinfo, shareContext, PR_TRUE, xsurface); return glContext.forget(); }