mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Fix OpenGL rendering with precise HighDPI.
This commit is contained in:
parent
311691a3bc
commit
af3cf63e5f
7 changed files with 50 additions and 39 deletions
|
@ -73,6 +73,7 @@ private:
|
||||||
|
|
||||||
QSize _viewport;
|
QSize _viewport;
|
||||||
float _factor = 1.;
|
float _factor = 1.;
|
||||||
|
int _ifactor = 1;
|
||||||
QVector2D _uniformViewport;
|
QVector2D _uniformViewport;
|
||||||
|
|
||||||
std::optional<QOpenGLBuffer> _contentBuffer;
|
std::optional<QOpenGLBuffer> _contentBuffer;
|
||||||
|
@ -189,9 +190,10 @@ void Panel::Incoming::RendererGL::paint(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto factor = widget->devicePixelRatio();
|
const auto factor = widget->devicePixelRatioF();
|
||||||
if (_factor != factor) {
|
if (_factor != factor) {
|
||||||
_factor = factor;
|
_factor = factor;
|
||||||
|
_ifactor = int(std::ceil(_factor));
|
||||||
_controlsShadowImage.invalidate();
|
_controlsShadowImage.invalidate();
|
||||||
}
|
}
|
||||||
_viewport = widget->size();
|
_viewport = widget->size();
|
||||||
|
@ -375,9 +377,9 @@ void Panel::Incoming::RendererGL::validateShadowImage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto size = st::callTitleShadowLeft.size();
|
const auto size = st::callTitleShadowLeft.size();
|
||||||
const auto full = QSize(size.width(), 2 * size.height()) * int(_factor);
|
const auto full = QSize(size.width(), 2 * size.height()) * _ifactor;
|
||||||
auto image = QImage(full, QImage::Format_ARGB32_Premultiplied);
|
auto image = QImage(full, QImage::Format_ARGB32_Premultiplied);
|
||||||
image.setDevicePixelRatio(_factor);
|
image.setDevicePixelRatio(_ifactor);
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
{
|
{
|
||||||
auto p = QPainter(&image);
|
auto p = QPainter(&image);
|
||||||
|
|
|
@ -414,16 +414,20 @@ void Viewport::RendererGL::deinit(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::RendererGL::setDefaultViewport(QOpenGLFunctions &f) {
|
void Viewport::RendererGL::setDefaultViewport(QOpenGLFunctions &f) {
|
||||||
const auto size = _viewport * _factor;
|
f.glViewport(
|
||||||
f.glViewport(0, 0, size.width(), size.height());
|
0,
|
||||||
|
0,
|
||||||
|
_viewport.width() * _factor,
|
||||||
|
_viewport.height() * _factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::RendererGL::paint(
|
void Viewport::RendererGL::paint(
|
||||||
not_null<QOpenGLWidget*> widget,
|
not_null<QOpenGLWidget*> widget,
|
||||||
QOpenGLFunctions &f) {
|
QOpenGLFunctions &f) {
|
||||||
const auto factor = widget->devicePixelRatio();
|
const auto factor = widget->devicePixelRatioF();
|
||||||
if (_factor != factor) {
|
if (_factor != factor) {
|
||||||
_factor = factor;
|
_factor = factor;
|
||||||
|
_ifactor = int(std::ceil(_factor));
|
||||||
_buttons.invalidate();
|
_buttons.invalidate();
|
||||||
}
|
}
|
||||||
_viewport = widget->size();
|
_viewport = widget->size();
|
||||||
|
@ -773,7 +777,7 @@ void Viewport::RendererGL::paintTile(
|
||||||
const auto program = _rgbaFrame
|
const auto program = _rgbaFrame
|
||||||
? &*_frameProgram.argb32
|
? &*_frameProgram.argb32
|
||||||
: &*_frameProgram.yuv420;
|
: &*_frameProgram.yuv420;
|
||||||
const auto uniformViewport = QSizeF(_viewport * _factor);
|
const auto uniformViewport = QSizeF(_viewport) * _factor;
|
||||||
|
|
||||||
program->setUniformValue("viewport", uniformViewport);
|
program->setUniformValue("viewport", uniformViewport);
|
||||||
program->setUniformValue(
|
program->setUniformValue(
|
||||||
|
@ -1122,18 +1126,18 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
||||||
+ backSize.height()
|
+ backSize.height()
|
||||||
+ muteSize.height()
|
+ muteSize.height()
|
||||||
+ pausedSize.height()));
|
+ pausedSize.height()));
|
||||||
const auto imageSize = fullSize * _factor;
|
const auto imageSize = fullSize * _ifactor;
|
||||||
auto image = _buttons.takeImage();
|
auto image = _buttons.takeImage();
|
||||||
if (image.size() != imageSize) {
|
if (image.size() != imageSize) {
|
||||||
image = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
|
image = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
|
||||||
}
|
}
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
image.setDevicePixelRatio(_factor);
|
image.setDevicePixelRatio(_ifactor);
|
||||||
{
|
{
|
||||||
auto p = Painter(&image);
|
auto p = Painter(&image);
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
|
||||||
_pinOn = QRect(QPoint(), pinOnSize * _factor);
|
_pinOn = QRect(QPoint(), pinOnSize * _ifactor);
|
||||||
VideoTile::PaintPinButton(
|
VideoTile::PaintPinButton(
|
||||||
p,
|
p,
|
||||||
true,
|
true,
|
||||||
|
@ -1145,8 +1149,8 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
||||||
|
|
||||||
const auto pinOffTop = pinOnSize.height();
|
const auto pinOffTop = pinOnSize.height();
|
||||||
_pinOff = QRect(
|
_pinOff = QRect(
|
||||||
QPoint(0, pinOffTop) * _factor,
|
QPoint(0, pinOffTop) * _ifactor,
|
||||||
pinOffSize * _factor);
|
pinOffSize * _ifactor);
|
||||||
VideoTile::PaintPinButton(
|
VideoTile::PaintPinButton(
|
||||||
p,
|
p,
|
||||||
false,
|
false,
|
||||||
|
@ -1157,7 +1161,7 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
||||||
&_pinIcon);
|
&_pinIcon);
|
||||||
|
|
||||||
const auto backTop = pinOffTop + pinOffSize.height();
|
const auto backTop = pinOffTop + pinOffSize.height();
|
||||||
_back = QRect(QPoint(0, backTop) * _factor, backSize * _factor);
|
_back = QRect(QPoint(0, backTop) * _ifactor, backSize * _ifactor);
|
||||||
VideoTile::PaintBackButton(
|
VideoTile::PaintBackButton(
|
||||||
p,
|
p,
|
||||||
0,
|
0,
|
||||||
|
@ -1166,18 +1170,18 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
||||||
&_pinBackground);
|
&_pinBackground);
|
||||||
|
|
||||||
const auto muteTop = backTop + backSize.height();
|
const auto muteTop = backTop + backSize.height();
|
||||||
_muteOn = QRect(QPoint(0, muteTop) * _factor, muteSize * _factor);
|
_muteOn = QRect(QPoint(0, muteTop) * _ifactor, muteSize * _ifactor);
|
||||||
_muteIcon.paint(p, { 0, muteTop }, 1.);
|
_muteIcon.paint(p, { 0, muteTop }, 1.);
|
||||||
|
|
||||||
_muteOff = QRect(
|
_muteOff = QRect(
|
||||||
QPoint(muteSize.width(), muteTop) * _factor,
|
QPoint(muteSize.width(), muteTop) * _ifactor,
|
||||||
muteSize * _factor);
|
muteSize * _ifactor);
|
||||||
_muteIcon.paint(p, { muteSize.width(), muteTop }, 0.);
|
_muteIcon.paint(p, { muteSize.width(), muteTop }, 0.);
|
||||||
|
|
||||||
const auto pausedTop = muteTop + muteSize.height();
|
const auto pausedTop = muteTop + muteSize.height();
|
||||||
_paused = QRect(
|
_paused = QRect(
|
||||||
QPoint(0, pausedTop) * _factor,
|
QPoint(0, pausedTop) * _ifactor,
|
||||||
pausedSize * _factor);
|
pausedSize * _ifactor);
|
||||||
st::groupCallPaused.paint(p, 0, pausedTop, fullSize.width());
|
st::groupCallPaused.paint(p, 0, pausedTop, fullSize.width());
|
||||||
}
|
}
|
||||||
_buttons.setImage(std::move(image));
|
_buttons.setImage(std::move(image));
|
||||||
|
|
|
@ -130,6 +130,7 @@ private:
|
||||||
const not_null<Viewport*> _owner;
|
const not_null<Viewport*> _owner;
|
||||||
|
|
||||||
GLfloat _factor = 1.;
|
GLfloat _factor = 1.;
|
||||||
|
int _ifactor = 1;
|
||||||
QSize _viewport;
|
QSize _viewport;
|
||||||
bool _rgbaFrame = false;
|
bool _rgbaFrame = false;
|
||||||
bool _userpicFrame;
|
bool _userpicFrame;
|
||||||
|
|
|
@ -263,9 +263,10 @@ void OverlayWidget::RendererGL::paint(
|
||||||
if (handleHideWorkaround(f)) {
|
if (handleHideWorkaround(f)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto factor = widget->devicePixelRatio();
|
const auto factor = widget->devicePixelRatioF();
|
||||||
if (_factor != factor) {
|
if (_factor != factor) {
|
||||||
_factor = factor;
|
_factor = factor;
|
||||||
|
_ifactor = int(std::ceil(factor));
|
||||||
_controlsImage.invalidate();
|
_controlsImage.invalidate();
|
||||||
|
|
||||||
// We use the fact that fade texture atlas
|
// We use the fact that fade texture atlas
|
||||||
|
@ -763,10 +764,10 @@ void OverlayWidget::RendererGL::validateControls() {
|
||||||
maxWidth = std::max(st::mediaviewIconOver, maxWidth);
|
maxWidth = std::max(st::mediaviewIconOver, maxWidth);
|
||||||
fullHeight += st::mediaviewIconOver;
|
fullHeight += st::mediaviewIconOver;
|
||||||
auto image = QImage(
|
auto image = QImage(
|
||||||
QSize(maxWidth, fullHeight) * _factor,
|
QSize(maxWidth, fullHeight) * _ifactor,
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
image.setDevicePixelRatio(_factor);
|
image.setDevicePixelRatio(_ifactor);
|
||||||
{
|
{
|
||||||
auto p = QPainter(&image);
|
auto p = QPainter(&image);
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
|
@ -774,8 +775,8 @@ void OverlayWidget::RendererGL::validateControls() {
|
||||||
for (const auto &meta : metas) {
|
for (const auto &meta : metas) {
|
||||||
meta.icon->paint(p, 0, height, maxWidth);
|
meta.icon->paint(p, 0, height, maxWidth);
|
||||||
_controlsTextures[index++] = QRect(
|
_controlsTextures[index++] = QRect(
|
||||||
QPoint(0, height) * _factor,
|
QPoint(0, height) * _ifactor,
|
||||||
meta.icon->size() * _factor);
|
meta.icon->size() * _ifactor);
|
||||||
height += meta.icon->height();
|
height += meta.icon->height();
|
||||||
}
|
}
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
@ -784,8 +785,8 @@ void OverlayWidget::RendererGL::validateControls() {
|
||||||
p.drawEllipse(
|
p.drawEllipse(
|
||||||
QRect(0, height, st::mediaviewIconOver, st::mediaviewIconOver));
|
QRect(0, height, st::mediaviewIconOver, st::mediaviewIconOver));
|
||||||
_controlsTextures[index++] = QRect(
|
_controlsTextures[index++] = QRect(
|
||||||
QPoint(0, height) * _factor,
|
QPoint(0, height) * _ifactor,
|
||||||
QSize(st::mediaviewIconOver, st::mediaviewIconOver) * _factor);
|
QSize(st::mediaviewIconOver, st::mediaviewIconOver) * _ifactor);
|
||||||
height += st::mediaviewIconOver;
|
height += st::mediaviewIconOver;
|
||||||
}
|
}
|
||||||
_controlsImage.setImage(std::move(image));
|
_controlsImage.setImage(std::move(image));
|
||||||
|
@ -817,10 +818,10 @@ void OverlayWidget::RendererGL::validateControlsFade() {
|
||||||
const auto height = bottomTop + bottom.height();
|
const auto height = bottomTop + bottom.height();
|
||||||
|
|
||||||
auto image = QImage(
|
auto image = QImage(
|
||||||
QSize(width, height) * _factor,
|
QSize(width, height) * _ifactor,
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
image.setDevicePixelRatio(_factor);
|
image.setDevicePixelRatio(_ifactor);
|
||||||
|
|
||||||
auto p = QPainter(&image);
|
auto p = QPainter(&image);
|
||||||
top.paint(p, 0, 0, width);
|
top.paint(p, 0, 0, width);
|
||||||
|
@ -1007,18 +1008,18 @@ void OverlayWidget::RendererGL::paintUsingRaster(
|
||||||
int bufferOffset,
|
int bufferOffset,
|
||||||
bool transparent) {
|
bool transparent) {
|
||||||
auto raster = image.takeImage();
|
auto raster = image.takeImage();
|
||||||
const auto size = rect.size() * _factor;
|
const auto size = rect.size() * _ifactor;
|
||||||
if (raster.width() < size.width() || raster.height() < size.height()) {
|
if (raster.width() < size.width() || raster.height() < size.height()) {
|
||||||
raster = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
raster = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
||||||
Assert(!raster.isNull());
|
Assert(!raster.isNull());
|
||||||
raster.setDevicePixelRatio(_factor);
|
raster.setDevicePixelRatio(_ifactor);
|
||||||
if (!transparent
|
if (!transparent
|
||||||
&& (raster.width() > size.width()
|
&& (raster.width() > size.width()
|
||||||
|| raster.height() > size.height())) {
|
|| raster.height() > size.height())) {
|
||||||
raster.fill(Qt::transparent);
|
raster.fill(Qt::transparent);
|
||||||
}
|
}
|
||||||
} else if (raster.devicePixelRatio() != _factor) {
|
} else if (raster.devicePixelRatio() != _ifactor) {
|
||||||
raster.setDevicePixelRatio(_factor);
|
raster.setDevicePixelRatio(_ifactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transparent) {
|
if (transparent) {
|
||||||
|
|
|
@ -114,6 +114,7 @@ private:
|
||||||
QOpenGLFunctions *_f = nullptr;
|
QOpenGLFunctions *_f = nullptr;
|
||||||
QSize _viewport;
|
QSize _viewport;
|
||||||
float _factor = 1.;
|
float _factor = 1.;
|
||||||
|
int _ifactor = 1;
|
||||||
QVector2D _uniformViewport;
|
QVector2D _uniformViewport;
|
||||||
|
|
||||||
std::optional<QOpenGLBuffer> _contentBuffer;
|
std::optional<QOpenGLBuffer> _contentBuffer;
|
||||||
|
|
|
@ -269,9 +269,10 @@ void Pip::RendererGL::createShadowTexture() {
|
||||||
void Pip::RendererGL::paint(
|
void Pip::RendererGL::paint(
|
||||||
not_null<QOpenGLWidget*> widget,
|
not_null<QOpenGLWidget*> widget,
|
||||||
QOpenGLFunctions &f) {
|
QOpenGLFunctions &f) {
|
||||||
const auto factor = widget->devicePixelRatio();
|
const auto factor = widget->devicePixelRatioF();
|
||||||
if (_factor != factor) {
|
if (_factor != factor) {
|
||||||
_factor = factor;
|
_factor = factor;
|
||||||
|
_ifactor = int(std::ceil(_factor));
|
||||||
_controlsImage.invalidate();
|
_controlsImage.invalidate();
|
||||||
}
|
}
|
||||||
_blendingEnabled = false;
|
_blendingEnabled = false;
|
||||||
|
@ -667,10 +668,10 @@ void Pip::RendererGL::validateControls() {
|
||||||
fullHeight += 2 * meta.icon->height();
|
fullHeight += 2 * meta.icon->height();
|
||||||
}
|
}
|
||||||
auto image = QImage(
|
auto image = QImage(
|
||||||
QSize(maxWidth, fullHeight) * _factor,
|
QSize(maxWidth, fullHeight) * _ifactor,
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
image.setDevicePixelRatio(_factor);
|
image.setDevicePixelRatio(_ifactor);
|
||||||
{
|
{
|
||||||
auto p = QPainter(&image);
|
auto p = QPainter(&image);
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
|
@ -678,8 +679,8 @@ void Pip::RendererGL::validateControls() {
|
||||||
const auto paint = [&](not_null<const style::icon*> icon) {
|
const auto paint = [&](not_null<const style::icon*> icon) {
|
||||||
icon->paint(p, 0, height, maxWidth);
|
icon->paint(p, 0, height, maxWidth);
|
||||||
_controlsTextures[index++] = QRect(
|
_controlsTextures[index++] = QRect(
|
||||||
QPoint(0, height) * _factor,
|
QPoint(0, height) * _ifactor,
|
||||||
icon->size() * _factor);
|
icon->size() * _ifactor);
|
||||||
height += icon->height();
|
height += icon->height();
|
||||||
};
|
};
|
||||||
for (const auto &meta : metas) {
|
for (const auto &meta : metas) {
|
||||||
|
@ -702,7 +703,7 @@ void Pip::RendererGL::paintUsingRaster(
|
||||||
int bufferOffset,
|
int bufferOffset,
|
||||||
bool transparent) {
|
bool transparent) {
|
||||||
auto raster = image.takeImage();
|
auto raster = image.takeImage();
|
||||||
const auto size = rect.size() * _factor;
|
const auto size = rect.size() * _ifactor;
|
||||||
if (raster.width() < size.width() || raster.height() < size.height()) {
|
if (raster.width() < size.width() || raster.height() < size.height()) {
|
||||||
raster = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
raster = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
||||||
raster.setDevicePixelRatio(_factor);
|
raster.setDevicePixelRatio(_factor);
|
||||||
|
@ -711,8 +712,8 @@ void Pip::RendererGL::paintUsingRaster(
|
||||||
|| raster.height() > size.height())) {
|
|| raster.height() > size.height())) {
|
||||||
raster.fill(Qt::transparent);
|
raster.fill(Qt::transparent);
|
||||||
}
|
}
|
||||||
} else if (raster.devicePixelRatio() != _factor) {
|
} else if (raster.devicePixelRatio() != _ifactor) {
|
||||||
raster.setDevicePixelRatio(_factor);
|
raster.setDevicePixelRatio(_ifactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transparent) {
|
if (transparent) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ private:
|
||||||
QOpenGLFunctions *_f = nullptr;
|
QOpenGLFunctions *_f = nullptr;
|
||||||
QSize _viewport;
|
QSize _viewport;
|
||||||
float _factor = 1.;
|
float _factor = 1.;
|
||||||
|
int _ifactor = 1;
|
||||||
QVector2D _uniformViewport;
|
QVector2D _uniformViewport;
|
||||||
|
|
||||||
std::optional<QOpenGLBuffer> _contentBuffer;
|
std::optional<QOpenGLBuffer> _contentBuffer;
|
||||||
|
|
Loading…
Add table
Reference in a new issue