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();
}