Пример #1
0
SceneOpenGL::SceneOpenGL(Workspace* ws)
    : Scene(ws)
    , m_resetModelViewProjectionMatrix(true)
    , init_ok(false)
{
    initGLX();
    // check for FBConfig support
    if (!hasGLExtension("GLX_SGIX_fbconfig") || !glXGetFBConfigAttrib || !glXGetFBConfigs ||
            !glXGetVisualFromFBConfig || !glXCreatePixmap || !glXDestroyPixmap ||
            !glXCreateWindow || !glXDestroyWindow) {
        kError(1212) << "GLX_SGIX_fbconfig or required GLX functions missing";
        return; // error
    }
    if (!selectMode())
        return; // error
    if (!initBuffer())  // create destination buffer
        return; // error
    if (!initRenderingContext())
        return; // error
    // Initialize OpenGL
    GLPlatform *glPlatform = GLPlatform::instance();
    glPlatform->detect();
    glPlatform->printResults();
    initGL();

    if (glPlatform->isSoftwareEmulation()) {
        kError(1212) << "OpenGL Software Rasterizer detected. Falling back to XRender.";
        QTimer::singleShot(0, Workspace::self(), SLOT(fallbackToXRenderCompositing()));
        return;
    }
    if (!hasGLExtension("GL_ARB_texture_non_power_of_two")
            && !hasGLExtension("GL_ARB_texture_rectangle")) {
        kError(1212) << "GL_ARB_texture_non_power_of_two and GL_ARB_texture_rectangle missing";
        return; // error
    }
    if (glPlatform->isMesaDriver() && glPlatform->mesaVersion() < kVersionNumber(7, 10)) {
        kError(1212) << "KWin requires at least Mesa 7.10 for OpenGL compositing.";
        return;
    }
    if (db)
        glDrawBuffer(GL_BACK);
    // Check whether certain features are supported
    has_waitSync = false;
    if (options->isGlVSync()) {
        if (glXGetVideoSync && glXSwapInterval && glXIsDirect(display(), ctxbuffer)) {
            unsigned int sync;
            if (glXGetVideoSync(&sync) == 0) {
                if (glXWaitVideoSync(1, 0, &sync) == 0) {
                    // NOTICE at this time we should actually check whether we can successfully
                    // deactivate the swapInterval "glXSwapInterval(0) == 0"
                    // (because we don't actually want it active unless we explicitly run a glXSwapBuffers)
                    // However mesa/dri will return a range error (6) because deactivating the
                    // swapinterval (as of today) seems completely unsupported
                    has_waitSync = true;
                    glXSwapInterval(0);
                }
                else
                    qWarning() << "NO VSYNC! glXWaitVideoSync(1,0,&uint) isn't 0 but" << glXWaitVideoSync(1, 0, &sync);
            } else
                qWarning() << "NO VSYNC! glXGetVideoSync(&uint) isn't 0 but" << glXGetVideoSync(&sync);
        } else
            qWarning() << "NO VSYNC! glXGetVideoSync, glXSwapInterval, glXIsDirect" <<
                        bool(glXGetVideoSync) << bool(glXSwapInterval) << glXIsDirect(display(), ctxbuffer);
    }

    debug = qstrcmp(qgetenv("KWIN_GL_DEBUG"), "1") == 0;

    // scene shader setup
    if (GLPlatform::instance()->supports(GLSL)) {
        if (!ShaderManager::instance()->isValid()) {
            kDebug(1212) << "No Scene Shaders available";
        } else {
            // push one shader on the stack so that one is always bound
            // consistency with GLES
            ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
        }
    }

    // OpenGL scene setup
    setupModelViewProjectionMatrix();
    if (checkGLError("Init")) {
        kError(1212) << "OpenGL compositing setup failed";
        return; // error
    }

    // set strict binding
    if (options->isGlStrictBindingFollowsDriver()) {
        options->setGlStrictBinding(!glPlatform->supports(LooseBinding));
    }
    kDebug(1212) << "DB:" << db << ", Direct:" << bool(glXIsDirect(display(), ctxbuffer)) << endl;
    init_ok = true;
}