diff --git a/litho-core/src/main/java/com/facebook/litho/ComponentTree.java b/litho-core/src/main/java/com/facebook/litho/ComponentTree.java index c2e22e7dc9a..772708e7f0a 100644 --- a/litho-core/src/main/java/com/facebook/litho/ComponentTree.java +++ b/litho-core/src/main/java/com/facebook/litho/ComponentTree.java @@ -46,6 +46,9 @@ import static com.facebook.litho.debug.LithoDebugEventAttributes.Root; import static com.facebook.litho.debug.LithoDebugEventAttributes.RootId; import static com.facebook.litho.debug.LithoDebugEventAttributes.SizeSpecsMatch; +import static com.facebook.rendercore.debug.DebugEventDispatcher.beginTrace; +import static com.facebook.rendercore.debug.DebugEventDispatcher.endTrace; +import static com.facebook.rendercore.debug.DebugEventDispatcher.generateTraceIdentifier; import static com.facebook.rendercore.instrumentation.HandlerInstrumenter.instrumentHandler; import static com.facebook.rendercore.utils.MeasureSpecUtils.getMeasureSpecDescription; @@ -88,6 +91,7 @@ import com.facebook.rendercore.visibility.VisibilityBoundsTransformer; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -1262,8 +1266,21 @@ private void preAllocateMountContent(boolean shouldPreallocatePerMountSpec) { mContext, logger, logger.newPerformanceEvent(EVENT_PRE_ALLOCATE_MOUNT_CONTENT)) : null; + Integer traceIdentifier = + generateTraceIdentifier(LithoDebugEvent.ComponentTreeMountContentPreallocated); + if (traceIdentifier != null) { + beginTrace( + traceIdentifier, + LithoDebugEvent.ComponentTreeMountContentPreallocated, + String.valueOf(mId), + new HashMap<>()); + } + toPrePopulate.preAllocateMountContent(shouldPreallocatePerMountSpec); + if (traceIdentifier != null) { + endTrace(traceIdentifier); + } if (event != null) { logger.logPerfEvent(event); } @@ -2238,6 +2255,7 @@ private void doResolve( .getUseInterruptibleResolution() || mContext.mLithoConfiguration.mComponentsConfiguration .getUseCancelableLayoutFutures()); + ResolveTreeFuture treeFuture = new ResolveTreeFuture( context, @@ -2288,6 +2306,7 @@ && isFromSyncLayout(source) } commitResolveResult(resolveResult, isCreateLayoutInProgress); + ComponentsLogger logger = getLogger(); if (logger != null && resolvePerfEvent != null) { logger.logPerfEvent(resolvePerfEvent); diff --git a/litho-core/src/main/java/com/facebook/litho/ResolveTreeFuture.java b/litho-core/src/main/java/com/facebook/litho/ResolveTreeFuture.java index 2bdbeeac166..2a87fcf3fa5 100644 --- a/litho-core/src/main/java/com/facebook/litho/ResolveTreeFuture.java +++ b/litho-core/src/main/java/com/facebook/litho/ResolveTreeFuture.java @@ -18,12 +18,21 @@ import static android.content.Context.ACCESSIBILITY_SERVICE; import static com.facebook.litho.ComponentTree.SIZE_UNINITIALIZED; +import static com.facebook.litho.LayoutState.layoutSourceToString; +import static com.facebook.litho.debug.LithoDebugEventAttributes.Attribution; +import static com.facebook.litho.debug.LithoDebugEventAttributes.ResolveSource; +import static com.facebook.litho.debug.LithoDebugEventAttributes.ResolveVersion; +import static com.facebook.litho.debug.LithoDebugEventAttributes.Root; +import static com.facebook.litho.debug.LithoDebugEventAttributes.RunsOnMainThread; import android.util.Pair; import android.view.accessibility.AccessibilityManager; import androidx.annotation.Nullable; import com.facebook.litho.debug.DebugOverlay; +import com.facebook.litho.debug.LithoDebugEvent; import com.facebook.litho.stats.LithoStats; +import com.facebook.rendercore.debug.DebugEventDispatcher; +import java.util.HashMap; import java.util.List; public class ResolveTreeFuture extends TreeFuture { @@ -36,6 +45,8 @@ public class ResolveTreeFuture extends TreeFuture { private final int mResolveVersion; private final @Nullable String mExtraAttribution; + private int mSource; + static final String DESCRIPTION = "resolve"; // TODO(T137275959): Refactor sync render logic to remove sizes from resolved tree future @@ -98,20 +109,38 @@ public ResolveTreeFuture( mExtraAttribution = extraAttribution; mSyncWidthSpec = syncWidthSpec; mSyncHeightSpec = syncHeightSpec; + mSource = source; } @Override protected ResolveResult calculate() { - return resolve( - mComponentContext, - mComponent, - mTreeState, - mResolveVersion, - mComponentTreeId, - mCurrentRootNode, - mExtraAttribution, - this, - mPerfEvent); + Integer resolveTraceIdentifier = + DebugEventDispatcher.generateTraceIdentifier(LithoDebugEvent.ComponentTreeResolve); + + if (resolveTraceIdentifier != null) { + DebugEventDispatcher.beginTrace( + resolveTraceIdentifier, + LithoDebugEvent.ComponentTreeResolve, + String.valueOf(mComponentTreeId), + createDebugAttributes()); + } + + try { + return resolve( + mComponentContext, + mComponent, + mTreeState, + mResolveVersion, + mComponentTreeId, + mCurrentRootNode, + mExtraAttribution, + this, + mPerfEvent); + } finally { + if (resolveTraceIdentifier != null) { + DebugEventDispatcher.endTrace(resolveTraceIdentifier); + } + } } @Override @@ -126,7 +155,34 @@ public String getDescription() { @Override protected ResolveResult resumeCalculation(ResolveResult partialResult) { - return resume(partialResult, mExtraAttribution); + Integer resolveTraceIdentifier = + DebugEventDispatcher.generateTraceIdentifier(LithoDebugEvent.ComponentTreeResolveResumed); + + if (resolveTraceIdentifier != null) { + DebugEventDispatcher.beginTrace( + resolveTraceIdentifier, + LithoDebugEvent.ComponentTreeResolveResumed, + String.valueOf(mComponentTreeId), + createDebugAttributes()); + } + + try { + return resume(partialResult, mExtraAttribution); + } finally { + if (resolveTraceIdentifier != null) { + DebugEventDispatcher.endTrace(resolveTraceIdentifier); + } + } + } + + private HashMap createDebugAttributes() { + HashMap attributes = new HashMap<>(); + attributes.put(RunsOnMainThread, ThreadUtils.isMainThread()); + attributes.put(Root, mComponent.getSimpleName()); + attributes.put(ResolveVersion, mResolveVersion); + attributes.put(ResolveSource, layoutSourceToString(mSource)); + attributes.put(Attribution, mExtraAttribution); + return attributes; } @Override diff --git a/litho-core/src/main/java/com/facebook/litho/Resolver.java b/litho-core/src/main/java/com/facebook/litho/Resolver.java index 7e63275518b..ee72491e99d 100644 --- a/litho-core/src/main/java/com/facebook/litho/Resolver.java +++ b/litho-core/src/main/java/com/facebook/litho/Resolver.java @@ -17,6 +17,10 @@ package com.facebook.litho; import static com.facebook.litho.NodeInfo.ENABLED_UNSET; +import static com.facebook.litho.debug.LithoDebugEvent.ComponentPrepared; +import static com.facebook.rendercore.debug.DebugEventDispatcher.beginTrace; +import static com.facebook.rendercore.debug.DebugEventDispatcher.endTrace; +import static com.facebook.rendercore.debug.DebugEventDispatcher.generateTraceIdentifier; import androidx.annotation.IntDef; import androidx.annotation.Nullable; @@ -24,10 +28,13 @@ import androidx.core.util.Preconditions; import com.facebook.infer.annotation.Nullsafe; import com.facebook.litho.config.ComponentsConfiguration; +import com.facebook.litho.debug.LithoDebugEvent; +import com.facebook.litho.debug.LithoDebugEventAttributes; import com.facebook.rendercore.utils.MeasureSpecUtils; import com.facebook.yoga.YogaFlexDirection; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Set; @@ -155,6 +162,20 @@ public class Resolver { ComponentsSystrace.beginSection("create-node:" + component.getSimpleName()); } + Integer componentResolvedIdentifier = + generateTraceIdentifier(LithoDebugEvent.ComponentResolved); + if (componentResolvedIdentifier != null) { + HashMap attributes = new HashMap<>(); + attributes.put(LithoDebugEventAttributes.RunsOnMainThread, ThreadUtils.isMainThread()); + attributes.put(LithoDebugEventAttributes.Component, component.getSimpleName()); + + beginTrace( + componentResolvedIdentifier, + LithoDebugEvent.ComponentResolved, + String.valueOf(resolveStateContext.getTreeId()), + attributes); + } + ComponentsLogger componentsLogger = resolveStateContext.getComponentsLogger(); PerfEvent resolveLayoutCreationEvent = createPerformanceEvent( @@ -223,15 +244,34 @@ else if (Component.isMountSpec(component)) { createPerformanceEvent( component, componentsLogger, FrameworkLogEvents.EVENT_COMPONENT_PREPARE); + Integer componentPrepareTraceIdentifier = generateTraceIdentifier(ComponentPrepared); + if (componentPrepareTraceIdentifier != null) { + HashMap attributes = new HashMap<>(); + attributes.put(LithoDebugEventAttributes.RunsOnMainThread, ThreadUtils.isMainThread()); + attributes.put(LithoDebugEventAttributes.Component, component.getSimpleName()); + + beginTrace( + componentPrepareTraceIdentifier, + ComponentPrepared, + String.valueOf(resolveStateContext.getTreeId()), + attributes); + } + if (isTracing) { ComponentsSystrace.beginSection("prepare:" + component.getSimpleName()); } - PrepareResult prepareResult = - component.prepare(resolveStateContext, scopedComponentInfo.getContext()); + PrepareResult prepareResult = null; + try { + prepareResult = component.prepare(resolveStateContext, scopedComponentInfo.getContext()); + } finally { + if (prepareEvent != null && componentsLogger != null) { + componentsLogger.logPerfEvent(prepareEvent); + } - if (prepareEvent != null && componentsLogger != null) { - componentsLogger.logPerfEvent(prepareEvent); + if (componentPrepareTraceIdentifier != null) { + endTrace(componentPrepareTraceIdentifier); + } } if (prepareResult != null) { @@ -305,6 +345,10 @@ else if (Component.isLayoutSpec(component)) { ComponentsSystrace.endSection(); } return null; + } finally { + if (componentResolvedIdentifier != null) { + endTrace(componentResolvedIdentifier); + } } if (resolveLayoutCreationEvent != null && componentsLogger != null) { diff --git a/litho-core/src/main/java/com/facebook/litho/debug/LithoDebugEvent.kt b/litho-core/src/main/java/com/facebook/litho/debug/LithoDebugEvent.kt index 3b6a703f3de..e50ab89d2dd 100644 --- a/litho-core/src/main/java/com/facebook/litho/debug/LithoDebugEvent.kt +++ b/litho-core/src/main/java/com/facebook/litho/debug/LithoDebugEvent.kt @@ -22,9 +22,13 @@ object LithoDebugEvent { val RenderCore: DebugEvent.Companion = DebugEvent const val RenderRequest = "Litho.RenderRequest" const val LayoutCommitted = "Litho.LayoutCommitted" - const val LayoutCalculated = "Litho.LayoutCalculated" const val StateUpdateEnqueued = "Litho.StateUpdateEnqueued" const val RenderOnMainThreadStarted = "RenderOnMainThreadStarted" + const val ComponentPrepared = "Litho.Resolve.ComponentPrepared" + const val ComponentResolved = "Litho.Resolve.ComponentResolved" + const val ComponentTreeResolve = "Litho.ComponentTree.Resolve" + const val ComponentTreeResolveResumed = "Litho.ComponentTree.Resolve.Resumed" + const val ComponentTreeMountContentPreallocated = "Litho.ComponentTree.MountContent.Preallocated" } object LithoDebugEventAttributes { @@ -46,4 +50,8 @@ object LithoDebugEventAttributes { const val RenderSource = "source" const val RenderExecutionMode = "execution-mode" const val Forced = "forced" + const val RunsOnMainThread = "runs_on_main_thread" + const val Component = "component" + const val ResolveVersion = "resolve_version" + const val ResolveSource = "resolve_source" }