Drop flag to indicate if swap buffers is blocking
We want the new compositing timing algorithm to be invariant regarding whether glXSwapBuffers() or eglSwapBuffers() block.
This commit is contained in:
parent
2152598cc4
commit
7a3fa88f02
11 changed files with 23 additions and 101 deletions
|
@ -789,34 +789,6 @@ void Compositor::setCompositeTimer()
|
||||||
|
|
||||||
uint waitTime = 1;
|
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) {
|
if (fpsInterval > m_timeSinceLastVBlank) {
|
||||||
waitTime = nanoToMilli(fpsInterval - m_timeSinceLastVBlank);
|
waitTime = nanoToMilli(fpsInterval - m_timeSinceLastVBlank);
|
||||||
if (!waitTime) {
|
if (!waitTime) {
|
||||||
|
@ -842,7 +814,7 @@ void Compositor::setCompositeTimer()
|
||||||
// "0" would be sufficient here, but the compositor isn't the WMs only task.
|
// "0" would be sufficient here, but the compositor isn't the WMs only task.
|
||||||
waitTime = 1;
|
waitTime = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Force 4fps minimum:
|
// Force 4fps minimum:
|
||||||
compositeTimer.start(qMin(waitTime, 250u), this);
|
compositeTimer.start(qMin(waitTime, 250u), this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace KWin
|
||||||
|
|
||||||
OpenGLBackend::OpenGLBackend()
|
OpenGLBackend::OpenGLBackend()
|
||||||
: m_syncsToVBlank(false)
|
: m_syncsToVBlank(false)
|
||||||
, m_blocksForRetrace(false)
|
|
||||||
, m_directRendering(false)
|
, m_directRendering(false)
|
||||||
, m_haveBufferAge(false)
|
, m_haveBufferAge(false)
|
||||||
, m_failed(false)
|
, m_failed(false)
|
||||||
|
|
|
@ -93,15 +93,6 @@ public:
|
||||||
bool syncsToVBlank() const {
|
bool syncsToVBlank() const {
|
||||||
return m_syncsToVBlank;
|
return m_syncsToVBlank;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @brief Whether VSync blocks execution until the screen is in the retrace
|
|
||||||
*
|
|
||||||
* Case for waitVideoSync and non triple buffering buffer swaps
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool blocksForRetrace() const {
|
|
||||||
return m_blocksForRetrace;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @brief Whether the backend uses direct rendering.
|
* @brief Whether the backend uses direct rendering.
|
||||||
*
|
*
|
||||||
|
@ -189,16 +180,6 @@ protected:
|
||||||
void setSyncsToVBlank(bool enabled) {
|
void setSyncsToVBlank(bool enabled) {
|
||||||
m_syncsToVBlank = enabled;
|
m_syncsToVBlank = enabled;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @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.
|
* @brief Sets whether the OpenGL context is direct.
|
||||||
*
|
*
|
||||||
|
@ -250,10 +231,6 @@ private:
|
||||||
* @brief Whether VSync is available and used, defaults to @c false.
|
* @brief Whether VSync is available and used, defaults to @c false.
|
||||||
*/
|
*/
|
||||||
bool m_syncsToVBlank;
|
bool m_syncsToVBlank;
|
||||||
/**
|
|
||||||
* @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.
|
* @brief Whether direct rendering is used, defaults to @c false.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,17 +34,11 @@ void EglMultiBackend::init()
|
||||||
for (auto b : qAsConst(m_backends)) {
|
for (auto b : qAsConst(m_backends)) {
|
||||||
b->init();
|
b->init();
|
||||||
}
|
}
|
||||||
// set all the values:
|
|
||||||
// if any block, set it to be blocking
|
|
||||||
setBlocksForRetrace(false);
|
|
||||||
// if any don't support it set it to not supported
|
// if any don't support it set it to not supported
|
||||||
setSupportsBufferAge(true);
|
setSupportsBufferAge(true);
|
||||||
setSupportsPartialUpdate(true);
|
setSupportsPartialUpdate(true);
|
||||||
setSupportsSwapBuffersWithDamage(true);
|
setSupportsSwapBuffersWithDamage(true);
|
||||||
for (auto b : qAsConst(m_backends)) {
|
for (auto b : qAsConst(m_backends)) {
|
||||||
if (b->blocksForRetrace()) {
|
|
||||||
setBlocksForRetrace(true);
|
|
||||||
}
|
|
||||||
if (!b->supportsBufferAge()) {
|
if (!b->supportsBufferAge()) {
|
||||||
setSupportsBufferAge(false);
|
setSupportsBufferAge(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,6 @@ void EglOnXBackend::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
setSyncsToVBlank(false);
|
setSyncsToVBlank(false);
|
||||||
setBlocksForRetrace(false);
|
|
||||||
if (surfaceHasSubPost) {
|
if (surfaceHasSubPost) {
|
||||||
qCDebug(KWIN_CORE) << "EGL implementation and surface support eglPostSubBufferNV, let's use it";
|
qCDebug(KWIN_CORE) << "EGL implementation and surface support eglPostSubBufferNV, let's use it";
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,6 @@ void GlxBackend::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
setSyncsToVBlank(false);
|
setSyncsToVBlank(false);
|
||||||
setBlocksForRetrace(false);
|
|
||||||
haveWaitSync = false;
|
haveWaitSync = false;
|
||||||
const bool wantSync = options->glPreferBufferSwap() != Options::NoSwapEncourage;
|
const bool wantSync = options->glPreferBufferSwap() != Options::NoSwapEncourage;
|
||||||
if (wantSync && glXIsDirect(display(), ctx)) {
|
if (wantSync && glXIsDirect(display(), ctx)) {
|
||||||
|
@ -227,7 +226,6 @@ void GlxBackend::init()
|
||||||
unsigned int sync;
|
unsigned int sync;
|
||||||
if (glXGetVideoSyncSGI(&sync) == 0 && glXWaitVideoSyncSGI(1, 0, &sync) == 0) {
|
if (glXGetVideoSyncSGI(&sync) == 0 && glXWaitVideoSyncSGI(1, 0, &sync) == 0) {
|
||||||
setSyncsToVBlank(true);
|
setSyncsToVBlank(true);
|
||||||
setBlocksForRetrace(true);
|
|
||||||
haveWaitSync = true;
|
haveWaitSync = true;
|
||||||
} else
|
} else
|
||||||
qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! glXSwapInterval is not supported, glXWaitVideoSync is supported but broken";
|
qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! glXSwapInterval is not supported, glXWaitVideoSync is supported but broken";
|
||||||
|
|
|
@ -487,11 +487,6 @@ bool SceneOpenGL::syncsToVBlank() const
|
||||||
return m_backend->syncsToVBlank();
|
return m_backend->syncsToVBlank();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneOpenGL::blocksForRetrace() const
|
|
||||||
{
|
|
||||||
return m_backend->blocksForRetrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SceneOpenGL::initFailed() const
|
bool SceneOpenGL::initFailed() const
|
||||||
{
|
{
|
||||||
return !init_ok;
|
return !init_ok;
|
||||||
|
|
|
@ -41,7 +41,6 @@ public:
|
||||||
void screenGeometryChanged(const QSize &size) override;
|
void screenGeometryChanged(const QSize &size) override;
|
||||||
OverlayWindow *overlayWindow() const override;
|
OverlayWindow *overlayWindow() const override;
|
||||||
bool usesOverlayWindow() const override;
|
bool usesOverlayWindow() const override;
|
||||||
bool blocksForRetrace() const override;
|
|
||||||
bool syncsToVBlank() const override;
|
bool syncsToVBlank() const override;
|
||||||
bool makeOpenGLContextCurrent() override;
|
bool makeOpenGLContextCurrent() override;
|
||||||
void doneOpenGLContextCurrent() override;
|
void doneOpenGLContextCurrent() override;
|
||||||
|
|
|
@ -615,11 +615,6 @@ void Scene::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen)
|
||||||
Q_UNUSED(opaqueFullscreen);
|
Q_UNUSED(opaqueFullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::blocksForRetrace() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Scene::syncsToVBlank() const
|
bool Scene::syncsToVBlank() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
1
scene.h
1
scene.h
|
@ -133,7 +133,6 @@ public:
|
||||||
enum ImageFilterType { ImageFilterFast, ImageFilterGood };
|
enum ImageFilterType { ImageFilterFast, ImageFilterGood };
|
||||||
// there's nothing to paint (adjust time_diff later)
|
// there's nothing to paint (adjust time_diff later)
|
||||||
void idle();
|
void idle();
|
||||||
virtual bool blocksForRetrace() const;
|
|
||||||
virtual bool syncsToVBlank() const;
|
virtual bool syncsToVBlank() const;
|
||||||
virtual OverlayWindow* overlayWindow() const = 0;
|
virtual OverlayWindow* overlayWindow() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -1624,11 +1624,6 @@ QString Workspace::supportInformation() const
|
||||||
}
|
}
|
||||||
|
|
||||||
support.append(QStringLiteral("OpenGL 2 Shaders are used\n"));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case XRenderCompositing:
|
case XRenderCompositing:
|
||||||
|
|
Loading…
Reference in a new issue