mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Show mute icon in OpenGL renderer.
This commit is contained in:
parent
302cffba1c
commit
699730b7f4
4 changed files with 161 additions and 306 deletions
|
@ -179,6 +179,8 @@ public:
|
||||||
Painter &p,
|
Painter &p,
|
||||||
QRect iconRect,
|
QRect iconRect,
|
||||||
MembersRowStyle style = MembersRowStyle::None);
|
MembersRowStyle style = MembersRowStyle::None);
|
||||||
|
[[nodiscard]] MembersRowDelegate::IconState computeIconState(
|
||||||
|
MembersRowStyle style = MembersRowStyle::None) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct BlobsAnimation;
|
struct BlobsAnimation;
|
||||||
|
@ -239,8 +241,6 @@ private:
|
||||||
int sizew,
|
int sizew,
|
||||||
int sizeh,
|
int sizeh,
|
||||||
MembersRowStyle style);
|
MembersRowStyle style);
|
||||||
[[nodiscard]] MembersRowDelegate::IconState computeIconState(
|
|
||||||
MembersRowStyle style = MembersRowStyle::None) const;
|
|
||||||
|
|
||||||
const not_null<MembersRowDelegate*> _delegate;
|
const not_null<MembersRowDelegate*> _delegate;
|
||||||
State _state = State::Inactive;
|
State _state = State::Inactive;
|
||||||
|
|
|
@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "calls/group/calls_group_viewport_tile.h"
|
#include "calls/group/calls_group_viewport_tile.h"
|
||||||
#include "webrtc/webrtc_video_track.h"
|
#include "webrtc/webrtc_video_track.h"
|
||||||
#include "media/view/media_view_pip.h"
|
#include "media/view/media_view_pip.h"
|
||||||
|
#include "calls/group/calls_group_members_row.h"
|
||||||
|
#include "ui/gl/gl_shader.h"
|
||||||
#include "styles/style_calls.h"
|
#include "styles/style_calls.h"
|
||||||
|
|
||||||
#include <QtGui/QOpenGLShader>
|
#include <QtGui/QOpenGLShader>
|
||||||
|
@ -17,146 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Calls::Group {
|
namespace Calls::Group {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct FloatRect {
|
using namespace Ui::GL;
|
||||||
FloatRect(QRect rect)
|
|
||||||
: x(rect.x())
|
|
||||||
, y(rect.y())
|
|
||||||
, width(rect.width())
|
|
||||||
, height(rect.height()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatRect(QRectF rect)
|
|
||||||
: x(rect.x())
|
|
||||||
, y(rect.y())
|
|
||||||
, width(rect.width())
|
|
||||||
, height(rect.height()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
float x = 0;
|
|
||||||
float y = 0;
|
|
||||||
float width = 0;
|
|
||||||
float height = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShaderPart {
|
|
||||||
QString header;
|
|
||||||
QString body;
|
|
||||||
};
|
|
||||||
|
|
||||||
[[nodiscard]] QString VertexShader(const std::vector<ShaderPart> &parts) {
|
|
||||||
const auto accumulate = [&](auto proj) {
|
|
||||||
return ranges::accumulate(parts, QString(), std::plus<>(), proj);
|
|
||||||
};
|
|
||||||
return R"(
|
|
||||||
#version 120
|
|
||||||
attribute vec2 position;
|
|
||||||
)" + accumulate(&ShaderPart::header) + R"(
|
|
||||||
void main() {
|
|
||||||
vec4 result = vec4(position, 0., 1.);
|
|
||||||
)" + accumulate(&ShaderPart::body) + R"(
|
|
||||||
gl_Position = result;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] QString FragmentShader(const std::vector<ShaderPart> &parts) {
|
|
||||||
const auto accumulate = [&](auto proj) {
|
|
||||||
return ranges::accumulate(parts, QString(), std::plus<>(), proj);
|
|
||||||
};
|
|
||||||
return R"(
|
|
||||||
#version 120
|
|
||||||
)" + accumulate(&ShaderPart::header) + R"(
|
|
||||||
void main() {
|
|
||||||
vec4 result = vec4(0., 0., 0., 0.);
|
|
||||||
)" + accumulate(&ShaderPart::body) + R"(
|
|
||||||
gl_FragColor = result;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] ShaderPart VertexPassTextureCoord() {
|
|
||||||
return {
|
|
||||||
.header = R"(
|
|
||||||
attribute vec2 texcoord;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
)",
|
|
||||||
.body = R"(
|
|
||||||
v_texcoord = texcoord;
|
|
||||||
)",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] ShaderPart FragmentSampleARGB32Texture() {
|
|
||||||
return {
|
|
||||||
.header = R"(
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
uniform sampler2D s_texture;
|
|
||||||
)",
|
|
||||||
.body = R"(
|
|
||||||
result = texture2D(s_texture, v_texcoord);
|
|
||||||
result = vec4(result.b, result.g, result.r, result.a);
|
|
||||||
)",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] ShaderPart FragmentSampleYUV420Texture() {
|
|
||||||
return {
|
|
||||||
.header = R"(
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
uniform sampler2D y_texture;
|
|
||||||
uniform sampler2D u_texture;
|
|
||||||
uniform sampler2D v_texture;
|
|
||||||
)",
|
|
||||||
.body = R"(
|
|
||||||
float y = texture2D(y_texture, v_texcoord).r;
|
|
||||||
float u = texture2D(u_texture, v_texcoord).r - 0.5;
|
|
||||||
float v = texture2D(v_texture, v_texcoord).r - 0.5;
|
|
||||||
result = vec4(y + 1.403 * v, y - 0.344 * u - 0.714 * v, y + 1.77 * u, 1);
|
|
||||||
)",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] ShaderPart VertexViewportTransform() {
|
|
||||||
return {
|
|
||||||
.header = R"(
|
|
||||||
uniform vec2 viewport;
|
|
||||||
vec4 transform(vec4 position) {
|
|
||||||
return vec4(
|
|
||||||
vec2(-1, -1) + 2 * position.xy / viewport,
|
|
||||||
position.z,
|
|
||||||
position.w);
|
|
||||||
}
|
|
||||||
)",
|
|
||||||
.body = R"(
|
|
||||||
result = transform(result);
|
|
||||||
)",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] ShaderPart FragmentRoundCorners() {
|
|
||||||
return {
|
|
||||||
.header = R"(
|
|
||||||
uniform vec4 roundRect;
|
|
||||||
uniform vec4 roundBg;
|
|
||||||
uniform float roundRadius;
|
|
||||||
float roundedCorner() {
|
|
||||||
vec2 rectHalf = roundRect.zw / 2;
|
|
||||||
vec2 rectCenter = roundRect.xy + rectHalf;
|
|
||||||
vec2 fromRectCenter = abs(gl_FragCoord.xy - rectCenter);
|
|
||||||
vec2 vectorRadius = vec2(roundRadius + 0.5, roundRadius + 0.5);
|
|
||||||
vec2 fromCenterWithRadius = fromRectCenter + vectorRadius;
|
|
||||||
vec2 fromRoundingCenter = max(fromCenterWithRadius, rectHalf)
|
|
||||||
- rectHalf;
|
|
||||||
float d = length(fromRoundingCenter) - roundRadius;
|
|
||||||
return 1. - smoothstep(0., 1., d);
|
|
||||||
}
|
|
||||||
)",
|
|
||||||
.body = R"(
|
|
||||||
float rounded = roundedCorner();
|
|
||||||
result = result * rounded + roundBg * (1. - rounded);
|
|
||||||
)",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Depends on FragmetSampleTexture().
|
// Depends on FragmetSampleTexture().
|
||||||
[[nodiscard]] ShaderPart FragmentFrameColor() {
|
[[nodiscard]] ShaderPart FragmentFrameColor() {
|
||||||
|
@ -184,91 +47,15 @@ float insideTexture() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ShaderPart FragmentStaticColor() {
|
void FillRectVertices(GLfloat *coords, Rect rect) {
|
||||||
return {
|
coords[0] = coords[10] = rect.left();
|
||||||
.header = R"(
|
coords[1] = coords[11] = rect.top();
|
||||||
uniform vec4 s_color;
|
coords[2] = rect.right();
|
||||||
)",
|
coords[3] = rect.top();
|
||||||
.body = R"(
|
coords[4] = coords[6] = rect.right();
|
||||||
result = s_color;
|
coords[5] = coords[7] = rect.bottom();
|
||||||
)",
|
coords[8] = rect.left();
|
||||||
};
|
coords[9] = rect.bottom();
|
||||||
}
|
|
||||||
|
|
||||||
not_null<QOpenGLShader*> MakeShader(
|
|
||||||
not_null<QOpenGLShaderProgram*> program,
|
|
||||||
QOpenGLShader::ShaderType type,
|
|
||||||
const QString &source) {
|
|
||||||
const auto result = new QOpenGLShader(type, program);
|
|
||||||
if (!result->compileSourceCode(source)) {
|
|
||||||
LOG(("Shader Compilation Failed: %1, error %2."
|
|
||||||
).arg(source
|
|
||||||
).arg(result->log()));
|
|
||||||
}
|
|
||||||
program->addShader(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Program {
|
|
||||||
not_null<QOpenGLShader*> vertex;
|
|
||||||
not_null<QOpenGLShader*> fragment;
|
|
||||||
};
|
|
||||||
|
|
||||||
Program LinkProgram(
|
|
||||||
not_null<QOpenGLShaderProgram*> program,
|
|
||||||
std::variant<QString, not_null<QOpenGLShader*>> vertex,
|
|
||||||
std::variant<QString, not_null<QOpenGLShader*>> fragment) {
|
|
||||||
const auto vertexAsSource = v::is<QString>(vertex);
|
|
||||||
const auto v = vertexAsSource
|
|
||||||
? MakeShader(
|
|
||||||
program,
|
|
||||||
QOpenGLShader::Vertex,
|
|
||||||
v::get<QString>(vertex))
|
|
||||||
: v::get<not_null<QOpenGLShader*>>(vertex);
|
|
||||||
if (!vertexAsSource) {
|
|
||||||
program->addShader(v);
|
|
||||||
}
|
|
||||||
const auto fragmentAsSource = v::is<QString>(fragment);
|
|
||||||
const auto f = fragmentAsSource
|
|
||||||
? MakeShader(
|
|
||||||
program,
|
|
||||||
QOpenGLShader::Fragment,
|
|
||||||
v::get<QString>(fragment))
|
|
||||||
: v::get<not_null<QOpenGLShader*>>(fragment);
|
|
||||||
if (!fragmentAsSource) {
|
|
||||||
program->addShader(f);
|
|
||||||
}
|
|
||||||
if (!program->link()) {
|
|
||||||
LOG(("Shader Link Failed: %1.").arg(program->log()));
|
|
||||||
}
|
|
||||||
return { v, f };
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] QVector4D Uniform(const QRect &rect, GLfloat factor) {
|
|
||||||
return QVector4D(
|
|
||||||
rect.x() * factor,
|
|
||||||
rect.y() * factor,
|
|
||||||
rect.width() * factor,
|
|
||||||
rect.height() * factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] QVector4D Uniform(const QColor &color) {
|
|
||||||
return QVector4D(
|
|
||||||
color.redF(),
|
|
||||||
color.greenF(),
|
|
||||||
color.blueF(),
|
|
||||||
color.alphaF());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRectVertices(GLfloat *coords, QRect rect, GLfloat factor) {
|
|
||||||
coords[0] = coords[10] = rect.x() * factor;
|
|
||||||
coords[1] = coords[11] = rect.y() * factor;
|
|
||||||
coords[2] = (rect.x() + rect.width()) * factor;
|
|
||||||
coords[3] = rect.y() * factor;
|
|
||||||
coords[4] = coords[6] = (rect.x() + rect.width()) * factor;
|
|
||||||
coords[5] = coords[7] = (rect.y() + rect.height()) * factor;
|
|
||||||
coords[8] = rect.x() * factor;
|
|
||||||
coords[9] = (rect.y() + rect.height()) * factor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillTriangles(
|
void FillTriangles(
|
||||||
|
@ -349,6 +136,7 @@ void FillTexturedRectangle(
|
||||||
Viewport::RendererGL::RendererGL(not_null<Viewport*> owner)
|
Viewport::RendererGL::RendererGL(not_null<Viewport*> owner)
|
||||||
: _owner(owner)
|
: _owner(owner)
|
||||||
, _pinIcon(st::groupCallLargeVideo.pin)
|
, _pinIcon(st::groupCallLargeVideo.pin)
|
||||||
|
, _muteIcon(st::groupCallLargeVideoCrossLine)
|
||||||
, _pinBackground(
|
, _pinBackground(
|
||||||
(st::groupCallLargeVideo.pinPadding.top()
|
(st::groupCallLargeVideo.pinPadding.top()
|
||||||
+ st::groupCallLargeVideo.pin.icon.height()
|
+ st::groupCallLargeVideo.pin.icon.height()
|
||||||
|
@ -357,7 +145,7 @@ Viewport::RendererGL::RendererGL(not_null<Viewport*> owner)
|
||||||
|
|
||||||
style::PaletteChanged(
|
style::PaletteChanged(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
_pinButtons.invalidate();
|
_buttons.invalidate();
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +223,7 @@ void Viewport::RendererGL::deinit(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeTextures(f);
|
freeTextures(f);
|
||||||
_pinButtons.destroy(f);
|
_buttons.destroy(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::RendererGL::resize(
|
void Viewport::RendererGL::resize(
|
||||||
|
@ -464,7 +252,7 @@ void Viewport::RendererGL::fillBackground(QOpenGLFunctions &f) {
|
||||||
const auto radiuses = QMargins{ radius, radius, radius, radius };
|
const auto radiuses = QMargins{ radius, radius, radius, radius };
|
||||||
auto bg = QRegion(QRect(QPoint(), _viewport));
|
auto bg = QRegion(QRect(QPoint(), _viewport));
|
||||||
for (const auto &tile : _owner->_tiles) {
|
for (const auto &tile : _owner->_tiles) {
|
||||||
bg -= tileGeometry(tile.get()).marginsRemoved(radiuses);
|
bg -= tile->geometry().marginsRemoved(radiuses);
|
||||||
}
|
}
|
||||||
if (bg.isEmpty()) {
|
if (bg.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -472,7 +260,7 @@ void Viewport::RendererGL::fillBackground(QOpenGLFunctions &f) {
|
||||||
_bgTriangles.resize((bg.end() - bg.begin()) * 12);
|
_bgTriangles.resize((bg.end() - bg.begin()) * 12);
|
||||||
auto coords = _bgTriangles.data();
|
auto coords = _bgTriangles.data();
|
||||||
for (const auto rect : bg) {
|
for (const auto rect : bg) {
|
||||||
FillRectVertices(coords, rect, _factor);
|
FillRectVertices(coords, transformRect(rect));
|
||||||
coords += 12;
|
coords += 12;
|
||||||
}
|
}
|
||||||
FillTriangles(
|
FillTriangles(
|
||||||
|
@ -494,11 +282,20 @@ void Viewport::RendererGL::paintTile(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto geometry = tile->geometry();
|
const auto geometry = tile->geometry();
|
||||||
const auto flipped = flipRect(geometry);
|
const auto x = geometry.x();
|
||||||
const auto x = flipped.x();
|
const auto y = geometry.y();
|
||||||
const auto y = flipped.y();
|
const auto width = geometry.width();
|
||||||
const auto width = flipped.width();
|
const auto height = geometry.height();
|
||||||
const auto height = flipped.height();
|
const auto &st = st::groupCallLargeVideo;
|
||||||
|
const auto shown = _owner->_controlsShownRatio;
|
||||||
|
const auto fullNameShift = st.namePosition.y() + st::normalFont->height;
|
||||||
|
const auto nameShift = anim::interpolate(fullNameShift, 0, shown);
|
||||||
|
const auto row = tile->row();
|
||||||
|
const auto style = row->computeIconState(MembersRowStyle::LargeVideo);
|
||||||
|
|
||||||
|
ensureButtonsImage();
|
||||||
|
|
||||||
|
// Frame.
|
||||||
const auto expand = !_owner->wide()/* && !tile->screencast()*/;
|
const auto expand = !_owner->wide()/* && !tile->screencast()*/;
|
||||||
const auto scaled = Media::View::FlipSizeByRotation(
|
const auto scaled = Media::View::FlipSizeByRotation(
|
||||||
data.yuv420->size,
|
data.yuv420->size,
|
||||||
|
@ -506,23 +303,22 @@ void Viewport::RendererGL::paintTile(
|
||||||
).scaled(
|
).scaled(
|
||||||
QSize(width, height),
|
QSize(width, height),
|
||||||
(expand ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio));
|
(expand ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio));
|
||||||
if (scaled.isEmpty()) {
|
const auto good = !scaled.isEmpty();
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto left = (width - scaled.width()) / 2;
|
const auto left = (width - scaled.width()) / 2;
|
||||||
const auto top = (height - scaled.height()) / 2;
|
const auto top = (height - scaled.height()) / 2;
|
||||||
const auto right = left + scaled.width();
|
const auto right = left + scaled.width();
|
||||||
const auto bottom = top + scaled.height();
|
const auto bottom = top + scaled.height();
|
||||||
const auto radius = GLfloat(st::roundRadiusLarge);
|
const auto radius = GLfloat(st::roundRadiusLarge);
|
||||||
auto dleft = float(left) / scaled.width();
|
auto dleft = good ? (float(left) / scaled.width()) : 0.f;
|
||||||
auto dright = float(width - left) / scaled.width();
|
auto dright = good ? (float(width - left) / scaled.width()) : 1.f;
|
||||||
auto dtop = float(top) / scaled.height();
|
auto dtop = good ? (float(top) / scaled.height()) : 0.f;
|
||||||
auto dbottom = float(height - top) / scaled.height();
|
auto dbottom = good ? (float(height - top) / scaled.height()) : 1.f;
|
||||||
const auto swap = (((data.rotation / 90) % 2) == 1);
|
const auto swap = (((data.rotation / 90) % 2) == 1);
|
||||||
if (swap) {
|
if (swap) {
|
||||||
std::swap(dleft, dtop);
|
std::swap(dleft, dtop);
|
||||||
std::swap(dright, dbottom);
|
std::swap(dright, dbottom);
|
||||||
}
|
}
|
||||||
|
const auto rect = transformRect(geometry);
|
||||||
auto texCoord = std::array<std::array<GLfloat, 2>, 4> { {
|
auto texCoord = std::array<std::array<GLfloat, 2>, 4> { {
|
||||||
{ { -dleft, 1.f + dtop } },
|
{ { -dleft, 1.f + dtop } },
|
||||||
{ { dright, 1.f + dtop } },
|
{ { dright, 1.f + dtop } },
|
||||||
|
@ -536,50 +332,67 @@ void Viewport::RendererGL::paintTile(
|
||||||
texCoord.end());
|
texCoord.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
ensurePinImage();
|
// Pin.
|
||||||
const auto pinRasterRect = tile->pinInner().translated(
|
const auto pin = _buttons.texturedRect(
|
||||||
geometry.topLeft());
|
tile->pinInner().translated(x, y),
|
||||||
const auto pinVisibleRect = pinRasterRect.intersected(geometry);
|
tile->pinned() ? _pinOn : _pinOff,
|
||||||
const auto pin = FloatRect(flipRect(pinVisibleRect));
|
geometry);
|
||||||
const auto pinTextureRect = tile->pinned() ? _pinOn : _pinOff;
|
const auto pinRect = transformRect(pin.geometry);
|
||||||
const auto pinUseTextureRect = QRect(
|
|
||||||
pinTextureRect.x(),
|
// Mute.
|
||||||
pinTextureRect.y() + pinVisibleRect.y() - pinRasterRect.y(),
|
const auto &icon = st::groupCallLargeVideoCrossLine.icon;
|
||||||
pinTextureRect.width(),
|
const auto iconLeft = x + width - st.iconPosition.x() - icon.width();
|
||||||
pinVisibleRect.height());
|
const auto iconTop = y + (height
|
||||||
const auto pinImageDimensions = _pinButtons.image().size();
|
- st.iconPosition.y()
|
||||||
const auto pinTexture = FloatRect(QRectF(
|
- icon.height()
|
||||||
pinUseTextureRect.x() / float(pinImageDimensions.width()),
|
+ nameShift);
|
||||||
pinUseTextureRect.y() / float(pinImageDimensions.height()),
|
const auto mute = _buttons.texturedRect(
|
||||||
pinUseTextureRect.width() / float(pinImageDimensions.width()),
|
QRect(iconLeft, iconTop, icon.width(), icon.height()),
|
||||||
pinUseTextureRect.height() / float(pinImageDimensions.height())));
|
(row->state() == MembersRow::State::Active
|
||||||
|
? _muteOff
|
||||||
|
: _muteOn),
|
||||||
|
geometry);
|
||||||
|
const auto muteRect = transformRect(mute.geometry);
|
||||||
|
|
||||||
const GLfloat coords[] = {
|
const GLfloat coords[] = {
|
||||||
// Frame.
|
rect.left(), rect.top(),
|
||||||
x * _factor, y * _factor,
|
|
||||||
texCoord[0][0], texCoord[0][1],
|
texCoord[0][0], texCoord[0][1],
|
||||||
|
|
||||||
(x + width) * _factor, y * _factor,
|
rect.right(), rect.top(),
|
||||||
texCoord[1][0], texCoord[1][1],
|
texCoord[1][0], texCoord[1][1],
|
||||||
|
|
||||||
(x + width) * _factor, (y + height) * _factor,
|
rect.right(), rect.bottom(),
|
||||||
texCoord[2][0], texCoord[2][1],
|
texCoord[2][0], texCoord[2][1],
|
||||||
|
|
||||||
x * _factor, (y + height) * _factor,
|
rect.left(), rect.bottom(),
|
||||||
texCoord[3][0], texCoord[3][1],
|
texCoord[3][0], texCoord[3][1],
|
||||||
|
|
||||||
// Pin button.
|
pinRect.left(), pinRect.top(),
|
||||||
pin.x * _factor, pin.y * _factor,
|
pin.texture.left(), pin.texture.bottom(),
|
||||||
pinTexture.x, pinTexture.y + pinTexture.height,
|
|
||||||
|
|
||||||
(pin.x + pin.width) * _factor, pin.y * _factor,
|
pinRect.right(), pinRect.top(),
|
||||||
pinTexture.x + pinTexture.width, pinTexture.y + pinTexture.height,
|
pin.texture.right(), pin.texture.bottom(),
|
||||||
|
|
||||||
(pin.x + pin.width) * _factor, (pin.y + pin.height) * _factor,
|
pinRect.right(), pinRect.bottom(),
|
||||||
pinTexture.x + pinTexture.width, pinTexture.y,
|
pin.texture.right(), pin.texture.top(),
|
||||||
|
|
||||||
pin.x * _factor, (pin.y + pin.height) * _factor,
|
pinRect.left(), pinRect.bottom(),
|
||||||
pinTexture.x, pinTexture.y,
|
pin.texture.left(), pin.texture.top(),
|
||||||
|
|
||||||
|
muteRect.left(), muteRect.top(),
|
||||||
|
mute.texture.left(), mute.texture.bottom(),
|
||||||
|
|
||||||
|
muteRect.right(), muteRect.top(),
|
||||||
|
mute.texture.right(), mute.texture.bottom(),
|
||||||
|
|
||||||
|
muteRect.right(), muteRect.bottom(),
|
||||||
|
mute.texture.right(), mute.texture.top(),
|
||||||
|
|
||||||
|
muteRect.left(), muteRect.bottom(),
|
||||||
|
mute.texture.left(), mute.texture.top(),
|
||||||
|
|
||||||
|
|
||||||
|
// Name.
|
||||||
};
|
};
|
||||||
|
|
||||||
tile->ensureTexturesCreated(f);
|
tile->ensureTexturesCreated(f);
|
||||||
|
@ -656,11 +469,9 @@ void Viewport::RendererGL::paintTile(
|
||||||
"frameBg",
|
"frameBg",
|
||||||
Uniform(st::groupCallMembersBg->c));
|
Uniform(st::groupCallMembersBg->c));
|
||||||
program->setUniformValue("roundRadius", radius * _factor);
|
program->setUniformValue("roundRadius", radius * _factor);
|
||||||
program->setUniformValue("roundRect", Uniform(flipped, _factor));
|
program->setUniformValue("roundRect", Uniform(rect));
|
||||||
program->setUniformValue("roundBg", Uniform(st::groupCallBg->c));
|
program->setUniformValue("roundBg", Uniform(st::groupCallBg->c));
|
||||||
|
|
||||||
const auto &st = st::groupCallLargeVideo;
|
|
||||||
const auto shown = _owner->_controlsShownRatio;
|
|
||||||
const auto shadowHeight = st.shadowHeight * _factor;
|
const auto shadowHeight = st.shadowHeight * _factor;
|
||||||
const auto shadowAlpha = kShadowMaxAlpha / 255.f;
|
const auto shadowAlpha = kShadowMaxAlpha / 255.f;
|
||||||
program->setUniformValue(
|
program->setUniformValue(
|
||||||
|
@ -670,7 +481,7 @@ void Viewport::RendererGL::paintTile(
|
||||||
FillTexturedRectangle(f, program);
|
FillTexturedRectangle(f, program);
|
||||||
|
|
||||||
const auto pinVisible = _owner->wide()
|
const auto pinVisible = _owner->wide()
|
||||||
&& (pinRasterRect.y() + pinRasterRect.height() > y);
|
&& (pin.geometry.bottom() > y);
|
||||||
if (shown == 0. && !pinVisible) {
|
if (shown == 0. && !pinVisible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -682,30 +493,51 @@ void Viewport::RendererGL::paintTile(
|
||||||
});
|
});
|
||||||
|
|
||||||
f.glUseProgram(_imageProgram->programId());
|
f.glUseProgram(_imageProgram->programId());
|
||||||
|
_imageProgram->setUniformValue("viewport", uniformViewport);
|
||||||
|
_imageProgram->setUniformValue("s_texture", GLint(0));
|
||||||
|
|
||||||
|
f.glActiveTexture(GL_TEXTURE0);
|
||||||
|
_buttons.bind(f);
|
||||||
|
|
||||||
if (pinVisible) {
|
if (pinVisible) {
|
||||||
f.glActiveTexture(GL_TEXTURE0);
|
|
||||||
_pinButtons.bind(f);
|
|
||||||
_imageProgram->setUniformValue("viewport", uniformViewport);
|
|
||||||
_imageProgram->setUniformValue("s_texture", GLint(0));
|
|
||||||
FillTexturedRectangle(f, &*_imageProgram, 4);
|
FillTexturedRectangle(f, &*_imageProgram, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shown == 0.) {
|
if (shown == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mute.
|
||||||
|
FillTexturedRectangle(f, &*_imageProgram, 8);
|
||||||
|
|
||||||
|
// Name.
|
||||||
|
//p.setPen(st::groupCallVideoTextFg);
|
||||||
|
//const auto hasWidth = width
|
||||||
|
// - st.iconPosition.x() - icon.width()
|
||||||
|
// - st.namePosition.x();
|
||||||
|
//const auto nameLeft = x + st.namePosition.x();
|
||||||
|
//const auto nameTop = y + (height
|
||||||
|
// - st.namePosition.y()
|
||||||
|
// - st::semiboldFont->height
|
||||||
|
// + shift);
|
||||||
|
//row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect Viewport::RendererGL::tileGeometry(not_null<VideoTile*> tile) const {
|
Rect Viewport::RendererGL::transformRect(const Rect &raster) const {
|
||||||
const auto raster = tile->geometry();
|
|
||||||
return flipRect(tile->geometry());
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect Viewport::RendererGL::flipRect(const QRect &raster) const {
|
|
||||||
return {
|
return {
|
||||||
raster.x(),
|
raster.left() * _factor,
|
||||||
_viewport.height() - raster.y() - raster.height(),
|
float(_viewport.height() - raster.bottom()) * _factor,
|
||||||
raster.width(),
|
raster.width() * _factor,
|
||||||
raster.height(),
|
raster.height() * _factor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect Viewport::RendererGL::transformRect(const QRect &raster) const {
|
||||||
|
return {
|
||||||
|
raster.x() * _factor,
|
||||||
|
(_viewport.height() - raster.y() - raster.height()) * _factor,
|
||||||
|
raster.width() * _factor,
|
||||||
|
raster.height() * _factor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,17 +547,24 @@ void Viewport::RendererGL::freeTextures(QOpenGLFunctions &f) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::RendererGL::ensurePinImage() {
|
void Viewport::RendererGL::ensureButtonsImage() {
|
||||||
if (_pinButtons) {
|
if (_buttons) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto factor = cIntRetinaFactor();
|
||||||
const auto pinOnSize = VideoTile::PinInnerSize(true);
|
const auto pinOnSize = VideoTile::PinInnerSize(true);
|
||||||
const auto pinOffSize = VideoTile::PinInnerSize(false);
|
const auto pinOffSize = VideoTile::PinInnerSize(false);
|
||||||
|
const auto muteSize = st::groupCallLargeVideoCrossLine.icon.size();
|
||||||
|
|
||||||
const auto fullSize = QSize(
|
const auto fullSize = QSize(
|
||||||
std::max(pinOnSize.width(), pinOffSize.width()),
|
std::max({
|
||||||
pinOnSize.height() + pinOffSize.height());
|
pinOnSize.width(),
|
||||||
const auto imageSize = fullSize * cIntRetinaFactor();
|
pinOffSize.width(),
|
||||||
auto image = _pinButtons.takeImage();
|
2 * muteSize.width(),
|
||||||
|
}),
|
||||||
|
pinOnSize.height() + pinOffSize.height() + muteSize.height());
|
||||||
|
const auto imageSize = fullSize * factor;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -734,7 +573,8 @@ void Viewport::RendererGL::ensurePinImage() {
|
||||||
{
|
{
|
||||||
auto p = Painter(&image);
|
auto p = Painter(&image);
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
_pinOn = QRect(QPoint(), pinOnSize);
|
|
||||||
|
_pinOn = QRect(QPoint(), pinOnSize * factor);
|
||||||
VideoTile::PaintPinButton(
|
VideoTile::PaintPinButton(
|
||||||
p,
|
p,
|
||||||
true,
|
true,
|
||||||
|
@ -743,7 +583,10 @@ void Viewport::RendererGL::ensurePinImage() {
|
||||||
fullSize.width(),
|
fullSize.width(),
|
||||||
&_pinBackground,
|
&_pinBackground,
|
||||||
&_pinIcon);
|
&_pinIcon);
|
||||||
_pinOff = QRect(QPoint(0, pinOnSize.height()), pinOffSize);
|
|
||||||
|
_pinOff = QRect(
|
||||||
|
QPoint(0, pinOnSize.height()) * factor,
|
||||||
|
pinOffSize * factor);
|
||||||
VideoTile::PaintPinButton(
|
VideoTile::PaintPinButton(
|
||||||
p,
|
p,
|
||||||
false,
|
false,
|
||||||
|
@ -752,8 +595,17 @@ void Viewport::RendererGL::ensurePinImage() {
|
||||||
fullSize.width(),
|
fullSize.width(),
|
||||||
&_pinBackground,
|
&_pinBackground,
|
||||||
&_pinIcon);
|
&_pinIcon);
|
||||||
|
|
||||||
|
const auto muteTop = pinOnSize.height() + pinOffSize.height();
|
||||||
|
_muteOn = QRect(QPoint(0, muteTop) * factor, muteSize * factor);
|
||||||
|
_muteIcon.paint(p, { 0, muteTop }, 1.);
|
||||||
|
|
||||||
|
_muteOff = QRect(
|
||||||
|
QPoint(muteSize.width(), muteTop) * factor,
|
||||||
|
muteSize * factor);
|
||||||
|
_muteIcon.paint(p, { muteSize.width(), muteTop }, 0.);
|
||||||
}
|
}
|
||||||
_pinButtons.setImage(std::move(image));
|
_buttons.setImage(std::move(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Calls::Group
|
} // namespace Calls::Group
|
||||||
|
|
|
@ -48,11 +48,11 @@ private:
|
||||||
QOpenGLFunctions &f,
|
QOpenGLFunctions &f,
|
||||||
not_null<VideoTile*> tile);
|
not_null<VideoTile*> tile);
|
||||||
void freeTextures(QOpenGLFunctions &f);
|
void freeTextures(QOpenGLFunctions &f);
|
||||||
[[nodiscard]] QRect tileGeometry(not_null<VideoTile*> tile) const;
|
[[nodiscard]] Ui::GL::Rect transformRect(const QRect &raster) const;
|
||||||
[[nodiscard]] QRect flipRect(const QRect &raster) const;
|
[[nodiscard]] Ui::GL::Rect transformRect(const Ui::GL::Rect &raster) const;
|
||||||
|
|
||||||
void ensureARGB32Program();
|
void ensureARGB32Program();
|
||||||
void ensurePinImage();
|
void ensureButtonsImage();
|
||||||
|
|
||||||
const not_null<Viewport*> _owner;
|
const not_null<Viewport*> _owner;
|
||||||
|
|
||||||
|
@ -66,13 +66,16 @@ private:
|
||||||
std::optional<QOpenGLShaderProgram> _bgProgram;
|
std::optional<QOpenGLShaderProgram> _bgProgram;
|
||||||
QOpenGLShader *_frameVertexShader = nullptr;
|
QOpenGLShader *_frameVertexShader = nullptr;
|
||||||
|
|
||||||
Ui::GL::Image _pinButtons;
|
Ui::GL::Image _buttons;
|
||||||
QRect _pinOn;
|
QRect _pinOn;
|
||||||
QRect _pinOff;
|
QRect _pinOff;
|
||||||
|
QRect _muteOn;
|
||||||
|
QRect _muteOff;
|
||||||
|
|
||||||
std::vector<GLfloat> _bgTriangles;
|
std::vector<GLfloat> _bgTriangles;
|
||||||
std::vector<Textures> _texturesToFree;
|
std::vector<Textures> _texturesToFree;
|
||||||
Ui::CrossLineAnimation _pinIcon;
|
Ui::CrossLineAnimation _pinIcon;
|
||||||
|
Ui::CrossLineAnimation _muteIcon;
|
||||||
Ui::RoundRect _pinBackground;
|
Ui::RoundRect _pinBackground;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2a26d4a91aca5f9850e5a3d7d5cd58ed0b74639a
|
Subproject commit 808f8c7deafb92ca9b20209e761f576076636565
|
Loading…
Add table
Reference in a new issue