示例#1
0
QByteArray compatibleShaderHeader(QOpenGLShader::ShaderType type)
{
#if BUG_GLES3_ANDROID
    if (isOpenGLES())
        return commonShaderHeader(type);
#endif //BUG_GLES3_ANDROID
    QByteArray h;
    // #version directive must occur in a compilation unit before anything else, except for comments and white spaces. Default is 100 if not set
    h.append("#version ").append(QByteArray::number(GLSLVersion()));
    if (isOpenGLES() && QOpenGLContext::currentContext()->format().majorVersion() > 2)
        h += " es";
    h += "\n";
    h += commonShaderHeader(type);
    if (GLSLVersion() >= 130) { // gl(es) 3
        if (type == QOpenGLShader::Vertex) {
            h += "#define attribute in\n"
                 "#define varying out\n"
                    ;
        } else if (type == QOpenGLShader::Fragment) {
            h += "#define varying in\n"
                 "#define gl_FragColor out_color\n"  //can not starts with 'gl_'
                 "out vec4 gl_FragColor;\n"
                 ;
        }
    }
    return h;
}
示例#2
0
bool hasRG()
{
    static int has_rg = -1;
    if (has_rg >= 0)
        return !!has_rg;
    qDebug("check desktop rg: %#X", gl_param_desktop[1].internal_format);
    if (test_gl_param(gl_param_desktop[1])) {
        has_rg = 1;
        return true;
    }
    qDebug("check es3 rg: %#X", gl_param_es3[1].internal_format);
    if (test_gl_param(gl_param_es3[1])) {
        has_rg = 1;
        return true;
    }
    qDebug("check GL_EXT_texture_rg");
    static const char* ext[] = { "GL_EXT_texture_rg", 0}; //RED, RG, R8, RG8
    if (hasExtension(ext)) {
        qDebug("has extension GL_EXT_texture_rg");
        has_rg = 1;
        return true;
    }
    qDebug("check gl es>=3 rg");
    if (QOpenGLContext::currentContext())
        has_rg = isOpenGLES() && QOpenGLContext::currentContext()->format().majorVersion() > 2;
    return has_rg;
}
示例#3
0
int GLSLVersion()
{
    static int v = -1;
    if (v >= 0)
        return v;
    if (!QOpenGLContext::currentContext()) {
        qWarning("%s: current context is null", __FUNCTION__);
        return 0;
    }
    const char* vs = (const char*)DYGL(glGetString(GL_SHADING_LANGUAGE_VERSION));
    int major = 0, minor = 0;
    // es: "OpenGL ES GLSL ES 1.00 (ANGLE 2.1.99...)" can use ""%*[ a-zA-Z] %d.%d" in sscanf, desktop: "2.1"
    //QRegExp rx("(\\d+)\\.(\\d+)");
    if (strncmp(vs, "OpenGL ES GLSL ES ", 18) == 0)
        vs += 18;
    if (sscanf(vs, "%d.%d", &major, &minor) == 2) {
        v = major * 100 + minor;
    } else {
        qWarning("Failed to detect glsl version using GL_SHADING_LANGUAGE_VERSION!");
        v = 110;
        if (isOpenGLES())
            v = QOpenGLContext::currentContext()->format().majorVersion() >= 3 ? 300 : 100;
    }
    return v;
}
示例#4
0
void GraphicsContext3DPrivate::createOffscreenBuffers()
{
    glGenFramebuffers(/* count */ 1, &m_context->m_fbo);

    glGenTextures(1, &m_context->m_texture);
    glBindTexture(GL_TEXTURE_2D, m_context->m_texture);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_2D, 0);

    // Create a multisample FBO.
    if (m_context->m_attrs.antialias) {
        glGenFramebuffers(1, &m_context->m_multisampleFBO);
        glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_multisampleFBO);
        m_context->m_state.boundFBO = m_context->m_multisampleFBO;
        glGenRenderbuffers(1, &m_context->m_multisampleColorBuffer);
        if (m_context->m_attrs.stencil || m_context->m_attrs.depth)
            glGenRenderbuffers(1, &m_context->m_multisampleDepthStencilBuffer);
    } else {
        // Bind canvas FBO.
        glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_fbo);
        m_context->m_state.boundFBO = m_context->m_fbo;
        if (isOpenGLES()) {
            if (m_context->m_attrs.depth)
                glGenRenderbuffers(1, &m_context->m_depthBuffer);
            if (m_context->m_attrs.stencil)
                glGenRenderbuffers(1, &m_context->m_stencilBuffer);
        }
        if (m_context->m_attrs.stencil || m_context->m_attrs.depth)
            glGenRenderbuffers(1, &m_context->m_depthStencilBuffer);
    }
}
static QSurfaceFormat formatFromConfig(EGLDisplay dpy, EGLConfig config)
{
    QSurfaceFormat format;
    EGLint value = 0;
#define HELPER(__egl__, __qt__) \
    eglGetConfigAttrib(dpy, config, EGL_##__egl__, &value); \
    format.set##__qt__(value); \
    value = 0;

#define BUFFER_HELPER(__eglColor__, __color__) \
    HELPER(__eglColor__##_SIZE, __color__##BufferSize)

    BUFFER_HELPER(RED, Red)
    BUFFER_HELPER(GREEN, Green)
    BUFFER_HELPER(BLUE, Blue)
    BUFFER_HELPER(ALPHA, Alpha)
    BUFFER_HELPER(STENCIL, Stencil)
    BUFFER_HELPER(DEPTH, Depth)
#undef BUFFER_HELPER
    HELPER(SAMPLES, Samples)
#undef HELPER
    format.setRenderableType(isOpenGLES() ? QSurfaceFormat::OpenGLES : QSurfaceFormat::OpenGL);
    format.setStereo(false);

    return format;
}
static EGLConfig configFromGLFormat(EGLDisplay dpy, const QSurfaceFormat &format)
{
#define SIZE( __buffer__ ) format.__buffer__##BufferSize() > 0 ? format.__buffer__##BufferSize() : 0
    // not setting samples as QtQuick doesn't need it
    const EGLint config_attribs[] = {
        EGL_SURFACE_TYPE,         EGL_WINDOW_BIT,
        EGL_RED_SIZE,             SIZE(red),
        EGL_GREEN_SIZE,           SIZE(green),
        EGL_BLUE_SIZE,            SIZE(blue),
        EGL_ALPHA_SIZE,           SIZE(alpha),
        EGL_DEPTH_SIZE,           SIZE(depth),
        EGL_STENCIL_SIZE,         SIZE(stencil),
        EGL_RENDERABLE_TYPE,      isOpenGLES() ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT,
        EGL_NONE,
    };
#undef SIZE

    EGLint count;
    EGLConfig configs[1024];
    if (eglChooseConfig(dpy, config_attribs, configs, 1, &count) == EGL_FALSE) {
        return 0;
    }
    if (count != 1) {
        return 0;
    }
    return configs[0];
}
bool AbstractPlatformContext::bindApi()
{
    if (eglBindAPI(isOpenGLES() ? EGL_OPENGL_ES_API : EGL_OPENGL_API) == EGL_FALSE) {
        return false;
    }
    return true;
}
示例#8
0
void GraphicsContext3DPrivate::blitMultisampleFramebuffer()
{
    if (!m_context->m_attrs.antialias)
        return;

    if (!isOpenGLES()) {
        glBindFramebuffer(GL_READ_FRAMEBUFFER, m_context->m_multisampleFBO);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_context->m_fbo);
        glBlitFramebuffer(0, 0, m_context->m_currentWidth, m_context->m_currentHeight, 0, 0, m_context->m_currentWidth, m_context->m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    }

    glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO);
}
示例#9
0
static const gl_param_t* get_gl_param()
{
    if (!QOpenGLContext::currentContext()) {
        qWarning("%s: current context is null", __FUNCTION__);
        return gl_param_compat;
    }
    static gl_param_t* gp = 0;
    if (gp)
        return gp;
    bool has_16 = false;
    // [4] is always available
    if (test_gl_param(gl_param_desktop[4], &has_16)) {
        if (has_16 && depth16BitTexture() == 16)
            gp = (gl_param_t*)gl_param_desktop;
        else
            gp = (gl_param_t*)gl_param_desktop_fallback;
        has_16_tex = has_16;
        if (!useDeprecatedFormats()) {
            qDebug("using gl_param_desktop%s", gp == gl_param_desktop? "" : "_fallback");
            return gp;
        }
    } else if (test_gl_param(gl_param_es3[4], &has_16)) { //3.0 will fail because no glGetTexLevelParameteriv
        gp = (gl_param_t*)gl_param_es3;
        has_16_tex = has_16;
        if (!useDeprecatedFormats()) {
            qDebug("using gl_param_es3");
            return gp;
        }
    } else if (isOpenGLES()) {
        if (QOpenGLContext::currentContext()->format().majorVersion() > 2)
            gp = (gl_param_t*)gl_param_es3; //for 3.0
        else if (hasRG())
            gp = (gl_param_t*)gl_param_es2rg;
        has_16_tex = has_16;
        if (gp && !useDeprecatedFormats()) {
            qDebug("using gl_param_%s", gp == gl_param_es3 ? "es3" : "es2rg");
            return gp;
        }
    }
    qDebug("fallback to gl_param_compat");
    gp = (gl_param_t*)gl_param_compat;
    has_16_tex = false;
    return gp;
}
示例#10
0
bool isEGL()
{
    static int is_egl = -1;
    if (is_egl >= 0)
        return !!is_egl;
#ifdef Q_OS_IOS
    is_egl = 0;
    return false;
#endif
    if (isOpenGLES()) { //TODO: ios has no egl
        is_egl = 1;
        return true;
    }
    // angle has no QTAV_HAVE(QT_EGL). TODO: no assert in capi, or check egl loaded
#if QTAV_HAVE(EGL_CAPI) //&& QTAV_HAVE(QT_EGL) //make sure no crash if no egl library
    if (!egl::api().loaded()) { //load twice, here and ns func call
        is_egl = 0;
        return false;
    }
    if (eglGetCurrentDisplay() != EGL_NO_DISPLAY) { //egl can be loaded but glx is used
        is_egl = 1;
        return true;
    }
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    if (QGuiApplication::platformName().contains(QLatin1String("egl"))) {
        is_egl = 1;
        return true;
    }
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
    if (QGuiApplication::platformName().contains(QLatin1String("xcb"))) {
        is_egl = qgetenv("QT_XCB_GL_INTEGRATION") == "xcb_egl";
        qDebug("xcb_egl=%d", is_egl);
        return !!is_egl;
    }
#endif //5.5.0
#endif
    // we can use QOpenGLContext::currentContext()->nativeHandle().value<QEGLNativeContext>(). but gl context is required
    if (QOpenGLContext::currentContext())
        is_egl = 0;
    return false;
}
void AbstractPlatformContext::createContext(EGLContext shareContext)
{
    const QByteArray eglExtensions = eglQueryString(eglDisplay(), EGL_EXTENSIONS);
    const QList<QByteArray> extensions = eglExtensions.split(' ');
    const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness"));
    const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context"));

    EGLContext context = EGL_NO_CONTEXT;
    if (isOpenGLES()) {
        if (haveCreateContext && haveRobustness) {
            const EGLint context_attribs[] = {
                EGL_CONTEXT_CLIENT_VERSION,                         2,
                EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,               EGL_TRUE,
                EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT,
                EGL_NONE
            };
            context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs);
        }
        if (context == EGL_NO_CONTEXT) {
            const EGLint context_attribs[] = {
                EGL_CONTEXT_CLIENT_VERSION, 2,
                EGL_NONE
            };

            context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs);
        }
    } else {
        // Try to create a 3.1 core context
        if (m_format.majorVersion() >= 3 && haveCreateContext) {
            if (haveRobustness) {
                const int attribs[] = {
                    EGL_CONTEXT_MAJOR_VERSION_KHR,                      m_format.majorVersion(),
                    EGL_CONTEXT_MINOR_VERSION_KHR,                      m_format.minorVersion(),
                    EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR,
                    EGL_CONTEXT_FLAGS_KHR,                              EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
                    EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,                m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
                    EGL_NONE
                };
                context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
            }
            if (context == EGL_NO_CONTEXT) {
                // try without robustness
                const EGLint attribs[] = {
                    EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(),
                    EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(),
                    EGL_CONTEXT_FLAGS_KHR,         EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
                    EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
                    EGL_NONE
                };
                context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
            }
        }

        if (context == EGL_NO_CONTEXT && haveRobustness && haveCreateContext) {
            const int attribs[] = {
                EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR,
                EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR,
                EGL_NONE
            };
            context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
        }
        if (context == EGL_NO_CONTEXT) {
            // and last but not least: try without robustness
            const EGLint attribs[] = {
                EGL_NONE
            };
            context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
        }
    }

    if (context == EGL_NO_CONTEXT) {
        return;
    }
    m_context = context;
}