From 2f986660ff80d06e9faf8cb89803990b66a12bdd Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 10 Jun 2021 23:37:09 +0400 Subject: [PATCH] Optimize background painting in OpenGL renderers. --- Telegram/CMakeLists.txt | 2 + .../calls/calls_video_incoming.cpp | 35 ++++------- .../group/calls_group_viewport_opengl.cpp | 29 ++------- .../calls/group/calls_group_viewport_opengl.h | 10 +-- .../media/view/media_view_overlay_opengl.cpp | 61 ++++++------------- .../media/view/media_view_overlay_opengl.h | 10 +-- .../media/view/media_view_pip_opengl.cpp | 34 ++++------- .../media/view/media_view_pip_opengl.h | 9 +-- Telegram/lib_ui | 2 +- 9 files changed, 57 insertions(+), 135 deletions(-) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 592ac2828f..78cc93362f 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -319,6 +319,8 @@ PRIVATE calls/calls_userpic.h calls/calls_video_bubble.cpp calls/calls_video_bubble.h + calls/calls_video_incoming.cpp + calls/calls_video_incoming.h chat_helpers/bot_keyboard.cpp chat_helpers/bot_keyboard.h chat_helpers/emoji_keywords.cpp diff --git a/Telegram/SourceFiles/calls/calls_video_incoming.cpp b/Telegram/SourceFiles/calls/calls_video_incoming.cpp index b4dc4014ba..4edec9b2c2 100644 --- a/Telegram/SourceFiles/calls/calls_video_incoming.cpp +++ b/Telegram/SourceFiles/calls/calls_video_incoming.cpp @@ -53,12 +53,6 @@ public: not_null widget, QOpenGLFunctions &f) override; - void resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) override; - void paint( not_null widget, QOpenGLFunctions &f) override; @@ -183,24 +177,6 @@ void Panel::Incoming::RendererGL::deinit( _contentBuffer = std::nullopt; } -void Panel::Incoming::RendererGL::resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) { - const auto factor = widget->devicePixelRatio(); - if (_factor != factor) { - _factor = factor; - _controlsShadowImage.invalidate(); - } - _viewport = QSize{ w, h }; - _uniformViewport = QVector2D( - _viewport.width() * _factor, - _viewport.height() * _factor); - const auto size = _viewport * _factor; - f.glViewport(0, 0, size.width(), size.height()); -} - void Panel::Incoming::RendererGL::paint( not_null widget, QOpenGLFunctions &f) { @@ -211,6 +187,17 @@ void Panel::Incoming::RendererGL::paint( if (data.format == Webrtc::FrameFormat::None) { return; } + + const auto factor = widget->devicePixelRatio(); + if (_factor != factor) { + _factor = factor; + _controlsShadowImage.invalidate(); + } + _viewport = widget->size(); + _uniformViewport = QVector2D( + _viewport.width() * _factor, + _viewport.height() * _factor); + const auto rgbaFrame = (data.format == Webrtc::FrameFormat::ARGB32); const auto upload = (_trackFrameIndex != data.index); _trackFrameIndex = data.index; diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp index d334ad790f..743c82d7df 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp @@ -374,8 +374,6 @@ void Viewport::RendererGL::init( })); validateNoiseTexture(f, 0); - - _background.init(f); } void Viewport::RendererGL::ensureARGB32Program() { @@ -403,8 +401,6 @@ void Viewport::RendererGL::ensureARGB32Program() { void Viewport::RendererGL::deinit( not_null widget, QOpenGLFunctions &f) { - _background.deinit(f); - _frameBuffer = std::nullopt; _frameVertexShader = nullptr; _imageProgram = std::nullopt; @@ -423,16 +419,6 @@ void Viewport::RendererGL::deinit( _buttons.destroy(f); } -void Viewport::RendererGL::resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) { - _factor = widget->devicePixelRatio(); - _viewport = QSize(w, h); - setDefaultViewport(f); -} - void Viewport::RendererGL::setDefaultViewport(QOpenGLFunctions &f) { const auto size = _viewport * _factor; f.glViewport(0, 0, size.width(), size.height()); @@ -442,10 +428,11 @@ void Viewport::RendererGL::paint( not_null widget, QOpenGLFunctions &f) { _factor = widget->devicePixelRatio(); + _viewport = widget->size(); + const auto defaultFramebufferObject = widget->defaultFramebufferObject(); validateDatas(); - fillBackground(f); auto index = 0; for (const auto &tile : _owner->_tiles) { if (!tile->shown()) { @@ -460,16 +447,8 @@ void Viewport::RendererGL::paint( } } -void Viewport::RendererGL::fillBackground(QOpenGLFunctions &f) { - const auto radius = st::roundRadiusLarge; - const auto radiuses = QMargins{ radius, radius, radius, radius }; - auto region = QRegion(QRect(QPoint(), _viewport)); - for (const auto &tile : _owner->_tiles) { - if (tile->shown()) { - region -= tile->geometry().marginsRemoved(radiuses); - } - } - _background.fill(f, region, _viewport, _factor, st::groupCallBg); +std::optional Viewport::RendererGL::clearColor() { + return st::groupCallBg->c; } void Viewport::RendererGL::validateUserpicFrame( diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.h b/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.h index 6409a52e24..991c218428 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.h +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.h @@ -36,16 +36,12 @@ public: not_null widget, QOpenGLFunctions &f) override; - void resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) override; - void paint( not_null widget, QOpenGLFunctions &f) override; + std::optional clearColor() override; + private: struct TileData { quintptr id = 0; @@ -72,7 +68,6 @@ private: }; void setDefaultViewport(QOpenGLFunctions &f); - void fillBackground(QOpenGLFunctions &f); void paintTile( QOpenGLFunctions &f, GLuint defaultFramebufferObject, @@ -138,7 +133,6 @@ private: QSize _viewport; bool _rgbaFrame = false; bool _userpicFrame; - Ui::GL::BackgroundFiller _background; std::optional _frameBuffer; Program _downscaleProgram; std::optional _blurProgram; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp index e82eaacedf..a1a4728086 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp @@ -119,14 +119,11 @@ void OverlayWidget::RendererGL::init( FragmentSampleARGB32Texture(), FragmentGlobalOpacity(), })); - - _background.init(f); } void OverlayWidget::RendererGL::deinit( not_null widget, QOpenGLFunctions &f) { - _background.deinit(f); _textures.destroy(f); _imageProgram = std::nullopt; _texturedVertexShader = nullptr; @@ -137,61 +134,43 @@ void OverlayWidget::RendererGL::deinit( _contentBuffer = std::nullopt; } -void OverlayWidget::RendererGL::resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) { - const auto factor = widget->devicePixelRatio(); - if (_factor != factor) { - _factor = factor; - _controlsImage.invalidate(); - } - _viewport = QSize{ w, h }; - _uniformViewport = QVector2D( - _viewport.width() * _factor, - _viewport.height() * _factor); - setDefaultViewport(f); -} - -void OverlayWidget::RendererGL::setDefaultViewport(QOpenGLFunctions &f) { - f.glViewport(0, 0, _uniformViewport.x(), _uniformViewport.y()); -} - void OverlayWidget::RendererGL::paint( not_null widget, QOpenGLFunctions &f) { if (handleHideWorkaround(f)) { return; } + const auto factor = widget->devicePixelRatio(); + if (_factor != factor) { + _factor = factor; + _controlsImage.invalidate(); + } + _viewport = widget->size(); + _uniformViewport = QVector2D( + _viewport.width() * _factor, + _viewport.height() * _factor); _f = &f; _owner->paint(this); _f = nullptr; } -bool OverlayWidget::RendererGL::handleHideWorkaround(QOpenGLFunctions &f) { - if (!Platform::IsWindows() || !_owner->_hideWorkaround) { - return false; +std::optional OverlayWidget::RendererGL::clearColor() { + if (Platform::IsWindows() && _owner->_hideWorkaround) { + return QColor(0, 0, 0, 0); + } else if (_owner->_fullScreenVideo) { + return st::mediaviewVideoBg->c; + } else { + return st::mediaviewBg->c; } +} + +bool OverlayWidget::RendererGL::handleHideWorkaround(QOpenGLFunctions &f) { // This is needed on Windows, // because on reopen it blinks with the last shown content. - f.glClearColor(0., 0., 0., 0.); - f.glClear(GL_COLOR_BUFFER_BIT); - return true; + return Platform::IsWindows() && _owner->_hideWorkaround; } void OverlayWidget::RendererGL::paintBackground() { - const auto &bg = _owner->_fullScreenVideo - ? st::mediaviewVideoBg - : st::mediaviewBg; - auto fill = QRegion(QRect(QPoint(), _viewport)); - toggleBlending(false); - _background.fill( - *_f, - fill, - _viewport, - _factor, - bg); _contentBuffer->bind(); } diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h index c1fbf0e596..c0c5b43e31 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h @@ -27,23 +27,18 @@ public: not_null widget, QOpenGLFunctions &f) override; - void resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) override; - void paint( not_null widget, QOpenGLFunctions &f) override; + std::optional clearColor() override; + private: struct Control { int index = -1; not_null icon; }; bool handleHideWorkaround(QOpenGLFunctions &f); - void setDefaultViewport(QOpenGLFunctions &f); void paintBackground() override; void paintTransformedVideoFrame(ContentGeometry geometry) override; @@ -102,7 +97,6 @@ private: const not_null _owner; QOpenGLFunctions *_f = nullptr; - Ui::GL::BackgroundFiller _background; QSize _viewport; float _factor = 1.; QVector2D _uniformViewport; diff --git a/Telegram/SourceFiles/media/view/media_view_pip_opengl.cpp b/Telegram/SourceFiles/media/view/media_view_pip_opengl.cpp index 60f18a7a88..16379f09f8 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip_opengl.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip_opengl.cpp @@ -235,27 +235,6 @@ void Pip::RendererGL::deinit( _contentBuffer = std::nullopt; } -void Pip::RendererGL::resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h) { - const auto factor = widget->devicePixelRatio(); - if (_factor != factor) { - _factor = factor; - _controlsImage.invalidate(); - } - _viewport = QSize{ w, h }; - _uniformViewport = QVector2D( - _viewport.width() * _factor, - _viewport.height() * _factor); - setDefaultViewport(f); -} - -void Pip::RendererGL::setDefaultViewport(QOpenGLFunctions &f) { - f.glViewport(0, 0, _uniformViewport.x(), _uniformViewport.y()); -} - void Pip::RendererGL::createShadowTexture() { const auto &shadow = st::callShadow; const auto size = 2 * st::callShadow.topLeft.size() @@ -279,11 +258,24 @@ void Pip::RendererGL::createShadowTexture() { void Pip::RendererGL::paint( not_null widget, QOpenGLFunctions &f) { + const auto factor = widget->devicePixelRatio(); + if (_factor != factor) { + _factor = factor; + _controlsImage.invalidate(); + } + _viewport = widget->size(); + _uniformViewport = QVector2D( + _viewport.width() * _factor, + _viewport.height() * _factor); _f = &f; _owner->paint(this); _f = nullptr; } +std::optional Pip::RendererGL::clearColor() { + return QColor(0, 0, 0, 0); +} + void Pip::RendererGL::paintTransformedVideoFrame( ContentGeometry geometry) { const auto data = _owner->videoFrameWithInfo(); diff --git a/Telegram/SourceFiles/media/view/media_view_pip_opengl.h b/Telegram/SourceFiles/media/view/media_view_pip_opengl.h index 4a56bb46c0..d9d06154ab 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip_opengl.h +++ b/Telegram/SourceFiles/media/view/media_view_pip_opengl.h @@ -27,23 +27,18 @@ public: not_null widget, QOpenGLFunctions &f) override; - void resize( - not_null widget, - QOpenGLFunctions &f, - int w, - int h); - void paint( not_null widget, QOpenGLFunctions &f) override; + std::optional clearColor() override; + private: struct Control { int index = -1; not_null icon; not_null iconOver; }; - void setDefaultViewport(QOpenGLFunctions &f); void createShadowTexture(); void paintTransformedVideoFrame(ContentGeometry geometry) override; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 1c004580eb..098eb59f2f 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 1c004580ebb1380d3cb19fadb017f416c85a0eef +Subproject commit 098eb59f2f4635640f8a5f2e53bee2f689f2d0b3