コード例 #1
0
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);
}
コード例 #2
0
already_AddRefed<GLContext>
GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
{
    if (!sGLXLibrary.EnsureInitialized()) {
        return nullptr;
    }

    // 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);
    if (!display) {
        NS_ERROR("X Display required for GLX Context provider");
        return nullptr;
    }

    int xscreen = DefaultScreen(display);
    Window window = GET_NATIVE_WINDOW(aWidget);

    int numConfigs;
    ScopedXFree<GLXFBConfig> cfgs;
    if (sGLXLibrary.IsATI() ||
        !sGLXLibrary.GLXVersionCheck(1, 3)) {
        const int attribs[] = {
            LOCAL_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 nullptr;
    }
    NS_ASSERTION(numConfigs > 0, "No FBConfigs found!");

    // XXX the visual ID is almost certainly the LOCAL_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");
        return nullptr;
    }
    const VisualID widgetVisualID = XVisualIDFromVisual(widgetAttrs.visual);
#ifdef DEBUG
    printf("[GLX] widget has VisualID 0x%lx\n", widgetVisualID);
#endif

    int matchIndex = -1;

    for (int i = 0; i < numConfigs; i++) {
        int visid = None;
        sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid);
        if (!visid) {
            continue;
        }
        if (sGLXLibrary.IsATI()) {
            int depth;
            Visual *visual;
            FindVisualAndDepth(display, visid, &visual, &depth);
            if (depth == widgetAttrs.depth &&
                AreCompatibleVisuals(widgetAttrs.visual, visual)) {
                matchIndex = i;
                break;
            }
        } else {
            if (widgetVisualID == static_cast<VisualID>(visid)) {
                matchIndex = i;
                break;
            }
        }
    }

    if (matchIndex == -1) {
        NS_WARNING("[GLX] Couldn't find a FBConfig matching widget visual");
        return nullptr;
    }

    GLContextGLX *shareContext = GetGlobalContextGLX();

    SurfaceCaps caps = SurfaceCaps::Any();
    nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(caps,
                                                                     shareContext,
                                                                     false,
                                                                     display,
                                                                     window,
                                                                     cfgs[matchIndex],
                                                                     false);

    return glContext.forget();
}
コード例 #3
0
bool
GLContextGLX::FindFBConfigForWindow(Display* display, int screen, Window window,
                                    ScopedXFree<GLXFBConfig>* const out_scopedConfigArr,
                                    GLXFBConfig* const out_config, int* const out_visid)
{
    ScopedXFree<GLXFBConfig>& cfgs = *out_scopedConfigArr;
    int numConfigs;
    if (sGLXLibrary.IsATI() ||
        !sGLXLibrary.GLXVersionCheck(1, 3)) {
        const int attribs[] = {
            LOCAL_GLX_DOUBLEBUFFER, False,
            0
        };
        cfgs = sGLXLibrary.xChooseFBConfig(display,
                                           screen,
                                           attribs,
                                           &numConfigs);
    } else {
        cfgs = sGLXLibrary.xGetFBConfigs(display,
                                         screen,
                                         &numConfigs);
    }

    if (!cfgs) {
        NS_WARNING("[GLX] glXGetFBConfigs() failed");
        return false;
    }
    NS_ASSERTION(numConfigs > 0, "No FBConfigs found!");

    // XXX the visual ID is almost certainly the LOCAL_GLX_FBCONFIG_ID, so
    // we could probably do this first and replace the glXGetFBConfigs
    // with glXChooseConfigs.  Docs are sparklingly clear as always.
    XWindowAttributes windowAttrs;
    if (!XGetWindowAttributes(display, window, &windowAttrs)) {
        NS_WARNING("[GLX] XGetWindowAttributes() failed");
        return false;
    }
    const VisualID windowVisualID = XVisualIDFromVisual(windowAttrs.visual);
#ifdef DEBUG
    printf("[GLX] window %lx has VisualID 0x%lx\n", window, windowVisualID);
#endif

    for (int i = 0; i < numConfigs; i++) {
        int visid = None;
        sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid);
        if (!visid) {
            continue;
        }
        if (sGLXLibrary.IsATI()) {
            int depth;
            Visual* visual;
            FindVisualAndDepth(display, visid, &visual, &depth);
            if (depth == windowAttrs.depth &&
                AreCompatibleVisuals(windowAttrs.visual, visual)) {
                *out_config = cfgs[i];
                *out_visid = visid;
                return true;
            }
        } else {
            if (windowVisualID == static_cast<VisualID>(visid)) {
                *out_config = cfgs[i];
                *out_visid = visid;
                return true;
            }
        }
    }

    NS_WARNING("[GLX] Couldn't find a FBConfig matching window visual");
    return false;
}