[qrhi] Added full multi-pass renderer with blur, YUV420 to group calls.

This commit is contained in:
23rd
2026-03-31 20:07:09 +03:00
parent 03aca09d24
commit f2ddfe72c6
6 changed files with 1788 additions and 0 deletions
+2
View File
@@ -438,6 +438,8 @@ PRIVATE
calls/group/calls_group_viewport_opengl.h
calls/group/calls_group_viewport_raster.cpp
calls/group/calls_group_viewport_raster.h
calls/group/calls_group_viewport_rhi.cpp
calls/group/calls_group_viewport_rhi.h
calls/group/calls_group_viewport_tile.cpp
calls/group/calls_group_viewport_tile.h
calls/group/calls_volume_item.cpp
@@ -10,6 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "calls/group/calls_group_viewport_tile.h"
#include "calls/group/calls_group_viewport_opengl.h"
#include "calls/group/calls_group_viewport_raster.h"
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
#include "calls/group/calls_group_viewport_rhi.h"
#endif
#include "calls/group/calls_group_common.h"
#include "calls/group/calls_group_call.h"
#include "calls/group/calls_group_members_row.h"
@@ -885,12 +888,22 @@ void Viewport::setPressed(Selection value) {
}
Ui::GL::ChosenRenderer Viewport::chooseRenderer(Ui::GL::Backend backend) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
if (backend == Ui::GL::Backend::QRhi) {
_opengl = true;
return {
.renderer = std::make_unique<RendererRhi>(this),
.backend = Ui::GL::Backend::QRhi,
};
}
#else
if (backend == Ui::GL::Backend::QRhi) {
return {
.renderer = std::make_unique<RendererSW>(this),
.backend = Ui::GL::Backend::QRhi,
};
}
#endif
_opengl = (backend == Ui::GL::Backend::OpenGL);
return {
.renderer = makeRenderer(),
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,218 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "calls/group/calls_group_viewport.h"
#include "ui/gl/gl_surface.h"
#include "ui/rhi/rhi_renderer.h"
#include "ui/rhi/rhi_image.h"
#include "ui/round_rect.h"
#include "ui/effects/animations.h"
#include "ui/effects/cross_line.h"
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
class QRhi;
class QRhiBuffer;
class QRhiTexture;
class QRhiSampler;
class QRhiGraphicsPipeline;
class QRhiShaderResourceBindings;
class QRhiResourceUpdateBatch;
class QRhiTextureRenderTarget;
class QRhiRenderPassDescriptor;
namespace Webrtc {
struct FrameWithInfo;
} // namespace Webrtc
namespace Calls::Group {
class Viewport::RendererRhi final
: public Ui::GL::Renderer
, public Ui::Rhi::Renderer {
public:
explicit RendererRhi(not_null<Viewport*> owner);
~RendererRhi();
void initialize(
QRhi *rhi,
QRhiRenderTarget *rt,
QRhiCommandBuffer *cb) override;
void render(
QRhi *rhi,
QRhiRenderTarget *rt,
QRhiCommandBuffer *cb) override;
void releaseResources() override;
QColor rhiClearColor() override;
std::optional<QColor> clearColor() override;
private:
struct TileData {
quintptr id = 0;
not_null<PeerData*> peer;
Ui::Animations::Simple outlined;
Ui::Animations::Simple paused;
QImage userpicFrame;
QRect nameRect;
int nameVersion = 0;
mutable int trackIndex = -1;
QRhiTexture *rgbaTexture = nullptr;
QSize rgbaSize;
QRhiTexture *yTexture = nullptr;
QRhiTexture *uTexture = nullptr;
QRhiTexture *vTexture = nullptr;
QSize lumaSize;
QSize chromaSize;
QRhiTexture *downscaleTexture = nullptr;
QRhiTextureRenderTarget *downscaleRt = nullptr;
QRhiRenderPassDescriptor *downscaleRpDesc = nullptr;
QRhiTexture *blurTexture = nullptr;
QRhiTextureRenderTarget *blurRt = nullptr;
QRhiRenderPassDescriptor *blurRpDesc = nullptr;
QSize blurSize;
bool stale = false;
bool pause = false;
bool outline = false;
};
struct PoolTexture {
QRhiTexture *texture = nullptr;
QSize size;
};
void createPipelines();
void ensureNoiseTexture();
void validateDatas();
void validateOutlineAnimation(
not_null<VideoTile*> tile,
TileData &data);
void validatePausedAnimation(
not_null<VideoTile*> tile,
TileData &data);
void validateUserpicFrame(
not_null<VideoTile*> tile,
TileData &data);
void ensureButtonsImage();
void paintTile(
not_null<VideoTile*> tile,
TileData &tileData);
void uploadFrame(
const Webrtc::FrameWithInfo &data,
TileData &tileData);
void prepareOffscreenTargets(
TileData &tileData,
QSize blurSize);
void drawDownscalePass(
TileData &tileData,
QSize blurSize);
void drawBlurPass(
TileData &tileData,
QSize blurSize);
void drawFramePass(
not_null<VideoTile*> tile,
TileData &tileData,
QSize blurSize);
void drawControls(
not_null<VideoTile*> tile,
TileData &tileData);
void paintUsingRaster(
QRect rect,
Fn<void(Painter&)> method,
float opacity = 1.f);
[[nodiscard]] QRhiTexture *acquirePoolTexture(QSize size);
[[nodiscard]] Ui::GL::Rect transformRect(const QRect &raster) const;
[[nodiscard]] Ui::GL::Rect transformRect(
const Ui::GL::Rect &raster) const;
[[nodiscard]] bool isExpanded(
not_null<VideoTile*> tile,
QSize unscaled,
QSize tileSize) const;
[[nodiscard]] float64 countExpandRatio(
not_null<VideoTile*> tile,
QSize unscaled,
const TileAnimation &animation) const;
const not_null<Viewport*> _owner;
QRhi *_rhi = nullptr;
QRhiRenderTarget *_rt = nullptr;
QRhiCommandBuffer *_cb = nullptr;
QRhiResourceUpdateBatch *_rub = nullptr;
QSize _viewport;
float _factor = 1.f;
int _ifactor = 1;
bool _rgbaFrame = false;
bool _userpicFrame = false;
QRhiBuffer *_offscreenVertexBuffer = nullptr;
QRhiBuffer *_onscreenVertexBuffer = nullptr;
QRhiBuffer *_uniformBuffer = nullptr;
QRhiSampler *_linearSampler = nullptr;
QRhiSampler *_nearestSampler = nullptr;
QRhiSampler *_noiseRepeatSampler = nullptr;
QRhiTexture *_placeholderTexture = nullptr;
QRhiGraphicsPipeline *_downscaleArgb32Pipeline = nullptr;
QRhiGraphicsPipeline *_downscaleYuv420Pipeline = nullptr;
QRhiGraphicsPipeline *_blurHPipeline = nullptr;
QRhiGraphicsPipeline *_blurVPipeline = nullptr;
QRhiGraphicsPipeline *_framePipeline = nullptr;
QRhiGraphicsPipeline *_controlsPipeline = nullptr;
QRhiShaderResourceBindings *_downscaleArgb32Srb = nullptr;
QRhiShaderResourceBindings *_downscaleYuv420Srb = nullptr;
QRhiShaderResourceBindings *_blurHSrb = nullptr;
QRhiRenderPassDescriptor *_offscreenRpDesc = nullptr;
QRhiTexture *_noiseTexture = nullptr;
Ui::Rhi::Image _buttons;
QRect _pinOn;
QRect _pinOff;
QRect _back;
QRect _muteOn;
QRect _muteOff;
QRect _pausedIcon;
Ui::Rhi::Image _names;
QRect _pausedTextRect;
std::vector<TileData> _tileData;
std::vector<int> _tileDataIndices;
std::vector<PoolTexture> _texturePool;
int _nextPoolIndex = 0;
std::vector<QRhiShaderResourceBindings*> _perDrawSrbs;
Ui::CrossLineAnimation _pinIcon;
Ui::CrossLineAnimation _muteIcon;
Ui::RoundRect _pinBackground;
bool _initialized = false;
rpl::lifetime _lifetime;
};
} // namespace Calls::Group
#endif // Qt >= 6.7
+28
View File
@@ -0,0 +1,28 @@
#version 450
layout(location = 0) in vec2 position;
layout(location = 1) in vec2 v_texcoordIn;
layout(location = 2) in vec2 b_texcoordIn;
layout(location = 0) out vec2 v_texcoord;
layout(location = 1) out vec2 b_texcoord;
layout(std140, binding = 0) uniform Params {
vec2 viewport;
vec4 frameBg;
vec4 shadow;
float paused;
vec4 roundRect;
vec2 radiusOutline;
vec4 roundBg;
vec4 outlineFg;
};
void main() {
v_texcoord = v_texcoordIn;
b_texcoord = b_texcoordIn;
gl_Position = vec4(
vec2(-1.0, -1.0) + 2.0 * position / viewport,
0.0,
1.0);
}
+11
View File
@@ -0,0 +1,11 @@
#version 450
layout(location = 0) in vec2 position;
layout(location = 1) in vec2 v_texcoordIn;
layout(location = 0) out vec2 v_texcoord;
void main() {
v_texcoord = v_texcoordIn;
gl_Position = vec4(position, 0.0, 1.0);
}