예제 #1
0
void
init(void) {
    load("libEGL.so.1");

    initX();

    eglExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
    if (eglExtensions &&
        checkExtension("EGL_EXT_platform_x11", eglExtensions)) {

        Attributes<EGLint> attribs;
        attribs.add(EGL_PLATFORM_X11_SCREEN_EXT, screen);
        attribs.add(EGL_NONE);

        eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, display, attribs);
    } else {
        eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
    }

    if (eglDisplay == EGL_NO_DISPLAY) {
        std::cerr << "error: unable to get EGL display\n";
        XCloseDisplay(display);
        exit(1);
    }

    EGLint major, minor;
    if (!eglInitialize(eglDisplay, &major, &minor)) {
        std::cerr << "error: unable to initialize EGL display\n";
        XCloseDisplay(display);
        exit(1);
    }

    eglExtensions = eglQueryString(eglDisplay, EGL_EXTENSIONS);
    has_EGL_KHR_create_context = checkExtension("EGL_KHR_create_context", eglExtensions);
}
예제 #2
0
Context *
createContext(const Visual *_visual, Context *shareContext, Profile profile)
{
    const GlxVisual *visual = static_cast<const GlxVisual *>(_visual);
    GLXContext share_context = NULL;
    GLXContext context;

    if (profile != PROFILE_COMPAT) {
        return NULL;
    }

    if (shareContext) {
        share_context = static_cast<GlxContext*>(shareContext)->context;
    }

    if (glxVersion >= 0x0104 && has_GLX_ARB_create_context) {
        Attributes<int> attribs;
        attribs.add(GLX_RENDER_TYPE, GLX_RGBA_TYPE);
        if (debug) {
            attribs.add(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB);
        }
        attribs.end();

        context = glXCreateContextAttribsARB(display, visual->fbconfig, share_context, True, attribs);
    } else 
           if (glxVersion >= 0x103) {
        context = glXCreateNewContext(display, visual->fbconfig, GLX_RGBA_TYPE, share_context, True);
    } else {
        context = glXCreateContext(display, visual->visinfo, share_context, True);
    }

    return new GlxContext(visual, profile, context);
}
예제 #3
0
  virtual Result<Attributes> slaveAttributesDecorator(
      const SlaveInfo& slaveInfo)
  {
    LOG(INFO) << "Executing 'slaveAttributesDecorator' hook";

    Attributes attributes = slaveInfo.attributes();
    attributes.add(Attributes::parse("rack", "rack1"));

    return attributes;
  }
예제 #4
0
Context *
createContext(const Visual *_visual, Context *shareContext, Profile profile, bool debug)
{
    const EglVisual *visual = static_cast<const EglVisual *>(_visual);
    EGLContext share_context = EGL_NO_CONTEXT;
    EGLContext context;
    Attributes<EGLint> attribs;

    if (shareContext) {
        share_context = static_cast<EglContext*>(shareContext)->context;
    }

    EGLint api = eglQueryAPI();

    switch (profile) {
    case PROFILE_COMPAT:
        load("libGL.so.1");
        eglBindAPI(EGL_OPENGL_API);
        break;
    case PROFILE_CORE:
        assert(0);
        return NULL;
    case PROFILE_ES1:
        load("libGLESv1_CM.so.1");
        eglBindAPI(EGL_OPENGL_ES_API);
        break;
    case PROFILE_ES2:
        load("libGLESv2.so.2");
        eglBindAPI(EGL_OPENGL_ES_API);
        attribs.add(EGL_CONTEXT_CLIENT_VERSION, 2);
        break;
    default:
        return NULL;
    }

    attribs.end(EGL_NONE);

    context = eglCreateContext(eglDisplay, visual->config, share_context, attribs);
    if (!context)
        return NULL;

    eglBindAPI(api);

    return new EglContext(visual, profile, context);
}
예제 #5
0
Attributes Attributes::parse(const string& s)
{
  // Tokenize and parse the value of "attributes".
  Attributes attributes;

  vector<string> tokens = strings::tokenize(s, ";\n");

  for (size_t i = 0; i < tokens.size(); i++) {
    const vector<string>& pairs = strings::tokenize(tokens[i], ":");
    if (pairs.size() != 2) {
      LOG(FATAL) << "Bad value for attributes, missing ':' within " << pairs[0];
    }

    attributes.add(parse(pairs[0], pairs[1]));
  }

  return attributes;
}
예제 #6
0
Visual *
createVisual(bool doubleBuffer, Profile profile) {
    EglVisual *visual = new EglVisual();
    // possible combinations
    const EGLint api_bits_gl[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT,
    };
    const EGLint api_bits_gles1[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT,
        EGL_OPENGL_ES2_BIT,
    };
    const EGLint api_bits_gles2[7] = {
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_ES2_BIT,
        EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT,
        EGL_OPENGL_BIT,
        EGL_OPENGL_ES_BIT,
    };
    const EGLint *api_bits;

    switch(profile) {
    case PROFILE_COMPAT:
        api_bits = api_bits_gl;
        break;
    case PROFILE_ES1:
        api_bits = api_bits_gles1;
        break;
    case PROFILE_ES2:
        api_bits = api_bits_gles2;
        break;
    default:
        return NULL;
    };

    for (int i = 0; i < 7; i++) {
        Attributes<EGLint> attribs;

        attribs.add(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
        attribs.add(EGL_RED_SIZE, 1);
        attribs.add(EGL_GREEN_SIZE, 1);
        attribs.add(EGL_BLUE_SIZE, 1);
        attribs.add(EGL_ALPHA_SIZE, 1);
        attribs.add(EGL_DEPTH_SIZE, 1);
        attribs.add(EGL_STENCIL_SIZE, 1);
        attribs.add(EGL_RENDERABLE_TYPE, api_bits[i]);
        attribs.end(EGL_NONE);

        EGLint num_configs, vid;
        if (eglChooseConfig(eglDisplay, attribs, &visual->config, 1, &num_configs) &&
            num_configs == 1 &&
            eglGetConfigAttrib(eglDisplay, visual->config, EGL_NATIVE_VISUAL_ID, &vid)) {
            XVisualInfo templ;
            int num_visuals;

            templ.visualid = vid;
            visual->visinfo = XGetVisualInfo(display, VisualIDMask, &templ, &num_visuals);
            break;
        }
    }

    assert(visual->visinfo);

    return visual;
}
예제 #7
0
Window
GlxDrawable::createPbuffer(Display *dpy, const GlxVisual *visinfo,
                           const glws::pbuffer_info *pbInfo, int w, int h)
{
    int samples = 0;

    // XXX ideally, we'd populate these attributes according to the Visual info
    Attributes<int> attribs;
    attribs.add(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
    attribs.add(GLX_RENDER_TYPE, GLX_RGBA_BIT);
    attribs.add(GLX_RED_SIZE, 1);
    attribs.add(GLX_GREEN_SIZE, 1);
    attribs.add(GLX_BLUE_SIZE, 1);
    attribs.add(GLX_ALPHA_SIZE, 1);
    //attribs.add(GLX_DOUBLEBUFFER, doubleBuffer ? GL_TRUE : GL_FALSE);
    attribs.add(GLX_DEPTH_SIZE, 1);
    attribs.add(GLX_STENCIL_SIZE, 1);
    if (samples > 1) {
        attribs.add(GLX_SAMPLE_BUFFERS, 1);
        attribs.add(GLX_SAMPLES_ARB, samples);
    }
    attribs.end();

    int num_configs = 0;
    GLXFBConfig *fbconfigs;
    fbconfigs = glXChooseFBConfig(dpy, screen, attribs, &num_configs);
    if (!num_configs || !fbconfigs) {
        std::cerr << "error: glXChooseFBConfig for pbuffer failed.\n";
        exit(1);
    }

    Attributes<int> pbAttribs;
    pbAttribs.add(GLX_PBUFFER_WIDTH, w);
    pbAttribs.add(GLX_PBUFFER_HEIGHT, h);
    pbAttribs.add(GLX_PRESERVED_CONTENTS, True);
    pbAttribs.end();

    GLXDrawable pbuffer = glXCreatePbuffer(dpy, fbconfigs[0], pbAttribs);
    if (!pbuffer) {
        std::cerr << "error: glXCreatePbuffer() failed\n";
        exit(1);
    }

    return pbuffer;
}
예제 #8
0
Context *
createContext(const Visual *_visual, Context *shareContext, bool debug)
{
    const GlxVisual *visual = static_cast<const GlxVisual *>(_visual);
    Profile profile = visual->profile;
    GLXContext share_context = NULL;
    GLXContext context;

    if (shareContext) {
        share_context = static_cast<GlxContext*>(shareContext)->context;
    }

    if (has_GLX_ARB_create_context) {
        Attributes<int> attribs;
        attribs.add(GLX_RENDER_TYPE, GLX_RGBA_TYPE);
        int contextFlags = 0;
        if (profile.api == glfeatures::API_GL) {
            attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, profile.major);
            attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, profile.minor);
            if (profile.versionGreaterOrEqual(3, 2)) {
                if (!has_GLX_ARB_create_context_profile) {
                    std::cerr << "error: GLX_ARB_create_context_profile not supported\n";
                    return NULL;
                }
                int profileMask = profile.core ? GLX_CONTEXT_CORE_PROFILE_BIT_ARB : GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
                attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, profileMask);
                if (profile.forwardCompatible) {
                    contextFlags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
                }
            }
        } else if (profile.api == glfeatures::API_GLES) {
            if (has_GLX_EXT_create_context_es_profile) {
                attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT);
                attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, profile.major);
                attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, profile.minor);
            } else if (profile.major < 2) {
                std::cerr << "error: " << profile << " requested but GLX_EXT_create_context_es_profile not supported\n";
                return NULL;
            } else if (has_GLX_EXT_create_context_es2_profile) {
                assert(profile.major >= 2);
                if (profile.major != 2 || profile.minor != 0) {
                    // We might still get a ES 3.0 context later (in particular Mesa does this)
                    std::cerr << "warning: " << profile << " requested but GLX_EXT_create_context_es_profile not supported\n";
                }
                attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT);
                attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, 2);
                attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, 0);
            } else {
                std::cerr << "warning: " << profile << " requested but GLX_EXT_create_context_es_profile or GLX_EXT_create_context_es2_profile not supported\n";
            }
        } else {
            assert(0);
        }
        if (debug) {
            contextFlags |= GLX_CONTEXT_DEBUG_BIT_ARB;
        }
        if (contextFlags) {
            attribs.add(GLX_CONTEXT_FLAGS_ARB, contextFlags);
        }
        attribs.end();

        context = glXCreateContextAttribsARB(display, visual->fbconfig, share_context, True, attribs);
        if (!context && debug) {
            // XXX: Mesa has problems with GLX_CONTEXT_DEBUG_BIT_ARB with
            // OpenGL ES contexts, so retry without it
            return createContext(_visual, shareContext, false);
        }
    } else {
        if (profile.api != glfeatures::API_GL ||
            profile.core) {
            return NULL;
        }

        context = glXCreateNewContext(display, visual->fbconfig, GLX_RGBA_TYPE, share_context, True);
    }

    if (!context) {
        return NULL;
    }

    return new GlxContext(visual, context);
}
예제 #9
0
Visual *
createVisual(bool doubleBuffer, unsigned samples, Profile profile) {
    GlxVisual *visual = new GlxVisual(profile);

    Attributes<int> attribs;
    attribs.add(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT);
    attribs.add(GLX_RENDER_TYPE, GLX_RGBA_BIT);
    attribs.add(GLX_RED_SIZE, 1);
    attribs.add(GLX_GREEN_SIZE, 1);
    attribs.add(GLX_BLUE_SIZE, 1);
    attribs.add(GLX_ALPHA_SIZE, 1);
    attribs.add(GLX_DOUBLEBUFFER, doubleBuffer ? GL_TRUE : GL_FALSE);
    attribs.add(GLX_DEPTH_SIZE, 1);
    attribs.add(GLX_STENCIL_SIZE, 1);
    if (samples > 1) {
        attribs.add(GLX_SAMPLE_BUFFERS, 1);
        attribs.add(GLX_SAMPLES_ARB, samples);
    }
    attribs.end();

    int num_configs = 0;
    GLXFBConfig * fbconfigs;
    fbconfigs = glXChooseFBConfig(display, screen, attribs, &num_configs);
    if (!num_configs || !fbconfigs) {
        return NULL;
    }
    visual->fbconfig = fbconfigs[0];
    assert(visual->fbconfig);
    visual->visinfo = glXGetVisualFromFBConfig(display, visual->fbconfig);
    assert(visual->visinfo);

    return visual;
}
예제 #10
0
Visual *
createVisual(bool doubleBuffer) {
    GlxVisual *visual = new GlxVisual;

    if (glxVersion >= 0x0103) {
        Attributes<int> attribs;
        attribs.add(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT);
        attribs.add(GLX_RENDER_TYPE, GLX_RGBA_BIT);
        attribs.add(GLX_RED_SIZE, 1);
        attribs.add(GLX_GREEN_SIZE, 1);
        attribs.add(GLX_BLUE_SIZE, 1);
        attribs.add(GLX_ALPHA_SIZE, 1);
        attribs.add(GLX_DOUBLEBUFFER, doubleBuffer ? GL_TRUE : GL_FALSE);
        attribs.add(GLX_DEPTH_SIZE, 1);
        attribs.add(GLX_STENCIL_SIZE, 1);
        attribs.end();

        int num_configs = 0;
        GLXFBConfig * fbconfigs;
        fbconfigs = glXChooseFBConfig(display, screen, attribs, &num_configs);
        assert(num_configs && fbconfigs);
        visual->fbconfig = fbconfigs[0];
        assert(visual->fbconfig);
        visual->visinfo = glXGetVisualFromFBConfig(display, visual->fbconfig);
        assert(visual->visinfo);
    } else {
        Attributes<int> attribs;
        attribs.add(GLX_RGBA);
        attribs.add(GLX_RED_SIZE, 1);
        attribs.add(GLX_GREEN_SIZE, 1);
        attribs.add(GLX_BLUE_SIZE, 1);
        attribs.add(GLX_ALPHA_SIZE, 1);
        if (doubleBuffer) {
            attribs.add(GLX_DOUBLEBUFFER);
        }
        attribs.add(GLX_DEPTH_SIZE, 1);
        attribs.add(GLX_STENCIL_SIZE, 1);
        attribs.end();

        visual->visinfo = glXChooseVisual(display, screen, attribs);
    }

    return visual;
}
예제 #11
0
Context *
createContext(const Visual *_visual, Context *shareContext, bool debug)
{
    Profile profile = _visual->profile;
    const EglVisual *visual = static_cast<const EglVisual *>(_visual);
    EGLContext share_context = EGL_NO_CONTEXT;
    EGLContext context;
    Attributes<EGLint> attribs;

    if (shareContext) {
        share_context = static_cast<EglContext*>(shareContext)->context;
    }

    int contextFlags = 0;
    if (profile.api == glprofile::API_GL) {
        if (has_EGL_KHR_create_context) {
            attribs.add(EGL_CONTEXT_MAJOR_VERSION_KHR, profile.major);
            attribs.add(EGL_CONTEXT_MINOR_VERSION_KHR, profile.minor);
            int profileMask = profile.core ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
            attribs.add(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, profileMask);
            if (profile.forwardCompatible) {
                contextFlags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
            }
        } else if (profile.versionGreaterOrEqual(3, 2)) {
            std::cerr << "error: EGL_KHR_create_context not supported\n";
            return NULL;
        }
    } else if (profile.api == glprofile::API_GLES) {
        if (has_EGL_KHR_create_context) {
            attribs.add(EGL_CONTEXT_MAJOR_VERSION_KHR, profile.major);
            attribs.add(EGL_CONTEXT_MINOR_VERSION_KHR, profile.minor);
        } else {
            attribs.add(EGL_CONTEXT_CLIENT_VERSION, profile.major);
        }
    } else {
        assert(0);
        return NULL;
    }

    if (debug) {
        contextFlags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
    }
    if (contextFlags && has_EGL_KHR_create_context) {
        attribs.add(EGL_CONTEXT_FLAGS_KHR, contextFlags);
    }
    attribs.end(EGL_NONE);

    EGLenum api = translateAPI(profile);
    bindAPI(api);

    context = eglCreateContext(eglDisplay, visual->config, share_context, attribs);
    if (!context) {
        if (debug) {
            // XXX: Mesa has problems with EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
            // with OpenGL ES contexts, so retry without it
            return createContext(_visual, shareContext, false);
        }
        return NULL;
    }

    return new EglContext(visual, context);
}
예제 #12
0
Visual *
createVisual(bool doubleBuffer, unsigned samples, Profile profile) {
    EGLint api_bits;
    if (profile.api == glprofile::API_GL) {
        api_bits = EGL_OPENGL_BIT;
        if (profile.core && !has_EGL_KHR_create_context) {
            return NULL;
        }
    } else if (profile.api == glprofile::API_GLES) {
        switch (profile.major) {
        case 1:
            api_bits = EGL_OPENGL_ES_BIT;
            break;
        case 3:
            if (has_EGL_KHR_create_context) {
                api_bits = EGL_OPENGL_ES3_BIT;
                break;
            }
            /* fall-through */
        case 2:
            api_bits = EGL_OPENGL_ES2_BIT;
            break;
        default:
            return NULL;
        }
    } else {
        assert(0);
        return NULL;
    }

    Attributes<EGLint> attribs;
    attribs.add(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
    attribs.add(EGL_RED_SIZE, 1);
    attribs.add(EGL_GREEN_SIZE, 1);
    attribs.add(EGL_BLUE_SIZE, 1);
    attribs.add(EGL_ALPHA_SIZE, 1);
    attribs.add(EGL_DEPTH_SIZE, 1);
    attribs.add(EGL_STENCIL_SIZE, 1);
    attribs.add(EGL_RENDERABLE_TYPE, api_bits);
    attribs.end(EGL_NONE);

    EGLint num_configs = 0;
    if (!eglGetConfigs(eglDisplay, NULL, 0, &num_configs) ||
        num_configs <= 0) {
        return NULL;
    }

    std::vector<EGLConfig> configs(num_configs);
    if (!eglChooseConfig(eglDisplay, attribs, &configs[0], num_configs,  &num_configs) ||
        num_configs <= 0) {
        return NULL;
    }

    // We can't tell what other APIs the trace will use afterwards, therefore
    // try to pick a config which supports the widest set of APIs.
    int bestScore = -1;
    EGLConfig config = configs[0];
    for (EGLint i = 0; i < num_configs; ++i) {
        EGLint renderable_type = EGL_NONE;
        eglGetConfigAttrib(eglDisplay, configs[i], EGL_RENDERABLE_TYPE, &renderable_type);
        int score = 0;
        assert(renderable_type & api_bits);
        renderable_type &= ~api_bits;
        if (renderable_type & EGL_OPENGL_ES2_BIT) {
            score += 1 << 4;
        }
        if (renderable_type & EGL_OPENGL_ES3_BIT) {
            score += 1 << 3;
        }
        if (renderable_type & EGL_OPENGL_ES_BIT) {
            score += 1 << 2;
        }
        if (renderable_type & EGL_OPENGL_BIT) {
            score += 1 << 1;
        }
        if (score > bestScore) {
            config = configs[i];
            bestScore = score;
        }
    }
    assert(bestScore >= 0);

    EGLint visual_id = -1;
    if (!eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &visual_id)) {
        assert(0);
        return NULL;
    }
    assert(visual_id != -1);

    EglVisual *visual = new EglVisual(profile);
    visual->config = config;
    visual->format = visual_id;

    return visual;
}
예제 #13
0
Context *
createContext(const Visual *_visual, Context *shareContext, bool debug)
{
    const GlxVisual *visual = static_cast<const GlxVisual *>(_visual);
    Profile profile = visual->profile;
    GLXContext share_context = NULL;
    GLXContext context;

    if (shareContext) {
        share_context = static_cast<GlxContext*>(shareContext)->context;
    }

    if (glxVersion >= 0x0104 && has_GLX_ARB_create_context) {
        Attributes<int> attribs;
        
        attribs.add(GLX_RENDER_TYPE, GLX_RGBA_TYPE);
        if (debug) {
            attribs.add(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB);
        }

        ProfileDesc desc;
        getProfileDesc(profile, desc);

        switch (profile) {
        case PROFILE_COMPAT:
            break;
        case PROFILE_ES1:
            if (!has_GLX_EXT_create_context_es_profile) {
                return NULL;
            }
            attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT);
            attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, 1);
            break;
        case PROFILE_ES2:
            if (!has_GLX_EXT_create_context_es_profile &&
                !has_GLX_EXT_create_context_es2_profile) {
                return NULL;
            }
            attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT);
            attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, 2);
            break;
        default:
            {
                attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, desc.major);
                attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, desc.minor);
                if (desc.versionGreaterOrEqual(3, 2)) {
                    if (!has_GLX_ARB_create_context_profile) {
                        return NULL;
                    }
                    int profileMask = desc.core ? GLX_CONTEXT_CORE_PROFILE_BIT_ARB : GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
                    attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, profileMask);
                }
                break;
            }
        }
        
        attribs.end();

        context = glXCreateContextAttribsARB(display, visual->fbconfig, share_context, True, attribs);
        if (!context && debug) {
            // XXX: Mesa has problems with GLX_CONTEXT_DEBUG_BIT_ARB with
            // OpenGL ES contexts, so retry without it
            return createContext(_visual, shareContext, false);
        }
    } else {
        if (profile != PROFILE_COMPAT) {
            return NULL;
        }

        if (glxVersion >= 0x103) {
            context = glXCreateNewContext(display, visual->fbconfig, GLX_RGBA_TYPE, share_context, True);
        } else {
            context = glXCreateContext(display, visual->visinfo, share_context, True);
        }
    }

    if (!context) {
        return NULL;
    }

    return new GlxContext(visual, context);
}
예제 #14
0
    bool
    createARB(HDC hDC) {
        bool required = profile.api != glfeatures::API_GL ||
                        profile.versionGreaterOrEqual(3, 1);

        // We need to create context through WGL_ARB_create_context.  This
        // implies binding a temporary context to get the extensions strings
        // and function pointers.

        // This function is only called inside makeCurrent, so we don't need
        // to save and restore the previous current context/drawable.
        BOOL bRet = wglMakeCurrent(hDC, hglrc);
        if (!bRet) {
            std::cerr << "error: wglMakeCurrent failed\n";
            exit(1);
        }

        pfnWglGetExtensionsStringARB =
            (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
        if (!pfnWglGetExtensionsStringARB) {
            if (required) {
                std::cerr << "error: WGL_ARB_extensions_string not supported\n";
                exit(1);
            } else {
                return false;
            }
        }
        const char * extensionsString = pfnWglGetExtensionsStringARB(hDC);
        assert(extensionsString);

        if (checkExtension("WGL_ARB_pbuffer", extensionsString)) {
            has_WGL_ARB_pbuffer = true;
            WGL_PROC(PFNWGLCREATEPBUFFERARBPROC,
                     pfnWglCreatePbufferARB, "wglCreatePbufferARB");
            WGL_PROC(PFNWGLGETPBUFFERDCARBPROC,
                     pfnWglGetPbufferDCARB, "wglGetPbufferDCARB");
            WGL_PROC(PFNWGLCHOOSEPIXELFORMATARBPROC,
                     pfnWglChoosePixelFormatARB, "wglChoosePixelFormatARB");
            WGL_PROC(PFNWGLDESTROYPBUFFERARBPROC,
                     pfnWglDestroyPbufferARB, "wglDestroyPbufferARB");
            WGL_PROC(PFNWGLRELEASEPBUFFERDCARBPROC,
                     pfnWglReleasePbufferDCARB, "wglReleasePbufferDCARB");
        }
        if (checkExtension("WGL_ARB_render_texture", extensionsString)) {
            assert(has_WGL_ARB_pbuffer);
            has_WGL_ARB_render_texture = true;
            WGL_PROC(PFNWGLBINDTEXIMAGEARBPROC,
                     pfnWglBindTexImageARB, "wglBindTexImageARB");
            WGL_PROC(PFNWGLRELEASETEXIMAGEARBPROC,
                     pfnWglReleaseTexImageARB, "wglReleaseTexImageARB");
            WGL_PROC(PFNWGLSETPBUFFERATTRIBARBPROC,
                     pfnWglSetPbufferAttribARB, "wglSetPbufferAttribARB");
        }

        if (!checkExtension("WGL_ARB_create_context", extensionsString)) {
            if (required) {
                std::cerr << "error: WGL_ARB_create_context not supported\n";
                exit(1);
            } else {
                return false;
            }
        }

        PFNWGLCREATECONTEXTATTRIBSARBPROC pfnWglCreateContextAttribsARB =
            (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
        if (!pfnWglCreateContextAttribsARB) {
            if (required) {
                std::cerr << "error: failed to get pointer to wglCreateContextAttribsARB\n";
                exit(1);
            } else {
                return false;
            }
        }

        wglMakeCurrent(hDC, NULL);

        Attributes<int> attribs;
        int contextFlags = 0;
        if (profile.api == glfeatures::API_GL) {
            attribs.add(WGL_CONTEXT_MAJOR_VERSION_ARB, profile.major);
            attribs.add(WGL_CONTEXT_MINOR_VERSION_ARB, profile.minor);
            if (profile.versionGreaterOrEqual(3, 2)) {
                if (!checkExtension("WGL_ARB_create_context_profile", extensionsString)) {
                    assert(required);
                    std::cerr << "error: WGL_ARB_create_context_profile not supported\n";
                    exit(1);
                }
                int profileMask = profile.core ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
                attribs.add(WGL_CONTEXT_PROFILE_MASK_ARB, profileMask);
                if (profile.forwardCompatible) {
                    contextFlags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
                }
            }
        } else if (profile.api == glfeatures::API_GLES) {
            if (checkExtension("WGL_EXT_create_context_es_profile", extensionsString)) {
                attribs.add(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_ES_PROFILE_BIT_EXT);
                attribs.add(WGL_CONTEXT_MAJOR_VERSION_ARB, profile.major);
                attribs.add(WGL_CONTEXT_MINOR_VERSION_ARB, profile.minor);
            } else if (profile.major != 2) {
                std::cerr << "warning: OpenGL ES " << profile.major << " requested but WGL_EXT_create_context_es_profile not supported\n";
            } else if (checkExtension("WGL_EXT_create_context_es2_profile", extensionsString)) {
                assert(profile.major == 2);
                attribs.add(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_ES2_PROFILE_BIT_EXT);
                attribs.add(WGL_CONTEXT_MAJOR_VERSION_ARB, profile.major);
                attribs.add(WGL_CONTEXT_MINOR_VERSION_ARB, profile.minor);
            } else {
                std::cerr << "warning: OpenGL ES " << profile.major << " requested but WGL_EXT_create_context_es_profile or WGL_EXT_create_context_es2_profile not supported\n";
            }
        } else {
            assert(0);
        }
        if (debug) {
            contextFlags |= WGL_CONTEXT_DEBUG_BIT_ARB;
        }
        if (contextFlags) {
            attribs.add(WGL_CONTEXT_FLAGS_ARB, contextFlags);
        }
        attribs.end();


        HGLRC new_hglrc;
        new_hglrc = pfnWglCreateContextAttribsARB(hDC,
                                                  shareContext ? shareContext->hglrc : 0,
                                                  attribs);
        if (!new_hglrc) {
            if (required) {
                std::cerr << "error: wglCreateContextAttribsARB failed\n";
                exit(1);
            } else {
                return false;
            }
        }

        wglDeleteContext(hglrc);
        hglrc = new_hglrc;

        return true;
    }
예제 #15
0
Context *
createContext(const Visual *_visual, Context *shareContext, bool debug)
{
    const GlxVisual *visual = static_cast<const GlxVisual *>(_visual);
    Profile profile = visual->profile;
    GLXContext share_context = NULL;
    GLXContext context;

    if (shareContext) {
        share_context = static_cast<GlxContext*>(shareContext)->context;
    }

    if (glxVersion >= 0x0104 && has_GLX_ARB_create_context) {
        Attributes<int> attribs;
        
        attribs.add(GLX_RENDER_TYPE, GLX_RGBA_TYPE);
        if (debug) {
            attribs.add(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB);
        }

        switch (profile) {
        case PROFILE_COMPAT:
            break;
        case PROFILE_ES1:
            return NULL;
        case PROFILE_ES2:
            attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT);
            break;
        default:
            {
                unsigned major, minor;
                bool core;
                getProfileVersion(profile, major, minor, core);
                attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, major);
                attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, minor);
                if (core) {
                    attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB);
                }
                break;
            }
        }
        
        attribs.end();

        context = glXCreateContextAttribsARB(display, visual->fbconfig, share_context, True, attribs);
    } else {
        if (profile != PROFILE_COMPAT) {
            return NULL;
        }

        if (glxVersion >= 0x103) {
            context = glXCreateNewContext(display, visual->fbconfig, GLX_RGBA_TYPE, share_context, True);
        } else {
            context = glXCreateContext(display, visual->visinfo, share_context, True);
        }
    }

    if (!context) {
        return NULL;
    }

    return new GlxContext(visual, context);
}
예제 #16
0
bool
glws::WglDrawable::createPbuffer(const Visual *vis,
                                 const glws::pbuffer_info *pbInfo,
                                 int width, int height)
{
    if (!has_WGL_ARB_pbuffer) {
        std::cerr << "error: WGL_ARB_pbuffer extension is unsupported\n";
        exit(1);
        return false;
    }

    // choose pixel format
    Attributes<int> attribs;
    attribs.add(WGL_DRAW_TO_PBUFFER_ARB, true);
    attribs.add(WGL_DEPTH_BITS_ARB, 24);
    attribs.add(WGL_STENCIL_BITS_ARB, 8);
    attribs.add(WGL_RED_BITS_ARB, 8);
    attribs.add(WGL_GREEN_BITS_ARB, 8);
    attribs.add(WGL_BLUE_BITS_ARB, 8);
    attribs.add(WGL_ALPHA_BITS_ARB, 8);
    attribs.add(WGL_COLOR_BITS_ARB, 32);
    if (pbInfo->texFormat) {
        if (pbInfo->texFormat == GL_RGBA)
            attribs.add(WGL_BIND_TO_TEXTURE_RGBA_ARB, true);
        else if (pbInfo->texFormat == GL_RGB)
            attribs.add(WGL_BIND_TO_TEXTURE_RGB_ARB, true);
        else {
            std::cerr << "error: unexpected texture format.\n";
            exit(1);
        }
    }
    attribs.end();

    int pixelFormats[20];
    UINT numPixelFormats;
    WglDrawable *wgl_draw = static_cast<WglDrawable *>(pbInfo->hdc_drawable);
    HDC hdc = wgl_draw->hDC;
    assert(hdc);

    if (!pfnWglChoosePixelFormatARB(hdc, attribs, NULL,
                                    20, pixelFormats,
                                    &numPixelFormats)) {
        std::cerr << "error: wglChoosePixelFormatARB failed.\n";
        exit(1);
    }

    // create pbuffer
    Attributes<int> pbAttribs;
    if (pbInfo->texFormat) {
        if (pbInfo->texFormat == GL_RGBA) {
            pbAttribs.add(WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB);
        } else if (pbInfo->texFormat == GL_RGB) {
            pbAttribs.add(WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGB_ARB);
        } else {
            std::cerr << "error: unexpected texture format.\n";
            exit(1);
        }
    }
    if (pbInfo->texTarget) {
        if (pbInfo->texTarget == GL_TEXTURE_1D) {
            pbAttribs.add(WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_1D_ARB);
        } else if (pbInfo->texTarget == GL_TEXTURE_2D) {
            pbAttribs.add(WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB);
        } else if (pbInfo->texTarget == GL_TEXTURE_CUBE_MAP) {
            pbAttribs.add(WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_CUBE_MAP_ARB);
        } else {
            std::cerr << "error: unexpected texture targett.\n";
            exit(1);
        }
    }
    if (pbInfo->texMipmap) {
        pbAttribs.add(WGL_MIPMAP_TEXTURE_ARB, pbInfo->texMipmap);
    }
    pbAttribs.end();

    hPBuffer = pfnWglCreatePbufferARB(hdc, pixelFormats[0],
                                      width, height, pbAttribs);
    if (!hPBuffer) {
        std::cerr << "error: wglCreatePbufferARB failed (format "
                  << pixelFormats[0] << ")\n";
        DWORD er = GetLastError();
        std::cerr << "error code " << er << "\n";
        exit(1);
    }
    hDC = pfnWglGetPbufferDCARB(hPBuffer);
    if (!hDC) {
        std::cerr << "error: wglGetPbufferDCARB failed\n";
        exit(1);
    }

    return true;
}
예제 #17
0
void ModuleSummaryIndex::exportToDot(raw_ostream& OS) const {
  std::vector<Edge> CrossModuleEdges;
  DenseMap<GlobalValue::GUID, std::vector<uint64_t>> NodeMap;
  StringMap<GVSummaryMapTy> ModuleToDefinedGVS;
  collectDefinedGVSummariesPerModule(ModuleToDefinedGVS);

  // Get node identifier in form MXXX_<GUID>. The MXXX prefix is required,
  // because we may have multiple linkonce functions summaries.
  auto NodeId = [](uint64_t ModId, GlobalValue::GUID Id) {
    return ModId == (uint64_t)-1 ? std::to_string(Id)
                                 : std::string("M") + std::to_string(ModId) +
                                       "_" + std::to_string(Id);
  };

  auto DrawEdge = [&](const char *Pfx, int SrcMod, GlobalValue::GUID SrcId,
                      int DstMod, GlobalValue::GUID DstId, int TypeOrHotness) {
    // 0 corresponds to alias edge, 1 to ref edge, 2 to call with unknown
    // hotness, ...
    TypeOrHotness += 2;
    static const char *EdgeAttrs[] = {
        " [style=dotted]; // alias",
        " [style=dashed]; // ref",
        " // call (hotness : Unknown)",
        " [color=blue]; // call (hotness : Cold)",
        " // call (hotness : None)",
        " [color=brown]; // call (hotness : Hot)",
        " [style=bold,color=red]; // call (hotness : Critical)"};

    assert(static_cast<size_t>(TypeOrHotness) <
           sizeof(EdgeAttrs) / sizeof(EdgeAttrs[0]));
    OS << Pfx << NodeId(SrcMod, SrcId) << " -> " << NodeId(DstMod, DstId)
       << EdgeAttrs[TypeOrHotness] << "\n";
  };

  OS << "digraph Summary {\n";
  for (auto &ModIt : ModuleToDefinedGVS) {
    auto ModId = getModuleId(ModIt.first());
    OS << "  // Module: " << ModIt.first() << "\n";
    OS << "  subgraph cluster_" << std::to_string(ModId) << " {\n";
    OS << "    style = filled;\n";
    OS << "    color = lightgrey;\n";
    OS << "    label = \"" << sys::path::filename(ModIt.first()) << "\";\n";
    OS << "    node [style=filled,fillcolor=lightblue];\n";

    auto &GVSMap = ModIt.second;
    auto Draw = [&](GlobalValue::GUID IdFrom, GlobalValue::GUID IdTo, int Hotness) {
      if (!GVSMap.count(IdTo)) {
        CrossModuleEdges.push_back({ModId, Hotness, IdFrom, IdTo});
        return;
      }
      DrawEdge("    ", ModId, IdFrom, ModId, IdTo, Hotness);
    };

    for (auto &SummaryIt : GVSMap) {
      NodeMap[SummaryIt.first].push_back(ModId);
      auto Flags = SummaryIt.second->flags();
      Attributes A;
      if (isa<FunctionSummary>(SummaryIt.second)) {
        A.add("shape", "record", "function");
      } else if (isa<AliasSummary>(SummaryIt.second)) {
        A.add("style", "dotted,filled", "alias");
        A.add("shape", "box");
      } else {
        A.add("shape", "Mrecord", "variable");
      }

      auto VI = getValueInfo(SummaryIt.first);
      A.add("label", getNodeLabel(VI, SummaryIt.second));
      if (!Flags.Live)
        A.add("fillcolor", "red", "dead");
      else if (Flags.NotEligibleToImport)
        A.add("fillcolor", "yellow", "not eligible to import");

      OS << "    " << NodeId(ModId, SummaryIt.first) << " " << A.getAsString()
         << "\n";
    }
    OS << "    // Edges:\n";

    for (auto &SummaryIt : GVSMap) {
      auto *GVS = SummaryIt.second;
      for (auto &R : GVS->refs())
        Draw(SummaryIt.first, R.getGUID(), -1);

      if (auto *AS = dyn_cast_or_null<AliasSummary>(SummaryIt.second)) {
        auto AliaseeOrigId = AS->getAliasee().getOriginalName();
        auto AliaseeId = getGUIDFromOriginalID(AliaseeOrigId);

        Draw(SummaryIt.first, AliaseeId ? AliaseeId : AliaseeOrigId, -2);
        continue;
      }

      if (auto *FS = dyn_cast_or_null<FunctionSummary>(SummaryIt.second))
        for (auto &CGEdge : FS->calls())
          Draw(SummaryIt.first, CGEdge.first.getGUID(),
               static_cast<int>(CGEdge.second.Hotness));
    }
    OS << "  }\n";
  }

  OS << "  // Cross-module edges:\n";
  for (auto &E : CrossModuleEdges) {
    auto &ModList = NodeMap[E.Dst];
    if (ModList.empty()) {
      defineExternalNode(OS, "  ", getValueInfo(E.Dst));
      // Add fake module to the list to draw an edge to an external node
      // in the loop below.
      ModList.push_back(-1);
    }
    for (auto DstMod : ModList)
      // The edge representing call or ref is drawn to every module where target
      // symbol is defined. When target is a linkonce symbol there can be
      // multiple edges representing a single call or ref, both intra-module and
      // cross-module. As we've already drawn all intra-module edges before we
      // skip it here.
      if (DstMod != E.SrcMod)
        DrawEdge("  ", E.SrcMod, E.Src, DstMod, E.Dst, E.Hotness);
  }

  OS << "}";
}