Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ void AnimationBackend::commitUpdates(

void AnimationBackend::synchronouslyUpdateProps(
const std::unordered_map<Tag, AnimatedProps>& updates) {
if (ReactNativeFeatureFlags::optimizedAnimatedPropUpdates()) {
if (auto uiManager = uiManager_.lock()) {
uiManager->synchronouslyUpdateAnimatedProps(updates);
}
return;
}
for (auto& [tag, animatedProps] : updates) {
// TODO: We shouldn't repack it into dynamic, but for that a rewrite
// of synchronouslyUpdateViewOnUIThread is needed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ void Scheduler::uiManagerShouldSynchronouslyUpdateViewOnUIThread(
}
}

void Scheduler::uiManagerShouldSynchronouslyUpdateAnimatedProps(
const std::unordered_map<Tag, AnimatedProps>& updates) {
if (delegate_ != nullptr) {
delegate_->schedulerShouldSynchronouslyUpdateAnimatedProps(updates);
}
}

void Scheduler::uiManagerDidUpdateShadowTree(
const std::unordered_map<Tag, folly::dynamic>& tagToProps) {
if (delegate_ != nullptr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class Scheduler final : public UIManagerDelegate {
bool isJSResponder,
bool blockNativeResponder) override;
void uiManagerShouldSynchronouslyUpdateViewOnUIThread(Tag tag, const folly::dynamic &props) override;
void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<Tag, AnimatedProps> &updates) override;
void uiManagerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic> &tagToProps) override;
void uiManagerDidCaptureViewSnapshot(Tag tag, SurfaceId surfaceId) override;
void uiManagerDidSetViewSnapshot(Tag sourceTag, Tag targetTag, SurfaceId surfaceId) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <memory>

#include <react/renderer/animationbackend/AnimatedPropsSerializer.h>
#include <react/renderer/core/ReactPrimitives.h>
#include <react/renderer/mounting/MountingCoordinator.h>
#include <react/renderer/mounting/ShadowView.h>
Expand Down Expand Up @@ -66,6 +67,13 @@ class SchedulerDelegate {

virtual void schedulerShouldSynchronouslyUpdateViewOnUIThread(Tag tag, const folly::dynamic &props) = 0;

virtual void schedulerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<Tag, AnimatedProps> &updates)
{
for (const auto &[tag, props] : updates) {
schedulerShouldSynchronouslyUpdateViewOnUIThread(tag, animationbackend::packAnimatedProps(props));
}
}

virtual void schedulerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic> &tagToProps) = 0;

// View transition bitmap snapshot capture and application.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <ReactCommon/RuntimeExecutor.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
#include <react/renderer/animationbackend/AnimatedPropsBuilder.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/root/RootComponentDescriptor.h>
#include <react/renderer/components/root/RootProps.h>
Expand Down Expand Up @@ -588,4 +589,36 @@ TEST_F(
EXPECT_EQ(delegate_->shouldRenderTransactionsCount(), 1);
}

TEST(SchedulerDelegateTest, animatedPropsUseExistingViewUpdatesByDefault) {
class PropsDelegate : public RecordingDelegate {
public:
std::unordered_map<Tag, folly::dynamic> received;

void schedulerShouldSynchronouslyUpdateViewOnUIThread(
Tag tag,
const folly::dynamic& props) override {
received.emplace(tag, props);
}
} delegate;

std::unordered_map<Tag, AnimatedProps> updates;
updates.emplace(
10,
AnimatedProps{
{},
std::make_unique<RawProps>(folly::dynamic::object("opacity", 0.25))});
AnimatedPropsBuilder builder;
builder.setOpacity(0.75);
updates.emplace(20, builder.get());

delegate.schedulerShouldSynchronouslyUpdateAnimatedProps(updates);

ASSERT_EQ(delegate.received.size(), 2);
folly::dynamic expectedRaw = folly::dynamic::object("opacity", 0.25);
folly::dynamic expectedTyped = folly::dynamic::object("opacity", 0.75);
EXPECT_EQ(delegate.received.at(10), expectedRaw);
EXPECT_EQ(delegate.received.at(20), expectedTyped);
EXPECT_EQ(updates.at(10).rawProps->toDynamic(), delegate.received.at(10));
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,13 @@ void UIManager::synchronouslyUpdateViewOnUIThread(
}
}

void UIManager::synchronouslyUpdateAnimatedProps(
const std::unordered_map<Tag, AnimatedProps>& updates) {
if (delegate_ != nullptr) {
delegate_->uiManagerShouldSynchronouslyUpdateAnimatedProps(updates);
}
}

#pragma mark ContextContainer

std::shared_ptr<const ContextContainer> UIManager::getContextContainer() const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class UIManager final : public ShadowTreeDelegate {

void synchronouslyUpdateViewOnUIThread(Tag tag, const folly::dynamic &props);

void synchronouslyUpdateAnimatedProps(const std::unordered_map<Tag, AnimatedProps> &updates);

/*
* Provides access to a UIManagerBinding.
* The `callback` methods will not be called if the internal pointer to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

namespace facebook::react {

struct AnimatedProps;

/*
* Abstract class for UIManager's delegate.
*/
Expand Down Expand Up @@ -71,6 +73,12 @@ class UIManagerDelegate {
*/
virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(Tag tag, const folly::dynamic &props) = 0;

/*
* Synchronous update of animated props for many views at once.
*/
virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(
const std::unordered_map<Tag, AnimatedProps> &updates) = 0;

/*
* Called after updateShadowTree is invoked.
*/
Expand Down
4 changes: 4 additions & 0 deletions scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -4618,6 +4618,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) final;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) override;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) final;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) override;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) override;
public void addEventListener(std::shared_ptr<const facebook::react::EventListener> listener);
public void animationTick() const;
Expand All @@ -4641,6 +4642,7 @@ class facebook::react::SchedulerDelegate {
public virtual void schedulerDidUpdateShadowTree(const std::unordered_map<facebook::react::Tag, folly::dynamic>& tagToProps) = 0;
public virtual void schedulerShouldMergeReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerShouldRenderTransactions(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public virtual void schedulerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~SchedulerDelegate() noexcept = default;
}
Expand Down Expand Up @@ -5372,6 +5374,7 @@ class facebook::react::UIManager : public facebook::react::ShadowTreeDelegate {
public void startEmptySurface(facebook::react::ShadowTree::Unique&& shadowTree) const noexcept;
public void startSurface(facebook::react::ShadowTree::Unique&& shadowTree, std::string moduleName, folly::dynamic props, facebook::react::DisplayMode displayMode) const noexcept;
public void stopSurfaceForAnimationDelegate(facebook::react::SurfaceId surfaceId) const;
public void synchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public void synchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props);
public void unregisterCommitHook(facebook::react::UIManagerCommitHook& commitHook);
public void unregisterMountHook(facebook::react::UIManagerMountHook& mountHook);
Expand Down Expand Up @@ -5439,6 +5442,7 @@ class facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) = 0;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) = 0;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~UIManagerDelegate() noexcept = default;
}
Expand Down
4 changes: 4 additions & 0 deletions scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -4434,6 +4434,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) final;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) override;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) final;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) override;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) override;
public void addEventListener(std::shared_ptr<const facebook::react::EventListener> listener);
public void animationTick() const;
Expand All @@ -4457,6 +4458,7 @@ class facebook::react::SchedulerDelegate {
public virtual void schedulerDidUpdateShadowTree(const std::unordered_map<facebook::react::Tag, folly::dynamic>& tagToProps) = 0;
public virtual void schedulerShouldMergeReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerShouldRenderTransactions(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public virtual void schedulerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~SchedulerDelegate() noexcept = default;
}
Expand Down Expand Up @@ -5182,6 +5184,7 @@ class facebook::react::UIManager : public facebook::react::ShadowTreeDelegate {
public void startEmptySurface(facebook::react::ShadowTree::Unique&& shadowTree) const noexcept;
public void startSurface(facebook::react::ShadowTree::Unique&& shadowTree, std::string moduleName, folly::dynamic props, facebook::react::DisplayMode displayMode) const noexcept;
public void stopSurfaceForAnimationDelegate(facebook::react::SurfaceId surfaceId) const;
public void synchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public void synchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props);
public void unregisterCommitHook(facebook::react::UIManagerCommitHook& commitHook);
public void unregisterMountHook(facebook::react::UIManagerMountHook& mountHook);
Expand Down Expand Up @@ -5249,6 +5252,7 @@ class facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) = 0;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) = 0;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~UIManagerDelegate() noexcept = default;
}
Expand Down
4 changes: 4 additions & 0 deletions scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -4615,6 +4615,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) final;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) override;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) final;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) override;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) override;
public void addEventListener(std::shared_ptr<const facebook::react::EventListener> listener);
public void animationTick() const;
Expand All @@ -4638,6 +4639,7 @@ class facebook::react::SchedulerDelegate {
public virtual void schedulerDidUpdateShadowTree(const std::unordered_map<facebook::react::Tag, folly::dynamic>& tagToProps) = 0;
public virtual void schedulerShouldMergeReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerShouldRenderTransactions(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public virtual void schedulerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~SchedulerDelegate() noexcept = default;
}
Expand Down Expand Up @@ -5363,6 +5365,7 @@ class facebook::react::UIManager : public facebook::react::ShadowTreeDelegate {
public void startEmptySurface(facebook::react::ShadowTree::Unique&& shadowTree) const noexcept;
public void startSurface(facebook::react::ShadowTree::Unique&& shadowTree, std::string moduleName, folly::dynamic props, facebook::react::DisplayMode displayMode) const noexcept;
public void stopSurfaceForAnimationDelegate(facebook::react::SurfaceId surfaceId) const;
public void synchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public void synchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props);
public void unregisterCommitHook(facebook::react::UIManagerCommitHook& commitHook);
public void unregisterMountHook(facebook::react::UIManagerMountHook& mountHook);
Expand Down Expand Up @@ -5430,6 +5433,7 @@ class facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) = 0;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) = 0;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~UIManagerDelegate() noexcept = default;
}
Expand Down
4 changes: 4 additions & 0 deletions scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -6767,6 +6767,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) final;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) override;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) final;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) override;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) override;
public void addEventListener(std::shared_ptr<const facebook::react::EventListener> listener);
public void animationTick() const;
Expand All @@ -6790,6 +6791,7 @@ class facebook::react::SchedulerDelegate {
public virtual void schedulerDidUpdateShadowTree(const std::unordered_map<facebook::react::Tag, folly::dynamic>& tagToProps) = 0;
public virtual void schedulerShouldMergeReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerShouldRenderTransactions(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public virtual void schedulerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~SchedulerDelegate() noexcept = default;
}
Expand Down Expand Up @@ -7502,6 +7504,7 @@ class facebook::react::UIManager : public facebook::react::ShadowTreeDelegate {
public void startEmptySurface(facebook::react::ShadowTree::Unique&& shadowTree) const noexcept;
public void startSurface(facebook::react::ShadowTree::Unique&& shadowTree, std::string moduleName, folly::dynamic props, facebook::react::DisplayMode displayMode) const noexcept;
public void stopSurfaceForAnimationDelegate(facebook::react::SurfaceId surfaceId) const;
public void synchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates);
public void synchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props);
public void unregisterCommitHook(facebook::react::UIManagerCommitHook& commitHook);
public void unregisterMountHook(facebook::react::UIManagerMountHook& mountHook);
Expand Down Expand Up @@ -7569,6 +7572,7 @@ class facebook::react::UIManagerDelegate {
public virtual void uiManagerShouldAddEventListener(std::shared_ptr<const facebook::react::EventListener> listener) = 0;
public virtual void uiManagerShouldAddOnSurfaceStartCallback(facebook::react::UIManagerDelegate::OnSurfaceStartCallback&& callback) = 0;
public virtual void uiManagerShouldRemoveEventListener(const std::shared_ptr<const facebook::react::EventListener>& listener) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateAnimatedProps(const std::unordered_map<facebook::react::Tag, facebook::react::AnimatedProps>& updates) = 0;
public virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag, const folly::dynamic& props) = 0;
public virtual ~UIManagerDelegate() noexcept = default;
}
Expand Down
Loading
Loading