diff --git a/composite.h b/composite.h --- a/composite.h +++ b/composite.h @@ -187,6 +187,8 @@ private: explicit WaylandCompositor(QObject *parent); + + int m_refreshRate; }; class KWIN_EXPORT X11Compositor : public Compositor diff --git a/composite.cpp b/composite.cpp --- a/composite.cpp +++ b/composite.cpp @@ -779,62 +779,7 @@ return; } - uint waitTime = 1; - - if (m_scene->blocksForRetrace()) { - - // TODO: make vBlankTime dynamic?! - // It's required because glXWaitVideoSync will *likely* block a full frame if one enters - // a retrace pass which can last a variable amount of time, depending on the actual screen - // Now, my ooold 19" CRT can do such retrace so that 2ms are entirely sufficient, - // while another ooold 15" TFT requires about 6ms - - qint64 padding = m_timeSinceLastVBlank; - if (padding > fpsInterval) { - // We're at low repaints or spent more time in painting than the user wanted to wait - // for that frame. Align to next vblank: - padding = vBlankInterval - (padding % vBlankInterval); - } else { - // Align to the next maxFps tick: - // "remaining time of the first vsync" + "time for the other vsyncs of the frame" - padding = ((vBlankInterval - padding % vBlankInterval) + - (fpsInterval / vBlankInterval - 1) * vBlankInterval); - } - - if (padding < options->vBlankTime()) { - // We'll likely miss this frame so we add one: - waitTime = nanoToMilli(padding + vBlankInterval - options->vBlankTime()); - } else { - waitTime = nanoToMilli(padding - options->vBlankTime()); - } - } - else { // w/o blocking vsync we just jump to the next demanded tick - if (fpsInterval > m_timeSinceLastVBlank) { - waitTime = nanoToMilli(fpsInterval - m_timeSinceLastVBlank); - if (!waitTime) { - // Will ensure we don't block out the eventloop - the system's just not faster ... - waitTime = 1; - } - } - /* else if (m_timeSinceLastVBlank - fpsInterval < (vBlankInterval<<1)) { - // NOTICE - "for later" ------------------------------------------------------------------ - // It can happen that we push two frames within one refresh cycle. - // Swapping will then block even with triple buffering when the GPU does not discard but - // queues frames - // now here's the mean part: if we take that as "OMG, we're late - next frame ASAP", - // there'll immediately be 2 frames in the pipe, swapping will block, we think we're - // late ... ewww - // so instead we pad to the clock again and add 2ms safety to ensure the pipe is really - // free - // NOTICE: obviously m_timeSinceLastVBlank can be too big because we're too slow as well - // So if this code was enabled, we'd needlessly half the framerate once more (15 instead of 30) - waitTime = nanoToMilli(vBlankInterval - (m_timeSinceLastVBlank - fpsInterval)%vBlankInterval) + 2; - }*/ - else { - // "0" would be sufficient here, but the compositor isn't the WMs only task. - waitTime = 1; - } - } + uint waitTime = 1000 / refreshRate(); // Force 4fps minimum: compositeTimer.start(qMin(waitTime, 250u), this); } @@ -863,6 +808,11 @@ return; } + // TODO: This is problematic on Wayland. We should get the highest refresh rate + // and not the one of the first output. Also on hotplug reevaluate. + // On X11 do it also like this? + m_refreshRate = KWin::currentRefreshRate(); + if (Workspace::self()) { startupWithWorkspace(); } else { @@ -873,10 +823,7 @@ int WaylandCompositor::refreshRate() const { - // TODO: This makes no sense on Wayland. First step would be to atleast - // set the refresh rate to the highest available one. Second step - // would be to not use a uniform value at all but per screen. - return KWin::currentRefreshRate(); + return m_refreshRate; } X11Compositor::X11Compositor(QObject *parent) diff --git a/platformsupport/scenes/opengl/backend.h b/platformsupport/scenes/opengl/backend.h --- a/platformsupport/scenes/opengl/backend.h +++ b/platformsupport/scenes/opengl/backend.h @@ -124,16 +124,6 @@ bool isFailed() const { return m_failed; } - /** - * @brief Whether VSync blocks execution until the screen is in the retrace - * - * Case for waitVideoSync and non triple buffering buffer swaps (triple buffering support - * has been removed). - * - */ - bool blocksForRetrace() const { - return m_blocksForRetrace; - } /** * @brief Whether the backend uses direct rendering. * @@ -202,16 +192,6 @@ * @param reason The reason why the initialization failed. */ void setFailed(const QString &reason); - /** - * @brief Sets whether the VSync iplementation blocks - * - * Should be called by the concrete subclass once it is determined how VSync works. - * If the subclass does not call this method, the backend defaults to @c false. - * @param enabled @c true if VSync blocks, @c false otherwise. - */ - void setBlocksForRetrace(bool enabled) { - m_blocksForRetrace = enabled; - } /** * @brief Sets whether the OpenGL context is direct. * @@ -264,10 +244,6 @@ } private: - /** - * @brief Whether present() will block execution until the next vertical retrace @c false. - */ - bool m_blocksForRetrace; /** * @brief Whether direct rendering is used, defaults to @c false. */ diff --git a/platformsupport/scenes/opengl/backend.cpp b/platformsupport/scenes/opengl/backend.cpp --- a/platformsupport/scenes/opengl/backend.cpp +++ b/platformsupport/scenes/opengl/backend.cpp @@ -30,8 +30,7 @@ { OpenGLBackend::OpenGLBackend() - : m_blocksForRetrace(false) - , m_directRendering(false) + : m_directRendering(false) , m_haveBufferAge(false) , m_failed(false) { diff --git a/plugins/platforms/x11/common/eglonxbackend.cpp b/plugins/platforms/x11/common/eglonxbackend.cpp --- a/plugins/platforms/x11/common/eglonxbackend.cpp +++ b/plugins/platforms/x11/common/eglonxbackend.cpp @@ -121,7 +121,6 @@ } } - setBlocksForRetrace(true); if (surfaceHasSubPost) { qCDebug(KWIN_CORE) << "EGL implementation and surface support eglPostSubBufferNV, let's use it"; @@ -355,8 +354,6 @@ { QRegion repaint; - present(); - if (supportsBufferAge()) repaint = accumulatedDamageHistory(m_bufferAge); @@ -386,16 +383,7 @@ } setLastDamage(renderedRegion); - - if (!blocksForRetrace()) { - // This also sets lastDamage to empty which prevents the frame from - // being posted again when prepareRenderingFrame() is called. - present(); - } else { - // Make sure that the GPU begins processing the command stream - // now and not the next time prepareRenderingFrame() is called. - glFlush(); - } + present(); if (m_overlayWindow && overlayWindow()->window()) // show the window only after the first pass, overlayWindow()->show(); // since that pass may take long diff --git a/plugins/platforms/x11/standalone/glxbackend.cpp b/plugins/platforms/x11/standalone/glxbackend.cpp --- a/plugins/platforms/x11/standalone/glxbackend.cpp +++ b/plugins/platforms/x11/standalone/glxbackend.cpp @@ -115,11 +115,6 @@ , m_bufferAge(0) , m_x11Display(display) { - // Ensures calls to glXSwapBuffers will always block until the next - // retrace when using the proprietary NVIDIA driver. This must be - // set before libGL.so is loaded. - setenv("__GL_MaxFramesAllowed", "1", true); - // Force initialization of GLX integration in the Qt's xcb backend // to make it call XESetWireToEvent callbacks, which is required // by Mesa when using DRI2. @@ -229,8 +224,6 @@ setSupportsBufferAge(true); } - setBlocksForRetrace(true); - if (m_haveEXTSwapControl) { glXSwapIntervalEXT(display(), glxWindow, 1); } else if (m_haveMESASwapControl) { @@ -726,13 +719,10 @@ { QRegion repaint; - present(); - if (supportsBufferAge()) repaint = accumulatedDamageHistory(m_bufferAge); startRenderTimer(); - glXWaitX(); return repaint; } @@ -757,16 +747,7 @@ } setLastDamage(renderedRegion); - - if (!blocksForRetrace()) { - // This also sets lastDamage to empty which prevents the frame from - // being posted again when prepareRenderingFrame() is called. - present(); - } else { - // Make sure that the GPU begins processing the command stream - // now and not the next time prepareRenderingFrame() is called. - glFlush(); - } + present(); if (overlayWindow()->window()) // show the window only after the first pass, overlayWindow()->show(); // since that pass may take long diff --git a/plugins/scenes/opengl/scene_opengl.h b/plugins/scenes/opengl/scene_opengl.h --- a/plugins/scenes/opengl/scene_opengl.h +++ b/plugins/scenes/opengl/scene_opengl.h @@ -53,7 +53,6 @@ void screenGeometryChanged(const QSize &size) override; OverlayWindow *overlayWindow() const override; bool usesOverlayWindow() const override; - bool blocksForRetrace() const override; bool makeOpenGLContextCurrent() override; void doneOpenGLContextCurrent() override; Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; diff --git a/plugins/scenes/opengl/scene_opengl.cpp b/plugins/scenes/opengl/scene_opengl.cpp --- a/plugins/scenes/opengl/scene_opengl.cpp +++ b/plugins/scenes/opengl/scene_opengl.cpp @@ -525,11 +525,6 @@ return m_backend->overlayWindow(); } -bool SceneOpenGL::blocksForRetrace() const -{ - return m_backend->blocksForRetrace(); -} - void SceneOpenGL::idle() { m_backend->idle(); diff --git a/scene.h b/scene.h --- a/scene.h +++ b/scene.h @@ -145,7 +145,6 @@ enum ImageFilterType { ImageFilterFast, ImageFilterGood }; // there's nothing to paint (adjust time_diff later) virtual void idle(); - virtual bool blocksForRetrace() const; virtual OverlayWindow* overlayWindow() const = 0; virtual bool makeOpenGLContextCurrent(); diff --git a/scene.cpp b/scene.cpp --- a/scene.cpp +++ b/scene.cpp @@ -627,11 +627,6 @@ Q_UNUSED(opaqueFullscreen); } -bool Scene::blocksForRetrace() const -{ - return false; -} - void Scene::screenGeometryChanged(const QSize &size) { if (!overlayWindow()) { diff --git a/workspace.cpp b/workspace.cpp --- a/workspace.cpp +++ b/workspace.cpp @@ -1609,11 +1609,6 @@ } support.append(QStringLiteral("OpenGL 2 Shaders are used\n")); - support.append(QStringLiteral("Painting blocks for vertical retrace: ")); - if (m_compositor->scene()->blocksForRetrace()) - support.append(QStringLiteral(" yes\n")); - else - support.append(QStringLiteral(" no\n")); break; } case XRenderCompositing: