Optimize background painting in OpenGL renderers.

This commit is contained in:
John Preston 2021-06-10 23:37:09 +04:00
parent f9f98975a1
commit 2f986660ff
9 changed files with 57 additions and 135 deletions

View file

@ -319,6 +319,8 @@ PRIVATE
calls/calls_userpic.h calls/calls_userpic.h
calls/calls_video_bubble.cpp calls/calls_video_bubble.cpp
calls/calls_video_bubble.h calls/calls_video_bubble.h
calls/calls_video_incoming.cpp
calls/calls_video_incoming.h
chat_helpers/bot_keyboard.cpp chat_helpers/bot_keyboard.cpp
chat_helpers/bot_keyboard.h chat_helpers/bot_keyboard.h
chat_helpers/emoji_keywords.cpp chat_helpers/emoji_keywords.cpp

View file

@ -53,12 +53,6 @@ public:
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
void resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) override;
void paint( void paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
@ -183,24 +177,6 @@ void Panel::Incoming::RendererGL::deinit(
_contentBuffer = std::nullopt; _contentBuffer = std::nullopt;
} }
void Panel::Incoming::RendererGL::resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) {
const auto factor = widget->devicePixelRatio();
if (_factor != factor) {
_factor = factor;
_controlsShadowImage.invalidate();
}
_viewport = QSize{ w, h };
_uniformViewport = QVector2D(
_viewport.width() * _factor,
_viewport.height() * _factor);
const auto size = _viewport * _factor;
f.glViewport(0, 0, size.width(), size.height());
}
void Panel::Incoming::RendererGL::paint( void Panel::Incoming::RendererGL::paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) { QOpenGLFunctions &f) {
@ -211,6 +187,17 @@ void Panel::Incoming::RendererGL::paint(
if (data.format == Webrtc::FrameFormat::None) { if (data.format == Webrtc::FrameFormat::None) {
return; return;
} }
const auto factor = widget->devicePixelRatio();
if (_factor != factor) {
_factor = factor;
_controlsShadowImage.invalidate();
}
_viewport = widget->size();
_uniformViewport = QVector2D(
_viewport.width() * _factor,
_viewport.height() * _factor);
const auto rgbaFrame = (data.format == Webrtc::FrameFormat::ARGB32); const auto rgbaFrame = (data.format == Webrtc::FrameFormat::ARGB32);
const auto upload = (_trackFrameIndex != data.index); const auto upload = (_trackFrameIndex != data.index);
_trackFrameIndex = data.index; _trackFrameIndex = data.index;

View file

@ -374,8 +374,6 @@ void Viewport::RendererGL::init(
})); }));
validateNoiseTexture(f, 0); validateNoiseTexture(f, 0);
_background.init(f);
} }
void Viewport::RendererGL::ensureARGB32Program() { void Viewport::RendererGL::ensureARGB32Program() {
@ -403,8 +401,6 @@ void Viewport::RendererGL::ensureARGB32Program() {
void Viewport::RendererGL::deinit( void Viewport::RendererGL::deinit(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) { QOpenGLFunctions &f) {
_background.deinit(f);
_frameBuffer = std::nullopt; _frameBuffer = std::nullopt;
_frameVertexShader = nullptr; _frameVertexShader = nullptr;
_imageProgram = std::nullopt; _imageProgram = std::nullopt;
@ -423,16 +419,6 @@ void Viewport::RendererGL::deinit(
_buttons.destroy(f); _buttons.destroy(f);
} }
void Viewport::RendererGL::resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) {
_factor = widget->devicePixelRatio();
_viewport = QSize(w, h);
setDefaultViewport(f);
}
void Viewport::RendererGL::setDefaultViewport(QOpenGLFunctions &f) { void Viewport::RendererGL::setDefaultViewport(QOpenGLFunctions &f) {
const auto size = _viewport * _factor; const auto size = _viewport * _factor;
f.glViewport(0, 0, size.width(), size.height()); f.glViewport(0, 0, size.width(), size.height());
@ -442,10 +428,11 @@ void Viewport::RendererGL::paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) { QOpenGLFunctions &f) {
_factor = widget->devicePixelRatio(); _factor = widget->devicePixelRatio();
_viewport = widget->size();
const auto defaultFramebufferObject = widget->defaultFramebufferObject(); const auto defaultFramebufferObject = widget->defaultFramebufferObject();
validateDatas(); validateDatas();
fillBackground(f);
auto index = 0; auto index = 0;
for (const auto &tile : _owner->_tiles) { for (const auto &tile : _owner->_tiles) {
if (!tile->shown()) { if (!tile->shown()) {
@ -460,16 +447,8 @@ void Viewport::RendererGL::paint(
} }
} }
void Viewport::RendererGL::fillBackground(QOpenGLFunctions &f) { std::optional<QColor> Viewport::RendererGL::clearColor() {
const auto radius = st::roundRadiusLarge; return st::groupCallBg->c;
const auto radiuses = QMargins{ radius, radius, radius, radius };
auto region = QRegion(QRect(QPoint(), _viewport));
for (const auto &tile : _owner->_tiles) {
if (tile->shown()) {
region -= tile->geometry().marginsRemoved(radiuses);
}
}
_background.fill(f, region, _viewport, _factor, st::groupCallBg);
} }
void Viewport::RendererGL::validateUserpicFrame( void Viewport::RendererGL::validateUserpicFrame(

View file

@ -36,16 +36,12 @@ public:
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
void resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) override;
void paint( void paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
std::optional<QColor> clearColor() override;
private: private:
struct TileData { struct TileData {
quintptr id = 0; quintptr id = 0;
@ -72,7 +68,6 @@ private:
}; };
void setDefaultViewport(QOpenGLFunctions &f); void setDefaultViewport(QOpenGLFunctions &f);
void fillBackground(QOpenGLFunctions &f);
void paintTile( void paintTile(
QOpenGLFunctions &f, QOpenGLFunctions &f,
GLuint defaultFramebufferObject, GLuint defaultFramebufferObject,
@ -138,7 +133,6 @@ private:
QSize _viewport; QSize _viewport;
bool _rgbaFrame = false; bool _rgbaFrame = false;
bool _userpicFrame; bool _userpicFrame;
Ui::GL::BackgroundFiller _background;
std::optional<QOpenGLBuffer> _frameBuffer; std::optional<QOpenGLBuffer> _frameBuffer;
Program _downscaleProgram; Program _downscaleProgram;
std::optional<QOpenGLShaderProgram> _blurProgram; std::optional<QOpenGLShaderProgram> _blurProgram;

View file

@ -119,14 +119,11 @@ void OverlayWidget::RendererGL::init(
FragmentSampleARGB32Texture(), FragmentSampleARGB32Texture(),
FragmentGlobalOpacity(), FragmentGlobalOpacity(),
})); }));
_background.init(f);
} }
void OverlayWidget::RendererGL::deinit( void OverlayWidget::RendererGL::deinit(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) { QOpenGLFunctions &f) {
_background.deinit(f);
_textures.destroy(f); _textures.destroy(f);
_imageProgram = std::nullopt; _imageProgram = std::nullopt;
_texturedVertexShader = nullptr; _texturedVertexShader = nullptr;
@ -137,61 +134,43 @@ void OverlayWidget::RendererGL::deinit(
_contentBuffer = std::nullopt; _contentBuffer = std::nullopt;
} }
void OverlayWidget::RendererGL::resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) {
const auto factor = widget->devicePixelRatio();
if (_factor != factor) {
_factor = factor;
_controlsImage.invalidate();
}
_viewport = QSize{ w, h };
_uniformViewport = QVector2D(
_viewport.width() * _factor,
_viewport.height() * _factor);
setDefaultViewport(f);
}
void OverlayWidget::RendererGL::setDefaultViewport(QOpenGLFunctions &f) {
f.glViewport(0, 0, _uniformViewport.x(), _uniformViewport.y());
}
void OverlayWidget::RendererGL::paint( void OverlayWidget::RendererGL::paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) { QOpenGLFunctions &f) {
if (handleHideWorkaround(f)) { if (handleHideWorkaround(f)) {
return; return;
} }
const auto factor = widget->devicePixelRatio();
if (_factor != factor) {
_factor = factor;
_controlsImage.invalidate();
}
_viewport = widget->size();
_uniformViewport = QVector2D(
_viewport.width() * _factor,
_viewport.height() * _factor);
_f = &f; _f = &f;
_owner->paint(this); _owner->paint(this);
_f = nullptr; _f = nullptr;
} }
bool OverlayWidget::RendererGL::handleHideWorkaround(QOpenGLFunctions &f) { std::optional<QColor> OverlayWidget::RendererGL::clearColor() {
if (!Platform::IsWindows() || !_owner->_hideWorkaround) { if (Platform::IsWindows() && _owner->_hideWorkaround) {
return false; return QColor(0, 0, 0, 0);
} else if (_owner->_fullScreenVideo) {
return st::mediaviewVideoBg->c;
} else {
return st::mediaviewBg->c;
} }
}
bool OverlayWidget::RendererGL::handleHideWorkaround(QOpenGLFunctions &f) {
// This is needed on Windows, // This is needed on Windows,
// because on reopen it blinks with the last shown content. // because on reopen it blinks with the last shown content.
f.glClearColor(0., 0., 0., 0.); return Platform::IsWindows() && _owner->_hideWorkaround;
f.glClear(GL_COLOR_BUFFER_BIT);
return true;
} }
void OverlayWidget::RendererGL::paintBackground() { void OverlayWidget::RendererGL::paintBackground() {
const auto &bg = _owner->_fullScreenVideo
? st::mediaviewVideoBg
: st::mediaviewBg;
auto fill = QRegion(QRect(QPoint(), _viewport));
toggleBlending(false);
_background.fill(
*_f,
fill,
_viewport,
_factor,
bg);
_contentBuffer->bind(); _contentBuffer->bind();
} }

View file

@ -27,23 +27,18 @@ public:
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
void resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) override;
void paint( void paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
std::optional<QColor> clearColor() override;
private: private:
struct Control { struct Control {
int index = -1; int index = -1;
not_null<const style::icon*> icon; not_null<const style::icon*> icon;
}; };
bool handleHideWorkaround(QOpenGLFunctions &f); bool handleHideWorkaround(QOpenGLFunctions &f);
void setDefaultViewport(QOpenGLFunctions &f);
void paintBackground() override; void paintBackground() override;
void paintTransformedVideoFrame(ContentGeometry geometry) override; void paintTransformedVideoFrame(ContentGeometry geometry) override;
@ -102,7 +97,6 @@ private:
const not_null<OverlayWidget*> _owner; const not_null<OverlayWidget*> _owner;
QOpenGLFunctions *_f = nullptr; QOpenGLFunctions *_f = nullptr;
Ui::GL::BackgroundFiller _background;
QSize _viewport; QSize _viewport;
float _factor = 1.; float _factor = 1.;
QVector2D _uniformViewport; QVector2D _uniformViewport;

View file

@ -235,27 +235,6 @@ void Pip::RendererGL::deinit(
_contentBuffer = std::nullopt; _contentBuffer = std::nullopt;
} }
void Pip::RendererGL::resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h) {
const auto factor = widget->devicePixelRatio();
if (_factor != factor) {
_factor = factor;
_controlsImage.invalidate();
}
_viewport = QSize{ w, h };
_uniformViewport = QVector2D(
_viewport.width() * _factor,
_viewport.height() * _factor);
setDefaultViewport(f);
}
void Pip::RendererGL::setDefaultViewport(QOpenGLFunctions &f) {
f.glViewport(0, 0, _uniformViewport.x(), _uniformViewport.y());
}
void Pip::RendererGL::createShadowTexture() { void Pip::RendererGL::createShadowTexture() {
const auto &shadow = st::callShadow; const auto &shadow = st::callShadow;
const auto size = 2 * st::callShadow.topLeft.size() const auto size = 2 * st::callShadow.topLeft.size()
@ -279,11 +258,24 @@ 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();
if (_factor != factor) {
_factor = factor;
_controlsImage.invalidate();
}
_viewport = widget->size();
_uniformViewport = QVector2D(
_viewport.width() * _factor,
_viewport.height() * _factor);
_f = &f; _f = &f;
_owner->paint(this); _owner->paint(this);
_f = nullptr; _f = nullptr;
} }
std::optional<QColor> Pip::RendererGL::clearColor() {
return QColor(0, 0, 0, 0);
}
void Pip::RendererGL::paintTransformedVideoFrame( void Pip::RendererGL::paintTransformedVideoFrame(
ContentGeometry geometry) { ContentGeometry geometry) {
const auto data = _owner->videoFrameWithInfo(); const auto data = _owner->videoFrameWithInfo();

View file

@ -27,23 +27,18 @@ public:
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
void resize(
not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f,
int w,
int h);
void paint( void paint(
not_null<QOpenGLWidget*> widget, not_null<QOpenGLWidget*> widget,
QOpenGLFunctions &f) override; QOpenGLFunctions &f) override;
std::optional<QColor> clearColor() override;
private: private:
struct Control { struct Control {
int index = -1; int index = -1;
not_null<const style::icon*> icon; not_null<const style::icon*> icon;
not_null<const style::icon*> iconOver; not_null<const style::icon*> iconOver;
}; };
void setDefaultViewport(QOpenGLFunctions &f);
void createShadowTexture(); void createShadowTexture();
void paintTransformedVideoFrame(ContentGeometry geometry) override; void paintTransformedVideoFrame(ContentGeometry geometry) override;

@ -1 +1 @@
Subproject commit 1c004580ebb1380d3cb19fadb017f416c85a0eef Subproject commit 098eb59f2f4635640f8a5f2e53bee2f689f2d0b3