Use QOpenGLWidget on all systems.

This commit is contained in:
John Preston 2021-05-18 14:20:29 +04:00
parent b421d0c5cc
commit c48c4d4283
7 changed files with 69 additions and 42 deletions

View File

@ -52,11 +52,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Calls { namespace Calls {
namespace { namespace {
#if defined Q_OS_MAC && !defined OS_MAC_OLD #if 1
#define USE_OPENGL_OVERLAY_WIDGET #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 #endif // Q_OS_MAC && !OS_MAC_OLD
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_OVERLAY_WIDGET
using IncomingParent = Ui::RpWidgetWrap<QOpenGLWidget>; using IncomingParent = Ui::RpWidgetWrap<QOpenGLWidget>;
#else // USE_OPENGL_OVERLAY_WIDGET #else // USE_OPENGL_OVERLAY_WIDGET
using IncomingParent = Ui::RpWidget; using IncomingParent = Ui::RpWidget;
@ -101,7 +103,7 @@ void Panel::Incoming::paintEvent(QPaintEvent *e) {
} else { } else {
using namespace Media::View; using namespace Media::View;
auto hq = PainterHighQualityEnabler(p); auto hq = PainterHighQualityEnabler(p);
if (UsePainterRotation(rotation)) { if (UsePainterRotation(rotation, USE_OPENGL_OVERLAY_WIDGET)) {
if (rotation) { if (rotation) {
p.save(); p.save();
p.rotate(rotation); p.rotate(rotation);

View File

@ -200,7 +200,7 @@ void LargeVideo::paint(QRect clip) {
const auto left = (size.width() - scaled.width()) / 2; const auto left = (size.width() - scaled.width()) / 2;
const auto top = (size.height() - scaled.height()) / 2; const auto top = (size.height() - scaled.height()) / 2;
const auto target = QRect(QPoint(left, top), scaled); const auto target = QRect(QPoint(left, top), scaled);
if (UsePainterRotation(rotation)) { if (UsePainterRotation(rotation, USE_OPENGL_LARGE_VIDEO)) {
if (rotation) { if (rotation) {
p.save(); p.save();
p.rotate(rotation); p.rotate(rotation);

View File

@ -11,8 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/cross_line.h" #include "ui/effects/cross_line.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#if defined Q_OS_MAC #if 1
#define USE_OPENGL_LARGE_VIDEO #define USE_OPENGL_LARGE_VIDEO 1
#else
#define USE_OPENGL_LARGE_VIDEO 0
#endif // Q_OS_MAC #endif // Q_OS_MAC
namespace style { namespace style {
@ -81,7 +83,7 @@ public:
} }
private: private:
#ifdef USE_OPENGL_LARGE_VIDEO #if USE_OPENGL_LARGE_VIDEO
using ContentParent = Ui::RpWidgetWrap<QOpenGLWidget>; using ContentParent = Ui::RpWidgetWrap<QOpenGLWidget>;
#else // USE_OPENGL_OVERLAY_WIDGET #else // USE_OPENGL_OVERLAY_WIDGET
using ContentParent = Ui::RpWidget; using ContentParent = Ui::RpWidget;

View File

@ -466,19 +466,28 @@ void OverlayWidget::updateGeometry() {
if (Platform::IsWayland()) { if (Platform::IsWayland()) {
return; return;
} }
const auto screen = windowHandle() && windowHandle()->screen() const auto window = windowHandle();
? windowHandle()->screen() const auto screen = window && window->screen()
? window->screen()
: QApplication::primaryScreen(); : QApplication::primaryScreen();
const auto available = screen->geometry(); 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; return;
} }
DEBUG_LOG(("Viewer Pos: Setting %1, %2, %3, %4") DEBUG_LOG(("Viewer Pos: Setting %1, %2, %3, %4")
.arg(available.x()) .arg(use.x())
.arg(available.y()) .arg(use.y())
.arg(available.width()) .arg(use.width())
.arg(available.height())); .arg(use.height()));
setGeometry(available); setGeometry(use);
if (window && useSizeHack) {
window->setMask(mask);
}
} }
void OverlayWidget::moveEvent(QMoveEvent *e) { void OverlayWidget::moveEvent(QMoveEvent *e) {
@ -552,7 +561,7 @@ QImage OverlayWidget::videoFrameForDirectPaint() const {
const auto result = videoFrame(); const auto result = videoFrame();
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_OVERLAY_WIDGET
const auto bytesPerLine = result.bytesPerLine(); const auto bytesPerLine = result.bytesPerLine();
if (bytesPerLine == result.width() * 4) { if (bytesPerLine == result.width() * 4) {
return result; return result;
@ -3385,7 +3394,7 @@ void OverlayWidget::paintTransformedVideoFrame(Painter &p) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
const auto rotation = contentRotation(); const auto rotation = contentRotation();
if (UsePainterRotation(rotation)) { if (UsePainterRotation(rotation, USE_OPENGL_OVERLAY_WIDGET)) {
if (rotation) { if (rotation) {
p.save(); p.save();
p.rotate(rotation); p.rotate(rotation);
@ -3415,7 +3424,7 @@ void OverlayWidget::paintTransformedStaticContent(Painter &p) {
return; return;
} }
const auto rotation = contentRotation(); const auto rotation = contentRotation();
if (UsePainterRotation(rotation)) { if (UsePainterRotation(rotation, USE_OPENGL_OVERLAY_WIDGET)) {
if (rotation) { if (rotation) {
p.save(); p.save();
p.rotate(rotation); p.rotate(rotation);
@ -3444,7 +3453,7 @@ void OverlayWidget::paintRadialLoading(
const auto inner = radialRect(); const auto inner = radialRect();
Assert(!inner.isEmpty()); Assert(!inner.isEmpty());
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_OVERLAY_WIDGET
{ {
if (_radialCache.size() != inner.size() * cIntRetinaFactor()) { if (_radialCache.size() != inner.size() * cIntRetinaFactor()) {
_radialCache = QImage( _radialCache = QImage(
@ -4349,7 +4358,7 @@ bool OverlayWidget::eventFilter(QObject *obj, QEvent *e) {
} }
void OverlayWidget::applyHideWindowWorkaround() { void OverlayWidget::applyHideWindowWorkaround() {
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_OVERLAY_WIDGET
// QOpenGLWidget can't properly destroy a child widget if // QOpenGLWidget can't properly destroy a child widget if
// it is hidden exactly after that, so it must be repainted // it is hidden exactly after that, so it must be repainted
// before it is hidden without the child widget. // before it is hidden without the child widget.

View File

@ -52,15 +52,17 @@ namespace View {
class GroupThumbs; class GroupThumbs;
class Pip; class Pip;
#if defined Q_OS_MAC && !defined OS_MAC_OLD #if 1
#define USE_OPENGL_OVERLAY_WIDGET #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 #endif // Q_OS_MAC && !OS_MAC_OLD
struct OverlayParentTraits : Ui::RpWidgetDefaultTraits { struct OverlayParentTraits : Ui::RpWidgetDefaultTraits {
static constexpr bool kSetZeroGeometry = false; static constexpr bool kSetZeroGeometry = false;
}; };
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_OVERLAY_WIDGET
using OverlayParent = Ui::RpWidgetWrap<QOpenGLWidget, OverlayParentTraits>; using OverlayParent = Ui::RpWidgetWrap<QOpenGLWidget, OverlayParentTraits>;
#else // USE_OPENGL_OVERLAY_WIDGET #else // USE_OPENGL_OVERLAY_WIDGET
using OverlayParent = Ui::RpWidgetWrap<QWidget, OverlayParentTraits>; using OverlayParent = Ui::RpWidgetWrap<QWidget, OverlayParentTraits>;

View File

@ -354,8 +354,8 @@ QRect RotatedRect(QRect rect, int rotation) {
Unexpected("Rotation in RotatedRect."); Unexpected("Rotation in RotatedRect.");
} }
bool UsePainterRotation(int rotation) { bool UsePainterRotation(int rotation, bool opengl) {
return Platform::IsMac() || !(rotation % 180); return opengl || !(rotation % 180);
} }
QSize FlipSizeByRotation(QSize size, int rotation) { QSize FlipSizeByRotation(QSize size, int rotation) {
@ -375,6 +375,9 @@ PipPanel::PipPanel(
Fn<void(QPainter&, FrameRequest)> paint) Fn<void(QPainter&, FrameRequest)> paint)
: _parent(parent) : _parent(parent)
, _paint(std::move(paint)) { , _paint(std::move(paint)) {
}
void PipPanel::init() {
setWindowFlags(Qt::Tool setWindowFlags(Qt::Tool
| Qt::WindowStaysOnTopHint | Qt::WindowStaysOnTopHint
| Qt::FramelessWindowHint | Qt::FramelessWindowHint
@ -592,8 +595,12 @@ void PipPanel::setPositionOnScreen(Position position, QRect available) {
void PipPanel::paintEvent(QPaintEvent *e) { void PipPanel::paintEvent(QPaintEvent *e) {
QPainter p(this); QPainter p(this);
if (_useTransparency) { if (_useTransparency && USE_OPENGL_PIP_WIDGET) {
Ui::Platform::StartTranslucentPaint(p, e->region()); p.setCompositionMode(QPainter::CompositionMode_Source);
for (const auto rect : e->region()) {
p.fillRect(rect, Qt::transparent);
}
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
} }
auto request = FrameRequest(); auto request = FrameRequest();
@ -898,6 +905,7 @@ Pip::Pip(
Pip::~Pip() = default; Pip::~Pip() = default;
void Pip::setupPanel() { void Pip::setupPanel() {
_panel.init();
const auto size = [&] { const auto size = [&] {
if (!_instance.info().video.size.isEmpty()) { if (!_instance.info().video.size.isEmpty()) {
return _instance.info().video.size; return _instance.info().video.size;
@ -1196,11 +1204,12 @@ void Pip::paint(QPainter &p, FrameRequest request) {
inner.topLeft(), inner.topLeft(),
request.outer / style::DevicePixelRatio() request.outer / style::DevicePixelRatio()
}; };
if (UsePainterRotation(_rotation)) { if (UsePainterRotation(_rotation, USE_OPENGL_PIP_WIDGET)) {
if (_rotation) { if (_rotation) {
p.save(); p.save();
p.rotate(_rotation); p.rotate(_rotation);
} }
auto hq = PainterHighQualityEnabler(p);
p.drawImage(RotatedRect(rect, _rotation), image); p.drawImage(RotatedRect(rect, _rotation), image);
if (_rotation) { if (_rotation) {
p.restore(); p.restore();
@ -1516,7 +1525,7 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
QImage Pip::videoFrameForDirectPaint(const FrameRequest &request) const { QImage Pip::videoFrameForDirectPaint(const FrameRequest &request) const {
const auto result = videoFrame(request); const auto result = videoFrame(request);
#ifdef USE_OPENGL_OVERLAY_WIDGET #ifdef USE_OPENGL_PIP_WIDGET
const auto bytesPerLine = result.bytesPerLine(); const auto bytesPerLine = result.bytesPerLine();
if (bytesPerLine == result.width() * 4) { if (bytesPerLine == result.width() * 4) {
return result; return result;
@ -1545,14 +1554,14 @@ QImage Pip::videoFrameForDirectPaint(const FrameRequest &request) const {
from += bytesPerLine; from += bytesPerLine;
} }
return cache; return cache;
#endif // USE_OPENGL_OVERLAY_WIDGET #endif // USE_OPENGL_PIP_WIDGET
return result; return result;
} }
void Pip::paintRadialLoading(QPainter &p) const { void Pip::paintRadialLoading(QPainter &p) const {
const auto inner = countRadialRect(); const auto inner = countRadialRect();
#ifdef USE_OPENGL_OVERLAY_WIDGET #ifdef USE_OPENGL_PIP_WIDGET
{ {
if (_radialCache.size() != inner.size() * cIntRetinaFactor()) { if (_radialCache.size() != inner.size() * cIntRetinaFactor()) {
_radialCache = QImage( _radialCache = QImage(
@ -1566,9 +1575,9 @@ void Pip::paintRadialLoading(QPainter &p) const {
paintRadialLoadingContent(q, inner.translated(-inner.topLeft())); paintRadialLoadingContent(q, inner.translated(-inner.topLeft()));
} }
p.drawImage(inner.topLeft(), _radialCache); p.drawImage(inner.topLeft(), _radialCache);
#else // USE_OPENGL_OVERLAY_WIDGET #else // USE_OPENGL_PIP_WIDGET
paintRadialLoadingContent(p, inner); paintRadialLoadingContent(p, inner);
#endif // USE_OPENGL_OVERLAY_WIDGET #endif // USE_OPENGL_PIP_WIDGET
} }
void Pip::paintRadialLoadingContent(QPainter &p, const QRect &inner) const { void Pip::paintRadialLoadingContent(QPainter &p, const QRect &inner) const {

View File

@ -34,19 +34,21 @@ namespace View {
class PlaybackProgress; class PlaybackProgress;
[[nodiscard]] QRect RotatedRect(QRect rect, int rotation); [[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]] QSize FlipSizeByRotation(QSize size, int rotation);
[[nodiscard]] QImage RotateFrameImage(QImage image, int rotation); [[nodiscard]] QImage RotateFrameImage(QImage image, int rotation);
#if defined Q_OS_MAC && !defined OS_MAC_OLD #if 1
#define USE_OPENGL_OVERLAY_WIDGET #define USE_OPENGL_PIP_WIDGET 1
#else
#define USE_OPENGL_PIP_WIDGET 0
#endif // Q_OS_MAC && !OS_MAC_OLD #endif // Q_OS_MAC && !OS_MAC_OLD
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_PIP_WIDGET
using PipParent = Ui::RpWidgetWrap<QOpenGLWidget>; using PipParent = Ui::RpWidgetWrap<QOpenGLWidget>;
#else // USE_OPENGL_OVERLAY_WIDGET #else // USE_OPENGL_PIP_WIDGET
using PipParent = Ui::RpWidget; using PipParent = Ui::RpWidget;
#endif // USE_OPENGL_OVERLAY_WIDGET #endif // USE_OPENGL_PIP_WIDGET
class PipPanel final : public PipParent { class PipPanel final : public PipParent {
public: public:
@ -61,6 +63,7 @@ public:
PipPanel( PipPanel(
QWidget *parent, QWidget *parent,
Fn<void(QPainter&, FrameRequest)> paint); Fn<void(QPainter&, FrameRequest)> paint);
void init();
void setAspectRatio(QSize ratio); void setAspectRatio(QSize ratio);
[[nodiscard]] Position countPosition() const; [[nodiscard]] Position countPosition() const;
@ -234,10 +237,10 @@ private:
FnMut<void()> _closeAndContinue; FnMut<void()> _closeAndContinue;
FnMut<void()> _destroy; FnMut<void()> _destroy;
#ifdef USE_OPENGL_OVERLAY_WIDGET #if USE_OPENGL_PIP_WIDGET
mutable QImage _frameForDirectPaint; mutable QImage _frameForDirectPaint;
mutable QImage _radialCache; mutable QImage _radialCache;
#endif // USE_OPENGL_OVERLAY_WIDGET #endif // USE_OPENGL_PIP_WIDGET
mutable QImage _preparedCoverStorage; mutable QImage _preparedCoverStorage;
mutable FrameRequest _preparedCoverRequest; mutable FrameRequest _preparedCoverRequest;