diff --git a/React/Fabric/RCTScheduler.mm b/React/Fabric/RCTScheduler.mm index 5e41dbf902b..60752913c55 100644 --- a/React/Fabric/RCTScheduler.mm +++ b/React/Fabric/RCTScheduler.mm @@ -24,7 +24,7 @@ public: SchedulerDelegateProxy(void *scheduler): scheduler_(scheduler) {} - void schedulerDidFinishTransaction(Tag rootTag, const ShadowViewMutationList &mutations) override { + void schedulerDidFinishTransaction(Tag rootTag, const ShadowViewMutationList &mutations, const long commitStartTime, const long layoutTime) override { RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_; [scheduler.delegate schedulerDidFinishTransaction:mutations rootTag:rootTag]; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 9c3edd31faa..b92269c973b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -6,18 +6,33 @@ */ package com.facebook.react.fabric; +import static com.facebook.infer.annotation.ThreadConfined.UI; import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getMaxSize; import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getMinSize; import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getYogaMeasureMode; import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getYogaSize; -import static com.facebook.infer.annotation.ThreadConfined.UI; import static com.facebook.react.uimanager.common.UIManagerType.FABRIC; import android.annotation.SuppressLint; +import android.os.SystemClock; import android.support.annotation.GuardedBy; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import com.facebook.common.logging.FLog; +import com.facebook.infer.annotation.Assertions; +import com.facebook.infer.annotation.ThreadConfined; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.GuardedRunnable; +import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.NativeMap; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableNativeMap; +import com.facebook.react.bridge.UIManager; +import com.facebook.react.bridge.UiThreadUtil; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.common.ReactConstants; import com.facebook.react.fabric.jsi.Binding; import com.facebook.react.fabric.jsi.EventBeatManager; import com.facebook.react.fabric.jsi.EventEmitterWrapper; @@ -35,20 +50,6 @@ import com.facebook.react.fabric.mounting.mountitems.UpdateEventEmitterMountItem import com.facebook.react.fabric.mounting.mountitems.UpdateLayoutMountItem; import com.facebook.react.fabric.mounting.mountitems.UpdateLocalDataMountItem; import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem; -import com.facebook.infer.annotation.Assertions; -import com.facebook.infer.annotation.ThreadConfined; -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.bridge.GuardedRunnable; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.NativeMap; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableNativeMap; -import com.facebook.react.bridge.UIManager; -import com.facebook.react.bridge.UiThreadUtil; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.common.ReactConstants; import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.ReactRootViewTagGenerator; @@ -109,6 +110,13 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { @ThreadConfined(UI) private boolean mIsMountingEnabled = true; + private long mRunStartTime = 0l; + private long mBatchedExecutionTime = 0l; + private long mNonBatchedExecutionTime = 0l; + private long mDispatchViewUpdatesTime = 0l; + private long mCommitStartTime = 0l; + private long mLayoutTime = 0l; + private long mFinishTransactionTime = 0l; public FabricUIManager( ReactApplicationContext reactContext, @@ -268,7 +276,17 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { */ @DoNotStrip @SuppressWarnings("unused") - private void scheduleMountItems(final MountItem mountItems) { + private void scheduleMountItems( + final MountItem mountItems, + long commitStartTime, + long layoutTime, + long finishTransactionStartTime) { + + // TODO T31905686: support multithreading + mCommitStartTime = commitStartTime; + mLayoutTime = layoutTime; + mFinishTransactionTime = SystemClock.uptimeMillis() - finishTransactionStartTime; + mDispatchViewUpdatesTime = SystemClock.uptimeMillis(); synchronized (mMountItemsLock) { mMountItems.add(mountItems); } @@ -294,26 +312,32 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { mPreMountItems = new ArrayList<>(); } + mRunStartTime = SystemClock.uptimeMillis(); List mountItemsToDispatch; synchronized (mMountItemsLock) { mountItemsToDispatch = mMountItems; mMountItems = new ArrayList<>(); } + long nonBatchedExecutionStartTime = SystemClock.uptimeMillis(); Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricUIManager::premountViews (" + preMountItemsToDispatch.size() + " batches)"); for (MountItem mountItem : preMountItemsToDispatch) { mountItem.execute(mMountingManager); } + mNonBatchedExecutionTime = SystemClock.uptimeMillis() - nonBatchedExecutionStartTime; Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricUIManager::mountViews (" + mountItemsToDispatch.size() + " batches)"); + + long batchedExecutionStartTime = SystemClock.uptimeMillis(); for (MountItem mountItem : mountItemsToDispatch) { mountItem.execute(mMountingManager); } + mBatchedExecutionTime = SystemClock.uptimeMillis() - batchedExecutionStartTime; Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); } catch (Exception ex) { FLog.e(ReactConstants.TAG, "Exception thrown when executing UIFrameGuarded", ex); @@ -379,7 +403,9 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { @Override public void dispatchCommand( final int reactTag, final int commandId, final ReadableArray commandArgs) { - scheduleMountItems(new DispatchCommandMountItem(reactTag, commandId, commandArgs)); + synchronized (mMountItemsLock) { + mMountItems.add(new DispatchCommandMountItem(reactTag, commandId, commandArgs)); + } } @Override @@ -394,12 +420,20 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { @Override public void profileNextBatch() { - // do nothing for now. + // TODO T31905686: Remove this method and add support for multi-threading performance counters } @Override public Map getPerformanceCounters() { - return new HashMap<>(); + HashMap performanceCounters = new HashMap<>(); + performanceCounters.put("CommitStartTime", mCommitStartTime); + performanceCounters.put("LayoutTime", mLayoutTime); + performanceCounters.put("DispatchViewUpdatesTime", mDispatchViewUpdatesTime); + performanceCounters.put("RunStartTime", mRunStartTime); + performanceCounters.put("BatchedExecutionTime", mBatchedExecutionTime); + performanceCounters.put("NonBatchedExecutionTime", mNonBatchedExecutionTime); + performanceCounters.put("FinishFabricTransactionTime", mFinishTransactionTime); + return performanceCounters; } private class DispatchUIFrameCallback extends GuardedFrameCallback { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp index d972f987330..77ec29f2744 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp @@ -20,6 +20,7 @@ #include #include #include +#include using namespace facebook::jni; using namespace facebook::jsi; @@ -249,12 +250,15 @@ local_ref createDeleteMountItem(const jni::global_ref> queue; // Upper bound estimation of mount items to be delivered to Java side. int size = mutations.size() * 3 + 42; + long finishTransactionStartTime = getTime(); + + local_ref> mountItemsArray = JArrayClass::newArray(size); auto mountItems = *(mountItemsArray); @@ -341,9 +345,9 @@ void Binding::schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewM static auto scheduleMountItems = jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod("scheduleMountItems"); + ->getMethod("scheduleMountItems"); - scheduleMountItems(javaUIManager_, batch.get()); + scheduleMountItems(javaUIManager_, batch.get(), commitStartTime, layoutTime, finishTransactionStartTime); } void Binding::setPixelDensity(float pointScaleFactor) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h index 1d854196ce4..4b967952e6b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h @@ -46,7 +46,7 @@ private: void stopSurface(jint surfaceId); - void schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewMutationList &mutations); + void schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewMutationList &mutations, const long commitStartTime, const long layoutTime); void schedulerDidRequestPreliminaryViewAllocation(const SurfaceId surfaceId, const ComponentName componentName, bool isLayoutable, const ComponentHandle componentHandle); diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index e3377c10a24..478fecc90a5 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -85,6 +86,7 @@ void Scheduler::startSurface( void Scheduler::renderTemplateToSurface( SurfaceId surfaceId, const std::string &uiTemplate) { + long commitStartTime = getTime(); try { if (uiTemplate.size() == 0) { return; @@ -106,7 +108,8 @@ void Scheduler::renderTemplateToSurface( ShadowNodeFragment{.children = std::make_shared( SharedShadowNodeList{tree})}); - }); + }, + commitStartTime); }); } catch (const std::exception &e) { LOG(ERROR) << " >>>> EXCEPTION <<< rendering uiTemplate in " @@ -115,16 +118,20 @@ void Scheduler::renderTemplateToSurface( } void Scheduler::stopSurface(SurfaceId surfaceId) const { - shadowTreeRegistry_.visit(surfaceId, [](const ShadowTree &shadowTree) { - // As part of stopping the Surface, we have to commit an empty tree. - return shadowTree.tryCommit( - [&](const SharedRootShadowNode &oldRootShadowNode) { - return std::make_shared( - *oldRootShadowNode, - ShadowNodeFragment{ - .children = ShadowNode::emptySharedShadowNodeSharedList()}); - }); - }); + long commitStartTime = getTime(); + shadowTreeRegistry_.visit( + surfaceId, [commitStartTime](const ShadowTree &shadowTree) { + // As part of stopping the Surface, we have to commit an empty tree. + return shadowTree.tryCommit( + [&](const SharedRootShadowNode &oldRootShadowNode) { + return std::make_shared( + *oldRootShadowNode, + ShadowNodeFragment{ + .children = + ShadowNode::emptySharedShadowNodeSharedList()}); + }, + commitStartTime); + }); auto shadowTree = shadowTreeRegistry_.remove(surfaceId); shadowTree->setDelegate(nullptr); @@ -140,15 +147,19 @@ Size Scheduler::measureSurface( SurfaceId surfaceId, const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const { + long commitStartTime = getTime(); + Size size; shadowTreeRegistry_.visit(surfaceId, [&](const ShadowTree &shadowTree) { - shadowTree.tryCommit([&](const SharedRootShadowNode &oldRootShadowNode) { - auto rootShadowNode = - oldRootShadowNode->clone(layoutConstraints, layoutContext); - rootShadowNode->layout(); - size = rootShadowNode->getLayoutMetrics().frame.size; - return nullptr; - }); + shadowTree.tryCommit( + [&](const SharedRootShadowNode &oldRootShadowNode) { + auto rootShadowNode = + oldRootShadowNode->clone(layoutConstraints, layoutContext); + rootShadowNode->layout(); + size = rootShadowNode->getLayoutMetrics().frame.size; + return nullptr; + }, + commitStartTime); }); return size; } @@ -157,10 +168,14 @@ void Scheduler::constraintSurfaceLayout( SurfaceId surfaceId, const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const { + long commitStartTime = getTime(); + shadowTreeRegistry_.visit(surfaceId, [&](const ShadowTree &shadowTree) { - shadowTree.commit([&](const SharedRootShadowNode &oldRootShadowNode) { - return oldRootShadowNode->clone(layoutConstraints, layoutContext); - }); + shadowTree.commit( + [&](const SharedRootShadowNode &oldRootShadowNode) { + return oldRootShadowNode->clone(layoutConstraints, layoutContext); + }, + commitStartTime); }); } @@ -178,10 +193,12 @@ SchedulerDelegate *Scheduler::getDelegate() const { void Scheduler::shadowTreeDidCommit( const ShadowTree &shadowTree, - const ShadowViewMutationList &mutations) const { + const ShadowViewMutationList &mutations, + long commitStartTime, + long layoutTime) const { if (delegate_) { delegate_->schedulerDidFinishTransaction( - shadowTree.getSurfaceId(), mutations); + shadowTree.getSurfaceId(), mutations, commitStartTime, layoutTime); } } @@ -189,12 +206,16 @@ void Scheduler::shadowTreeDidCommit( void Scheduler::uiManagerDidFinishTransaction( SurfaceId surfaceId, - const SharedShadowNodeUnsharedList &rootChildNodes) { + const SharedShadowNodeUnsharedList &rootChildNodes, + long startCommitTime) { shadowTreeRegistry_.visit(surfaceId, [&](const ShadowTree &shadowTree) { - shadowTree.commit([&](const SharedRootShadowNode &oldRootShadowNode) { - return std::make_shared( - *oldRootShadowNode, ShadowNodeFragment{.children = rootChildNodes}); - }); + shadowTree.commit( + [&](const SharedRootShadowNode &oldRootShadowNode) { + return std::make_shared( + *oldRootShadowNode, + ShadowNodeFragment{.children = rootChildNodes}); + }, + startCommitTime); }); } diff --git a/ReactCommon/fabric/uimanager/Scheduler.h b/ReactCommon/fabric/uimanager/Scheduler.h index 839b88f5b14..1d2bc10f63b 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.h +++ b/ReactCommon/fabric/uimanager/Scheduler.h @@ -81,7 +81,8 @@ class Scheduler final : public UIManagerDelegate, public ShadowTreeDelegate { void uiManagerDidFinishTransaction( SurfaceId surfaceId, - const SharedShadowNodeUnsharedList &rootChildNodes) override; + const SharedShadowNodeUnsharedList &rootChildNodes, + long startCommitTime) override; void uiManagerDidCreateShadowNode( const SharedShadowNode &shadowNode) override; @@ -89,7 +90,9 @@ class Scheduler final : public UIManagerDelegate, public ShadowTreeDelegate { void shadowTreeDidCommit( const ShadowTree &shadowTree, - const ShadowViewMutationList &mutations) const override; + const ShadowViewMutationList &mutations, + long commitStartTime, + long layoutTime) const override; private: SchedulerDelegate *delegate_; diff --git a/ReactCommon/fabric/uimanager/SchedulerDelegate.h b/ReactCommon/fabric/uimanager/SchedulerDelegate.h index 946e4eb6bc9..e62c31b7fa8 100644 --- a/ReactCommon/fabric/uimanager/SchedulerDelegate.h +++ b/ReactCommon/fabric/uimanager/SchedulerDelegate.h @@ -26,7 +26,9 @@ class SchedulerDelegate { */ virtual void schedulerDidFinishTransaction( Tag rootTag, - const ShadowViewMutationList &mutations) = 0; + const ShadowViewMutationList &mutations, + const long commitStartTime, + const long layoutTime) = 0; /* * Called right after a new ShadowNode was created. diff --git a/ReactCommon/fabric/uimanager/ShadowTree.cpp b/ReactCommon/fabric/uimanager/ShadowTree.cpp index 41309de87ef..d61207bda80 100644 --- a/ReactCommon/fabric/uimanager/ShadowTree.cpp +++ b/ReactCommon/fabric/uimanager/ShadowTree.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "ShadowTreeDelegate.h" @@ -96,25 +97,29 @@ ShadowTree::ShadowTree( } ShadowTree::~ShadowTree() { - commit([](const SharedRootShadowNode &oldRootShadowNode) { - return std::make_shared( - *oldRootShadowNode, - ShadowNodeFragment{.children = - ShadowNode::emptySharedShadowNodeSharedList()}); - }); + commit( + [](const SharedRootShadowNode &oldRootShadowNode) { + return std::make_shared( + *oldRootShadowNode, + ShadowNodeFragment{ + .children = ShadowNode::emptySharedShadowNodeSharedList()}); + }, + getTime()); } Tag ShadowTree::getSurfaceId() const { return surfaceId_; } -void ShadowTree::commit(ShadowTreeCommitTransaction transaction, int *revision) - const { +void ShadowTree::commit( + ShadowTreeCommitTransaction transaction, + long commitStartTime, + int *revision) const { int attempts = 0; while (true) { attempts++; - if (tryCommit(transaction, revision)) { + if (tryCommit(transaction, commitStartTime, revision)) { return; } @@ -126,6 +131,7 @@ void ShadowTree::commit(ShadowTreeCommitTransaction transaction, int *revision) bool ShadowTree::tryCommit( ShadowTreeCommitTransaction transaction, + long commitStartTime, int *revision) const { SharedRootShadowNode oldRootShadowNode; @@ -141,7 +147,9 @@ bool ShadowTree::tryCommit( return false; } + long layoutTime = getTime(); newRootShadowNode->layout(); + layoutTime = getTime() - layoutTime; newRootShadowNode->sealRecursive(); auto mutations = @@ -175,7 +183,8 @@ bool ShadowTree::tryCommit( emitLayoutEvents(mutations); if (delegate_) { - delegate_->shadowTreeDidCommit(*this, mutations); + delegate_->shadowTreeDidCommit( + *this, mutations, commitStartTime, layoutTime); } return true; diff --git a/ReactCommon/fabric/uimanager/ShadowTree.h b/ReactCommon/fabric/uimanager/ShadowTree.h index 38c39314c42..03e9de41173 100644 --- a/ReactCommon/fabric/uimanager/ShadowTree.h +++ b/ReactCommon/fabric/uimanager/ShadowTree.h @@ -52,13 +52,16 @@ class ShadowTree final { */ bool tryCommit( ShadowTreeCommitTransaction transaction, + long commitStartTime, int *revision = nullptr) const; /* * Calls `tryCommit` in a loop until it finishes successfully. */ - void commit(ShadowTreeCommitTransaction transaction, int *revision = nullptr) - const; + void commit( + ShadowTreeCommitTransaction transaction, + long commitStartTime, + int *revision = nullptr) const; #pragma mark - Delegate diff --git a/ReactCommon/fabric/uimanager/ShadowTreeDelegate.h b/ReactCommon/fabric/uimanager/ShadowTreeDelegate.h index c5a47ad6dcc..8ab9abf5d69 100644 --- a/ReactCommon/fabric/uimanager/ShadowTreeDelegate.h +++ b/ReactCommon/fabric/uimanager/ShadowTreeDelegate.h @@ -22,7 +22,9 @@ class ShadowTreeDelegate { */ virtual void shadowTreeDidCommit( const ShadowTree &shadowTree, - const ShadowViewMutationList &mutations) const = 0; + const ShadowViewMutationList &mutations, + long commitStartTime, + long layoutTime) const = 0; virtual ~ShadowTreeDelegate() noexcept = default; }; diff --git a/ReactCommon/fabric/uimanager/TimeUtils.h b/ReactCommon/fabric/uimanager/TimeUtils.h new file mode 100644 index 00000000000..7c7bc3fad51 --- /dev/null +++ b/ReactCommon/fabric/uimanager/TimeUtils.h @@ -0,0 +1,30 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#pragma once + +namespace facebook { +namespace react { + +inline static long getTime() { +#ifdef ANDROID + static const int64_t NANOSECONDS_IN_SECOND = 1000000000LL; + static const int64_t NANOSECONDS_IN_MILLISECOND = 1000000LL; + + // Since SystemClock.uptimeMillis() is commonly used for performance + // measurement in Java and uptimeMillis() internally uses + // clock_gettime(CLOCK_MONOTONIC), we use the same API here. We need that to + // make sure we use the same time system on both JS and Java sides. Links to + // the source code: + // https://android.googlesource.com/platform/frameworks/native/+/jb-mr1-release/libs/utils/SystemClock.cpp + // https://android.googlesource.com/platform/system/core/+/master/libutils/Timers.cpp + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + int64_t nano = now.tv_sec * NANOSECONDS_IN_SECOND + now.tv_nsec; + return nano / (double)NANOSECONDS_IN_MILLISECOND; +#else + return 0l; +#endif +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/uimanager/UIManager.cpp b/ReactCommon/fabric/uimanager/UIManager.cpp index 37e50bed4b6..49e77170039 100644 --- a/ReactCommon/fabric/uimanager/UIManager.cpp +++ b/ReactCommon/fabric/uimanager/UIManager.cpp @@ -3,6 +3,7 @@ #include "UIManager.h" #include +#include namespace facebook { namespace react { @@ -61,13 +62,15 @@ void UIManager::completeSurface( SurfaceId surfaceId, const SharedShadowNodeUnsharedList &rootChildren) const { if (delegate_) { - delegate_->uiManagerDidFinishTransaction(surfaceId, rootChildren); + delegate_->uiManagerDidFinishTransaction( + surfaceId, rootChildren, getTime()); } } void UIManager::setNativeProps( const SharedShadowNode &shadowNode, const RawProps &rawProps) const { + long startCommitTime = getTime(); auto &componentDescriptor = componentDescriptorRegistry_->at(shadowNode->getComponentHandle()); auto props = componentDescriptor.cloneProps(shadowNode->getProps(), rawProps); @@ -78,13 +81,15 @@ void UIManager::setNativeProps( shadowTree.tryCommit( [&](const SharedRootShadowNode &oldRootShadowNode) { return oldRootShadowNode->clone(shadowNode, newShadowNode); - }); + }, + startCommitTime); }); } LayoutMetrics UIManager::getRelativeLayoutMetrics( const ShadowNode &shadowNode, const ShadowNode *ancestorShadowNode) const { + long startCommitTime = getTime(); if (!ancestorShadowNode) { shadowTreeRegistry_->visit( shadowNode.getRootTag(), [&](const ShadowTree &shadowTree) { @@ -92,7 +97,8 @@ LayoutMetrics UIManager::getRelativeLayoutMetrics( [&](const SharedRootShadowNode &oldRootShadowNode) { ancestorShadowNode = oldRootShadowNode.get(); return nullptr; - }); + }, + startCommitTime); }); } diff --git a/ReactCommon/fabric/uimanager/UIManagerDelegate.h b/ReactCommon/fabric/uimanager/UIManagerDelegate.h index cd6b881615b..b2841b58c43 100644 --- a/ReactCommon/fabric/uimanager/UIManagerDelegate.h +++ b/ReactCommon/fabric/uimanager/UIManagerDelegate.h @@ -24,7 +24,8 @@ class UIManagerDelegate { */ virtual void uiManagerDidFinishTransaction( SurfaceId surfaceId, - const SharedShadowNodeUnsharedList &rootChildNodes) = 0; + const SharedShadowNodeUnsharedList &rootChildNodes, + long startCommitTime) = 0; /* * Called each time when UIManager constructs a new Shadow Node. Receiver