From c48c4d428373373b4712f8fbbea93b959ad07d22 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 18 May 2021 14:20:29 +0400 Subject: [PATCH] Use QOpenGLWidget on all systems. --- Telegram/SourceFiles/calls/calls_panel.cpp | 10 +++--- .../calls/group/calls_group_large_video.cpp | 2 +- .../calls/group/calls_group_large_video.h | 8 +++-- .../media/view/media_view_overlay_widget.cpp | 35 ++++++++++++------- .../media/view/media_view_overlay_widget.h | 8 +++-- .../SourceFiles/media/view/media_view_pip.cpp | 29 +++++++++------ .../SourceFiles/media/view/media_view_pip.h | 19 +++++----- 7 files changed, 69 insertions(+), 42 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp index b3812ca2a..1d476a789 100644 --- a/Telegram/SourceFiles/calls/calls_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_panel.cpp @@ -52,11 +52,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Calls { namespace { -#if defined Q_OS_MAC && !defined OS_MAC_OLD -#define USE_OPENGL_OVERLAY_WIDGET +#if 1 +#define USE_OPENGL_OVERLAY_WIDGET 1 +#else // Q_OS_MAC && !OS_MAC_OLD +#define USE_OPENGL_OVERLAY_WIDGET 0 #endif // Q_OS_MAC && !OS_MAC_OLD -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_OVERLAY_WIDGET using IncomingParent = Ui::RpWidgetWrap; #else // USE_OPENGL_OVERLAY_WIDGET using IncomingParent = Ui::RpWidget; @@ -101,7 +103,7 @@ void Panel::Incoming::paintEvent(QPaintEvent *e) { } else { using namespace Media::View; auto hq = PainterHighQualityEnabler(p); - if (UsePainterRotation(rotation)) { + if (UsePainterRotation(rotation, USE_OPENGL_OVERLAY_WIDGET)) { if (rotation) { p.save(); p.rotate(rotation); diff --git a/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp b/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp index d59ba9947..687ee7d43 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp @@ -200,7 +200,7 @@ void LargeVideo::paint(QRect clip) { const auto left = (size.width() - scaled.width()) / 2; const auto top = (size.height() - scaled.height()) / 2; const auto target = QRect(QPoint(left, top), scaled); - if (UsePainterRotation(rotation)) { + if (UsePainterRotation(rotation, USE_OPENGL_LARGE_VIDEO)) { if (rotation) { p.save(); p.rotate(rotation); diff --git a/Telegram/SourceFiles/calls/group/calls_group_large_video.h b/Telegram/SourceFiles/calls/group/calls_group_large_video.h index ecdb08c9d..0f7d7a069 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_large_video.h +++ b/Telegram/SourceFiles/calls/group/calls_group_large_video.h @@ -11,8 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/cross_line.h" #include "ui/effects/animations.h" -#if defined Q_OS_MAC -#define USE_OPENGL_LARGE_VIDEO +#if 1 +#define USE_OPENGL_LARGE_VIDEO 1 +#else +#define USE_OPENGL_LARGE_VIDEO 0 #endif // Q_OS_MAC namespace style { @@ -81,7 +83,7 @@ public: } private: -#ifdef USE_OPENGL_LARGE_VIDEO +#if USE_OPENGL_LARGE_VIDEO using ContentParent = Ui::RpWidgetWrap; #else // USE_OPENGL_OVERLAY_WIDGET using ContentParent = Ui::RpWidget; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 21f04f85d..ec783ec5c 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -466,19 +466,28 @@ void OverlayWidget::updateGeometry() { if (Platform::IsWayland()) { return; } - const auto screen = windowHandle() && windowHandle()->screen() - ? windowHandle()->screen() + const auto window = windowHandle(); + const auto screen = window && window->screen() + ? window->screen() : QApplication::primaryScreen(); const auto available = screen->geometry(); - if (geometry() == available) { + const auto useSizeHack = (USE_OPENGL_OVERLAY_WIDGET + && Platform::IsWindows()); + const auto use = available.marginsAdded({ 0, 0, 0, 1 }); + const auto mask = useSizeHack ? QRegion(available) : QRegion(); + if ((geometry() == use) + && (!useSizeHack || (window && window->mask() == mask))) { return; } DEBUG_LOG(("Viewer Pos: Setting %1, %2, %3, %4") - .arg(available.x()) - .arg(available.y()) - .arg(available.width()) - .arg(available.height())); - setGeometry(available); + .arg(use.x()) + .arg(use.y()) + .arg(use.width()) + .arg(use.height())); + setGeometry(use); + if (window && useSizeHack) { + window->setMask(mask); + } } void OverlayWidget::moveEvent(QMoveEvent *e) { @@ -552,7 +561,7 @@ QImage OverlayWidget::videoFrameForDirectPaint() const { const auto result = videoFrame(); -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_OVERLAY_WIDGET const auto bytesPerLine = result.bytesPerLine(); if (bytesPerLine == result.width() * 4) { return result; @@ -3385,7 +3394,7 @@ void OverlayWidget::paintTransformedVideoFrame(Painter &p) { PainterHighQualityEnabler hq(p); const auto rotation = contentRotation(); - if (UsePainterRotation(rotation)) { + if (UsePainterRotation(rotation, USE_OPENGL_OVERLAY_WIDGET)) { if (rotation) { p.save(); p.rotate(rotation); @@ -3415,7 +3424,7 @@ void OverlayWidget::paintTransformedStaticContent(Painter &p) { return; } const auto rotation = contentRotation(); - if (UsePainterRotation(rotation)) { + if (UsePainterRotation(rotation, USE_OPENGL_OVERLAY_WIDGET)) { if (rotation) { p.save(); p.rotate(rotation); @@ -3444,7 +3453,7 @@ void OverlayWidget::paintRadialLoading( const auto inner = radialRect(); Assert(!inner.isEmpty()); -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_OVERLAY_WIDGET { if (_radialCache.size() != inner.size() * cIntRetinaFactor()) { _radialCache = QImage( @@ -4349,7 +4358,7 @@ bool OverlayWidget::eventFilter(QObject *obj, QEvent *e) { } void OverlayWidget::applyHideWindowWorkaround() { -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_OVERLAY_WIDGET // QOpenGLWidget can't properly destroy a child widget if // it is hidden exactly after that, so it must be repainted // before it is hidden without the child widget. diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index dc9234e0a..7483549a0 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -52,15 +52,17 @@ namespace View { class GroupThumbs; class Pip; -#if defined Q_OS_MAC && !defined OS_MAC_OLD -#define USE_OPENGL_OVERLAY_WIDGET +#if 1 +#define USE_OPENGL_OVERLAY_WIDGET 1 +#else // Q_OS_MAC && !OS_MAC_OLD +#define USE_OPENGL_OVERLAY_WIDGET 0 #endif // Q_OS_MAC && !OS_MAC_OLD struct OverlayParentTraits : Ui::RpWidgetDefaultTraits { static constexpr bool kSetZeroGeometry = false; }; -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_OVERLAY_WIDGET using OverlayParent = Ui::RpWidgetWrap; #else // USE_OPENGL_OVERLAY_WIDGET using OverlayParent = Ui::RpWidgetWrap; diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp index f224f8045..0628c19c0 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp @@ -354,8 +354,8 @@ QRect RotatedRect(QRect rect, int rotation) { Unexpected("Rotation in RotatedRect."); } -bool UsePainterRotation(int rotation) { - return Platform::IsMac() || !(rotation % 180); +bool UsePainterRotation(int rotation, bool opengl) { + return opengl || !(rotation % 180); } QSize FlipSizeByRotation(QSize size, int rotation) { @@ -375,6 +375,9 @@ PipPanel::PipPanel( Fn paint) : _parent(parent) , _paint(std::move(paint)) { +} + +void PipPanel::init() { setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint @@ -592,8 +595,12 @@ void PipPanel::setPositionOnScreen(Position position, QRect available) { void PipPanel::paintEvent(QPaintEvent *e) { QPainter p(this); - if (_useTransparency) { - Ui::Platform::StartTranslucentPaint(p, e->region()); + if (_useTransparency && USE_OPENGL_PIP_WIDGET) { + p.setCompositionMode(QPainter::CompositionMode_Source); + for (const auto rect : e->region()) { + p.fillRect(rect, Qt::transparent); + } + p.setCompositionMode(QPainter::CompositionMode_SourceOver); } auto request = FrameRequest(); @@ -898,6 +905,7 @@ Pip::Pip( Pip::~Pip() = default; void Pip::setupPanel() { + _panel.init(); const auto size = [&] { if (!_instance.info().video.size.isEmpty()) { return _instance.info().video.size; @@ -1196,11 +1204,12 @@ void Pip::paint(QPainter &p, FrameRequest request) { inner.topLeft(), request.outer / style::DevicePixelRatio() }; - if (UsePainterRotation(_rotation)) { + if (UsePainterRotation(_rotation, USE_OPENGL_PIP_WIDGET)) { if (_rotation) { p.save(); p.rotate(_rotation); } + auto hq = PainterHighQualityEnabler(p); p.drawImage(RotatedRect(rect, _rotation), image); if (_rotation) { p.restore(); @@ -1516,7 +1525,7 @@ QImage Pip::videoFrame(const FrameRequest &request) const { QImage Pip::videoFrameForDirectPaint(const FrameRequest &request) const { const auto result = videoFrame(request); -#ifdef USE_OPENGL_OVERLAY_WIDGET +#ifdef USE_OPENGL_PIP_WIDGET const auto bytesPerLine = result.bytesPerLine(); if (bytesPerLine == result.width() * 4) { return result; @@ -1545,14 +1554,14 @@ QImage Pip::videoFrameForDirectPaint(const FrameRequest &request) const { from += bytesPerLine; } return cache; -#endif // USE_OPENGL_OVERLAY_WIDGET +#endif // USE_OPENGL_PIP_WIDGET return result; } void Pip::paintRadialLoading(QPainter &p) const { const auto inner = countRadialRect(); -#ifdef USE_OPENGL_OVERLAY_WIDGET +#ifdef USE_OPENGL_PIP_WIDGET { if (_radialCache.size() != inner.size() * cIntRetinaFactor()) { _radialCache = QImage( @@ -1566,9 +1575,9 @@ void Pip::paintRadialLoading(QPainter &p) const { paintRadialLoadingContent(q, inner.translated(-inner.topLeft())); } p.drawImage(inner.topLeft(), _radialCache); -#else // USE_OPENGL_OVERLAY_WIDGET +#else // USE_OPENGL_PIP_WIDGET paintRadialLoadingContent(p, inner); -#endif // USE_OPENGL_OVERLAY_WIDGET +#endif // USE_OPENGL_PIP_WIDGET } void Pip::paintRadialLoadingContent(QPainter &p, const QRect &inner) const { diff --git a/Telegram/SourceFiles/media/view/media_view_pip.h b/Telegram/SourceFiles/media/view/media_view_pip.h index a4a5f80e5..f421ad583 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.h +++ b/Telegram/SourceFiles/media/view/media_view_pip.h @@ -34,19 +34,21 @@ namespace View { class PlaybackProgress; [[nodiscard]] QRect RotatedRect(QRect rect, int rotation); -[[nodiscard]] bool UsePainterRotation(int rotation); +[[nodiscard]] bool UsePainterRotation(int rotation, bool opengl); [[nodiscard]] QSize FlipSizeByRotation(QSize size, int rotation); [[nodiscard]] QImage RotateFrameImage(QImage image, int rotation); -#if defined Q_OS_MAC && !defined OS_MAC_OLD -#define USE_OPENGL_OVERLAY_WIDGET +#if 1 +#define USE_OPENGL_PIP_WIDGET 1 +#else +#define USE_OPENGL_PIP_WIDGET 0 #endif // Q_OS_MAC && !OS_MAC_OLD -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_PIP_WIDGET using PipParent = Ui::RpWidgetWrap; -#else // USE_OPENGL_OVERLAY_WIDGET +#else // USE_OPENGL_PIP_WIDGET using PipParent = Ui::RpWidget; -#endif // USE_OPENGL_OVERLAY_WIDGET +#endif // USE_OPENGL_PIP_WIDGET class PipPanel final : public PipParent { public: @@ -61,6 +63,7 @@ public: PipPanel( QWidget *parent, Fn paint); + void init(); void setAspectRatio(QSize ratio); [[nodiscard]] Position countPosition() const; @@ -234,10 +237,10 @@ private: FnMut _closeAndContinue; FnMut _destroy; -#ifdef USE_OPENGL_OVERLAY_WIDGET +#if USE_OPENGL_PIP_WIDGET mutable QImage _frameForDirectPaint; mutable QImage _radialCache; -#endif // USE_OPENGL_OVERLAY_WIDGET +#endif // USE_OPENGL_PIP_WIDGET mutable QImage _preparedCoverStorage; mutable FrameRequest _preparedCoverRequest;