diff --git a/Telegram/SourceFiles/core/sandbox.cpp b/Telegram/SourceFiles/core/sandbox.cpp index 1cef35347..73c2a6290 100644 --- a/Telegram/SourceFiles/core/sandbox.cpp +++ b/Telegram/SourceFiles/core/sandbox.cpp @@ -598,3 +598,11 @@ void Sandbox::execExternal(const QString &cmd) { } } // namespace Core + +namespace crl { + +rpl::producer<> on_main_update_requests() { + return Core::Sandbox::Instance().widgetUpdateRequests(); +} + +} // namespace crl diff --git a/Telegram/SourceFiles/lottie/lottie_animation.cpp b/Telegram/SourceFiles/lottie/lottie_animation.cpp index f7de59c21..1f833651d 100644 --- a/Telegram/SourceFiles/lottie/lottie_animation.cpp +++ b/Telegram/SourceFiles/lottie/lottie_animation.cpp @@ -85,7 +85,7 @@ std::unique_ptr FromData(const QByteArray &data) { } Animation::Animation(QByteArray &&content) -: _timer([=] { checkNextFrame(); }) { +: _timer([=] { checkNextFrameRender(); }) { const auto weak = base::make_weak(this); crl::async([=, content = base::take(content)]() mutable { content = UnpackGzip(content); @@ -130,13 +130,18 @@ void Animation::parseDone(std::unique_ptr state) { || information.framesCount <= 0 || information.size.isEmpty()) { _updates.fire_error(Error::NotSupported); - } else { - _state = state.get(); - _state->start(this, crl::now()); - _renderer = FrameRenderer::Instance(); - _renderer->append(std::move(state)); - _updates.fire({ std::move(information) }); + return; } + _state = state.get(); + _state->start(this, crl::now()); + _renderer = FrameRenderer::Instance(); + _renderer->append(std::move(state)); + _updates.fire({ std::move(information) }); + + crl::on_main_update_requests( + ) | rpl::start_with_next([=] { + checkStep(); + }, _lifetime); } void Animation::parseFailed() { @@ -181,20 +186,35 @@ crl::time Animation::markFrameShown() { return result; } -void Animation::checkNextFrame() { +void Animation::checkStep() { + if (_nextFrameTime != kTimeUnknown) { + checkNextFrameRender(); + } else { + checkNextFrameAvailability(); + } +} + +void Animation::checkNextFrameAvailability() { Expects(_renderer != nullptr); - const auto time = _state->nextFrameDisplayTime(); - if (time == kTimeUnknown) { - return; + _nextFrameTime = _state->nextFrameDisplayTime(); + if (_nextFrameTime != kTimeUnknown) { + checkStep(); } +} + +void Animation::checkNextFrameRender() { + Expects(_nextFrameTime != kTimeUnknown); const auto now = crl::now(); - if (time > now) { - _timer.callOnce(time - now); + if (now < _nextFrameTime) { + if (!_timer.isActive()) { + _timer.callOnce(_nextFrameTime - now); + } } else { _timer.cancel(); + _nextFrameTime = kTimeUnknown; const auto position = markFrameDisplayed(now); _updates.fire({ DisplayFrameRequest{ position } }); } diff --git a/Telegram/SourceFiles/lottie/lottie_animation.h b/Telegram/SourceFiles/lottie/lottie_animation.h index 686f0fad1..5dd194001 100644 --- a/Telegram/SourceFiles/lottie/lottie_animation.h +++ b/Telegram/SourceFiles/lottie/lottie_animation.h @@ -50,16 +50,20 @@ public: crl::time markFrameDisplayed(crl::time now); crl::time markFrameShown(); - void checkNextFrame(); + void checkStep(); private: void parseDone(std::unique_ptr state); void parseFailed(); + void checkNextFrameAvailability(); + void checkNextFrameRender(); + //crl::time _started = 0; //PlaybackOptions _options; base::Timer _timer; + crl::time _nextFrameTime = kTimeUnknown; SharedState *_state = nullptr; std::shared_ptr _renderer; rpl::event_stream _updates; diff --git a/Telegram/SourceFiles/lottie/lottie_common.h b/Telegram/SourceFiles/lottie/lottie_common.h index be003fd10..5e593af47 100644 --- a/Telegram/SourceFiles/lottie/lottie_common.h +++ b/Telegram/SourceFiles/lottie/lottie_common.h @@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Lottie { +constexpr auto kTimeUnknown = std::numeric_limits::min(); + class Animation; struct PlaybackOptions { diff --git a/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp b/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp index ccf34b0b7..3cc1a61f9 100644 --- a/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp +++ b/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp @@ -279,7 +279,7 @@ bool SharedState::renderNextFrame(const FrameRequest &request) { (counter + 1) % (2 * kFramesCount), std::memory_order_release); crl::on_main(_owner, [=] { - _owner->checkNextFrame(); + _owner->checkStep(); }); return true; }; @@ -340,6 +340,10 @@ crl::time SharedState::nextFrameDisplayTime() const { const auto next = (counter + 1) % (2 * kFramesCount); const auto index = next / 2; const auto frame = getFrame(index); + if (frame->displayed != kTimeUnknown) { + // Frame already displayed, but not yet shown. + return kTimeUnknown; + } Assert(IsRendered(frame)); Assert(frame->display != kTimeUnknown); diff --git a/Telegram/SourceFiles/lottie/lottie_frame_renderer.h b/Telegram/SourceFiles/lottie/lottie_frame_renderer.h index 454739aad..c55255990 100644 --- a/Telegram/SourceFiles/lottie/lottie_frame_renderer.h +++ b/Telegram/SourceFiles/lottie/lottie_frame_renderer.h @@ -22,8 +22,6 @@ class QImage; namespace Lottie { -constexpr auto kTimeUnknown = std::numeric_limits::min(); - class Animation; class JsonObject; diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp index bc1da6a70..5bfa16010 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp @@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/streaming/media_streaming_video_track.h" #include "media/audio/media_audio.h" // for SupportsSpeedControl() #include "data/data_document.h" // for DocumentData::duration() -#include "core/sandbox.h" // for widgetUpdateRequests() producer namespace Media { namespace Streaming { @@ -658,7 +657,7 @@ void Player::start() { } }, _sessionLifetime); - Core::Sandbox::Instance().widgetUpdateRequests( + crl::on_main_update_requests( ) | rpl::filter([=] { return !_videoFinished; }) | rpl::start_with_next([=] { diff --git a/Telegram/SourceFiles/ui/effects/animations.cpp b/Telegram/SourceFiles/ui/effects/animations.cpp index 20193d0f6..738bf799f 100644 --- a/Telegram/SourceFiles/ui/effects/animations.cpp +++ b/Telegram/SourceFiles/ui/effects/animations.cpp @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/animations.h" #include "core/application.h" -#include "core/sandbox.h" namespace Ui { namespace Animations { @@ -52,7 +51,7 @@ void Basic::markStopped() { } Manager::Manager() { - Core::Sandbox::Instance().widgetUpdateRequests( + crl::on_main_update_requests( ) | rpl::filter([=] { return (_lastUpdateTime + kIgnoreUpdatesTimeout < crl::now()); }) | rpl::start_with_next([=] { diff --git a/Telegram/ThirdParty/crl b/Telegram/ThirdParty/crl index 84072fba7..d259aebc1 160000 --- a/Telegram/ThirdParty/crl +++ b/Telegram/ThirdParty/crl @@ -1 +1 @@ -Subproject commit 84072fba75f14620935e5e91788ce603daeb1988 +Subproject commit d259aebc11df52cb6ff8c738580dc4d8f245d681