Fix stickers lagging on macOS.

This commit is contained in:
John Preston 2019-05-28 13:39:38 +02:00
parent ab16c88473
commit ff0ff1d99c
9 changed files with 56 additions and 22 deletions

View File

@ -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

View File

@ -85,7 +85,7 @@ std::unique_ptr<Animation> 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<SharedState> 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 } });
}

View File

@ -50,16 +50,20 @@ public:
crl::time markFrameDisplayed(crl::time now);
crl::time markFrameShown();
void checkNextFrame();
void checkStep();
private:
void parseDone(std::unique_ptr<SharedState> 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<FrameRenderer> _renderer;
rpl::event_stream<Update, Error> _updates;

View File

@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Lottie {
constexpr auto kTimeUnknown = std::numeric_limits<crl::time>::min();
class Animation;
struct PlaybackOptions {

View File

@ -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);

View File

@ -22,8 +22,6 @@ class QImage;
namespace Lottie {
constexpr auto kTimeUnknown = std::numeric_limits<crl::time>::min();
class Animation;
class JsonObject;

View File

@ -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([=] {

View File

@ -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([=] {

@ -1 +1 @@
Subproject commit 84072fba75f14620935e5e91788ce603daeb1988
Subproject commit d259aebc11df52cb6ff8c738580dc4d8f245d681