From 8071ade9a83b4c320f4d22bf2f727e20ffdf8324 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 17 Dec 2022 21:04:46 +0200 Subject: [PATCH] scene: Make ItemRenderer responsible for pushing fbo It makes more sense for an output layer to return the render target fbo. The user of the render target will then take appropriate steps to bind the fbo. It reduces the amount of boilerplate code in output layers too. --- src/backends/drm/drm_egl_layer_surface.cpp | 6 ++---- src/backends/drm/drm_output.cpp | 5 +++++ src/backends/drm/drm_virtual_egl_layer.cpp | 2 -- src/backends/virtual/virtual_egl_backend.cpp | 2 -- src/backends/wayland/wayland_egl_backend.cpp | 5 ----- src/backends/wayland/wayland_output.cpp | 5 +++++ src/backends/x11/standalone/x11_standalone_egl_backend.cpp | 5 ----- src/backends/x11/standalone/x11_standalone_glx_backend.cpp | 3 --- src/backends/x11/windowed/x11_windowed_egl_backend.cpp | 5 ----- src/backends/x11/windowed/x11_windowed_output.cpp | 5 +++++ src/scene/itemrenderer_opengl.cpp | 4 ++++ 11 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/backends/drm/drm_egl_layer_surface.cpp b/src/backends/drm/drm_egl_layer_surface.cpp index 85560432ec..e6d4d9ae31 100644 --- a/src/backends/drm/drm_egl_layer_surface.cpp +++ b/src/backends/drm/drm_egl_layer_surface.cpp @@ -96,9 +96,7 @@ std::optional EglGbmLayerSurface::startRendering(cons } } - GLFramebuffer::pushFramebuffer(m_surface.gbmSurface->fbo()); if (m_shadowBuffer) { - GLFramebuffer::pushFramebuffer(m_shadowBuffer->fbo()); // the blit after rendering will completely overwrite the back buffer anyways return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_shadowBuffer->fbo()), @@ -130,11 +128,11 @@ void EglGbmLayerSurface::aboutToStartPainting(DrmOutput *output, const QRegion & bool EglGbmLayerSurface::endRendering(DrmPlane::Transformations renderOrientation, const QRegion &damagedRegion) { if (m_shadowBuffer) { - GLFramebuffer::popFramebuffer(); + GLFramebuffer::pushFramebuffer(m_surface.gbmSurface->fbo()); // TODO handle bufferOrientation != Rotate0 m_shadowBuffer->render(renderOrientation); + GLFramebuffer::popFramebuffer(); } - GLFramebuffer::popFramebuffer(); const auto gbmBuffer = m_surface.gbmSurface->swapBuffers(damagedRegion); if (!gbmBuffer) { return false; diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 8dc0139c92..7ceb84c282 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -500,6 +500,9 @@ void DrmOutput::renderCursorOpengl(const RenderTarget &renderTarget, const QSize QMatrix4x4 mvp; mvp.ortho(QRect(QPoint(), renderTarget.size())); + GLFramebuffer *fbo = std::get(renderTarget.nativeHandle()); + GLFramebuffer::pushFramebuffer(fbo); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); @@ -512,6 +515,8 @@ void DrmOutput::renderCursorOpengl(const RenderTarget &renderTarget, const QSize m_cursor.texture->render(QRect(0, 0, cursorSize.width(), cursorSize.height()), renderTarget.devicePixelRatio()); m_cursor.texture->unbind(); glDisable(GL_BLEND); + + GLFramebuffer::popFramebuffer(); } void DrmOutput::renderCursorQPainter(const RenderTarget &renderTarget) diff --git a/src/backends/drm/drm_virtual_egl_layer.cpp b/src/backends/drm/drm_virtual_egl_layer.cpp index fab7b8bfc6..749c83be5f 100644 --- a/src/backends/drm/drm_virtual_egl_layer.cpp +++ b/src/backends/drm/drm_virtual_egl_layer.cpp @@ -69,7 +69,6 @@ std::optional VirtualEglGbmLayer::beginFrame() if (!m_gbmSurface->makeContextCurrent()) { return std::nullopt; } - GLFramebuffer::pushFramebuffer(m_gbmSurface->fbo()); return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_gbmSurface->fbo()), .repaint = m_gbmSurface->repaintRegion(), @@ -78,7 +77,6 @@ std::optional VirtualEglGbmLayer::beginFrame() bool VirtualEglGbmLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) { - GLFramebuffer::popFramebuffer(); const auto buffer = m_gbmSurface->swapBuffers(damagedRegion); if (buffer) { m_currentBuffer = buffer; diff --git a/src/backends/virtual/virtual_egl_backend.cpp b/src/backends/virtual/virtual_egl_backend.cpp index 24ba6707bc..2bc8f244ff 100644 --- a/src/backends/virtual/virtual_egl_backend.cpp +++ b/src/backends/virtual/virtual_egl_backend.cpp @@ -48,7 +48,6 @@ std::optional VirtualEglLayer::beginFrame() m_fbo = std::make_unique(m_texture.get()); } - GLFramebuffer::pushFramebuffer(m_fbo.get()); return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_fbo.get()), .repaint = infiniteRegion(), @@ -57,7 +56,6 @@ std::optional VirtualEglLayer::beginFrame() bool VirtualEglLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) { - GLFramebuffer::popFramebuffer(); return true; } diff --git a/src/backends/wayland/wayland_egl_backend.cpp b/src/backends/wayland/wayland_egl_backend.cpp index 6f3be7bc6b..b193aa9e0a 100644 --- a/src/backends/wayland/wayland_egl_backend.cpp +++ b/src/backends/wayland/wayland_egl_backend.cpp @@ -197,7 +197,6 @@ std::optional WaylandEglPrimaryLayer::beginFrame() repair = m_damageJournal.accumulate(m_buffer->age(), infiniteRegion()); } - GLFramebuffer::pushFramebuffer(m_buffer->framebuffer()); return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_buffer->framebuffer()), .repaint = repair, @@ -207,7 +206,6 @@ std::optional WaylandEglPrimaryLayer::beginFrame() bool WaylandEglPrimaryLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) { m_damageJournal.add(damagedRegion); - GLFramebuffer::popFramebuffer(); return true; } @@ -279,7 +277,6 @@ std::optional WaylandEglCursorLayer::beginFrame() m_framebuffer = std::make_unique(m_texture.get()); } - GLFramebuffer::pushFramebuffer(m_framebuffer.get()); return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_framebuffer.get()), .repaint = infiniteRegion(), @@ -288,8 +285,6 @@ std::optional WaylandEglCursorLayer::beginFrame() bool WaylandEglCursorLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) { - GLFramebuffer::popFramebuffer(); - // Technically, we could pass a linux-dmabuf buffer, but host kwin does not support that atm. const QImage image = m_texture->toImage().mirrored(false, true); KWayland::Client::Buffer::Ptr buffer = m_output->backend()->display()->shmPool()->createBuffer(image); diff --git a/src/backends/wayland/wayland_output.cpp b/src/backends/wayland/wayland_output.cpp index 57f06ea201..9025f3a50c 100644 --- a/src/backends/wayland/wayland_output.cpp +++ b/src/backends/wayland/wayland_output.cpp @@ -215,6 +215,9 @@ void WaylandOutput::renderCursorOpengl(WaylandEglBackend *backend, const QImage QMatrix4x4 mvp; mvp.ortho(QRect(QPoint(), beginInfo->renderTarget.size())); + GLFramebuffer *fbo = std::get(beginInfo->renderTarget.nativeHandle()); + GLFramebuffer::pushFramebuffer(fbo); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); @@ -231,6 +234,8 @@ void WaylandOutput::renderCursorOpengl(WaylandEglBackend *backend, const QImage glDisable(GL_BLEND); } + GLFramebuffer::popFramebuffer(); + cursorLayer->endFrame(infiniteRegion(), infiniteRegion()); } diff --git a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp index 122559af5c..ae3476778f 100644 --- a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp @@ -165,8 +165,6 @@ OutputLayerBeginFrameInfo EglBackend::beginFrame() eglWaitNative(EGL_CORE_NATIVE_ENGINE); - // Push the default framebuffer to the render target stack. - GLFramebuffer::pushFramebuffer(m_fbo.get()); return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_fbo.get()), .repaint = repaint, @@ -199,9 +197,6 @@ void EglBackend::present(Output *output) } } - // Pop the default render target from the render target stack. - GLFramebuffer::popFramebuffer(); - presentSurface(surface(), effectiveRenderedRegion, workspace()->geometry()); if (overlayWindow() && overlayWindow()->window()) { // show the window only after the first pass, diff --git a/src/backends/x11/standalone/x11_standalone_glx_backend.cpp b/src/backends/x11/standalone/x11_standalone_glx_backend.cpp index 18f7d41860..358700f900 100644 --- a/src/backends/x11/standalone/x11_standalone_glx_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_glx_backend.cpp @@ -783,7 +783,6 @@ OutputLayerBeginFrameInfo GlxBackend::beginFrame() QRegion repaint; makeCurrent(); - GLFramebuffer::pushFramebuffer(m_fbo.get()); if (supportsBufferAge()) { repaint = m_damageJournal.accumulate(m_bufferAge, infiniteRegion()); } @@ -823,8 +822,6 @@ void GlxBackend::present(Output *output) effectiveRenderedRegion = displayRect; } - GLFramebuffer::popFramebuffer(); - present(effectiveRenderedRegion); if (overlayWindow()->window()) { // show the window only after the first pass, diff --git a/src/backends/x11/windowed/x11_windowed_egl_backend.cpp b/src/backends/x11/windowed/x11_windowed_egl_backend.cpp index 106408cebf..de17496658 100644 --- a/src/backends/x11/windowed/x11_windowed_egl_backend.cpp +++ b/src/backends/x11/windowed/x11_windowed_egl_backend.cpp @@ -41,7 +41,6 @@ std::optional X11WindowedEglPrimaryLayer::beginFrame( { eglMakeCurrent(m_backend->eglDisplay(), m_eglSurface, m_eglSurface, m_backend->context()); ensureFbo(); - GLFramebuffer::pushFramebuffer(m_fbo.get()); QRegion repaint = m_output->exposedArea() + m_output->rect(); m_output->clearExposedArea(); @@ -55,7 +54,6 @@ std::optional X11WindowedEglPrimaryLayer::beginFrame( bool X11WindowedEglPrimaryLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) { m_lastDamage = damagedRegion; - GLFramebuffer::popFramebuffer(); return true; } @@ -112,7 +110,6 @@ std::optional X11WindowedEglCursorLayer::beginFrame() m_framebuffer = std::make_unique(m_texture.get()); } - GLFramebuffer::pushFramebuffer(m_framebuffer.get()); return OutputLayerBeginFrameInfo{ .renderTarget = RenderTarget(m_framebuffer.get()), .repaint = infiniteRegion(), @@ -121,8 +118,6 @@ std::optional X11WindowedEglCursorLayer::beginFrame() bool X11WindowedEglCursorLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) { - GLFramebuffer::popFramebuffer(); - const QImage buffer = m_texture->toImage().mirrored(false, true); m_output->cursor()->update(buffer, m_hotspot); diff --git a/src/backends/x11/windowed/x11_windowed_output.cpp b/src/backends/x11/windowed/x11_windowed_output.cpp index 5d19677a0d..acddbeb243 100644 --- a/src/backends/x11/windowed/x11_windowed_output.cpp +++ b/src/backends/x11/windowed/x11_windowed_output.cpp @@ -315,6 +315,9 @@ void X11WindowedOutput::renderCursorOpengl(X11WindowedEglBackend *backend, const QMatrix4x4 mvp; mvp.ortho(QRect(QPoint(), beginInfo->renderTarget.size())); + GLFramebuffer *fbo = std::get(beginInfo->renderTarget.nativeHandle()); + GLFramebuffer::pushFramebuffer(fbo); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); @@ -331,6 +334,8 @@ void X11WindowedOutput::renderCursorOpengl(X11WindowedEglBackend *backend, const glDisable(GL_BLEND); } + GLFramebuffer::popFramebuffer(); + cursorLayer->endFrame(infiniteRegion(), infiniteRegion()); } diff --git a/src/scene/itemrenderer_opengl.cpp b/src/scene/itemrenderer_opengl.cpp index 3216996414..0ccda15766 100644 --- a/src/scene/itemrenderer_opengl.cpp +++ b/src/scene/itemrenderer_opengl.cpp @@ -20,12 +20,16 @@ ItemRendererOpenGL::ItemRendererOpenGL() void ItemRendererOpenGL::beginFrame(RenderTarget *renderTarget) { + GLFramebuffer *fbo = std::get(renderTarget->nativeHandle()); + GLFramebuffer::pushFramebuffer(fbo); + GLVertexBuffer::streamingBuffer()->beginFrame(); } void ItemRendererOpenGL::endFrame() { GLVertexBuffer::streamingBuffer()->endOfFrame(); + GLFramebuffer::popFramebuffer(); } QVector4D ItemRendererOpenGL::modulate(float opacity, float brightness) const