diff --git a/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/platformsupport/scenes/opengl/abstract_egl_backend.cpp --- a/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -152,6 +152,8 @@ if (useBufferAge != "0") setSupportsBufferAge(true); } + + setSupportsPartialUpdate(hasExtension(QByteArrayLiteral("EGL_KHR_partial_update"))); } void AbstractEglBackend::initWayland() 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 @@ -159,6 +159,10 @@ return m_haveBufferAge; } + bool supportsPartialUpdate() const { + return m_havePartialUpdate; + } + /** * @returns whether the context is surfaceless */ @@ -248,6 +252,10 @@ m_haveBufferAge = value; } + void setSupportsPartialUpdate(bool value) { + m_havePartialUpdate = value; + } + /** * @return const QRegion& Damage of previously rendered frame */ @@ -299,6 +307,10 @@ * @brief Whether the backend supports GLX_EXT_buffer_age / EGL_EXT_buffer_age. */ bool m_haveBufferAge; + /** + * @brief Whether the backend supports EGL_KHR_partial_update + */ + bool m_havePartialUpdate; /** * @brief Whether the initialization failed, of course default to @c false. */ diff --git a/plugins/platforms/drm/egl_gbm_backend.cpp b/plugins/platforms/drm/egl_gbm_backend.cpp --- a/plugins/platforms/drm/egl_gbm_backend.cpp +++ b/plugins/platforms/drm/egl_gbm_backend.cpp @@ -502,6 +502,25 @@ region = output.output->geometry(); } + if (output.bufferAge > 0 && supportsPartialUpdate()) { +// https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt + QVector rects; + rects.reserve(region.rectCount() * 4); + const QRect v = output.output->geometry(); + for (const auto &rect : region) { + rects << rect.left(); + rects << rect.right(); + rects << v.height() - rect.top(); + rects << v.height() - rect.bottom(); + } + + bool correct = rects.isEmpty() + || eglSetDamageRegionKHR(eglDisplay(), output.eglSurface, + rects.data(), rects.count()/4); + if (!correct) { + qCritical() << "failed eglSetDamageRegionKHR" << eglGetError(); + } + } return region; } return QRegion();