From b22363224fd5b45ed895c5b67064d9eb927a7b89 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 31 May 2021 18:40:41 +0400 Subject: [PATCH] Track tiles visibility separately from geometry. --- .../calls/group/calls_group_viewport.cpp | 17 +++++++++++------ .../group/calls_group_viewport_opengl.cpp | 18 +++++++++++++----- .../group/calls_group_viewport_raster.cpp | 3 +-- .../calls/group/calls_group_viewport_tile.cpp | 6 +++++- .../calls/group/calls_group_viewport_tile.h | 5 +++++ 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp index 0d2395d48..d4b9e53c4 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport.cpp @@ -175,7 +175,9 @@ void Viewport::updateSelected(QPoint position) { return; } for (const auto &tile : _tiles) { - const auto geometry = tile->geometry(); + const auto geometry = tile->shown() + ? tile->geometry() + : QRect(); if (geometry.contains(position)) { const auto pin = wide() && tile->pinOuter().contains(position - geometry.topLeft()); @@ -215,7 +217,9 @@ void Viewport::add( [=] { widget()->update(); })); _tiles.back()->trackSizeValue( - ) | rpl::start_with_next([=] { + ) | rpl::filter([](QSize size) { + return !size.isEmpty(); + }) | rpl::start_with_next([=] { updateTilesGeometry(); }, _tiles.back()->lifetime()); } @@ -427,7 +431,7 @@ void Viewport::updateTilesGeometryNarrow(int outerWidth) { const auto video = tile.get(); const auto size = video->trackSize(); if (size.isEmpty()) { - video->setGeometry({ 0, y, outerWidth, 0 }); + setTileGeometry(video, { 0, y, outerWidth, 0 }); } else { sizes.emplace(video, size); } @@ -444,7 +448,7 @@ void Viewport::updateTilesGeometryNarrow(int outerWidth) { Qt::KeepAspectRatio); const auto height = std::max(scaled.height(), heightMin); const auto skip = st::groupCallVideoSmallSkip; - sizes.front().first->setGeometry({ 0, y, outerWidth, height }); + setTileGeometry(sizes.front().first, { 0, y, outerWidth, height }); _fullHeight = height + skip; return; } @@ -455,7 +459,7 @@ void Viewport::updateTilesGeometryNarrow(int outerWidth) { const auto square = (outerWidth - st::groupCallVideoSmallSkip) / 2; const auto skip = (outerWidth - 2 * square); const auto put = [&](not_null tile, int column, int row) { - tile->setGeometry({ + setTileGeometry(tile, { (column == 2) ? 0 : column ? (outerWidth - square) : 0, y + row * (min + skip), (column == 2) ? outerWidth : square, @@ -492,7 +496,7 @@ void Viewport::updateTilesGeometryColumn(int outerWidth) { const auto height = shown ? st::groupCallNarrowVideoHeight : 0; - tile->setGeometry({ 0, y + top, outerWidth, height }); + setTileGeometry(tile, { 0, y + top, outerWidth, height }); top += height ? (height + st::groupCallVideoSmallSkip) : 0; }; const auto topPeer = _large ? _large->row()->peer().get() : nullptr; @@ -532,6 +536,7 @@ void Viewport::updateTilesGeometryColumn(int outerWidth) { void Viewport::setTileGeometry(not_null tile, QRect geometry) { tile->setGeometry(geometry); + tile->setShown(!geometry.isEmpty()); const auto min = std::min(geometry.width(), geometry.height()); const auto kMedium = style::ConvertScale(480); diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp index 495833a08..15008e8b0 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_opengl.cpp @@ -383,6 +383,9 @@ void Viewport::RendererGL::paint( const auto defaultFramebufferObject = widget->defaultFramebufferObject(); auto index = 0; for (const auto &tile : _owner->_tiles) { + if (!tile->shown()) { + continue; + } paintTile( f, defaultFramebufferObject, @@ -396,7 +399,9 @@ void Viewport::RendererGL::fillBackground(QOpenGLFunctions &f) { const auto radiuses = QMargins{ radius, radius, radius, radius }; auto bg = QRegion(QRect(QPoint(), _viewport)); for (const auto &tile : _owner->_tiles) { - bg -= tile->geometry().marginsRemoved(radiuses); + if (tile->shown()) { + bg -= tile->geometry().marginsRemoved(radiuses); + } } if (bg.isEmpty()) { return; @@ -427,12 +432,9 @@ void Viewport::RendererGL::paintTile( return; } Assert(!data.yuv420->size.isEmpty()); - const auto geometry = tile->geometry(); - if (geometry.isEmpty()) { - return; - } _rgbaFrame = (data.format == Webrtc::FrameFormat::ARGB32); + const auto geometry = tile->geometry(); const auto x = geometry.x(); const auto y = geometry.y(); const auto width = geometry.width(); @@ -1019,9 +1021,15 @@ void Viewport::RendererGL::validateDatas() { - st.iconPosition.x() - st::groupCallVideoCrossLine.icon.width() - st.namePosition.x(); + if (hasWidth < 1) { + return 0; + } return std::clamp(row->name().maxWidth(), 1, hasWidth) * factor; }; for (auto i = 0; i != count; ++i) { + if (!tiles[i]->shown()) { + continue; + } tiles[i]->row()->lazyInitialize(st::groupCallMembersListItem); const auto width = nameWidth(i); if (width <= 0) { diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp index 92b318019..05e2f82c0 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_raster.cpp @@ -54,7 +54,7 @@ void Viewport::Renderer::paintTile( const auto data = track->frameWithInfo(true); const auto &image = data.original; const auto rotation = data.rotation; - if (image.isNull()) { + if (image.isNull() || !tile->shown()) { return; } @@ -150,7 +150,6 @@ void Viewport::Renderer::paintTileControls( const auto wide = _owner->wide(); if (wide) { // Pin. - const auto pinInner = tile->pinInner(); VideoTile::PaintPinButton( p, diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.cpp b/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.cpp index 049194ea1..9b7a3cc2e 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.cpp @@ -63,6 +63,10 @@ void Viewport::VideoTile::setGeometry(QRect geometry) { updateTopControlsGeometry(); } +void Viewport::VideoTile::setShown(bool shown) { + _shown = shown; +} + void Viewport::VideoTile::toggleTopControlsShown(bool shown) { if (_topControlsShown == shown) { return; @@ -76,7 +80,7 @@ void Viewport::VideoTile::toggleTopControlsShown(bool shown) { } bool Viewport::VideoTile::updateRequestedQuality(VideoQuality quality) { - if (_geometry.isEmpty()) { + if (!_shown) { _quality = std::nullopt; return false; } else if (_quality && *_quality == quality) { diff --git a/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.h b/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.h index 6695eff05..68501c65c 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.h +++ b/Telegram/SourceFiles/calls/group/calls_group_viewport_tile.h @@ -41,6 +41,9 @@ public: [[nodiscard]] bool pinned() const { return _pinned; } + [[nodiscard]] bool shown() const { + return _shown && !_geometry.isEmpty(); + } [[nodiscard]] QRect pinOuter() const; [[nodiscard]] QRect pinInner() const; [[nodiscard]] QRect backOuter() const; @@ -57,6 +60,7 @@ public: [[nodiscard]] bool screencast() const; void setGeometry(QRect geometry); + void setShown(bool shown); void toggleTopControlsShown(bool shown); bool updateRequestedQuality(VideoQuality quality); @@ -100,6 +104,7 @@ private: Ui::Animations::Simple _topControlsShownAnimation; bool _topControlsShown = false; bool _pinned = false; + bool _shown = false; std::optional _quality; rpl::lifetime _lifetime;