From 9255d7103857395e91c2e546edbf8eaed86da4ca Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 30 Jun 2021 11:47:15 +0300 Subject: [PATCH 01/14] Suggest single-component texture format. --- ui/gl/gl_image.cpp | 10 ++++++++++ ui/gl/gl_image.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/ui/gl/gl_image.cpp b/ui/gl/gl_image.cpp index 56bb89f..1d5a7fe 100644 --- a/ui/gl/gl_image.cpp +++ b/ui/gl/gl_image.cpp @@ -155,4 +155,14 @@ TexturedRect Image::texturedRect( }; } +GLint CurrentSingleComponentFormat() { + const auto context = QOpenGLContext::currentContext(); + Assert(context != nullptr); + + const auto format = context->format(); + return (format.renderableType() == QSurfaceFormat::OpenGLES) + ? GL_LUMINANCE + : GL_RED; +} + } // namespace Ui::GL diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index a1c9167..a54ec9e 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -134,4 +134,6 @@ private: }; +[[nodiscard]] GLint CurrentSingleComponentFormat(); + } // namespace Ui::GL From 3a51a253cddf25ad0c1adcf930ab5e90a8f614c4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 1 Jul 2021 00:12:34 +0300 Subject: [PATCH 02/14] Use updated SafeLoadLibrary from lib_base. --- ui/platform/win/ui_window_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 2c9876f..2f853c3 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -94,7 +94,7 @@ HRESULT WinApiSetWindowTheme( LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); auto result = f_SetWindowTheme(); - const auto loaded = base::Platform::SafeLoadLibrary(u"uxtheme.dll"_q); + const auto loaded = base::Platform::SafeLoadLibrary(L"uxtheme.dll"); base::Platform::LoadMethod(loaded, "SetWindowTheme", result); return result; }(); From 7577f063a6c6075dcee5556de9e1f96d07b2a12d Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 30 Jun 2021 18:21:15 +0300 Subject: [PATCH 03/14] Allow settings ANGLE backends. --- ui/gl/gl_detection.cpp | 78 ++++++++++++++++++++++++++++++++++++++++-- ui/gl/gl_detection.h | 16 +++++++++ ui/integration.cpp | 16 ++++----- ui/integration.h | 6 ++-- 4 files changed, 100 insertions(+), 16 deletions(-) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 7ee5767..8adfe4e 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -10,6 +10,7 @@ #include "base/debug_log.h" #include +#include #include #include #include @@ -22,6 +23,16 @@ namespace { bool ForceDisabled/* = false*/; +ANGLE ResolvedANGLE = ANGLE::Auto; + +void CrashCheckStart() { + auto f = QFile(Integration::Instance().openglCheckFilePath()); + if (f.open(QIODevice::WriteOnly)) { + f.write("1", 1); + f.close(); + } +} + } // namespace Capabilities CheckCapabilities(QWidget *widget) { @@ -47,9 +58,9 @@ Capabilities CheckCapabilities(QWidget *widget) { auto tester = QOpenGLWidget(widget); tester.setFormat(format); - Ui::Integration::Instance().openglCheckStart(); + CrashCheckStart(); tester.grabFramebuffer(); // Force initialize(). - Ui::Integration::Instance().openglCheckFinish(); + CrashCheckFinish(); if (!tester.window()->windowHandle()) { tester.window()->createWinId(); @@ -123,8 +134,71 @@ Capabilities CheckCapabilities(QWidget *widget) { return result; } +bool LastCrashCheckFailed() { + return QFile::exists(Integration::Instance().openglCheckFilePath()); +} + +void CrashCheckFinish() { + QFile::remove(Integration::Instance().openglCheckFilePath()); +} + void ForceDisable(bool disable) { ForceDisabled = disable; } +#ifdef Q_OS_WIN + +void ConfigureANGLE() { + qunsetenv("DESKTOP_APP_QT_ANGLE_PLATFORM"); + const auto path = Ui::Integration::Instance().angleBackendFilePath(); + if (path.isEmpty()) { + return; + } + auto f = QFile(path); + if (!f.open(QIODevice::ReadOnly)) { + return; + } + auto bytes = f.read(32); + const auto check = [&](const char *backend, ANGLE angle) { + if (bytes.startsWith(backend)) { + ResolvedANGLE = angle; + qputenv("DESKTOP_APP_QT_ANGLE_PLATFORM", backend); + } + }; + check("d3d11on12", ANGLE::D3D11on12); + check("d3d11", ANGLE::D3D11); + check("d3d9", ANGLE::D3D9); + check("gl", ANGLE::OpenGL); + if (ResolvedANGLE == ANGLE::Auto) { + LOG(("ANGLE Warning: Unknown backend: %1" + ).arg(QString::fromUtf8(bytes))); + } +} + +void ChangeANGLE(ANGLE backend) { + const auto path = Ui::Integration::Instance().angleBackendFilePath(); + const auto write = [&](QByteArray backend) { + auto f = QFile(path); + if (!f.open(QIODevice::WriteOnly)) { + LOG(("ANGLE Warning: Could not write to %1.").arg(path)); + return; + } + f.write(backend); + }; + switch (backend) { + case ANGLE::Auto: QFile(path).remove(); break; + case ANGLE::D3D9: write("d3d9"); break; + case ANGLE::D3D11: write("d3d11"); break; + case ANGLE::D3D11on12: write("d3d11on12"); break; + case ANGLE::OpenGL: write("gl"); break; + default: Unexpected("ANGLE backend value."); + } +} + +ANGLE CurrentANGLE() { + return ResolvedANGLE; +} + +#endif // Q_OS_WIN + } // namespace Ui::GL diff --git a/ui/gl/gl_detection.h b/ui/gl/gl_detection.h index 9641fad..c50cab7 100644 --- a/ui/gl/gl_detection.h +++ b/ui/gl/gl_detection.h @@ -24,4 +24,20 @@ struct Capabilities { void ForceDisable(bool disable); +[[nodiscard]] bool LastCrashCheckFailed(); +void CrashCheckFinish(); + +// Windows only. +enum class ANGLE { + Auto, + D3D9, + D3D11, + D3D11on12, + OpenGL, +}; + +void ConfigureANGLE(); // Requires Ui::Integration being set. +void ChangeANGLE(ANGLE backend); +[[nodiscard]] ANGLE CurrentANGLE(); + } // namespace Ui::GL diff --git a/ui/integration.cpp b/ui/integration.cpp index f7879f0..999140b 100644 --- a/ui/integration.cpp +++ b/ui/integration.cpp @@ -6,8 +6,10 @@ // #include "ui/integration.h" +#include "ui/gl/gl_detection.h" #include "ui/text/text_entity.h" #include "ui/basic_click_handlers.h" +#include "base/platform/base_platform_info.h" namespace Ui { namespace { @@ -18,6 +20,10 @@ Integration *IntegrationInstance = nullptr; void Integration::Set(not_null instance) { IntegrationInstance = instance; + + if constexpr (Platform::IsWindows()) { + GL::ConfigureANGLE(); + } } Integration &Integration::Instance() { @@ -30,16 +36,6 @@ bool Integration::Exists() { return (IntegrationInstance != nullptr); } -void Integration::openglCheckStart() { -} - -void Integration::openglCheckFinish() { -} - -bool Integration::openglLastCheckFailed() { - return false; -} - void Integration::textActionsUpdated() { } diff --git a/ui/integration.h b/ui/integration.h index 955ea72..cd7704b 100644 --- a/ui/integration.h +++ b/ui/integration.h @@ -35,11 +35,9 @@ public: virtual void registerLeaveSubscription(not_null widget) = 0; virtual void unregisterLeaveSubscription(not_null widget) = 0; - virtual void openglCheckStart(); - virtual void openglCheckFinish(); - [[nodiscard]] virtual bool openglLastCheckFailed(); - [[nodiscard]] virtual QString emojiCacheFolder() = 0; + [[nodiscard]] virtual QString openglCheckFilePath() = 0; + [[nodiscard]] virtual QString angleBackendFilePath() = 0; virtual void textActionsUpdated(); virtual void activationFromTopPanel(); From ac97c608c851cb3099aa98332354c179b4821e39 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 1 Jul 2021 10:45:42 +0300 Subject: [PATCH 04/14] Fix D3D11on12 backend choosing. --- ui/gl/gl_detection.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 8adfe4e..9cfef26 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -165,10 +165,10 @@ void ConfigureANGLE() { qputenv("DESKTOP_APP_QT_ANGLE_PLATFORM", backend); } }; - check("d3d11on12", ANGLE::D3D11on12); - check("d3d11", ANGLE::D3D11); - check("d3d9", ANGLE::D3D9); check("gl", ANGLE::OpenGL); + check("d3d9", ANGLE::D3D9); + check("d3d11", ANGLE::D3D11); + check("d3d11on12", ANGLE::D3D11on12); if (ResolvedANGLE == ANGLE::Auto) { LOG(("ANGLE Warning: Unknown backend: %1" ).arg(QString::fromUtf8(bytes))); From 3b3413e618864a9b1bec40911ca713f68726b177 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 2 Jul 2021 00:37:17 +0300 Subject: [PATCH 05/14] Try disabling native child OpenGL workaround. --- ui/gl/gl_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/gl/gl_window.cpp b/ui/gl/gl_window.cpp index 7c51cfc..2cc0f86 100644 --- a/ui/gl/gl_window.cpp +++ b/ui/gl/gl_window.cpp @@ -22,7 +22,7 @@ namespace Ui::GL { namespace { -constexpr auto kUseNativeChild = ::Platform::IsWindows(); +constexpr auto kUseNativeChild = false;// ::Platform::IsWindows(); } // namespace From baf4d80867e719a6fc0ae0cefd192ce061c3b879 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 2 Jul 2021 17:57:13 +0300 Subject: [PATCH 06/14] Add Ui::PathShiftGradient effect. --- CMakeLists.txt | 2 + ui/effects/path_shift_gradient.cpp | 175 +++++++++++++++++++++++++++++ ui/effects/path_shift_gradient.h | 64 +++++++++++ 3 files changed, 241 insertions(+) create mode 100644 ui/effects/path_shift_gradient.cpp create mode 100644 ui/effects/path_shift_gradient.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a22f9e..55310c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,8 @@ PRIVATE ui/effects/numbers_animation.h ui/effects/panel_animation.cpp ui/effects/panel_animation.h + ui/effects/path_shift_gradient.cpp + ui/effects/path_shift_gradient.h ui/effects/radial_animation.cpp ui/effects/radial_animation.h ui/effects/ripple_animation.cpp diff --git a/ui/effects/path_shift_gradient.cpp b/ui/effects/path_shift_gradient.cpp new file mode 100644 index 0000000..7e7c4cb --- /dev/null +++ b/ui/effects/path_shift_gradient.cpp @@ -0,0 +1,175 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/effects/path_shift_gradient.h" + +#include "base/call_delayed.h" +#include "ui/effects/animations.h" + +namespace Ui { +namespace { + +constexpr auto kSlideDuration = crl::time(1000); +constexpr auto kWaitDuration = crl::time(1000); +constexpr auto kFullDuration = kSlideDuration + kWaitDuration; + +} // namespace + +struct PathShiftGradient::AnimationData { + Ui::Animations::Simple animation; + base::flat_set> active; + bool scheduled = false; +}; + +std::weak_ptr PathShiftGradient::Animation; + +PathShiftGradient::PathShiftGradient( + const style::color &bg, + const style::color &fg, + Fn animationCallback) +: _bg(bg) +, _fg(fg) +, _animationCallback(std::move(animationCallback)) { + refreshColors(); + style::PaletteChanged( + ) | rpl::start_with_next([=] { + refreshColors(); + }, _lifetime); +} + +PathShiftGradient::~PathShiftGradient() { + if (const auto strong = _animation.get()) { + strong->active.erase(this); + } +} + +void PathShiftGradient::overrideColors( + const style::color &bg, + const style::color &fg) { + _colorsOverriden = true; + refreshColors(bg, fg); +} + +void PathShiftGradient::clearOverridenColors() { + if (!_colorsOverriden) { + return; + } + _colorsOverriden = false; + refreshColors(); +} + +void PathShiftGradient::startFrame( + int viewportLeft, + int viewportWidth, + int gradientWidth) { + _viewportLeft = viewportLeft; + _viewportWidth = viewportWidth; + _gradientWidth = gradientWidth; + _geometryUpdated = false; +} + +void PathShiftGradient::updateGeometry() { + if (_geometryUpdated) { + return; + } + _geometryUpdated = true; + const auto now = crl::now(); + const auto period = now % kFullDuration; + if (period >= kSlideDuration) { + _gradientEnabled = false; + return; + } + const auto progress = period / float64(kSlideDuration); + _gradientStart = anim::interpolate( + _viewportLeft - _gradientWidth, + _viewportLeft + _viewportWidth, + progress); + _gradientFinalStop = _gradientStart + _gradientWidth; + _gradientEnabled = true; +} + +bool PathShiftGradient::paint(Fn painter) { + updateGeometry(); + if (_gradientEnabled) { + _gradient.setStart(_gradientStart, 0); + _gradient.setFinalStop(_gradientFinalStop, 0); + } + const auto background = _gradientEnabled + ? Background(&_gradient) + : _bgOverride + ? *_bgOverride + : _bg; + if (!painter(background)) { + return false; + } + activateAnimation(); + return true; +} + +void PathShiftGradient::activateAnimation() { + if (_animationActive) { + return; + } + _animationActive = true; + if (!_animation) { + _animation = Animation.lock(); + if (!_animation) { + _animation = std::make_shared(); + Animation = _animation; + } + } + const auto raw = _animation.get(); + if (_animationCallback) { + raw->active.emplace(this); + } + + const auto globalCallback = [] { + const auto strong = Animation.lock(); + if (!strong) { + return; + } + strong->scheduled = false; + while (!strong->active.empty()) { + const auto entry = strong->active.back(); + strong->active.erase(strong->active.end() - 1); + entry->_animationActive = false; + entry->_animationCallback(); + } + }; + + const auto now = crl::now(); + const auto period = now % kFullDuration; + if (period >= kSlideDuration) { + const auto tillWaitFinish = kFullDuration - period; + if (!raw->scheduled) { + raw->scheduled = true; + raw->animation.stop(); + base::call_delayed(tillWaitFinish, globalCallback); + } + } else { + const auto tillSlideFinish = kSlideDuration - period; + if (!raw->animation.animating()) { + raw->animation.start(globalCallback, 0., 1., tillSlideFinish); + } + } +} + +void PathShiftGradient::refreshColors() { + refreshColors(_bg, _fg); +} + +void PathShiftGradient::refreshColors( + const style::color &bg, + const style::color &fg) { + _gradient.setStops({ + { 0., bg->c }, + { 0.5, fg->c }, + { 1., bg->c }, + }); + _bgOverride = _colorsOverriden ? &bg : nullptr; +} + +} // namespace Ui diff --git a/ui/effects/path_shift_gradient.h b/ui/effects/path_shift_gradient.h new file mode 100644 index 0000000..db44ba3 --- /dev/null +++ b/ui/effects/path_shift_gradient.h @@ -0,0 +1,64 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + +#include "ui/style/style_core_types.h" + +#include + +namespace Ui { + +class PathShiftGradient final { +public: + PathShiftGradient( + const style::color &bg, + const style::color &fg, + Fn animationCallback); + ~PathShiftGradient(); + + void startFrame( + int viewportLeft, + int viewportWidth, + int gradientWidth); + + void overrideColors(const style::color &bg, const style::color &fg); + void clearOverridenColors(); + + using Background = std::variant; + bool paint(Fn painter); + +private: + struct AnimationData; + + void refreshColors(); + void refreshColors(const style::color &bg, const style::color &fg); + void updateGeometry(); + void activateAnimation(); + + static std::weak_ptr Animation; + + const style::color &_bg; + const style::color &_fg; + const style::color *_bgOverride = nullptr; + QLinearGradient _gradient; + std::shared_ptr _animation; + const Fn _animationCallback; + int _viewportLeft = 0; + int _viewportWidth = 0; + int _gradientWidth = 0; + int _gradientStart = 0; + int _gradientFinalStop = 0; + bool _gradientEnabled = false; + bool _geometryUpdated = false; + bool _animationActive = false; + bool _colorsOverriden = false; + + rpl::lifetime _lifetime; + +}; + +} // namespace Ui From 8c7ebd89f6e68210ce9d2c368348a150b5e6242e Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 17 Feb 2021 08:50:16 +0300 Subject: [PATCH 07/14] Added ability to pass custom layer widgets to stack. --- ui/layers/layer_widget.cpp | 91 +++++++++++++++++++++----------------- ui/layers/layer_widget.h | 20 +++++---- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/ui/layers/layer_widget.cpp b/ui/layers/layer_widget.cpp index c0ffe93..5eb99f7 100644 --- a/ui/layers/layer_widget.cpp +++ b/ui/layers/layer_widget.cpp @@ -652,37 +652,6 @@ void LayerStackWidget::resizeEvent(QResizeEvent *e) { updateLayerBoxes(); } -void LayerStackWidget::showBox( - object_ptr box, - LayerOptions options, - anim::type animated) { - if (options & LayerOption::KeepOther) { - if (options & LayerOption::ShowAfterOther) { - prependBox(std::move(box), animated); - } else { - appendBox(std::move(box), animated); - } - } else { - replaceBox(std::move(box), animated); - } -} - -void LayerStackWidget::replaceBox( - object_ptr box, - anim::type animated) { - const auto pointer = pushBox(std::move(box), animated); - const auto removeTill = ranges::find( - _layers, - pointer, - &std::unique_ptr::get); - _closingLayers.insert( - end(_closingLayers), - std::make_move_iterator(begin(_layers)), - std::make_move_iterator(removeTill)); - _layers.erase(begin(_layers), removeTill); - clearClosingLayers(); -} - void LayerStackWidget::prepareForAnimation() { if (isHidden()) { show(); @@ -789,14 +758,33 @@ void LayerStackWidget::showMainMenu( }, Action::ShowMainMenu, animated); } -void LayerStackWidget::appendBox( +void LayerStackWidget::showBox( object_ptr box, + LayerOptions options, anim::type animated) { - pushBox(std::move(box), animated); + showLayer( + std::make_unique(this, std::move(box)), + options, + animated); } -LayerWidget *LayerStackWidget::pushBox( - object_ptr box, +void LayerStackWidget::showLayer( + std::unique_ptr layer, + LayerOptions options, + anim::type animated) { + if (options & LayerOption::KeepOther) { + if (options & LayerOption::ShowAfterOther) { + prependLayer(std::move(layer), animated); + } else { + appendLayer(std::move(layer), animated); + } + } else { + replaceLayer(std::move(layer), animated); + } +} + +LayerWidget *LayerStackWidget::pushLayer( + std::unique_ptr layer, anim::type animated) { const auto oldLayer = currentLayer(); if (oldLayer) { @@ -805,8 +793,7 @@ LayerWidget *LayerStackWidget::pushBox( } oldLayer->hide(); } - _layers.push_back( - std::make_unique(this, std::move(box))); + _layers.push_back(std::move(layer)); const auto raw = _layers.back().get(); initChildLayer(raw); @@ -824,21 +811,43 @@ LayerWidget *LayerStackWidget::pushBox( return raw; } -void LayerStackWidget::prependBox( - object_ptr box, +void LayerStackWidget::appendLayer( + std::unique_ptr layer, + anim::type animated) { + pushLayer(std::move(layer), animated); +} + +void LayerStackWidget::prependLayer( + std::unique_ptr layer, anim::type animated) { if (_layers.empty()) { - replaceBox(std::move(box), animated); + replaceLayer(std::move(layer), animated); return; } _layers.insert( begin(_layers), - std::make_unique(this, std::move(box))); + std::move(layer)); const auto raw = _layers.front().get(); raw->hide(); initChildLayer(raw); } +void LayerStackWidget::replaceLayer( + std::unique_ptr layer, + anim::type animated) { + const auto pointer = pushLayer(std::move(layer), animated); + const auto removeTill = ranges::find( + _layers, + pointer, + &std::unique_ptr::get); + _closingLayers.insert( + end(_closingLayers), + std::make_move_iterator(begin(_layers)), + std::make_move_iterator(removeTill)); + _layers.erase(begin(_layers), removeTill); + clearClosingLayers(); +} + bool LayerStackWidget::takeToThirdSection() { return _specialLayer ? _specialLayer->takeToThirdSection() diff --git a/ui/layers/layer_widget.h b/ui/layers/layer_widget.h index f673678..f45f16e 100644 --- a/ui/layers/layer_widget.h +++ b/ui/layers/layer_widget.h @@ -111,6 +111,10 @@ public: object_ptr box, LayerOptions options, anim::type animated); + void showLayer( + std::unique_ptr layer, + LayerOptions options, + anim::type animated); void showSpecialLayer( object_ptr layer, anim::type animated); @@ -149,19 +153,19 @@ protected: void resizeEvent(QResizeEvent *e) override; private: - void appendBox( - object_ptr box, + void appendLayer( + std::unique_ptr layer, anim::type animated); - void prependBox( - object_ptr box, + void prependLayer( + std::unique_ptr layer, anim::type animated); - void replaceBox( - object_ptr box, + void replaceLayer( + std::unique_ptr layer, anim::type animated); void backgroundClicked(); - LayerWidget *pushBox( - object_ptr box, + LayerWidget *pushLayer( + std::unique_ptr layer, anim::type animated); void showFinished(); void hideCurrent(anim::type animated); From eee528500bcac588e95b78e991f05ab36d7656fc Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 24 Feb 2021 11:05:36 +0300 Subject: [PATCH 08/14] Added color for handle circle in photo editor. --- ui/colors.palette | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/colors.palette b/ui/colors.palette index c0863bb..72db887 100644 --- a/ui/colors.palette +++ b/ui/colors.palette @@ -640,3 +640,5 @@ sideBarBadgeBgMuted: #8393a3; // filters side bar unimportant badge background sideBarBadgeFg: #ffffff; // filters side bar badge text songCoverOverlayFg: #00000066; // song cover overlay + +photoEditorItemBaseHandleFg: #3ccaef; // photo editor handle circle From 3b4dfc26f9850b3ecc7c90ed8f7eb6e4e49c0981 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 5 May 2021 00:31:26 +0300 Subject: [PATCH 09/14] Added background color in photo editor. --- ui/colors.palette | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/colors.palette b/ui/colors.palette index 72db887..cc892dd 100644 --- a/ui/colors.palette +++ b/ui/colors.palette @@ -641,4 +641,5 @@ sideBarBadgeFg: #ffffff; // filters side bar badge text songCoverOverlayFg: #00000066; // song cover overlay +photoEditorBg: boxTitleAdditionalFg; // photo editor background photoEditorItemBaseHandleFg: #3ccaef; // photo editor handle circle From b0c950b02aa7eb06e4f46f592bcf43ebc44efe82 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Mon, 12 Jul 2021 10:35:03 +0400 Subject: [PATCH 10/14] Fix -Wunused-function warnings --- ui/widgets/input_fields.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index f35ce56..ad71419 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -163,29 +163,6 @@ bool IsNewline(QChar ch) { return !CheckFullTextTag(textWithTags, tag).isEmpty(); } -QString GetFullSimpleTextTag(const TextWithTags &textWithTags) { - const auto &text = textWithTags.text; - const auto &tags = textWithTags.tags; - const auto tag = (tags.size() == 1) ? tags[0] : TextWithTags::Tag(); - auto from = 0; - auto till = int(text.size()); - for (; from != till; ++from) { - if (!IsNewline(text[from]) && !Text::IsSpace(text[from])) { - break; - } - } - while (till != from) { - if (!IsNewline(text[till - 1]) && !Text::IsSpace(text[till - 1])) { - break; - } - --till; - } - return ((tag.offset <= from) - && (tag.offset + tag.length >= till)) - ? (tag.id == kTagPre ? kTagCode : tag.id) - : QString(); -} - class TagAccumulator { public: TagAccumulator(TextWithTags::Tags &tags) : _tags(tags) { From f0c474c6aef064a084fe567428076edd458b1e8d Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Mon, 12 Jul 2021 00:13:55 +0400 Subject: [PATCH 11/14] Fix clang warnings Fixes -Wrange-loop-construct and -Wdeprecated-enum-enum-conversion --- ui/gl/gl_detection.cpp | 2 +- ui/widgets/input_fields.cpp | 2 +- ui/widgets/scroll_area.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 9cfef26..5843839 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -113,7 +113,7 @@ Capabilities CheckCapabilities(QWidget *widget) { functions->glGetString(GL_VERSION)); LOG(("OpenGL Version: %1").arg(version ? version : "[nullptr]")); auto list = QStringList(); - for (const auto extension : context->extensions()) { + for (const auto &extension : context->extensions()) { list.append(QString::fromLatin1(extension)); } LOG(("OpenGL Extensions: %1").arg(list.join(", "))); diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index ad71419..f15f7aa 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -1329,7 +1329,7 @@ InputField::InputField( _inner->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _inner->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - _inner->setFrameStyle(QFrame::NoFrame | QFrame::Plain); + _inner->setFrameStyle(int(QFrame::NoFrame) | QFrame::Plain); _inner->viewport()->setAutoFillBackground(false); _inner->setContentsMargins(0, 0, 0, 0); diff --git a/ui/widgets/scroll_area.cpp b/ui/widgets/scroll_area.cpp index 07082bf..8639388 100644 --- a/ui/widgets/scroll_area.cpp +++ b/ui/widgets/scroll_area.cpp @@ -292,7 +292,7 @@ ScrollArea::ScrollArea(QWidget *parent, const style::ScrollArea &st, bool handle setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setFrameStyle(QFrame::NoFrame | QFrame::Plain); + setFrameStyle(int(QFrame::NoFrame) | QFrame::Plain); viewport()->setAutoFillBackground(false); _horizontalValue = horizontalScrollBar()->value(); From b8485c0d8ab86cdeaf037477bcb2e09ece2cb3bd Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 13 Jul 2021 21:36:37 +0400 Subject: [PATCH 12/14] Fix -Wunused-variable warnings --- ui/effects/panel_animation.cpp | 3 --- ui/effects/radial_animation.cpp | 4 ---- ui/emoji_config.cpp | 2 ++ ui/gl/gl_detection.cpp | 6 ++++-- ui/image/image_prepare.cpp | 2 +- ui/layers/box_content.cpp | 1 - ui/platform/ui_platform_window.cpp | 1 - ui/style/style_core.cpp | 1 - ui/text/text.cpp | 1 - ui/text/text_block.cpp | 2 -- ui/text/text_entity.cpp | 4 +--- ui/toast/toast_widget.cpp | 1 - ui/widgets/checkbox.cpp | 1 - ui/widgets/inner_dropdown.cpp | 7 ------- ui/widgets/input_fields.cpp | 14 +++----------- ui/widgets/labels.cpp | 1 - 16 files changed, 11 insertions(+), 40 deletions(-) diff --git a/ui/effects/panel_animation.cpp b/ui/effects/panel_animation.cpp index 0ac70ef..9109599 100644 --- a/ui/effects/panel_animation.cpp +++ b/ui/effects/panel_animation.cpp @@ -416,7 +416,6 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float if (fadeTop != fadeBottom) { auto painterFadeTop = fadeTop / pixelRatio; auto painterFrameWidth = frameWidth / pixelRatio; - auto painterFrameHeight = frameHeight / pixelRatio; p.drawPixmap(painterFrameLeft, painterFadeTop, painterFrameWidth, painterFadeBottom - painterFadeTop, _fadeMask, 0, fadeSkipLines, pixelRatio, fadeBottom - fadeTop); } if (fadeBottom != frameBottom) { @@ -424,8 +423,6 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float } } } - auto frameInts = _frameInts + frameLeft + frameTop * _frameIntsPerLine; - auto frameIntsPerLineAdd = (_finalWidth - frameWidth) + _frameIntsPerLineAdded; // Draw corners paintCorner(_topLeft, frameLeft, frameTop); diff --git a/ui/effects/radial_animation.cpp b/ui/effects/radial_animation.cpp index 287f9b2..21e5a13 100644 --- a/ui/effects/radial_animation.cpp +++ b/ui/effects/radial_animation.cpp @@ -222,7 +222,6 @@ RadialState InfiniteRadialAnimation::computeState() { kFullArcLength }; } if (anim::Disabled()) { - const auto shown = 1.; return { 1., 0, kFullArcLength }; } const auto min = int(std::round(kFullArcLength * _st.arcMin)); @@ -245,9 +244,6 @@ RadialState InfiniteRadialAnimation::computeState() { const auto cycles = (now - _workStarted) / _st.sinePeriod; const auto relative = (now - _workStarted) % _st.sinePeriod; const auto smallDuration = _st.sineShift - _st.sineDuration; - const auto largeDuration = _st.sinePeriod - - _st.sineShift - - _st.sineDuration; const auto basic = int((linear + min + (cycles * (kFullArcLength + min - max))) % kFullArcLength); diff --git a/ui/emoji_config.cpp b/ui/emoji_config.cpp index 3d75700..6680854 100644 --- a/ui/emoji_config.cpp +++ b/ui/emoji_config.cpp @@ -35,7 +35,9 @@ constexpr auto kSetVersion = uint32(2); constexpr auto kCacheVersion = uint32(6); constexpr auto kMaxId = uint32(1 << 8); +#if defined Q_OS_MAC && !defined OS_MAC_OLD constexpr auto kScaleForTouchBar = 150; +#endif enum class ConfigResult { Invalid, diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 5843839..195f2bc 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -16,14 +16,16 @@ #include #include -#define LOG_ONCE(x) static auto logged = [&] { LOG(x); return true; }(); +#define LOG_ONCE(x) [[maybe_unused]] static auto logged = [&] { LOG(x); return true; }(); namespace Ui::GL { namespace { bool ForceDisabled/* = false*/; +#ifdef Q_OS_WIN ANGLE ResolvedANGLE = ANGLE::Auto; +#endif // Q_OS_WIN void CrashCheckStart() { auto f = QFile(Integration::Instance().openglCheckFilePath()); @@ -102,7 +104,7 @@ Capabilities CheckCapabilities(QWidget *widget) { LOG_ONCE(("OpenGL Profile: Compatibility.")); } break; } - static const auto extensionsLogged = [&] { + [[maybe_unused]] static const auto extensionsLogged = [&] { const auto renderer = reinterpret_cast( functions->glGetString(GL_RENDERER)); LOG(("OpenGL Renderer: %1").arg(renderer ? renderer : "[nullptr]")); diff --git a/ui/image/image_prepare.cpp b/ui/image/image_prepare.cpp index ea650d7..aaa4469 100644 --- a/ui/image/image_prepare.cpp +++ b/ui/image/image_prepare.cpp @@ -124,7 +124,7 @@ QImage prepareBlur(QImage img) { uchar *pix = img.bits(); if (pix) { - int w = img.width(), h = img.height(), wold = w, hold = h; + int w = img.width(), h = img.height(); const int radius = 3; const int r1 = radius + 1; const int div = radius * 2 + 1; diff --git a/ui/layers/box_content.cpp b/ui/layers/box_content.cpp index cd6a406..d27c19e 100644 --- a/ui/layers/box_content.cpp +++ b/ui/layers/box_content.cpp @@ -175,7 +175,6 @@ void BoxContent::setInnerTopSkip(int innerTopSkip, bool scrollBottomFixed) { void BoxContent::setInnerBottomSkip(int innerBottomSkip) { if (_innerBottomSkip != innerBottomSkip) { - auto delta = innerBottomSkip - _innerBottomSkip; _innerBottomSkip = innerBottomSkip; if (_scroll && width() > 0) { updateScrollAreaGeometry(); diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 5eef4af..42949a3 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -115,7 +115,6 @@ void BasicWindowHelper::setupBodyTitleAreaEvents() { == Qt::LeftButton)) { _mousePressed = true; } else if (e->type() == QEvent::MouseMove) { - const auto mouseEvent = static_cast(e.get()); if (_mousePressed #ifndef Q_OS_WIN // We handle fullscreen startSystemMove() only on Windows. && !_window->isFullScreen() diff --git a/ui/style/style_core.cpp b/ui/style/style_core.cpp index 2a68082..9914e50 100644 --- a/ui/style/style_core.cpp +++ b/ui/style/style_core.cpp @@ -97,7 +97,6 @@ void colorizeImage(const QImage &src, QColor c, QImage *outResult, QRect srcRect auto pattern = anim::shifted(c); - auto resultBytesPerPixel = (src.depth() >> 3); constexpr auto resultIntsPerPixel = 1; auto resultIntsPerLine = (outResult->bytesPerLine() >> 2); auto resultIntsAdded = resultIntsPerLine - width * resultIntsPerPixel; diff --git a/ui/text/text.cpp b/ui/text/text.cpp index 2f07c5c..fa2d582 100644 --- a/ui/text/text.cpp +++ b/ui/text/text.cpp @@ -79,7 +79,6 @@ TextWithEntities PrepareRichFromRich( int32 i = 0, l = preparsed.size(); result.entities.clear(); result.entities.reserve(l); - const QChar s = result.text.size(); for (; i < l; ++i) { auto type = preparsed.at(i).type(); if (((type == EntityType::Mention || type == EntityType::MentionName) && !parseMentions) || diff --git a/ui/text/text_block.cpp b/ui/text/text_block.cpp index b07c14b..bc34603 100644 --- a/ui/text/text_block.cpp +++ b/ui/text/text_block.cpp @@ -222,8 +222,6 @@ void BlockParser::parseWords(QFixed minResizeWidth, int blockFrom) { int item = -1; int newItem = eng->findItem(0); - style::align alignment = eng->option.alignment(); - const QCharAttributes *attributes = eng->attributes(); if (!attributes) return; diff --git a/ui/text/text_entity.cpp b/ui/text/text_entity.cpp index b183ac8..467add2 100644 --- a/ui/text/text_entity.cpp +++ b/ui/text/text_entity.cpp @@ -1315,7 +1315,7 @@ QString EscapeForRichParsing(const QString &text) { QString SingleLine(const QString &text) { auto result = text; - auto s = text.unicode(), ch = s, e = text.unicode() + text.size(); + auto s = text.unicode(), e = text.unicode() + text.size(); // Trim. while (s < e && IsTrimmed(*s)) { @@ -1405,7 +1405,6 @@ QStringList PrepareSearchWords( ? *SplitterOverride : RegExpWordSplit(), base::QStringSkipEmptyParts); - auto size = list.size(); result.reserve(list.size()); for (const auto &word : std::as_const(list)) { auto trimmed = word.trimmed(); @@ -2196,7 +2195,6 @@ EntitiesInText ConvertTextTagsToEntities(const TextWithTags::Tags &tags) { } return result; }; - auto till = offset; for (const auto &tag : tags) { if (tag.offset > offset) { processState(State()); diff --git a/ui/toast/toast_widget.cpp b/ui/toast/toast_widget.cpp index 3f8f2a0..0081af7 100644 --- a/ui/toast/toast_widget.cpp +++ b/ui/toast/toast_widget.cpp @@ -165,7 +165,6 @@ void Widget::mouseMoveEvent(QMouseEvent *e) { } const auto point = e->pos() - QPoint(_st->padding.left(), _textTop); - const auto lines = _maxTextHeight / _st->style.font->height; const auto state = _text.getStateElided(point, _textWidth + 1); const auto was = ClickHandler::getActive(); if (was != state.link) { diff --git a/ui/widgets/checkbox.cpp b/ui/widgets/checkbox.cpp index 29014e9..e75482b 100644 --- a/ui/widgets/checkbox.cpp +++ b/ui/widgets/checkbox.cpp @@ -564,7 +564,6 @@ void Checkbox::paintEvent(QPaintEvent *e) { Painter p(this); auto check = checkRect(); - auto ms = crl::now(); auto active = _check->currentAnimationValue(); if (isDisabled()) { p.setOpacity(_st.disabledOpacity); diff --git a/ui/widgets/inner_dropdown.cpp b/ui/widgets/inner_dropdown.cpp index 98f40f5..1edff2a 100644 --- a/ui/widgets/inner_dropdown.cpp +++ b/ui/widgets/inner_dropdown.cpp @@ -12,13 +12,6 @@ #include "ui/image/image_prepare.h" #include "ui/ui_utility.h" -namespace { - -constexpr float64 kFadeHeight = 1. / 3; -constexpr int kFadeAlphaMax = 160; - -} // namespace - namespace Ui { InnerDropdown::InnerDropdown( diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index f15f7aa..2dd8674 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -108,7 +108,6 @@ bool IsNewline(QChar ch) { auto resultLink = QString(); const auto checkingLink = (tag == kTagCheckLinkMeta); const auto &text = textWithTags.text; - const auto &tags = textWithTags.tags; auto from = 0; auto till = int(text.size()); const auto adjust = [&] { @@ -1038,8 +1037,7 @@ void FlatInput::touchEvent(QTouchEvent *e) { if (!_touchPress) return; auto weak = MakeWeak(this); if (!_touchMove && window()) { - Qt::MouseButton btn(_touchRightButton ? Qt::RightButton : Qt::LeftButton); - QPoint mapped(mapFromGlobal(_touchStart)), winMapped(window()->mapFromGlobal(_touchStart)); + QPoint mapped(mapFromGlobal(_touchStart)); if (_touchRightButton) { QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart); @@ -1077,7 +1075,6 @@ void FlatInput::finishAnimations() { void FlatInput::paintEvent(QPaintEvent *e) { Painter p(this); - auto ms = crl::now(); auto placeholderFocused = _placeholderFocusedAnimation.value(_focused ? 1. : 0.); auto pen = anim::pen(_st.borderColor, _st.borderActive, placeholderFocused); pen.setWidth(_st.borderWidth); @@ -1650,8 +1647,7 @@ void InputField::handleTouchEvent(QTouchEvent *e) { if (!_touchPress) return; auto weak = MakeWeak(this); if (!_touchMove && window()) { - Qt::MouseButton btn(_touchRightButton ? Qt::RightButton : Qt::LeftButton); - QPoint mapped(mapFromGlobal(_touchStart)), winMapped(window()->mapFromGlobal(_touchStart)); + QPoint mapped(mapFromGlobal(_touchStart)); if (_touchRightButton) { QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart); @@ -2280,9 +2276,6 @@ void InputField::onDocumentContentsChange( ? _realCharsAdded : charsAdded; - const auto removePosition = position; - const auto removeLength = charsRemoved; - _correcting = true; QTextCursor(document->docHandle(), 0).joinPreviousEditBlock(); const auto guard = gsl::finally([&] { @@ -3855,8 +3848,7 @@ void MaskedInputField::touchEvent(QTouchEvent *e) { if (!_touchPress) return; auto weak = MakeWeak(this); if (!_touchMove && window()) { - Qt::MouseButton btn(_touchRightButton ? Qt::RightButton : Qt::LeftButton); - QPoint mapped(mapFromGlobal(_touchStart)), winMapped(window()->mapFromGlobal(_touchStart)); + QPoint mapped(mapFromGlobal(_touchStart)); if (_touchRightButton) { QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart); diff --git a/ui/widgets/labels.cpp b/ui/widgets/labels.cpp index d64d859..ec388b5 100644 --- a/ui/widgets/labels.cpp +++ b/ui/widgets/labels.cpp @@ -551,7 +551,6 @@ bool FlatLabel::eventHook(QEvent *e) { } void FlatLabel::touchEvent(QTouchEvent *e) { - const Qt::TouchPointStates &states(e->touchPointStates()); if (e->type() == QEvent::TouchCancel) { // cancel if (!_touchInProgress) return; _touchInProgress = false; From 9c552215ab54e5372ef54b1b324d0505a1b19315 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 12 Jul 2021 18:42:52 +0300 Subject: [PATCH 13/14] Added ability to pass animation type to SlideWrap. --- ui/wrap/slide_wrap.cpp | 7 ++++--- ui/wrap/slide_wrap.h | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ui/wrap/slide_wrap.cpp b/ui/wrap/slide_wrap.cpp index cfc8f4c..8075c5b 100644 --- a/ui/wrap/slide_wrap.cpp +++ b/ui/wrap/slide_wrap.cpp @@ -80,11 +80,12 @@ SlideWrap *SlideWrap::finishAnimating() { } SlideWrap *SlideWrap::toggleOn( - rpl::producer &&shown) { + rpl::producer &&shown, + anim::type animated) { std::move( shown - ) | rpl::start_with_next([this](bool shown) { - toggle(shown, anim::type::normal); + ) | rpl::start_with_next([=](bool shown) { + toggle(shown, animated); }, lifetime()); finishAnimating(); return this; diff --git a/ui/wrap/slide_wrap.h b/ui/wrap/slide_wrap.h index 32d4475..d972d7f 100644 --- a/ui/wrap/slide_wrap.h +++ b/ui/wrap/slide_wrap.h @@ -39,7 +39,9 @@ public: return toggle(false, animated); } SlideWrap *finishAnimating(); - SlideWrap *toggleOn(rpl::producer &&shown); + SlideWrap *toggleOn( + rpl::producer &&shown, + anim::type animated = anim::type::normal); bool animating() const { return _animation.animating(); @@ -104,8 +106,10 @@ public: SlideWrap *finishAnimating() { return chain(Parent::finishAnimating()); } - SlideWrap *toggleOn(rpl::producer &&shown) { - return chain(Parent::toggleOn(std::move(shown))); + SlideWrap *toggleOn( + rpl::producer &&shown, + anim::type animated = anim::type::normal) { + return chain(Parent::toggleOn(std::move(shown), animated)); } private: From ed6c2cb5414b74013d98a365211f68401d27a286 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 14 Jul 2021 20:03:22 +0300 Subject: [PATCH 14/14] Use GL_BGRA_EXT format with ANGLE. --- ui/gl/gl_image.cpp | 6 +++--- ui/gl/gl_image.h | 8 ++++++++ ui/gl/gl_primitives.h | 1 - ui/gl/gl_shader.cpp | 5 ++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ui/gl/gl_image.cpp b/ui/gl/gl_image.cpp index 1d5a7fe..633d108 100644 --- a/ui/gl/gl_image.cpp +++ b/ui/gl/gl_image.cpp @@ -91,11 +91,11 @@ void Image::bind(QOpenGLFunctions &f) { f.glTexImage2D( GL_TEXTURE_2D, 0, - GL_RGBA, + kFormatRGBA, _subimage.width(), _subimage.height(), 0, - GL_RGBA, + kFormatRGBA, GL_UNSIGNED_BYTE, _image.constBits()); } else { @@ -106,7 +106,7 @@ void Image::bind(QOpenGLFunctions &f) { 0, _subimage.width(), _subimage.height(), - GL_RGBA, + kFormatRGBA, GL_UNSIGNED_BYTE, _image.constBits()); } diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index a54ec9e..fe8fd3e 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -136,4 +136,12 @@ private: [[nodiscard]] GLint CurrentSingleComponentFormat(); +#ifdef Q_OS_WIN +inline constexpr auto kFormatRGBA = GL_BGRA_EXT; +inline constexpr auto kSwizzleRedBlue = false; +#else // Q_OS_WIN +inline constexpr auto kFormatRGBA = GL_RGBA; +inline constexpr auto kSwizzleRedBlue = true; +#endif // Q_OS_WIN + } // namespace Ui::GL diff --git a/ui/gl/gl_primitives.h b/ui/gl/gl_primitives.h index bfd13bc..1988ffe 100644 --- a/ui/gl/gl_primitives.h +++ b/ui/gl/gl_primitives.h @@ -25,7 +25,6 @@ void FillTriangles( const QColor &color, Fn additional = nullptr); - void FillRectangle( QOpenGLFunctions &f, not_null program, diff --git a/ui/gl/gl_shader.cpp b/ui/gl/gl_shader.cpp index bf51d05..3079a52 100644 --- a/ui/gl/gl_shader.cpp +++ b/ui/gl/gl_shader.cpp @@ -6,6 +6,7 @@ // #include "ui/gl/gl_shader.h" +#include "ui/gl/gl_image.h" #include "base/debug_log.h" #include @@ -72,8 +73,10 @@ uniform sampler2D s_texture; )", .body = R"( result = texture2D(s_texture, v_texcoord); +)" + (kSwizzleRedBlue + ? R"( result = vec4(result.b, result.g, result.r, result.a); -)", +)" : QString()), }; }