Пример #1
0
static bool
glx_platform_dl_can_open(struct wcore_platform *wc_self,
                         int32_t waffle_dl)
{
    return linux_platform_dl_can_open(glx_platform(wc_self)->linux,
                                      waffle_dl);
}
Пример #2
0
static bool
glx_platform_destroy(struct wcore_platform *wc_self)
{
    struct glx_platform *self = glx_platform(wc_self);
    bool ok = true;
    int error = 0;

    if (!self)
        return true;

    if (self->linux)
        ok &= linux_platform_destroy(self->linux);

    if (self->glxHandle) {
        error = dlclose(self->glxHandle);
        if (error) {
            ok &= false;
            wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                         "dlclose(\"%s\") failed: %s",
                         libGL_filename, dlerror());
        }
    }

    ok &= wcore_platform_teardown(wc_self);
    free(self);
    return ok;
}
Пример #3
0
static void*
glx_platform_get_proc_address(struct wcore_platform *wc_self,
                              const char *name)
{
    struct glx_platform *self = glx_platform(wc_self);
    return self->glXGetProcAddress((const GLubyte*) name);
}
Пример #4
0
static void*
glx_platform_dl_sym(struct wcore_platform *wc_self,
                    int32_t waffle_dl,
                    const char *name)
{
    return linux_platform_dl_sym(glx_platform(wc_self)->linux,
                                              waffle_dl,
                                              name);
}
Пример #5
0
bool
glx_window_swap_buffers(struct wcore_window *wc_self)
{
    struct glx_window *self = glx_window(wc_self);
    struct glx_display *dpy = glx_display(wc_self->display);
    struct glx_platform *plat = glx_platform(wc_self->display->platform);

    wrapped_glXSwapBuffers(plat, dpy->x11.xlib, self->x11.xcb);

    return true;
}
Пример #6
0
static bool
glx_platform_destroy(struct wcore_platform *wc_self)
{
    struct glx_platform *self = glx_platform(wc_self);
    bool ok = true;

    if (!self)
        return true;

    if (self->linux)
        ok &= linux_platform_destroy(self->linux);

    ok &= wcore_platform_teardown(wc_self);
    free(self);
    return ok;
}
Пример #7
0
static bool
glx_platform_make_current(struct wcore_platform *wc_self,
                          struct wcore_display *wc_dpy,
                          struct wcore_window *wc_window,
                          struct wcore_context *wc_ctx)
{
    struct glx_platform *self = glx_platform(wc_self);
    Display *dpy = glx_display(wc_dpy)->x11.xlib;
    GLXDrawable win = wc_window ? glx_window(wc_window)->x11.xcb : 0;
    GLXContext ctx = wc_ctx ? glx_context(wc_ctx)->glx : NULL;
    bool ok;

    ok = wrapped_glXMakeCurrent(self, dpy, win, ctx);
    if (!ok) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXMakeCurrent failed");
    }

    return ok;
}
Пример #8
0
/// @brief Check the values of `attrs->context_*`.
static bool
glx_config_check_context_attrs(struct glx_display *dpy,
                               const struct wcore_config_attrs *attrs)
{
    struct glx_platform *plat = glx_platform(dpy->wcore.platform);

    if (attrs->context_forward_compatible) {
        assert(attrs->context_api == WAFFLE_CONTEXT_OPENGL);
        assert(wcore_config_attrs_version_ge(attrs, 30));
    }

    if (attrs->context_debug && !dpy->ARB_create_context) {
        wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                     "GLX_ARB_create_context is required in order to "
                     "request a debug context");
        return false;
    }

    if (attrs->context_robust && !dpy->ARB_create_context_robustness) {
        wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                     "GLX_ARB_create_context_robustness is required in order to "
                     "request a robust access context");
        return false;
    }

    switch (attrs->context_api) {
        case WAFFLE_CONTEXT_OPENGL:
            if (!wcore_config_attrs_version_eq(attrs, 10) && !dpy->ARB_create_context) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "GLX_ARB_create_context is required in order to "
                             "request an OpenGL version not equal to the default "
                             "value 1.0");
                return false;
            }
            else if (wcore_config_attrs_version_ge(attrs, 32) && !dpy->ARB_create_context_profile) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "GLX_ARB_create_context_profile is required "
                             "to create a context with version >= 3.2");
                return false;
            }
            else if (wcore_config_attrs_version_ge(attrs, 32)) {
                assert(attrs->context_profile == WAFFLE_CONTEXT_CORE_PROFILE ||
                       attrs->context_profile == WAFFLE_CONTEXT_COMPATIBILITY_PROFILE);
            }

            if (attrs->context_forward_compatible && !dpy->ARB_create_context) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "GLX_ARB_create_context is required in order to "
                             "request a forward-compatible context");
                return false;
            }

            return true;

        case WAFFLE_CONTEXT_OPENGL_ES1:
            assert(wcore_config_attrs_version_eq(attrs, 10) ||
                   wcore_config_attrs_version_eq(attrs, 11));
            assert(!attrs->context_forward_compatible);

            if (!dpy->EXT_create_context_es_profile) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "GLX_EXT_create_context_es_profile is required "
                             "to create an OpenGL ES1 context");
                return false;
            }
            else if (!linux_platform_dl_can_open(plat->linux,
                                            WAFFLE_DL_OPENGL_ES1)) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "failed to open the OpenGL ES1 library");
                return false;
            }

            return true;

        case WAFFLE_CONTEXT_OPENGL_ES2:
            assert(attrs->context_major_version == 2);
            assert(!attrs->context_forward_compatible);

            if (!dpy->EXT_create_context_es_profile
                && !dpy->EXT_create_context_es2_profile) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "GLX_EXT_create_context_es_profile or "
                             "GLX_EXT_create_context_es2_profile is required "
                             "to create an OpenGL ES2 context");
                return false;
            }
            if (!linux_platform_dl_can_open(plat->linux,
                                            WAFFLE_DL_OPENGL_ES2)) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "failed to open the OpenGL ES2 library");
                return false;
            }
            return true;

        case WAFFLE_CONTEXT_OPENGL_ES3:
            assert(attrs->context_major_version == 3);

            if (!dpy->EXT_create_context_es_profile) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "GLX_EXT_create_context_es_profile is required "
                             "to create an OpenGL ES3 context");
                return false;
            }

            if (!linux_platform_dl_can_open(plat->linux,
                                            WAFFLE_DL_OPENGL_ES3)) {
                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                             "failed to open the OpenGL ES3 library");
                return false;
            }

            return true;

        default:
            wcore_error_internal("context_api has bad value %#x",
                                 attrs->context_api);
            return false;
    }
}
Пример #9
0
struct wcore_config*
glx_config_choose(struct wcore_platform *wc_plat,
                  struct wcore_display *wc_dpy,
                  const struct wcore_config_attrs *attrs)
{
    struct glx_config *self;
    struct glx_display *dpy = glx_display(wc_dpy);
    struct glx_platform *plat = glx_platform(wc_plat);

    GLXFBConfig *configs = NULL;
    int num_configs = 0;
    XVisualInfo *vi = NULL;

    bool ok = true;

    if (!glx_config_check_context_attrs(dpy, attrs))
        return NULL;

    self = wcore_calloc(sizeof(*self));
    if (self == NULL)
        return NULL;

    ok = wcore_config_init(&self->wcore, wc_dpy, attrs);
    if (!ok)
        goto error;

    int attrib_list[] = {
        // From page 12 (18 of pdf) of the GLX 1.4 spec:
        //
        //    For GLXFBConfigs that correspond to a TrueColor or DirectColor
        //    visual, GLX BUFFER SIZE is the sum of GLX RED SIZE, GLX GREEN
        //    SIZE, GLX BLUE SIZE, and GLX ALPHA SIZE.
        GLX_BUFFER_SIZE,        attrs->rgba_size,
        GLX_RED_SIZE,           attrs->red_size,
        GLX_GREEN_SIZE,         attrs->green_size,
        GLX_BLUE_SIZE,          attrs->blue_size,
        GLX_ALPHA_SIZE,         attrs->alpha_size,

        GLX_DEPTH_SIZE,         attrs->depth_size,
        GLX_STENCIL_SIZE,       attrs->stencil_size,

        GLX_SAMPLE_BUFFERS,     attrs->sample_buffers,
        GLX_SAMPLES,            attrs->samples,

        GLX_DOUBLEBUFFER,       attrs->double_buffered,

        GLX_ACCUM_RED_SIZE,     attrs->accum_buffer,
        GLX_ACCUM_GREEN_SIZE,   attrs->accum_buffer,
        GLX_ACCUM_BLUE_SIZE,    attrs->accum_buffer,
        GLX_ACCUM_ALPHA_SIZE,   attrs->accum_buffer,

        // According to the GLX 1.4 spec Table 3.4, the default value of
        // GLX_DRAWABLE_TYPE is GLX_WINDOW_BIT. Explicitly set the default
        // here for the sake of self-documentation.
        GLX_DRAWABLE_TYPE,      GLX_WINDOW_BIT,

        0,
    };

    // Set glx_fbconfig.
    configs = wrapped_glXChooseFBConfig(plat, dpy->x11.xlib,
                                        dpy->x11.screen,
                                        attrib_list,
                                        &num_configs);
    if (!configs || num_configs == 0) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "glXChooseFBConfig returned no matching configs");
        goto error;
    }
    // Simply take the first.
    self->glx_fbconfig = configs[0];

    // Set glx_fbconfig_id.
    ok = !wrapped_glXGetFBConfigAttrib(plat, dpy->x11.xlib,
                                       self->glx_fbconfig,
                                       GLX_FBCONFIG_ID,
                                       &self->glx_fbconfig_id);
    if (!ok) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glxGetFBConfigAttrib failed");
        goto error;
    }

    // Set xcb_visual_id.
    vi = wrapped_glXGetVisualFromFBConfig(plat, dpy->x11.xlib,
                                          self->glx_fbconfig);
    if (!vi) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "glXGetVisualInfoFromFBConfig failed with "
                     "GLXFBConfigID=0x%x\n", self->glx_fbconfig_id);
        goto error;
    }
    self->xcb_visual_id = vi->visualid;

    goto cleanup;

error:
    glx_config_destroy(&self->wcore);
    self = NULL;

cleanup:
    if (configs)
        XFree(configs);
    if (vi)
        XFree(vi);

    return &self->wcore;
}