From 63ba8e0eafea83bf7847ab9849743760f7515d64 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 24 Nov 2022 15:44:47 +0100 Subject: [PATCH] scenes/opengl: Use hardware clipping for clearing the background Right now, when `paintBackground()` is called to clear the background, we use custom geometry and render that when the damage region isn't infinite. Rather than using geometry, we can instead use `glScissor()` to set the area that needs to be cleared and then use `glClear()` to clear it. In addition, if we have only one rect in the damage region and that rect matches the render target rect, we can completely skip all that setup and use `glClear()` directly. --- src/scenes/opengl/scene_opengl.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/scenes/opengl/scene_opengl.cpp b/src/scenes/opengl/scene_opengl.cpp index 06a62e033c..2131ee9544 100644 --- a/src/scenes/opengl/scene_opengl.cpp +++ b/src/scenes/opengl/scene_opengl.cpp @@ -92,24 +92,23 @@ void SceneOpenGL::paint(RenderTarget *renderTarget, const QRegion ®ion) void SceneOpenGL::paintBackground(const QRegion ®ion) { - if (region == infiniteRegion()) { + if (region == infiniteRegion() || (region.rectCount() == 1 && (*region.begin()) == renderTargetRect())) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); } else if (!region.isEmpty()) { - QVector verts; - verts.reserve(region.rectCount() * 6 * 2); + glClearColor(0, 0, 0, 0); + glEnable(GL_SCISSOR_TEST); const auto scale = renderTargetScale(); + const auto targetRect = scaledRect(renderTargetRect(), scale).toRect(); for (const QRect &r : region) { - verts << (r.x() + r.width()) * scale << r.y() * scale; - verts << r.x() * scale << r.y() * scale; - verts << r.x() * scale << (r.y() + r.height()) * scale; - verts << r.x() * scale << (r.y() + r.height()) * scale; - verts << (r.x() + r.width()) * scale << (r.y() + r.height()) * scale; - verts << (r.x() + r.width()) * scale << r.y() * scale; + auto deviceRect = scaledRect(r, scale).toAlignedRect(); + glScissor(deviceRect.x(), targetRect.height() - (deviceRect.y() + deviceRect.height()), deviceRect.width(), deviceRect.height()); + glClear(GL_COLOR_BUFFER_BIT); } - doPaintBackground(verts); + + glDisable(GL_SCISSOR_TEST); } }