diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 45a84f6..ecde47f 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -206,26 +206,46 @@
     uint64_t diff(const layer_state_t& other) const;
     bool hasBufferChanges() const;
 
-    // Changes to the tree structure.
-    static constexpr uint64_t HIERARCHY_CHANGES = layer_state_t::eLayerChanged |
-            layer_state_t::eRelativeLayerChanged | layer_state_t::eReparent |
-            layer_state_t::eBackgroundColorChanged;
+    // Layer hierarchy updates.
+    static constexpr uint64_t HIERARCHY_CHANGES = layer_state_t::eBackgroundColorChanged |
+            layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged |
+            layer_state_t::eReparent;
+
+    // Geometry updates.
+    static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::eBufferCropChanged |
+            layer_state_t::eBufferTransformChanged | layer_state_t::eCropChanged |
+            layer_state_t::eDestinationFrameChanged | layer_state_t::eMatrixChanged |
+            layer_state_t::ePositionChanged | layer_state_t::eTransformToDisplayInverseChanged |
+            layer_state_t::eTransparentRegionChanged;
+
+    // Buffer and related updates.
+    static constexpr uint64_t BUFFER_CHANGES = layer_state_t::eApiChanged |
+            layer_state_t::eBufferChanged | layer_state_t::eBufferCropChanged |
+            layer_state_t::eBufferTransformChanged | layer_state_t::eDataspaceChanged |
+            layer_state_t::eSidebandStreamChanged | layer_state_t::eSurfaceDamageRegionChanged |
+            layer_state_t::eTransformToDisplayInverseChanged |
+            layer_state_t::eTransparentRegionChanged;
+
     // Content updates.
-    static constexpr uint64_t CONTENT_CHANGES = layer_state_t::eAlphaChanged |
-            layer_state_t::eTransparentRegionChanged | layer_state_t::eShadowRadiusChanged |
-            layer_state_t::eRenderBorderChanged | layer_state_t::eColorChanged |
-            layer_state_t::eBufferChanged | layer_state_t::eDataspaceChanged |
-            layer_state_t::eApiChanged | layer_state_t::eSidebandStreamChanged |
+    static constexpr uint64_t CONTENT_CHANGES = layer_state_t::BUFFER_CHANGES |
+            layer_state_t::eAlphaChanged | layer_state_t::eAutoRefreshChanged |
+            layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBackgroundColorChanged |
+            layer_state_t::eBlurRegionsChanged | layer_state_t::eColorChanged |
+            layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged |
+            layer_state_t::eCornerRadiusChanged | layer_state_t::eHdrMetadataChanged |
+            layer_state_t::eRenderBorderChanged | layer_state_t::eShadowRadiusChanged |
+            layer_state_t::eStretchChanged;
+
+    // Changes which invalidates the layer's visible region in CE.
+    static constexpr uint64_t CONTENT_DIRTY = layer_state_t::CONTENT_CHANGES |
+            layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES;
+
+    // Changes affecting child states.
+    static constexpr uint64_t AFFECTS_CHILDREN = layer_state_t::GEOMETRY_CHANGES |
+            layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged |
             layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged |
-            layer_state_t::eBackgroundColorChanged | layer_state_t::eColorSpaceAgnosticChanged |
-            layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBlurRegionsChanged |
-            layer_state_t::eAutoRefreshChanged | layer_state_t::eStretchChanged;
-    // Changes to content or children size.
-    static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::ePositionChanged |
-            layer_state_t::eMatrixChanged | layer_state_t::eTransparentRegionChanged |
-            layer_state_t::eBufferCropChanged | layer_state_t::eBufferTransformChanged |
-            layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eCropChanged |
-            layer_state_t::eDestinationFrameChanged;
+            layer_state_t::eFlagsChanged | layer_state_t::eLayerStackChanged |
+            layer_state_t::eTrustedOverlayChanged;
 
     bool hasValidBuffer() const;
     void sanitize(int32_t permissions);
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 5647b73..fe7cff7 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -157,6 +157,8 @@
         "EventLog/EventLog.cpp",
         "FrontEnd/LayerCreationArgs.cpp",
         "FrontEnd/LayerHandle.cpp",
+        "FrontEnd/LayerSnapshot.cpp",
+        "FrontEnd/LayerSnapshotBuilder.cpp",
         "FrontEnd/LayerHierarchy.cpp",
         "FrontEnd/LayerLifecycleManager.cpp",
         "FrontEnd/RequestedLayerState.cpp",
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
index db4e8af..514a642 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
@@ -131,7 +131,7 @@
 
 std::string LayerHierarchy::getDebugStringShort() const {
     std::string debug = "LayerHierarchy{";
-    debug += ((mLayer) ? mLayer->getDebugStringShort() : "root") + " ";
+    debug += ((mLayer) ? mLayer->getDebugString() : "root") + " ";
     if (mChildren.empty()) {
         debug += "no children";
     } else {
@@ -401,10 +401,13 @@
     return it->second;
 }
 
-LayerHierarchy::TraversalPath LayerHierarchy::TraversalPath::ROOT_TRAVERSAL_ID =
+const LayerHierarchy::TraversalPath LayerHierarchy::TraversalPath::ROOT =
         {.id = UNASSIGNED_LAYER_ID, .variant = LayerHierarchy::Attached};
 
 std::string LayerHierarchy::TraversalPath::toString() const {
+    if (id == UNASSIGNED_LAYER_ID) {
+        return "TraversalPath{ROOT}";
+    }
     std::string debugString = "TraversalPath{.id = " + std::to_string(id);
 
     if (!mirrorRootIds.empty()) {
@@ -437,20 +440,22 @@
                                                                    LayerHierarchy::Variant variant)
       : mTraversalPath(traversalPath),
         mParentId(traversalPath.id),
-        mParentVariant(traversalPath.variant) {
+        mParentVariant(traversalPath.variant),
+        mParentDetached(traversalPath.detached) {
     // Update the traversal id with the child layer id and variant. Parent id and variant are
     // stored to reset the id upon destruction.
     traversalPath.id = layerId;
     traversalPath.variant = variant;
     if (variant == LayerHierarchy::Variant::Mirror) {
         traversalPath.mirrorRootIds.emplace_back(layerId);
-    }
-    if (variant == LayerHierarchy::Variant::Relative) {
+    } else if (variant == LayerHierarchy::Variant::Relative) {
         if (std::find(traversalPath.relativeRootIds.begin(), traversalPath.relativeRootIds.end(),
                       layerId) != traversalPath.relativeRootIds.end()) {
             traversalPath.invalidRelativeRootId = layerId;
         }
         traversalPath.relativeRootIds.emplace_back(layerId);
+    } else if (variant == LayerHierarchy::Variant::Detached) {
+        traversalPath.detached = true;
     }
 }
 LayerHierarchy::ScopedAddToTraversalPath::~ScopedAddToTraversalPath() {
@@ -458,8 +463,7 @@
     // the constructor.
     if (mTraversalPath.variant == LayerHierarchy::Variant::Mirror) {
         mTraversalPath.mirrorRootIds.pop_back();
-    }
-    if (mTraversalPath.variant == LayerHierarchy::Variant::Relative) {
+    } else if (mTraversalPath.variant == LayerHierarchy::Variant::Relative) {
         mTraversalPath.relativeRootIds.pop_back();
     }
     if (mTraversalPath.invalidRelativeRootId == mTraversalPath.id) {
@@ -467,6 +471,7 @@
     }
     mTraversalPath.id = mParentId;
     mTraversalPath.variant = mParentVariant;
+    mTraversalPath.detached = mParentDetached;
 }
 
 } // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
index f83a859..8cdc240 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
@@ -63,15 +63,22 @@
         // First duplicate relative root id found. If this is a valid layer id that means we are
         // in a loop.
         uint32_t invalidRelativeRootId = UNASSIGNED_LAYER_ID;
+        // See isAttached()
+        bool detached = false;
         bool hasRelZLoop() const { return invalidRelativeRootId != UNASSIGNED_LAYER_ID; }
-        bool isRelative() { return !relativeRootIds.empty(); }
+        // Returns true if this node is reached via one or more relative parents.
+        bool isRelative() const { return !relativeRootIds.empty(); }
+        // Returns true if the node or its parents are not Detached.
+        bool isAttached() const { return !detached; }
+        // Returns true if the node is a clone.
+        bool isClone() const { return !mirrorRootIds.empty(); }
 
         bool operator==(const TraversalPath& other) const {
             return id == other.id && mirrorRootIds == other.mirrorRootIds;
         }
         std::string toString() const;
 
-        static TraversalPath ROOT_TRAVERSAL_ID;
+        static const TraversalPath ROOT;
     };
 
     // Helper class to add nodes to an existing traversal id and removes the
@@ -86,6 +93,7 @@
         TraversalPath& mTraversalPath;
         uint32_t mParentId;
         LayerHierarchy::Variant mParentVariant;
+        bool mParentDetached;
     };
     LayerHierarchy(RequestedLayerState* layer);
 
@@ -98,12 +106,14 @@
 
     // Traverse the hierarchy and visit all child variants.
     void traverse(const Visitor& visitor) const {
-        traverse(visitor, TraversalPath::ROOT_TRAVERSAL_ID);
+        TraversalPath root = TraversalPath::ROOT;
+        traverse(visitor, root);
     }
 
     // Traverse the hierarchy in z-order, skipping children that have relative parents.
     void traverseInZOrder(const Visitor& visitor) const {
-        traverseInZOrder(visitor, TraversalPath::ROOT_TRAVERSAL_ID);
+        TraversalPath root = TraversalPath::ROOT;
+        traverseInZOrder(visitor, root);
     }
 
     const RequestedLayerState* getLayer() const;
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
index fdf60b3..5514c06 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
@@ -210,10 +210,7 @@
                 layer->touchCropId = linkLayer(layer->touchCropId, layer->id);
             }
 
-            mGlobalChanges |= layer->changes &
-                    (RequestedLayerState::Changes::Hierarchy |
-                     RequestedLayerState::Changes::Geometry |
-                     RequestedLayerState::Changes::Content);
+            mGlobalChanges |= layer->changes;
         }
     }
 }
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
new file mode 100644
index 0000000..d483a99
--- /dev/null
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#undef LOG_TAG
+#define LOG_TAG "LayerSnapshot"
+
+#include "LayerSnapshot.h"
+
+namespace android::surfaceflinger::frontend {
+
+using namespace ftl::flag_operators;
+
+LayerSnapshot::LayerSnapshot(const RequestedLayerState& state,
+                             const LayerHierarchy::TraversalPath& path)
+      : path(path) {
+    sequence = static_cast<int32_t>(state.id);
+    name = state.name;
+    textureName = state.textureName;
+    premultipliedAlpha = state.premultipliedAlpha;
+    inputInfo.name = state.name;
+    inputInfo.id = static_cast<int32_t>(state.id);
+    inputInfo.ownerUid = static_cast<int32_t>(state.ownerUid);
+    inputInfo.ownerPid = state.ownerPid;
+}
+
+// As documented in libhardware header, formats in the range
+// 0x100 - 0x1FF are specific to the HAL implementation, and
+// are known to have no alpha channel
+// TODO: move definition for device-specific range into
+// hardware.h, instead of using hard-coded values here.
+#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
+
+bool LayerSnapshot::isOpaqueFormat(PixelFormat format) {
+    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
+        return true;
+    }
+    switch (format) {
+        case PIXEL_FORMAT_RGBA_8888:
+        case PIXEL_FORMAT_BGRA_8888:
+        case PIXEL_FORMAT_RGBA_FP16:
+        case PIXEL_FORMAT_RGBA_1010102:
+        case PIXEL_FORMAT_R_8:
+            return false;
+    }
+    // in all other case, we have no blending (also for unknown formats)
+    return true;
+}
+
+bool LayerSnapshot::hasBufferOrSidebandStream() const {
+    return ((sidebandStream != nullptr) || (buffer != nullptr));
+}
+
+bool LayerSnapshot::drawShadows() const {
+    return shadowSettings.length > 0.f;
+}
+
+bool LayerSnapshot::fillsColor() const {
+    return !hasBufferOrSidebandStream() && color.r >= 0.0_hf && color.g >= 0.0_hf &&
+            color.b >= 0.0_hf;
+}
+
+bool LayerSnapshot::hasBlur() const {
+    return backgroundBlurRadius > 0 || blurRegions.size() > 0;
+}
+
+bool LayerSnapshot::hasEffect() const {
+    return fillsColor() || drawShadows() || hasBlur();
+}
+
+bool LayerSnapshot::hasSomethingToDraw() const {
+    return hasEffect() || hasBufferOrSidebandStream();
+}
+
+bool LayerSnapshot::isContentOpaque() const {
+    // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
+    // layer's opaque flag.
+    if (!hasSomethingToDraw()) {
+        return false;
+    }
+
+    // if the layer has the opaque flag, then we're always opaque
+    if (layerOpaqueFlagSet) {
+        return true;
+    }
+
+    // If the buffer has no alpha channel, then we are opaque
+    if (hasBufferOrSidebandStream() &&
+        isOpaqueFormat(buffer ? buffer->getPixelFormat() : PIXEL_FORMAT_NONE)) {
+        return true;
+    }
+
+    // Lastly consider the layer opaque if drawing a color with alpha == 1.0
+    return fillsColor() && color.a == 1.0_hf;
+}
+
+bool LayerSnapshot::isHiddenByPolicy() const {
+    if (CC_UNLIKELY(invalidTransform)) {
+        ALOGW("Hide layer %s because it has invalid transformation.", name.c_str());
+        return true;
+    }
+    return isHiddenByPolicyFromParent || isHiddenByPolicyFromRelativeParent;
+}
+
+bool LayerSnapshot::getIsVisible() const {
+    if (!hasSomethingToDraw()) {
+        return false;
+    }
+
+    if (isHiddenByPolicy()) {
+        return false;
+    }
+
+    return color.a > 0.0f || hasBlur();
+}
+
+std::string LayerSnapshot::getIsVisibleReason() const {
+    if (!hasSomethingToDraw()) {
+        return "!hasSomethingToDraw";
+    }
+
+    if (isHiddenByPolicy()) {
+        return "isHiddenByPolicy";
+    }
+
+    if (color.a > 0.0f || hasBlur()) {
+        return "";
+    }
+
+    return "alpha = 0 and !hasBlur";
+}
+
+bool LayerSnapshot::canReceiveInput() const {
+    return !isHiddenByPolicy() && (!hasBufferOrSidebandStream() || color.a > 0.0f);
+}
+
+bool LayerSnapshot::isTransformValid(const ui::Transform& t) {
+    float transformDet = t.det();
+    return transformDet != 0 && !isinf(transformDet) && !isnan(transformDet);
+}
+
+std::string LayerSnapshot::getDebugString() const {
+    return "Snapshot(" + base::StringPrintf("%p", this) + "){" + path.toString() + name +
+            " isHidden=" + std::to_string(isHiddenByPolicyFromParent) +
+            " isHiddenRelative=" + std::to_string(isHiddenByPolicyFromRelativeParent) +
+            " isVisible=" + std::to_string(isVisible) + " " + getIsVisibleReason() + "}";
+}
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
new file mode 100644
index 0000000..d14bd3a
--- /dev/null
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <compositionengine/LayerFECompositionState.h>
+#include <renderengine/LayerSettings.h>
+#include "LayerHierarchy.h"
+#include "RequestedLayerState.h"
+#include "android-base/stringprintf.h"
+
+namespace android::surfaceflinger::frontend {
+
+struct RoundedCornerState {
+    RoundedCornerState() = default;
+    RoundedCornerState(const FloatRect& cropRect, const vec2& radius)
+          : cropRect(cropRect), radius(radius) {}
+
+    // Rounded rectangle in local layer coordinate space.
+    FloatRect cropRect = FloatRect();
+    // Radius of the rounded rectangle.
+    vec2 radius;
+    bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; }
+    bool operator==(RoundedCornerState const& rhs) const {
+        return cropRect == rhs.cropRect && radius == rhs.radius;
+    }
+};
+
+// LayerSnapshot stores Layer state used by CompositionEngine and RenderEngine. Composition
+// Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
+// passed to Render Engine are created using properties stored on this struct.
+struct LayerSnapshot : public compositionengine::LayerFECompositionState {
+    LayerSnapshot() = default;
+    LayerSnapshot(const RequestedLayerState&, const LayerHierarchy::TraversalPath&);
+
+    LayerHierarchy::TraversalPath path;
+    size_t globalZ = std::numeric_limits<ssize_t>::max();
+    bool invalidTransform = false;
+    bool isHiddenByPolicyFromParent = false;
+    bool isHiddenByPolicyFromRelativeParent = false;
+    ftl::Flags<RequestedLayerState::Changes> changes;
+    int32_t sequence;
+    std::string name;
+    uint32_t textureName;
+    bool contentOpaque;
+    bool layerOpaqueFlagSet;
+    RoundedCornerState roundedCorner;
+    FloatRect transformedBounds;
+    renderengine::ShadowSettings shadowSettings;
+    bool premultipliedAlpha;
+    bool isHdrY410;
+    bool bufferNeedsFiltering;
+    ui::Transform parentTransform;
+    Rect bufferSize;
+    Rect croppedBufferSize;
+    std::shared_ptr<renderengine::ExternalTexture> externalTexture;
+    gui::LayerMetadata layerMetadata;
+    gui::LayerMetadata relativeLayerMetadata;
+    bool hasReadyFrame;
+    ui::Transform localTransformInverse;
+    gui::WindowInfo inputInfo;
+    ui::Transform localTransform;
+    gui::DropInputMode dropInputMode;
+    bool isTrustedOverlay;
+
+    static bool isOpaqueFormat(PixelFormat format);
+    static bool isTransformValid(const ui::Transform& t);
+
+    bool canReceiveInput() const;
+    bool drawShadows() const;
+    bool fillsColor() const;
+    bool getIsVisible() const;
+    bool hasBlur() const;
+    bool hasBufferOrSidebandStream() const;
+    bool hasEffect() const;
+    bool hasSomethingToDraw() const;
+    bool isContentOpaque() const;
+    bool isHiddenByPolicy() const;
+    std::string getDebugString() const;
+    std::string getIsVisibleReason() const;
+};
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
new file mode 100644
index 0000000..bff12d7
--- /dev/null
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -0,0 +1,833 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#undef LOG_TAG
+#define LOG_TAG "LayerSnapshotBuilder"
+
+#include "LayerSnapshotBuilder.h"
+#include <gui/TraceUtils.h>
+#include <numeric>
+#include "DisplayHardware/HWC2.h"
+#include "DisplayHardware/Hal.h"
+#include "ftl/small_map.h"
+
+namespace android::surfaceflinger::frontend {
+
+using namespace ftl::flag_operators;
+
+namespace {
+FloatRect getMaxDisplayBounds(
+        const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays) {
+    const ui::Size maxSize = [&displays] {
+        if (displays.empty()) return ui::Size{5000, 5000};
+
+        return std::accumulate(displays.begin(), displays.end(), ui::kEmptySize,
+                               [](ui::Size size, const auto& pair) -> ui::Size {
+                                   const auto& display = pair.second;
+                                   return {std::max(size.getWidth(), display.info.logicalWidth),
+                                           std::max(size.getHeight(), display.info.logicalHeight)};
+                               });
+    }();
+
+    // Ignore display bounds for now since they will be computed later. Use a large Rect bound
+    // to ensure it's bigger than an actual display will be.
+    const float xMax = static_cast<float>(maxSize.getWidth()) * 10.f;
+    const float yMax = static_cast<float>(maxSize.getHeight()) * 10.f;
+
+    return {-xMax, -yMax, xMax, yMax};
+}
+
+// Applies the given transform to the region, while protecting against overflows caused by any
+// offsets. If applying the offset in the transform to any of the Rects in the region would result
+// in an overflow, they are not added to the output Region.
+Region transformTouchableRegionSafely(const ui::Transform& t, const Region& r,
+                                      const std::string& debugWindowName) {
+    // Round the translation using the same rounding strategy used by ui::Transform.
+    const auto tx = static_cast<int32_t>(t.tx() + 0.5);
+    const auto ty = static_cast<int32_t>(t.ty() + 0.5);
+
+    ui::Transform transformWithoutOffset = t;
+    transformWithoutOffset.set(0.f, 0.f);
+
+    const Region transformed = transformWithoutOffset.transform(r);
+
+    // Apply the translation to each of the Rects in the region while discarding any that overflow.
+    Region ret;
+    for (const auto& rect : transformed) {
+        Rect newRect;
+        if (__builtin_add_overflow(rect.left, tx, &newRect.left) ||
+            __builtin_add_overflow(rect.top, ty, &newRect.top) ||
+            __builtin_add_overflow(rect.right, tx, &newRect.right) ||
+            __builtin_add_overflow(rect.bottom, ty, &newRect.bottom)) {
+            ALOGE("Applying transform to touchable region of window '%s' resulted in an overflow.",
+                  debugWindowName.c_str());
+            continue;
+        }
+        ret.orSelf(newRect);
+    }
+    return ret;
+}
+
+/*
+ * We don't want to send the layer's transform to input, but rather the
+ * parent's transform. This is because Layer's transform is
+ * information about how the buffer is placed on screen. The parent's
+ * transform makes more sense to send since it's information about how the
+ * layer is placed on screen. This transform is used by input to determine
+ * how to go from screen space back to window space.
+ */
+ui::Transform getInputTransform(const LayerSnapshot& snapshot) {
+    if (!snapshot.hasBufferOrSidebandStream()) {
+        return snapshot.geomLayerTransform;
+    }
+    return snapshot.parentTransform;
+}
+
+/**
+ * Similar to getInputTransform, we need to update the bounds to include the transform.
+ * This is because bounds don't include the buffer transform, where the input assumes
+ * that's already included.
+ */
+Rect getInputBounds(const LayerSnapshot& snapshot) {
+    if (!snapshot.hasBufferOrSidebandStream()) {
+        return snapshot.croppedBufferSize;
+    }
+
+    if (snapshot.localTransform.getType() == ui::Transform::IDENTITY ||
+        !snapshot.croppedBufferSize.isValid()) {
+        return snapshot.croppedBufferSize;
+    }
+    return snapshot.localTransform.transform(snapshot.croppedBufferSize);
+}
+
+void fillInputFrameInfo(gui::WindowInfo& info, const ui::Transform& screenToDisplay,
+                        const LayerSnapshot& snapshot) {
+    Rect tmpBounds = getInputBounds(snapshot);
+    if (!tmpBounds.isValid()) {
+        info.touchableRegion.clear();
+        // A layer could have invalid input bounds and still expect to receive touch input if it has
+        // replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated
+        // correctly to determine the coordinate space for input events. Use an empty rect so that
+        // the layer will receive input in its own layer space.
+        tmpBounds = Rect::EMPTY_RECT;
+    }
+
+    // InputDispatcher works in the display device's coordinate space. Here, we calculate the
+    // frame and transform used for the layer, which determines the bounds and the coordinate space
+    // within which the layer will receive input.
+    //
+    // The coordinate space within which each of the bounds are specified is explicitly documented
+    // in the variable name. For example "inputBoundsInLayer" is specified in layer space. A
+    // Transform converts one coordinate space to another, which is apparent in its naming. For
+    // example, "layerToDisplay" transforms layer space to display space.
+    //
+    // Coordinate space definitions:
+    //   - display: The display device's coordinate space. Correlates to pixels on the display.
+    //   - screen: The post-rotation coordinate space for the display, a.k.a. logical display space.
+    //   - layer: The coordinate space of this layer.
+    //   - input: The coordinate space in which this layer will receive input events. This could be
+    //            different than layer space if a surfaceInset is used, which changes the origin
+    //            of the input space.
+    const FloatRect inputBoundsInLayer = tmpBounds.toFloatRect();
+
+    // Clamp surface inset to the input bounds.
+    const auto surfaceInset = static_cast<float>(info.surfaceInset);
+    const float xSurfaceInset =
+            std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getWidth() / 2.f));
+    const float ySurfaceInset =
+            std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getHeight() / 2.f));
+
+    // Apply the insets to the input bounds.
+    const FloatRect insetBoundsInLayer(inputBoundsInLayer.left + xSurfaceInset,
+                                       inputBoundsInLayer.top + ySurfaceInset,
+                                       inputBoundsInLayer.right - xSurfaceInset,
+                                       inputBoundsInLayer.bottom - ySurfaceInset);
+
+    // Crop the input bounds to ensure it is within the parent's bounds.
+    const FloatRect croppedInsetBoundsInLayer =
+            snapshot.geomLayerBounds.intersect(insetBoundsInLayer);
+
+    const ui::Transform layerToScreen = getInputTransform(snapshot);
+    const ui::Transform layerToDisplay = screenToDisplay * layerToScreen;
+
+    const Rect roundedFrameInDisplay{layerToDisplay.transform(croppedInsetBoundsInLayer)};
+    info.frameLeft = roundedFrameInDisplay.left;
+    info.frameTop = roundedFrameInDisplay.top;
+    info.frameRight = roundedFrameInDisplay.right;
+    info.frameBottom = roundedFrameInDisplay.bottom;
+
+    ui::Transform inputToLayer;
+    inputToLayer.set(insetBoundsInLayer.left, insetBoundsInLayer.top);
+    const ui::Transform inputToDisplay = layerToDisplay * inputToLayer;
+
+    // InputDispatcher expects a display-to-input transform.
+    info.transform = inputToDisplay.inverse();
+
+    // The touchable region is specified in the input coordinate space. Change it to display space.
+    info.touchableRegion =
+            transformTouchableRegionSafely(inputToDisplay, info.touchableRegion, snapshot.name);
+}
+
+void handleDropInputMode(LayerSnapshot& snapshot, const LayerSnapshot& parentSnapshot) {
+    if (snapshot.inputInfo.inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
+        return;
+    }
+
+    // Check if we need to drop input unconditionally
+    const gui::DropInputMode dropInputMode = snapshot.dropInputMode;
+    if (dropInputMode == gui::DropInputMode::ALL) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::DROP_INPUT;
+        ALOGV("Dropping input for %s as requested by policy.", snapshot.name.c_str());
+        return;
+    }
+
+    // Check if we need to check if the window is obscured by parent
+    if (dropInputMode != gui::DropInputMode::OBSCURED) {
+        return;
+    }
+
+    // Check if the parent has set an alpha on the layer
+    if (parentSnapshot.color.a != 1.0_hf) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::DROP_INPUT;
+        ALOGV("Dropping input for %s as requested by policy because alpha=%f",
+              snapshot.name.c_str(), static_cast<float>(parentSnapshot.color.a));
+    }
+
+    // Check if the parent has cropped the buffer
+    Rect bufferSize = snapshot.croppedBufferSize;
+    if (!bufferSize.isValid()) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED;
+        return;
+    }
+
+    // Screenbounds are the layer bounds cropped by parents, transformed to screenspace.
+    // To check if the layer has been cropped, we take the buffer bounds, apply the local
+    // layer crop and apply the same set of transforms to move to screenspace. If the bounds
+    // match then the layer has not been cropped by its parents.
+    Rect bufferInScreenSpace(snapshot.geomLayerTransform.transform(bufferSize));
+    bool croppedByParent = bufferInScreenSpace != Rect{snapshot.transformedBounds};
+
+    if (croppedByParent) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::DROP_INPUT;
+        ALOGV("Dropping input for %s as requested by policy because buffer is cropped by parent",
+              snapshot.name.c_str());
+    } else {
+        // If the layer is not obscured by its parents (by setting an alpha or crop), then only drop
+        // input if the window is obscured. This check should be done in surfaceflinger but the
+        // logic currently resides in inputflinger. So pass the if_obscured check to input to only
+        // drop input events if the window is obscured.
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED;
+    }
+}
+
+bool getBufferNeedsFiltering(const LayerSnapshot& snapshot, const ui::Size& unrotatedBufferSize) {
+    const int32_t layerWidth = static_cast<int32_t>(snapshot.geomLayerBounds.getWidth());
+    const int32_t layerHeight = static_cast<int32_t>(snapshot.geomLayerBounds.getHeight());
+    return layerWidth != unrotatedBufferSize.width || layerHeight != unrotatedBufferSize.height;
+}
+
+auto getBlendMode(const LayerSnapshot& snapshot, const RequestedLayerState& requested) {
+    auto blendMode = Hwc2::IComposerClient::BlendMode::NONE;
+    if (snapshot.alpha != 1.0f || !snapshot.isContentOpaque()) {
+        blendMode = requested.premultipliedAlpha ? Hwc2::IComposerClient::BlendMode::PREMULTIPLIED
+                                                 : Hwc2::IComposerClient::BlendMode::COVERAGE;
+    }
+    return blendMode;
+}
+
+} // namespace
+
+LayerSnapshot LayerSnapshotBuilder::getRootSnapshot() {
+    LayerSnapshot snapshot;
+    snapshot.changes = ftl::Flags<RequestedLayerState::Changes>();
+    snapshot.isHiddenByPolicyFromParent = false;
+    snapshot.isHiddenByPolicyFromRelativeParent = false;
+    snapshot.parentTransform.reset();
+    snapshot.geomLayerTransform.reset();
+    snapshot.geomInverseLayerTransform.reset();
+    snapshot.geomLayerBounds = getMaxDisplayBounds({});
+    snapshot.roundedCorner = RoundedCornerState();
+    snapshot.stretchEffect = {};
+    snapshot.outputFilter.layerStack = ui::DEFAULT_LAYER_STACK;
+    snapshot.outputFilter.toInternalDisplay = false;
+    snapshot.isSecure = false;
+    snapshot.color.a = 1.0_hf;
+    snapshot.colorTransformIsIdentity = true;
+    snapshot.shadowRadius = 0.f;
+    snapshot.layerMetadata.mMap.clear();
+    snapshot.relativeLayerMetadata.mMap.clear();
+    snapshot.inputInfo.touchOcclusionMode = gui::TouchOcclusionMode::BLOCK_UNTRUSTED;
+    snapshot.dropInputMode = gui::DropInputMode::NONE;
+    snapshot.isTrustedOverlay = false;
+    return snapshot;
+}
+
+LayerSnapshotBuilder::LayerSnapshotBuilder() : mRootSnapshot(getRootSnapshot()) {}
+
+LayerSnapshotBuilder::LayerSnapshotBuilder(Args args) : LayerSnapshotBuilder() {
+    args.forceUpdate = true;
+    updateSnapshots(args);
+}
+
+bool LayerSnapshotBuilder::tryFastUpdate(const Args& args) {
+    if (args.forceUpdate) {
+        // force update requested, so skip the fast path
+        return false;
+    }
+
+    if (args.layerLifecycleManager.getGlobalChanges().get() == 0) {
+        // there are no changes, so just clear the change flags from before.
+        for (auto& snapshot : mSnapshots) {
+            snapshot->changes.clear();
+            snapshot->contentDirty = false;
+        }
+        return true;
+    }
+
+    if (args.layerLifecycleManager.getGlobalChanges() != RequestedLayerState::Changes::Content) {
+        // We have changes that require us to walk the hierarchy and update child layers.
+        // No fast path for you.
+        return false;
+    }
+
+    // There are only content changes which do not require any child layer snapshots to be updated.
+    ALOGV("%s", __func__);
+    ATRACE_NAME("FastPath");
+
+    // Collect layers with changes
+    ftl::SmallMap<uint32_t, RequestedLayerState*, 10> layersWithChanges;
+    for (auto& layer : args.layerLifecycleManager.getLayers()) {
+        if (layer->changes.test(RequestedLayerState::Changes::Content)) {
+            layersWithChanges.emplace_or_replace(layer->id, layer.get());
+        }
+    }
+
+    // Walk through the snapshots, clearing previous change flags and updating the snapshots
+    // if needed.
+    for (auto& snapshot : mSnapshots) {
+        snapshot->changes.clear();
+        snapshot->contentDirty = false;
+        auto it = layersWithChanges.find(snapshot->path.id);
+        if (it != layersWithChanges.end()) {
+            ALOGV("%s fast path snapshot changes = %s", __func__,
+                  mRootSnapshot.changes.string().c_str());
+            LayerHierarchy::TraversalPath root = LayerHierarchy::TraversalPath::ROOT;
+            updateSnapshot(*snapshot, args, *it->second, mRootSnapshot, root);
+        }
+    }
+    return true;
+}
+
+void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
+    ATRACE_NAME("UpdateSnapshots");
+    ALOGV("%s updateSnapshots force = %s", __func__, std::to_string(args.forceUpdate).c_str());
+    if (args.forceUpdate || args.displayChanges) {
+        mRootSnapshot.geomLayerBounds = getMaxDisplayBounds(args.displays);
+    }
+    if (args.displayChanges) {
+        mRootSnapshot.changes = RequestedLayerState::Changes::AffectsChildren |
+                RequestedLayerState::Changes::Geometry;
+    }
+    LayerHierarchy::TraversalPath root = LayerHierarchy::TraversalPath::ROOT;
+    for (auto& [childHierarchy, variant] : args.root.mChildren) {
+        LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root,
+                                                                childHierarchy->getLayer()->id,
+                                                                variant);
+        updateSnapshotsInHierarchy(args, *childHierarchy, root, mRootSnapshot);
+    }
+
+    sortSnapshotsByZ(args);
+    mRootSnapshot.changes.clear();
+
+    // Destroy unreachable snapshots
+    if (args.layerLifecycleManager.getDestroyedLayers().empty()) {
+        return;
+    }
+
+    std::unordered_set<uint32_t> destroyedLayerIds;
+    for (auto& destroyedLayer : args.layerLifecycleManager.getDestroyedLayers()) {
+        destroyedLayerIds.emplace(destroyedLayer->id);
+    }
+    auto it = mSnapshots.begin();
+    while (it < mSnapshots.end()) {
+        auto& traversalPath = it->get()->path;
+        if (destroyedLayerIds.find(traversalPath.id) == destroyedLayerIds.end()) {
+            it++;
+            continue;
+        }
+
+        mIdToSnapshot.erase(traversalPath);
+        std::iter_swap(it, mSnapshots.end() - 1);
+        mSnapshots.erase(mSnapshots.end() - 1);
+    }
+}
+
+void LayerSnapshotBuilder::update(const Args& args) {
+    if (tryFastUpdate(args)) {
+        return;
+    }
+    updateSnapshots(args);
+}
+
+void LayerSnapshotBuilder::updateSnapshotsInHierarchy(const Args& args,
+                                                      const LayerHierarchy& hierarchy,
+                                                      LayerHierarchy::TraversalPath& traversalPath,
+                                                      const LayerSnapshot& parentSnapshot) {
+    const RequestedLayerState* layer = hierarchy.getLayer();
+    LayerSnapshot* snapshot = getOrCreateSnapshot(traversalPath, *layer);
+    if (traversalPath.isRelative()) {
+        bool parentIsRelative = traversalPath.variant == LayerHierarchy::Variant::Relative;
+        updateRelativeState(*snapshot, parentSnapshot, parentIsRelative, args);
+    } else {
+        if (traversalPath.isAttached()) {
+            resetRelativeState(*snapshot);
+        }
+        updateSnapshot(*snapshot, args, *layer, parentSnapshot, traversalPath);
+    }
+
+    // If layer is hidden by policy we can avoid update its children. If the visibility
+    // changed this update, then we still need to set the visibility on all the children.
+    if (snapshot->isHiddenByPolicy() &&
+        (!snapshot->changes.any(RequestedLayerState::Changes::Visibility |
+                                RequestedLayerState::Changes::Hierarchy))) {
+        return;
+    }
+
+    for (auto& [childHierarchy, variant] : hierarchy.mChildren) {
+        LayerHierarchy::ScopedAddToTraversalPath addChildToPath(traversalPath,
+                                                                childHierarchy->getLayer()->id,
+                                                                variant);
+        updateSnapshotsInHierarchy(args, *childHierarchy, traversalPath, *snapshot);
+    }
+}
+
+LayerSnapshot* LayerSnapshotBuilder::getSnapshot(uint32_t layerId) const {
+    if (layerId == UNASSIGNED_LAYER_ID) {
+        return nullptr;
+    }
+    LayerHierarchy::TraversalPath path{.id = layerId};
+    return getSnapshot(path);
+}
+
+LayerSnapshot* LayerSnapshotBuilder::getSnapshot(const LayerHierarchy::TraversalPath& id) const {
+    auto it = mIdToSnapshot.find(id);
+    return it == mIdToSnapshot.end() ? nullptr : it->second;
+}
+
+LayerSnapshot* LayerSnapshotBuilder::getOrCreateSnapshot(const LayerHierarchy::TraversalPath& id,
+                                                         const RequestedLayerState& layer) {
+    auto snapshot = getSnapshot(id);
+    if (snapshot) {
+        return snapshot;
+    }
+
+    mSnapshots.emplace_back(std::make_unique<LayerSnapshot>(layer, id));
+    snapshot = mSnapshots.back().get();
+    snapshot->globalZ = static_cast<size_t>(mSnapshots.size()) - 1;
+    mIdToSnapshot[id] = snapshot;
+    return snapshot;
+}
+
+void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) {
+    if (!args.forceUpdate &&
+        !args.layerLifecycleManager.getGlobalChanges().any(
+                RequestedLayerState::Changes::Hierarchy |
+                RequestedLayerState::Changes::Visibility)) {
+        // We are not force updating and there are no hierarchy or visibility changes. Avoid sorting
+        // the snapshots.
+        return;
+    }
+
+    size_t globalZ = 0;
+    args.root.traverseInZOrder(
+            [this, &globalZ](const LayerHierarchy&,
+                             const LayerHierarchy::TraversalPath& traversalPath) -> bool {
+                LayerSnapshot* snapshot = getSnapshot(traversalPath);
+                if (!snapshot) {
+                    return false;
+                }
+
+                if (snapshot->isHiddenByPolicy() &&
+                    !snapshot->changes.test(RequestedLayerState::Changes::Visibility)) {
+                    return false;
+                }
+
+                if (snapshot->isVisible) {
+                    size_t oldZ = snapshot->globalZ;
+                    size_t newZ = globalZ++;
+                    snapshot->globalZ = newZ;
+                    if (oldZ == newZ) {
+                        return true;
+                    }
+                    mSnapshots[newZ]->globalZ = oldZ;
+                    std::iter_swap(mSnapshots.begin() + static_cast<ssize_t>(oldZ),
+                                   mSnapshots.begin() + static_cast<ssize_t>(newZ));
+                }
+
+                return true;
+            });
+
+    while (globalZ < mSnapshots.size()) {
+        mSnapshots[globalZ]->globalZ = globalZ;
+        mSnapshots[globalZ]->isVisible = false;
+        globalZ++;
+    }
+}
+
+void LayerSnapshotBuilder::updateRelativeState(LayerSnapshot& snapshot,
+                                               const LayerSnapshot& parentSnapshot,
+                                               bool parentIsRelative, const Args& args) {
+    if (parentIsRelative) {
+        snapshot.isHiddenByPolicyFromRelativeParent = parentSnapshot.isHiddenByPolicyFromParent;
+        if (args.includeMetadata) {
+            snapshot.relativeLayerMetadata = parentSnapshot.layerMetadata;
+        }
+    } else {
+        snapshot.isHiddenByPolicyFromRelativeParent =
+                parentSnapshot.isHiddenByPolicyFromRelativeParent;
+        if (args.includeMetadata) {
+            snapshot.relativeLayerMetadata = parentSnapshot.relativeLayerMetadata;
+        }
+    }
+    snapshot.isVisible = snapshot.getIsVisible();
+}
+
+void LayerSnapshotBuilder::resetRelativeState(LayerSnapshot& snapshot) {
+    snapshot.isHiddenByPolicyFromRelativeParent = false;
+    snapshot.relativeLayerMetadata.mMap.clear();
+}
+
+uint32_t getDisplayRotationFlags(
+        const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays,
+        const ui::LayerStack& layerStack) {
+    static frontend::DisplayInfo sDefaultDisplayInfo = {.isPrimary = false};
+    auto display = displays.get(layerStack).value_or(sDefaultDisplayInfo).get();
+    return display.isPrimary ? display.rotationFlags : 0;
+}
+
+void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& args,
+                                          const RequestedLayerState& requested,
+                                          const LayerSnapshot& parentSnapshot,
+                                          const LayerHierarchy::TraversalPath& path) {
+    // Always update flags and visibility
+    ftl::Flags<RequestedLayerState::Changes> parentChanges = parentSnapshot.changes &
+            (RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Geometry |
+             RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Metadata |
+             RequestedLayerState::Changes::AffectsChildren);
+    snapshot.changes = parentChanges | requested.changes;
+    snapshot.isHiddenByPolicyFromParent =
+            parentSnapshot.isHiddenByPolicyFromParent || requested.isHiddenByPolicy();
+    snapshot.contentDirty = requested.what & layer_state_t::CONTENT_DIRTY;
+    if (snapshot.isHiddenByPolicyFromParent) {
+        snapshot.isVisible = false;
+        return;
+    }
+
+    uint32_t displayRotationFlags =
+            getDisplayRotationFlags(args.displays, snapshot.outputFilter.layerStack);
+
+    const bool forceUpdate = args.forceUpdate ||
+            snapshot.changes.any(RequestedLayerState::Changes::Visibility |
+                                 RequestedLayerState::Changes::Created);
+
+    if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::AffectsChildren)) {
+        // If root layer, use the layer stack otherwise get the parent's layer stack.
+        snapshot.color.a = parentSnapshot.color.a * requested.color.a;
+        snapshot.alpha = snapshot.color.a;
+        snapshot.isSecure =
+                parentSnapshot.isSecure || (requested.flags & layer_state_t::eLayerSecure);
+        snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
+        snapshot.outputFilter.layerStack = requested.parentId != UNASSIGNED_LAYER_ID
+                ? parentSnapshot.outputFilter.layerStack
+                : requested.layerStack;
+        snapshot.outputFilter.toInternalDisplay = parentSnapshot.outputFilter.toInternalDisplay ||
+                (requested.flags & layer_state_t::eLayerSkipScreenshot);
+        snapshot.stretchEffect = (requested.stretchEffect.hasEffect())
+                ? requested.stretchEffect
+                : parentSnapshot.stretchEffect;
+        if (!parentSnapshot.colorTransformIsIdentity) {
+            snapshot.colorTransform = parentSnapshot.colorTransform * requested.colorTransform;
+            snapshot.colorTransformIsIdentity = false;
+        } else {
+            snapshot.colorTransform = requested.colorTransform;
+            snapshot.colorTransformIsIdentity = !requested.hasColorTransform;
+        }
+    }
+
+    if (forceUpdate || requested.changes.get() != 0) {
+        snapshot.compositionType = requested.getCompositionType();
+        snapshot.dimmingEnabled = requested.dimmingEnabled;
+        snapshot.layerOpaqueFlagSet =
+                (requested.flags & layer_state_t::eLayerOpaque) == layer_state_t::eLayerOpaque;
+    }
+
+    if (forceUpdate || requested.what & layer_state_t::BUFFER_CHANGES) {
+        snapshot.acquireFence =
+                (requested.bufferData) ? requested.bufferData->acquireFence : Fence::NO_FENCE;
+        snapshot.buffer =
+                requested.externalTexture ? requested.externalTexture->getBuffer() : nullptr;
+        snapshot.bufferSize = requested.getBufferSize(displayRotationFlags);
+        snapshot.geomBufferSize = snapshot.bufferSize;
+        snapshot.croppedBufferSize = requested.getCroppedBufferSize(snapshot.bufferSize);
+        snapshot.dataspace = requested.dataspace;
+        snapshot.externalTexture = requested.externalTexture;
+        snapshot.frameNumber = (requested.bufferData) ? requested.bufferData->frameNumber : 0;
+        snapshot.geomBufferTransform = requested.bufferTransform;
+        snapshot.geomBufferUsesDisplayInverseTransform = requested.transformToDisplayInverse;
+        snapshot.geomContentCrop = requested.getBufferCrop();
+        snapshot.geomUsesSourceCrop = snapshot.hasBufferOrSidebandStream();
+        snapshot.hasProtectedContent = requested.externalTexture &&
+                requested.externalTexture->getUsage() & GRALLOC_USAGE_PROTECTED;
+        snapshot.isHdrY410 = requested.dataspace == ui::Dataspace::BT2020_ITU_PQ &&
+                requested.api == NATIVE_WINDOW_API_MEDIA &&
+                requested.bufferData->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102;
+        snapshot.sidebandStream = requested.sidebandStream;
+        snapshot.surfaceDamage = requested.surfaceDamageRegion;
+        snapshot.transparentRegionHint = requested.transparentRegion;
+    }
+
+    if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Content)) {
+        snapshot.color.rgb = requested.getColor().rgb;
+        snapshot.isColorspaceAgnostic = requested.colorSpaceAgnostic;
+        snapshot.backgroundBlurRadius = static_cast<int>(requested.backgroundBlurRadius);
+        snapshot.blurRegions = requested.blurRegions;
+        snapshot.hdrMetadata = requested.hdrMetadata;
+    }
+
+    if (forceUpdate ||
+        snapshot.changes.any(RequestedLayerState::Changes::Hierarchy |
+                             RequestedLayerState::Changes::Geometry)) {
+        updateLayerBounds(snapshot, requested, parentSnapshot, displayRotationFlags);
+        updateRoundedCorner(snapshot, requested, parentSnapshot);
+    }
+
+    if (forceUpdate ||
+        snapshot.changes.any(RequestedLayerState::Changes::Hierarchy |
+                             RequestedLayerState::Changes::Geometry |
+                             RequestedLayerState::Changes::Input)) {
+        static frontend::DisplayInfo sDefaultInfo = {.isSecure = false};
+        const std::optional<frontend::DisplayInfo> displayInfo =
+                args.displays.get(snapshot.outputFilter.layerStack);
+        bool noValidDisplay = !displayInfo.has_value();
+        updateInput(snapshot, requested, parentSnapshot, displayInfo.value_or(sDefaultInfo),
+                    noValidDisplay, path);
+    }
+
+    // computed snapshot properties
+    updateShadows(snapshot, requested, args.globalShadowSettings);
+    if (args.includeMetadata) {
+        snapshot.layerMetadata = parentSnapshot.layerMetadata;
+        snapshot.layerMetadata.merge(requested.metadata);
+    }
+    snapshot.forceClientComposition = snapshot.isHdrY410 || snapshot.shadowSettings.length > 0 ||
+            requested.blurRegions.size() > 0 || snapshot.stretchEffect.hasEffect();
+    snapshot.isVisible = snapshot.getIsVisible();
+    snapshot.isOpaque = snapshot.isContentOpaque() && !snapshot.roundedCorner.hasRoundedCorners() &&
+            snapshot.color.a == 1.f;
+    snapshot.blendMode = getBlendMode(snapshot, requested);
+
+    ALOGV("%supdated [%d]%s changes parent:%s global:%s local:%s requested:%s %s from parent %s",
+          args.forceUpdate ? "Force " : "", requested.id, requested.name.c_str(),
+          parentSnapshot.changes.string().c_str(), snapshot.changes.string().c_str(),
+          requested.changes.string().c_str(), std::to_string(requested.what).c_str(),
+          snapshot.getDebugString().c_str(), parentSnapshot.getDebugString().c_str());
+}
+
+void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot,
+                                               const RequestedLayerState& requested,
+                                               const LayerSnapshot& parentSnapshot) {
+    snapshot.roundedCorner = RoundedCornerState();
+    RoundedCornerState parentRoundedCorner;
+    if (parentSnapshot.roundedCorner.hasRoundedCorners()) {
+        parentRoundedCorner = parentSnapshot.roundedCorner;
+        ui::Transform t = snapshot.localTransform.inverse();
+        parentRoundedCorner.cropRect = t.transform(parentRoundedCorner.cropRect);
+        parentRoundedCorner.radius.x *= t.getScaleX();
+        parentRoundedCorner.radius.y *= t.getScaleY();
+    }
+
+    FloatRect layerCropRect = snapshot.croppedBufferSize.toFloatRect();
+    const vec2 radius(requested.cornerRadius, requested.cornerRadius);
+    RoundedCornerState layerSettings(layerCropRect, radius);
+    const bool layerSettingsValid = layerSettings.hasRoundedCorners() && !layerCropRect.isEmpty();
+    const bool parentRoundedCornerValid = parentRoundedCorner.hasRoundedCorners();
+    if (layerSettingsValid && parentRoundedCornerValid) {
+        // If the parent and the layer have rounded corner settings, use the parent settings if
+        // the parent crop is entirely inside the layer crop. This has limitations and cause
+        // rendering artifacts. See b/200300845 for correct fix.
+        if (parentRoundedCorner.cropRect.left > layerCropRect.left &&
+            parentRoundedCorner.cropRect.top > layerCropRect.top &&
+            parentRoundedCorner.cropRect.right < layerCropRect.right &&
+            parentRoundedCorner.cropRect.bottom < layerCropRect.bottom) {
+            snapshot.roundedCorner = parentRoundedCorner;
+        } else {
+            snapshot.roundedCorner = layerSettings;
+        }
+    } else if (layerSettingsValid) {
+        snapshot.roundedCorner = layerSettings;
+    } else if (parentRoundedCornerValid) {
+        snapshot.roundedCorner = parentRoundedCorner;
+    }
+}
+
+void LayerSnapshotBuilder::updateLayerBounds(LayerSnapshot& snapshot,
+                                             const RequestedLayerState& requested,
+                                             const LayerSnapshot& parentSnapshot,
+                                             uint32_t displayRotationFlags) {
+    snapshot.croppedBufferSize = requested.getCroppedBufferSize(snapshot.bufferSize);
+    snapshot.geomCrop = requested.crop;
+    snapshot.localTransform = requested.getTransform(displayRotationFlags);
+    snapshot.localTransformInverse = snapshot.localTransform.inverse();
+    snapshot.geomLayerTransform = parentSnapshot.geomLayerTransform * snapshot.localTransform;
+    snapshot.invalidTransform = !LayerSnapshot::isTransformValid(snapshot.geomLayerTransform);
+    if (snapshot.invalidTransform) {
+        ALOGW("Resetting transform for %s because it has an invalid transformation.",
+              requested.getDebugStringShort().c_str());
+        snapshot.geomLayerTransform.reset();
+    }
+    snapshot.geomInverseLayerTransform = snapshot.geomLayerTransform.inverse();
+
+    FloatRect parentBounds = parentSnapshot.geomLayerBounds;
+    parentBounds = snapshot.localTransform.inverse().transform(parentBounds);
+    snapshot.geomLayerBounds =
+            (requested.externalTexture) ? snapshot.bufferSize.toFloatRect() : parentBounds;
+    if (!requested.crop.isEmpty()) {
+        snapshot.geomLayerBounds = snapshot.geomLayerBounds.intersect(requested.crop.toFloatRect());
+    }
+    snapshot.geomLayerBounds = snapshot.geomLayerBounds.intersect(parentBounds);
+    snapshot.transformedBounds = snapshot.geomLayerTransform.transform(snapshot.geomLayerBounds);
+    snapshot.parentTransform = parentSnapshot.geomLayerTransform;
+
+    // Subtract the transparent region and snap to the bounds
+    Rect bounds =
+            RequestedLayerState::reduce(snapshot.croppedBufferSize, requested.transparentRegion);
+    snapshot.cursorFrame = snapshot.geomLayerTransform.transform(bounds);
+
+    // TODO(b/238781169) use dest vs src
+    snapshot.bufferNeedsFiltering = snapshot.externalTexture &&
+            getBufferNeedsFiltering(snapshot,
+                                    requested.getUnrotatedBufferSize(displayRotationFlags));
+}
+
+void LayerSnapshotBuilder::updateShadows(LayerSnapshot& snapshot,
+                                         const RequestedLayerState& requested,
+                                         const renderengine::ShadowSettings& globalShadowSettings) {
+    snapshot.shadowRadius = requested.shadowRadius;
+    snapshot.shadowSettings.length = requested.shadowRadius;
+    if (snapshot.shadowRadius > 0.f) {
+        snapshot.shadowSettings = globalShadowSettings;
+
+        // Note: this preserves existing behavior of shadowing the entire layer and not cropping
+        // it if transparent regions are present. This may not be necessary since shadows are
+        // typically cast by layers without transparent regions.
+        snapshot.shadowSettings.boundaries = snapshot.geomLayerBounds;
+
+        // If the casting layer is translucent, we need to fill in the shadow underneath the
+        // layer. Otherwise the generated shadow will only be shown around the casting layer.
+        snapshot.shadowSettings.casterIsTranslucent =
+                !snapshot.isContentOpaque() || (snapshot.alpha < 1.0f);
+        snapshot.shadowSettings.ambientColor *= snapshot.alpha;
+        snapshot.shadowSettings.spotColor *= snapshot.alpha;
+    }
+}
+
+void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot,
+                                       const RequestedLayerState& requested,
+                                       const LayerSnapshot& parentSnapshot,
+                                       const frontend::DisplayInfo& displayInfo,
+                                       bool noValidDisplay,
+                                       const LayerHierarchy::TraversalPath& path) {
+    snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id);
+    if (!requested.hasInputInfo()) {
+        snapshot.inputInfo.inputConfig = gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL;
+        return;
+    }
+
+    fillInputFrameInfo(snapshot.inputInfo, displayInfo.transform, snapshot);
+
+    if (noValidDisplay) {
+        // Do not let the window receive touches if it is not associated with a valid display
+        // transform. We still allow the window to receive keys and prevent ANRs.
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::NOT_TOUCHABLE;
+    }
+
+    // For compatibility reasons we let layers which can receive input
+    // receive input before they have actually submitted a buffer. Because
+    // of this we use canReceiveInput instead of isVisible to check the
+    // policy-visibility, ignoring the buffer state. However for layers with
+    // hasInputInfo()==false we can use the real visibility state.
+    // We are just using these layers for occlusion detection in
+    // InputDispatcher, and obviously if they aren't visible they can't occlude
+    // anything.
+    const bool visible = requested.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible;
+    snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible);
+
+    snapshot.inputInfo.alpha = snapshot.color.a;
+    snapshot.inputInfo.touchOcclusionMode = parentSnapshot.inputInfo.touchOcclusionMode;
+    if (requested.dropInputMode == gui::DropInputMode::ALL ||
+        parentSnapshot.dropInputMode == gui::DropInputMode::ALL) {
+        snapshot.dropInputMode = gui::DropInputMode::ALL;
+    } else if (requested.dropInputMode == gui::DropInputMode::OBSCURED ||
+               parentSnapshot.dropInputMode == gui::DropInputMode::OBSCURED) {
+        snapshot.dropInputMode = gui::DropInputMode::OBSCURED;
+    } else {
+        snapshot.dropInputMode = gui::DropInputMode::NONE;
+    }
+
+    handleDropInputMode(snapshot, parentSnapshot);
+
+    // If the window will be blacked out on a display because the display does not have the secure
+    // flag and the layer has the secure flag set, then drop input.
+    if (!displayInfo.isSecure && snapshot.isSecure) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::DROP_INPUT;
+    }
+
+    auto cropLayerSnapshot = getSnapshot(requested.touchCropId);
+    if (snapshot.inputInfo.replaceTouchableRegionWithCrop) {
+        const Rect bounds(cropLayerSnapshot ? cropLayerSnapshot->transformedBounds
+                                            : snapshot.transformedBounds);
+        snapshot.inputInfo.touchableRegion = Region(displayInfo.transform.transform(bounds));
+    } else if (cropLayerSnapshot) {
+        snapshot.inputInfo.touchableRegion = snapshot.inputInfo.touchableRegion.intersect(
+                displayInfo.transform.transform(Rect{cropLayerSnapshot->transformedBounds}));
+    }
+
+    // Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
+    // if it was set by WM for a known system overlay
+    if (snapshot.isTrustedOverlay) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::TRUSTED_OVERLAY;
+    }
+
+    // If the layer is a clone, we need to crop the input region to cloned root to prevent
+    // touches from going outside the cloned area.
+    if (path.isClone()) {
+        snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::CLONE;
+        auto clonedRootSnapshot = getSnapshot(path.mirrorRootIds.back());
+        if (clonedRootSnapshot) {
+            const Rect rect =
+                    displayInfo.transform.transform(Rect{clonedRootSnapshot->transformedBounds});
+            snapshot.inputInfo.touchableRegion = snapshot.inputInfo.touchableRegion.intersect(rect);
+        }
+    }
+}
+
+std::vector<std::unique_ptr<LayerSnapshot>>& LayerSnapshotBuilder::getSnapshots() {
+    return mSnapshots;
+}
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
new file mode 100644
index 0000000..33b250c
--- /dev/null
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Display/DisplayMap.h"
+#include "FrontEnd/DisplayInfo.h"
+#include "FrontEnd/LayerLifecycleManager.h"
+#include "LayerHierarchy.h"
+#include "LayerSnapshot.h"
+#include "RequestedLayerState.h"
+
+namespace android::surfaceflinger::frontend {
+
+// Walks through the layer hierarchy to build an ordered list
+// of LayerSnapshots that can be passed on to CompositionEngine.
+// This builder does a minimum amount of work to update
+// an existing set of snapshots based on hierarchy changes
+// and RequestedLayerState changes.
+
+// The builder also uses a fast path to update
+// snapshots when there are only buffer updates.
+class LayerSnapshotBuilder {
+public:
+    struct Args {
+        const LayerHierarchy& root;
+        const LayerLifecycleManager& layerLifecycleManager;
+        bool forceUpdate = false;
+        bool includeMetadata = false;
+        const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays;
+        // Set to true if there were display changes since last update.
+        bool displayChanges = false;
+        const renderengine::ShadowSettings& globalShadowSettings;
+    };
+    LayerSnapshotBuilder();
+
+    // Rebuild the snapshots from scratch.
+    LayerSnapshotBuilder(Args);
+
+    // Update an existing set of snapshot using change flags in RequestedLayerState
+    // and LayerLifecycleManager. This needs to be called before
+    // LayerLifecycleManager.commitChanges is called as that function will clear all
+    // change flags.
+    void update(const Args&);
+    std::vector<std::unique_ptr<LayerSnapshot>>& getSnapshots();
+
+private:
+    friend class LayerSnapshotTest;
+    LayerSnapshot* getSnapshot(uint32_t layerId) const;
+    LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const;
+    static LayerSnapshot getRootSnapshot();
+
+    // return true if we were able to successfully update the snapshots via
+    // the fast path.
+    bool tryFastUpdate(const Args& args);
+
+    void updateSnapshots(const Args& args);
+
+    void updateSnapshotsInHierarchy(const Args&, const LayerHierarchy& hierarchy,
+                                    LayerHierarchy::TraversalPath& traversalPath,
+                                    const LayerSnapshot& parentSnapshot);
+    void updateSnapshot(LayerSnapshot& snapshot, const Args& args, const RequestedLayerState&,
+                        const LayerSnapshot& parentSnapshot,
+                        const LayerHierarchy::TraversalPath& path);
+    static void updateRelativeState(LayerSnapshot& snapshot, const LayerSnapshot& parentSnapshot,
+                                    bool parentIsRelative, const Args& args);
+    static void resetRelativeState(LayerSnapshot& snapshot);
+    static void updateRoundedCorner(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
+                                    const LayerSnapshot& parentSnapshot);
+    static void updateLayerBounds(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
+                                  const LayerSnapshot& parentSnapshot,
+                                  uint32_t displayRotationFlags);
+    static void updateShadows(LayerSnapshot& snapshot, const RequestedLayerState& requested,
+                              const renderengine::ShadowSettings& globalShadowSettings);
+    void updateInput(LayerSnapshot& snapshot, const RequestedLayerState& requested,
+                     const LayerSnapshot& parentSnapshot, const frontend::DisplayInfo& displayInfo,
+                     bool noValidDisplay, const LayerHierarchy::TraversalPath& path);
+    void sortSnapshotsByZ(const Args& args);
+    LayerSnapshot* getOrCreateSnapshot(const LayerHierarchy::TraversalPath& id,
+                                       const RequestedLayerState& layer);
+
+    struct TraversalPathHash {
+        std::size_t operator()(const LayerHierarchy::TraversalPath& key) const {
+            uint32_t hashCode = key.id * 31;
+            for (auto mirrorRoot : key.mirrorRootIds) {
+                hashCode += mirrorRoot * 31;
+            }
+            return std::hash<size_t>{}(hashCode);
+        }
+    };
+    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*, TraversalPathHash>
+            mIdToSnapshot;
+    std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
+    LayerSnapshot mRootSnapshot;
+};
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 054382c..dcc16e8 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -118,7 +118,7 @@
 
 void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) {
     bool oldFlags = flags;
-    Rect oldBufferSize = getBufferSize();
+    Rect oldBufferSize = getBufferSize(0);
     const layer_state_t& clientState = resolvedComposerState.state;
 
     uint64_t clientChanges = what | layer_state_t::diff(clientState);
@@ -133,7 +133,7 @@
             changes |= RequestedLayerState::Changes::Geometry;
         }
     }
-    if (clientState.what & layer_state_t::eBufferChanged && oldBufferSize != getBufferSize()) {
+    if (clientState.what & layer_state_t::eBufferChanged && oldBufferSize != getBufferSize(0)) {
         changes |= RequestedLayerState::Changes::Geometry;
     }
     if (clientChanges & layer_state_t::HIERARCHY_CHANGES)
@@ -142,6 +142,8 @@
         changes |= RequestedLayerState::Changes::Content;
     if (clientChanges & layer_state_t::GEOMETRY_CHANGES)
         changes |= RequestedLayerState::Changes::Geometry;
+    if (clientChanges & layer_state_t::AFFECTS_CHILDREN)
+        changes |= RequestedLayerState::Changes::AffectsChildren;
 
     if (clientState.what & layer_state_t::eColorTransformChanged) {
         static const mat4 identityMatrix = mat4();
@@ -205,7 +207,22 @@
     }
 }
 
-ui::Transform RequestedLayerState::getTransform() const {
+ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const {
+    uint32_t bufferWidth = externalTexture->getWidth();
+    uint32_t bufferHeight = externalTexture->getHeight();
+    // Undo any transformations on the buffer.
+    if (bufferTransform & ui::Transform::ROT_90) {
+        std::swap(bufferWidth, bufferHeight);
+    }
+    if (transformToDisplayInverse) {
+        if (displayRotationFlags & ui::Transform::ROT_90) {
+            std::swap(bufferWidth, bufferHeight);
+        }
+    }
+    return {bufferWidth, bufferHeight};
+}
+
+ui::Transform RequestedLayerState::getTransform(uint32_t displayRotationFlags) const {
     if ((flags & layer_state_t::eIgnoreDestinationFrame) || destinationFrame.isEmpty()) {
         // If destination frame is not set, use the requested transform set via
         // Transaction::setPosition and Transaction::setMatrix.
@@ -230,22 +247,10 @@
         return transform;
     }
 
-    uint32_t bufferWidth = externalTexture->getWidth();
-    uint32_t bufferHeight = externalTexture->getHeight();
-    // Undo any transformations on the buffer.
-    if (bufferTransform & ui::Transform::ROT_90) {
-        std::swap(bufferWidth, bufferHeight);
-    }
-    // TODO(b/238781169) remove dep
-    uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
-    if (transformToDisplayInverse) {
-        if (invTransform & ui::Transform::ROT_90) {
-            std::swap(bufferWidth, bufferHeight);
-        }
-    }
+    ui::Size bufferSize = getUnrotatedBufferSize(displayRotationFlags);
 
-    float sx = static_cast<float>(destW) / static_cast<float>(bufferWidth);
-    float sy = static_cast<float>(destH) / static_cast<float>(bufferHeight);
+    float sx = static_cast<float>(destW) / static_cast<float>(bufferSize.width);
+    float sy = static_cast<float>(destH) / static_cast<float>(bufferSize.height);
     ui::Transform transform;
     transform.set(sx, 0, 0, sy);
     transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
@@ -279,7 +284,7 @@
     }
     return color;
 }
-Rect RequestedLayerState::getBufferSize() const {
+Rect RequestedLayerState::getBufferSize(uint32_t displayRotationFlags) const {
     // for buffer state layers we use the display frame size as the buffer size.
     if (!externalTexture) {
         return Rect::INVALID_RECT;
@@ -294,8 +299,7 @@
     }
 
     if (transformToDisplayInverse) {
-        // TODO(b/238781169) pass in display metrics (would be useful for input info as well
-        uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
+        uint32_t invTransform = displayRotationFlags;
         if (invTransform & ui::Transform::ROT_90) {
             std::swap(bufWidth, bufHeight);
         }
@@ -304,8 +308,8 @@
     return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
 }
 
-Rect RequestedLayerState::getCroppedBufferSize() const {
-    Rect size = getBufferSize();
+Rect RequestedLayerState::getCroppedBufferSize(const Rect& bufferSize) const {
+    Rect size = bufferSize;
     if (!crop.isEmpty() && size.isValid()) {
         size.intersect(crop, &size);
     } else if (!crop.isEmpty()) {
@@ -367,4 +371,13 @@
     return isRelativeOf && parentId != relativeParentId;
 }
 
+bool RequestedLayerState::hasInputInfo() const {
+    if (!windowInfoHandle) {
+        return false;
+    }
+    const auto windowInfo = windowInfoHandle->getInfo();
+    return windowInfo->token != nullptr ||
+            windowInfo->inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL);
+}
+
 } // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.h b/services/surfaceflinger/FrontEnd/RequestedLayerState.h
index 7849165..95240d0 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.h
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.h
@@ -47,22 +47,26 @@
         RelativeParent = 1u << 9,
         Metadata = 1u << 10,
         Visibility = 1u << 11,
+        AffectsChildren = 1u << 12,
     };
     static Rect reduce(const Rect& win, const Region& exclude);
     RequestedLayerState(const LayerCreationArgs&);
     void merge(const ResolvedComposerState&);
-    ui::Transform getTransform() const;
+    // Currently we only care about the primary display
+    ui::Transform getTransform(uint32_t displayRotationFlags) const;
+    ui::Size getUnrotatedBufferSize(uint32_t displayRotationFlags) const;
     bool canBeDestroyed() const;
     bool isRoot() const;
     bool isHiddenByPolicy() const;
     half4 getColor() const;
-    Rect getBufferSize() const;
-    Rect getCroppedBufferSize() const;
+    Rect getBufferSize(uint32_t displayRotationFlags) const;
+    Rect getCroppedBufferSize(const Rect& bufferSize) const;
     Rect getBufferCrop() const;
     std::string getDebugString() const;
     std::string getDebugStringShort() const;
     aidl::android::hardware::graphics::composer3::Composition getCompositionType() const;
     bool hasValidRelativeParent() const;
+    bool hasInputInfo() const;
 
     // Layer serial number.  This gives layers an explicit ordering, so we
     // have a stable sort order when their layer stack and Z-order are
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index de9ea04..0179d62 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -128,6 +128,8 @@
 using namespace ftl::flag_operators;
 
 using base::StringAppendF;
+using frontend::LayerSnapshot;
+using frontend::RoundedCornerState;
 using gui::GameMode;
 using gui::LayerMetadata;
 using gui::WindowInfo;
@@ -208,7 +210,7 @@
     mSnapshot->name = getDebugName();
     mSnapshot->textureName = mTextureName;
     mSnapshot->premultipliedAlpha = mPremultipliedAlpha;
-    mSnapshot->transform = {};
+    mSnapshot->parentTransform = {};
 }
 
 void Layer::onFirstRef() {
@@ -473,7 +475,7 @@
     snapshot->geomLayerTransform = getTransform();
     snapshot->geomInverseLayerTransform = snapshot->geomLayerTransform.inverse();
     snapshot->transparentRegionHint = getActiveTransparentRegion(drawingState);
-    snapshot->blurRegionTransform = getActiveTransform(drawingState).inverse();
+    snapshot->localTransformInverse = getActiveTransform(drawingState).inverse();
     snapshot->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
     snapshot->alpha = alpha;
     snapshot->backgroundBlurRadius = drawingState.backgroundBlurRadius;
@@ -3526,7 +3528,7 @@
     }
 
     // If the buffer has no alpha channel, then we are opaque
-    if (hasBufferOrSidebandStream() && isOpaqueFormat(getPixelFormat())) {
+    if (hasBufferOrSidebandStream() && LayerSnapshot::isOpaqueFormat(getPixelFormat())) {
         return true;
     }
 
@@ -3700,29 +3702,6 @@
             (mBufferInfo.mBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
 }
 
-// As documented in libhardware header, formats in the range
-// 0x100 - 0x1FF are specific to the HAL implementation, and
-// are known to have no alpha channel
-// TODO: move definition for device-specific range into
-// hardware.h, instead of using hard-coded values here.
-#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
-
-bool Layer::isOpaqueFormat(PixelFormat format) {
-    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
-        return true;
-    }
-    switch (format) {
-        case PIXEL_FORMAT_RGBA_8888:
-        case PIXEL_FORMAT_BGRA_8888:
-        case PIXEL_FORMAT_RGBA_FP16:
-        case PIXEL_FORMAT_RGBA_1010102:
-        case PIXEL_FORMAT_R_8:
-            return false;
-    }
-    // in all other case, we have no blending (also for unknown formats)
-    return true;
-}
-
 bool Layer::needsFiltering(const DisplayDevice* display) const {
     if (!hasBufferOrSidebandStream()) {
         return false;
@@ -3913,13 +3892,15 @@
         snapshot->shadowSettings.length = mEffectiveShadowRadius;
     }
     snapshot->contentOpaque = isOpaque(mDrawingState);
+    snapshot->layerOpaqueFlagSet =
+            (mDrawingState.flags & layer_state_t::eLayerOpaque) == layer_state_t::eLayerOpaque;
     snapshot->isHdrY410 = isHdrY410();
     snapshot->bufferNeedsFiltering = bufferNeedsFiltering();
     sp<Layer> p = mDrawingParent.promote();
     if (p != nullptr) {
-        snapshot->transform = p->getTransform();
+        snapshot->parentTransform = p->getTransform();
     } else {
-        snapshot->transform.reset();
+        snapshot->parentTransform.reset();
     }
     snapshot->bufferSize = getBufferSize(mDrawingState);
     snapshot->externalTexture = mBufferInfo.mBuffer;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 08a13a3..8281140 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -324,8 +324,8 @@
     virtual sp<LayerFE> getCompositionEngineLayerFE() const;
     virtual sp<LayerFE> copyCompositionEngineLayerFE() const;
 
-    const LayerSnapshot* getLayerSnapshot() const;
-    LayerSnapshot* editLayerSnapshot();
+    const frontend::LayerSnapshot* getLayerSnapshot() const;
+    frontend::LayerSnapshot* editLayerSnapshot();
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
@@ -464,7 +464,7 @@
     // Returns how rounded corners should be drawn for this layer.
     // A layer can override its parent's rounded corner settings if the parent's rounded
     // corner crop does not intersect with its own rounded corner crop.
-    virtual RoundedCornerState getRoundedCornerState() const;
+    virtual frontend::RoundedCornerState getRoundedCornerState() const;
 
     bool hasRoundedCorners() const { return getRoundedCornerState().hasRoundedCorners(); }
 
@@ -746,12 +746,12 @@
      */
     bool hasInputInfo() const;
 
-    // Sets the GameMode for the tree rooted at this layer. A layer in the tree inherits this
-    // GameMode unless it (or an ancestor) has GAME_MODE_METADATA.
-    void setGameModeForTree(GameMode);
+    // Sets the gui::GameMode for the tree rooted at this layer. A layer in the tree inherits this
+    // gui::GameMode unless it (or an ancestor) has GAME_MODE_METADATA.
+    void setGameModeForTree(gui::GameMode);
 
-    void setGameMode(GameMode gameMode) { mGameMode = gameMode; }
-    GameMode getGameMode() const { return mGameMode; }
+    void setGameMode(gui::GameMode gameMode) { mGameMode = gameMode; }
+    gui::GameMode getGameMode() const { return mGameMode; }
 
     virtual uid_t getOwnerUid() const { return mOwnerUid; }
 
@@ -827,7 +827,9 @@
     void gatherBufferInfo();
     void onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame>&);
 
-    sp<Layer> getClonedFrom() { return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr; }
+    sp<Layer> getClonedFrom() const {
+        return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr;
+    }
     bool isClone() { return mClonedFrom != nullptr; }
     bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
 
@@ -1064,7 +1066,7 @@
     float mEffectiveShadowRadius = 0.f;
 
     // Game mode for the layer. Set by WindowManagerShell and recorded by SurfaceFlingerStats.
-    GameMode mGameMode = GameMode::Unsupported;
+    gui::GameMode mGameMode = gui::GameMode::Unsupported;
 
     // A list of regions on this layer that should have blurs.
     const std::vector<BlurRegion> getBlurRegions() const;
@@ -1120,7 +1122,8 @@
     ui::Transform mRequestedTransform;
 
     sp<LayerFE> mLayerFE;
-    std::unique_ptr<LayerSnapshot> mSnapshot = std::make_unique<LayerSnapshot>();
+    std::unique_ptr<frontend::LayerSnapshot> mSnapshot =
+            std::make_unique<frontend::LayerSnapshot>();
 
     friend class LayerSnapshotGuard;
 };
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index 363adc6..c31a2e3 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -148,14 +148,14 @@
         case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled:
             layerSettings.backgroundBlurRadius = mSnapshot->backgroundBlurRadius;
             layerSettings.blurRegions = mSnapshot->blurRegions;
-            layerSettings.blurRegionTransform = mSnapshot->blurRegionTransform.asMatrix4();
+            layerSettings.blurRegionTransform = mSnapshot->localTransformInverse.asMatrix4();
             break;
         case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly:
             layerSettings.backgroundBlurRadius = mSnapshot->backgroundBlurRadius;
             break;
         case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly:
             layerSettings.blurRegions = mSnapshot->blurRegions;
-            layerSettings.blurRegionTransform = mSnapshot->blurRegionTransform.asMatrix4();
+            layerSettings.blurRegionTransform = mSnapshot->localTransformInverse.asMatrix4();
             break;
         case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled:
         default:
@@ -275,7 +275,7 @@
          * of a camera where the buffer remains in native orientation,
          * we want the pixels to always be upright.
          */
-        const auto parentTransform = mSnapshot->transform;
+        const auto parentTransform = mSnapshot->parentTransform;
         tr = tr * inverseOrientation(parentTransform.getOrientation());
 
         // and finally apply it to the original texture matrix
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
index 822bcb7..01da019 100644
--- a/services/surfaceflinger/LayerFE.h
+++ b/services/surfaceflinger/LayerFE.h
@@ -17,48 +17,12 @@
 #pragma once
 
 #include <gui/LayerMetadata.h>
-
+#include "FrontEnd/LayerSnapshot.h"
 #include "compositionengine/LayerFE.h"
 #include "compositionengine/LayerFECompositionState.h"
 #include "renderengine/LayerSettings.h"
 
 namespace android {
-struct RoundedCornerState {
-    RoundedCornerState() = default;
-    RoundedCornerState(const FloatRect& cropRect, const vec2& radius)
-          : cropRect(cropRect), radius(radius) {}
-
-    // Rounded rectangle in local layer coordinate space.
-    FloatRect cropRect = FloatRect();
-    // Radius of the rounded rectangle.
-    vec2 radius;
-    bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; }
-};
-
-// LayerSnapshot stores Layer state used by CompositionEngine and RenderEngine. Composition
-// Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
-// passed to Render Engine are created using properties stored on this struct.
-struct LayerSnapshot : public compositionengine::LayerFECompositionState {
-    int32_t sequence;
-    std::string name;
-    uint32_t textureName;
-    bool contentOpaque;
-    RoundedCornerState roundedCorner;
-    StretchEffect stretchEffect;
-    FloatRect transformedBounds;
-    renderengine::ShadowSettings shadowSettings;
-    bool premultipliedAlpha;
-    bool isHdrY410;
-    bool bufferNeedsFiltering;
-    ui::Transform transform;
-    Rect bufferSize;
-    std::shared_ptr<renderengine::ExternalTexture> externalTexture;
-    gui::LayerMetadata layerMetadata;
-    gui::LayerMetadata relativeLayerMetadata;
-    bool contentDirty;
-    bool hasReadyFrame;
-    ui::Transform blurRegionTransform;
-};
 
 struct CompositionResult {
     // TODO(b/238781169) update CE to no longer pass refreshStartTime to LayerFE::onPreComposition
@@ -86,7 +50,7 @@
             compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
     CompositionResult&& stealCompositionResult();
 
-    std::unique_ptr<LayerSnapshot> mSnapshot;
+    std::unique_ptr<surfaceflinger::frontend::LayerSnapshot> mSnapshot;
 
 private:
     std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal(
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 824899b..87c3c65 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -94,6 +94,7 @@
         "LayerMetadataTest.cpp",
         "LayerHierarchyTest.cpp",
         "LayerLifecycleManagerTest.cpp",
+        "LayerSnapshotTest.cpp",
         "LayerTest.cpp",
         "LayerTestUtils.cpp",
         "MessageQueueTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
index 8560902..33c9440 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
@@ -21,6 +21,7 @@
 #include "FrontEnd/LayerHierarchy.h"
 #include "FrontEnd/LayerLifecycleManager.h"
 #include "Layer.h"
+#include "LayerHierarchyTest.h"
 #include "gui/SurfaceComposerClient.h"
 
 #define UPDATE_AND_VERIFY(HIERARCHY)  \
@@ -31,16 +32,6 @@
 
 namespace android::surfaceflinger::frontend {
 
-namespace {
-LayerCreationArgs createArgs(uint32_t id, bool canBeRoot, wp<IBinder> parent, wp<IBinder> mirror) {
-    LayerCreationArgs args(nullptr, nullptr, "testlayer", 0, {}, std::make_optional(id));
-    args.addToRoot = canBeRoot;
-    args.parentHandle = parent;
-    args.mirrorLayerHandle = mirror;
-    return args;
-}
-} // namespace
-
 // To run test:
 /**
  mp :libsurfaceflinger_unittest && adb sync; adb shell \
@@ -50,163 +41,9 @@
     --gtest_brief=1
 */
 
-class LayerHierarchyTest : public testing::Test {
+class LayerHierarchyTest : public LayerHierarchyTestBase {
 protected:
-    LayerHierarchyTest() {
-        // tree with 3 levels of children
-        // ROOT
-        // ├── 1
-        // │   ├── 11
-        // │   │   └── 111
-        // │   ├── 12
-        // │   │   ├── 121
-        // │   │   └── 122
-        // │   │       └── 1221
-        // │   └── 13
-        // └── 2
-
-        createRootLayer(1);
-        createRootLayer(2);
-        createLayer(11, 1);
-        createLayer(12, 1);
-        createLayer(13, 1);
-        createLayer(111, 11);
-        createLayer(121, 12);
-        createLayer(122, 12);
-        createLayer(1221, 122);
-        mLifecycleManager.commitChanges();
-    }
-    std::vector<uint32_t> getTraversalPath(const LayerHierarchy& hierarchy) const {
-        std::vector<uint32_t> layerIds;
-        hierarchy.traverse([&layerIds = layerIds](const LayerHierarchy& hierarchy,
-                                                  const LayerHierarchy::TraversalPath&) -> bool {
-            layerIds.emplace_back(hierarchy.getLayer()->id);
-            return true;
-        });
-        return layerIds;
-    }
-
-    std::vector<uint32_t> getTraversalPathInZOrder(const LayerHierarchy& hierarchy) const {
-        std::vector<uint32_t> layerIds;
-        hierarchy.traverseInZOrder(
-                [&layerIds = layerIds](const LayerHierarchy& hierarchy,
-                                       const LayerHierarchy::TraversalPath&) -> bool {
-                    layerIds.emplace_back(hierarchy.getLayer()->id);
-                    return true;
-                });
-        return layerIds;
-    }
-
-    void createRootLayer(uint32_t id) {
-        sp<LayerHandle> handle = sp<LayerHandle>::make(id);
-        mHandles[id] = handle;
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createArgs(/*id=*/id, /*canBeRoot=*/true, /*parent=*/nullptr, /*mirror=*/nullptr)));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    void createLayer(uint32_t id, uint32_t parentId) {
-        sp<LayerHandle> handle = sp<LayerHandle>::make(id);
-        mHandles[id] = handle;
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/mHandles[parentId],
-                           /*mirror=*/nullptr)));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    void reparentLayer(uint32_t id, uint32_t newParentId) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        if (newParentId == UNASSIGNED_LAYER_ID) {
-            transactions.back().states.front().state.parentSurfaceControlForChild = nullptr;
-        } else {
-            auto parentHandle = mHandles[newParentId];
-            transactions.back().states.front().state.parentSurfaceControlForChild =
-                    sp<SurfaceControl>::make(SurfaceComposerClient::getDefault(), parentHandle,
-                                             static_cast<int32_t>(newParentId), "Test");
-        }
-        transactions.back().states.front().state.what = layer_state_t::eReparent;
-        transactions.back().states.front().state.surface = mHandles[id];
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void reparentRelativeLayer(uint32_t id, uint32_t relativeParentId) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        if (relativeParentId == UNASSIGNED_LAYER_ID) {
-            transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
-        } else {
-            auto parentHandle = mHandles[relativeParentId];
-            transactions.back().states.front().state.relativeLayerSurfaceControl =
-                    sp<SurfaceControl>::make(SurfaceComposerClient::getDefault(), parentHandle,
-                                             static_cast<int32_t>(relativeParentId), "test");
-            transactions.back().states.front().state.what = layer_state_t::eRelativeLayerChanged;
-        }
-        transactions.back().states.front().state.surface = mHandles[id];
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void mirrorLayer(uint32_t id, uint32_t parent, uint32_t layerToMirror) {
-        auto parentHandle = (parent == UNASSIGNED_LAYER_ID) ? nullptr : mHandles[parent];
-        auto mirrorHandle =
-                (layerToMirror == UNASSIGNED_LAYER_ID) ? nullptr : mHandles[layerToMirror];
-
-        sp<LayerHandle> handle = sp<LayerHandle>::make(id);
-        mHandles[id] = handle;
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentHandle,
-                           /*mirror=*/mHandles[layerToMirror])));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    void updateBackgroundColor(uint32_t id, half alpha) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
-        transactions.back().states.front().state.bgColorAlpha = alpha;
-        transactions.back().states.front().state.surface = mHandles[id];
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({id}); }
-
-    void updateAndVerify(LayerHierarchyBuilder& hierarchyBuilder) {
-        if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
-            hierarchyBuilder.update(mLifecycleManager.getLayers(),
-                                    mLifecycleManager.getDestroyedLayers());
-        }
-        mLifecycleManager.commitChanges();
-
-        // rebuild layer hierarchy from scratch and verify that it matches the updated state.
-        LayerHierarchyBuilder newBuilder(mLifecycleManager.getLayers());
-        EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()),
-                  getTraversalPath(newBuilder.getHierarchy()));
-        EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()),
-                  getTraversalPathInZOrder(newBuilder.getHierarchy()));
-        EXPECT_FALSE(
-                mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
-    }
-
-    void setZ(uint32_t id, int32_t z) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
-        transactions.back().states.front().state.layerId = static_cast<int32_t>(id);
-        transactions.back().states.front().state.z = z;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-    LayerLifecycleManager mLifecycleManager;
-    std::unordered_map<uint32_t, sp<LayerHandle>> mHandles;
+    LayerHierarchyTest() : LayerHierarchyTestBase() { mLifecycleManager.commitChanges(); }
 };
 
 // reparenting tests
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
new file mode 100644
index 0000000..08727f2
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "FrontEnd/LayerHandle.h"
+#include "FrontEnd/LayerHierarchy.h"
+#include "FrontEnd/LayerLifecycleManager.h"
+#include "Layer.h"
+#include "gui/SurfaceComposerClient.h"
+
+namespace android::surfaceflinger::frontend {
+
+class LayerHierarchyTestBase : public testing::Test {
+protected:
+    LayerHierarchyTestBase() {
+        // tree with 3 levels of children
+        // ROOT
+        // ├── 1
+        // │   ├── 11
+        // │   │   └── 111
+        // │   ├── 12
+        // │   │   ├── 121
+        // │   │   └── 122
+        // │   │       └── 1221
+        // │   └── 13
+        // └── 2
+
+        createRootLayer(1);
+        createRootLayer(2);
+        createLayer(11, 1);
+        createLayer(12, 1);
+        createLayer(13, 1);
+        createLayer(111, 11);
+        createLayer(121, 12);
+        createLayer(122, 12);
+        createLayer(1221, 122);
+    }
+
+    LayerCreationArgs createArgs(uint32_t id, bool canBeRoot, wp<IBinder> parent,
+                                 wp<IBinder> mirror) {
+        LayerCreationArgs args(nullptr, nullptr, "testlayer", 0, {}, std::make_optional(id));
+        args.addToRoot = canBeRoot;
+        args.parentHandle = parent;
+        args.mirrorLayerHandle = mirror;
+        return args;
+    }
+
+    std::vector<uint32_t> getTraversalPath(const LayerHierarchy& hierarchy) const {
+        std::vector<uint32_t> layerIds;
+        hierarchy.traverse([&layerIds = layerIds](const LayerHierarchy& hierarchy,
+                                                  const LayerHierarchy::TraversalPath&) -> bool {
+            layerIds.emplace_back(hierarchy.getLayer()->id);
+            return true;
+        });
+        return layerIds;
+    }
+
+    std::vector<uint32_t> getTraversalPathInZOrder(const LayerHierarchy& hierarchy) const {
+        std::vector<uint32_t> layerIds;
+        hierarchy.traverseInZOrder(
+                [&layerIds = layerIds](const LayerHierarchy& hierarchy,
+                                       const LayerHierarchy::TraversalPath&) -> bool {
+                    layerIds.emplace_back(hierarchy.getLayer()->id);
+                    return true;
+                });
+        return layerIds;
+    }
+
+    virtual void createRootLayer(uint32_t id) {
+        sp<LayerHandle> handle = sp<LayerHandle>::make(id);
+        mHandles[id] = handle;
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createArgs(/*id=*/id, /*canBeRoot=*/true, /*parent=*/nullptr, /*mirror=*/nullptr)));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    virtual void createLayer(uint32_t id, uint32_t parentId) {
+        sp<LayerHandle> handle = sp<LayerHandle>::make(id);
+        mHandles[id] = handle;
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/mHandles[parentId],
+                           /*mirror=*/nullptr)));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    void reparentLayer(uint32_t id, uint32_t newParentId) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        if (newParentId == UNASSIGNED_LAYER_ID) {
+            transactions.back().states.front().state.parentSurfaceControlForChild = nullptr;
+        } else {
+            auto parentHandle = mHandles[newParentId];
+            transactions.back().states.front().state.parentSurfaceControlForChild =
+                    sp<SurfaceControl>::make(SurfaceComposerClient::getDefault(), parentHandle,
+                                             static_cast<int32_t>(newParentId), "Test");
+        }
+        transactions.back().states.front().state.what = layer_state_t::eReparent;
+        transactions.back().states.front().state.surface = mHandles[id];
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void reparentRelativeLayer(uint32_t id, uint32_t relativeParentId) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        if (relativeParentId == UNASSIGNED_LAYER_ID) {
+            transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
+        } else {
+            auto parentHandle = mHandles[relativeParentId];
+            transactions.back().states.front().state.relativeLayerSurfaceControl =
+                    sp<SurfaceControl>::make(SurfaceComposerClient::getDefault(), parentHandle,
+                                             static_cast<int32_t>(relativeParentId), "test");
+            transactions.back().states.front().state.what = layer_state_t::eRelativeLayerChanged;
+        }
+        transactions.back().states.front().state.surface = mHandles[id];
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    virtual void mirrorLayer(uint32_t id, uint32_t parent, uint32_t layerToMirror) {
+        auto parentHandle = (parent == UNASSIGNED_LAYER_ID) ? nullptr : mHandles[parent];
+        auto mirrorHandle =
+                (layerToMirror == UNASSIGNED_LAYER_ID) ? nullptr : mHandles[layerToMirror];
+
+        sp<LayerHandle> handle = sp<LayerHandle>::make(id);
+        mHandles[id] = handle;
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentHandle,
+                           /*mirror=*/mHandles[layerToMirror])));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    void updateBackgroundColor(uint32_t id, half alpha) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
+        transactions.back().states.front().state.bgColorAlpha = alpha;
+        transactions.back().states.front().state.surface = mHandles[id];
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({id}); }
+
+    void updateAndVerify(LayerHierarchyBuilder& hierarchyBuilder) {
+        if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
+            hierarchyBuilder.update(mLifecycleManager.getLayers(),
+                                    mLifecycleManager.getDestroyedLayers());
+        }
+        mLifecycleManager.commitChanges();
+
+        // rebuild layer hierarchy from scratch and verify that it matches the updated state.
+        LayerHierarchyBuilder newBuilder(mLifecycleManager.getLayers());
+        EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()),
+                  getTraversalPath(newBuilder.getHierarchy()));
+        EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()),
+                  getTraversalPathInZOrder(newBuilder.getHierarchy()));
+        EXPECT_FALSE(
+                mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
+    }
+
+    void setZ(uint32_t id, int32_t z) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
+        transactions.back().states.front().state.surface = mHandles[id];
+        transactions.back().states.front().state.layerId = static_cast<int32_t>(id);
+        transactions.back().states.front().state.z = z;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setCrop(uint32_t id, const Rect& crop) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eCropChanged;
+        transactions.back().states.front().state.surface = mHandles[id];
+        transactions.back().states.front().state.layerId = static_cast<int32_t>(id);
+        transactions.back().states.front().state.crop = crop;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setFlags(uint32_t id, uint32_t mask, uint32_t flags) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eFlagsChanged;
+        transactions.back().states.front().state.flags = flags;
+        transactions.back().states.front().state.mask = mask;
+        transactions.back().states.front().state.surface = mHandles[id];
+        transactions.back().states.front().state.layerId = static_cast<int32_t>(id);
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setAlpha(uint32_t id, float alpha) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eAlphaChanged;
+        transactions.back().states.front().state.surface = mHandles[id];
+        transactions.back().states.front().state.layerId = static_cast<int32_t>(id);
+        transactions.back().states.front().state.color.a = static_cast<half>(alpha);
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void hideLayer(uint32_t id) {
+        setFlags(id, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
+    }
+
+    void showLayer(uint32_t id) { setFlags(id, layer_state_t::eLayerHidden, 0); }
+
+    void setColor(uint32_t id, half3 rgb = half3(1._hf, 1._hf, 1._hf)) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::eColorChanged;
+        transactions.back().states.front().state.color.rgb = rgb;
+        transactions.back().states.front().state.surface = mHandles[id];
+        transactions.back().states.front().state.layerId = static_cast<int32_t>(id);
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    LayerLifecycleManager mLifecycleManager;
+    std::unordered_map<uint32_t, sp<LayerHandle>> mHandles;
+};
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
new file mode 100644
index 0000000..2441c06
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "FrontEnd/LayerHandle.h"
+#include "FrontEnd/LayerHierarchy.h"
+#include "FrontEnd/LayerLifecycleManager.h"
+#include "FrontEnd/LayerSnapshotBuilder.h"
+#include "Layer.h"
+#include "LayerHierarchyTest.h"
+
+#define UPDATE_AND_VERIFY(BUILDER, ...)                                    \
+    ({                                                                     \
+        SCOPED_TRACE("");                                                  \
+        updateAndVerify((BUILDER), /*displayChanges=*/false, __VA_ARGS__); \
+    })
+
+#define UPDATE_AND_VERIFY_WITH_DISPLAY_CHANGES(BUILDER, ...)              \
+    ({                                                                    \
+        SCOPED_TRACE("");                                                 \
+        updateAndVerify((BUILDER), /*displayChanges=*/true, __VA_ARGS__); \
+    })
+
+namespace android::surfaceflinger::frontend {
+
+// To run test:
+/**
+ mp :libsurfaceflinger_unittest && adb sync; adb shell \
+    /data/nativetest/libsurfaceflinger_unittest/libsurfaceflinger_unittest \
+    --gtest_filter="LayerSnapshotTest.*" --gtest_brief=1
+*/
+
+class LayerSnapshotTest : public LayerHierarchyTestBase {
+protected:
+    LayerSnapshotTest() : LayerHierarchyTestBase() {
+        UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    }
+
+    void createRootLayer(uint32_t id) override {
+        LayerHierarchyTestBase::createRootLayer(id);
+        setColor(id);
+    }
+
+    void createLayer(uint32_t id, uint32_t parentId) override {
+        LayerHierarchyTestBase::createLayer(id, parentId);
+        setColor(parentId);
+    }
+
+    void mirrorLayer(uint32_t id, uint32_t parent, uint32_t layerToMirror) override {
+        LayerHierarchyTestBase::mirrorLayer(id, parent, layerToMirror);
+        setColor(id);
+    }
+
+    void updateAndVerify(LayerSnapshotBuilder& actualBuilder, bool hasDisplayChanges,
+                         const std::vector<uint32_t> expectedVisibleLayerIdsInZOrder) {
+        if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
+            mHierarchyBuilder.update(mLifecycleManager.getLayers(),
+                                     mLifecycleManager.getDestroyedLayers());
+        }
+        LayerSnapshotBuilder::Args args{
+                .root = mHierarchyBuilder.getHierarchy(),
+                .layerLifecycleManager = mLifecycleManager,
+                .includeMetadata = false,
+                .displays = mFrontEndDisplayInfos,
+                .displayChanges = hasDisplayChanges,
+                .globalShadowSettings = globalShadowSettings,
+        };
+        actualBuilder.update(args);
+
+        // rebuild layer snapshots from scratch and verify that it matches the updated state.
+        LayerSnapshotBuilder expectedBuilder(args);
+        mLifecycleManager.commitChanges();
+        ASSERT_TRUE(expectedBuilder.getSnapshots().size() > 0);
+        ASSERT_TRUE(actualBuilder.getSnapshots().size() > 0);
+
+        std::vector<std::unique_ptr<LayerSnapshot>>& snapshots = actualBuilder.getSnapshots();
+        std::vector<uint32_t> actualVisibleLayerIdsInZOrder;
+        for (auto& snapshot : snapshots) {
+            if (!snapshot->isVisible) {
+                break;
+            }
+            actualVisibleLayerIdsInZOrder.push_back(snapshot->path.id);
+        }
+        EXPECT_EQ(expectedVisibleLayerIdsInZOrder, actualVisibleLayerIdsInZOrder);
+    }
+
+    LayerSnapshot* getSnapshot(uint32_t layerId) { return mSnapshotBuilder.getSnapshot(layerId); }
+
+    LayerHierarchyBuilder mHierarchyBuilder{{}};
+    LayerSnapshotBuilder mSnapshotBuilder;
+    std::unordered_map<uint32_t, sp<LayerHandle>> mHandles;
+    display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos;
+    renderengine::ShadowSettings globalShadowSettings;
+    static const std::vector<uint32_t> STARTING_ZORDER;
+};
+const std::vector<uint32_t> LayerSnapshotTest::STARTING_ZORDER = {1,   11,   111, 12, 121,
+                                                                  122, 1221, 13,  2};
+
+TEST_F(LayerSnapshotTest, buildSnapshot) {
+    LayerSnapshotBuilder::Args args{
+            .root = mHierarchyBuilder.getHierarchy(),
+            .layerLifecycleManager = mLifecycleManager,
+            .includeMetadata = false,
+            .displays = mFrontEndDisplayInfos,
+            .globalShadowSettings = globalShadowSettings,
+    };
+    LayerSnapshotBuilder builder(args);
+}
+
+TEST_F(LayerSnapshotTest, updateSnapshot) {
+    LayerSnapshotBuilder::Args args{
+            .root = mHierarchyBuilder.getHierarchy(),
+            .layerLifecycleManager = mLifecycleManager,
+            .includeMetadata = false,
+            .displays = mFrontEndDisplayInfos,
+            .globalShadowSettings = globalShadowSettings,
+    };
+
+    LayerSnapshotBuilder builder;
+    builder.update(args);
+}
+
+// update using parent snapshot data
+TEST_F(LayerSnapshotTest, croppedByParent) {
+    /// MAKE ALL LAYERS VISIBLE BY DEFAULT
+    DisplayInfo info;
+    info.info.logicalHeight = 100;
+    info.info.logicalWidth = 200;
+    mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info);
+    Rect layerCrop(0, 0, 10, 20);
+    setCrop(11, layerCrop);
+    EXPECT_TRUE(mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Geometry));
+    UPDATE_AND_VERIFY_WITH_DISPLAY_CHANGES(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(11)->geomCrop, layerCrop);
+    EXPECT_EQ(getSnapshot(111)->geomLayerBounds, layerCrop.toFloatRect());
+    float maxHeight = static_cast<float>(info.info.logicalHeight * 10);
+    float maxWidth = static_cast<float>(info.info.logicalWidth * 10);
+
+    FloatRect maxDisplaySize(-maxWidth, -maxHeight, maxWidth, maxHeight);
+    EXPECT_EQ(getSnapshot(1)->geomLayerBounds, maxDisplaySize);
+}
+
+// visibility tests
+TEST_F(LayerSnapshotTest, newLayerHiddenByPolicy) {
+    createLayer(112, 11);
+    hideLayer(112);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+
+    showLayer(112);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 11, 111, 112, 12, 121, 122, 1221, 13, 2});
+}
+
+TEST_F(LayerSnapshotTest, hiddenByParent) {
+    hideLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2});
+}
+
+TEST_F(LayerSnapshotTest, reparentShowsChild) {
+    hideLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2});
+
+    showLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+}
+
+TEST_F(LayerSnapshotTest, reparentHidesChild) {
+    hideLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2});
+
+    reparentLayer(121, 11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 122, 1221, 13, 2});
+}
+
+TEST_F(LayerSnapshotTest, unHidingUpdatesSnapshot) {
+    hideLayer(11);
+    Rect crop(1, 2, 3, 4);
+    setCrop(111, crop);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2});
+
+    showLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(111)->geomLayerBounds, crop.toFloatRect());
+}
+
+TEST_F(LayerSnapshotTest, childBehindParentCanBeHiddenByParent) {
+    setZ(111, -1);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 111, 11, 12, 121, 122, 1221, 13, 2});
+
+    hideLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2});
+}
+
+// relative tests
+TEST_F(LayerSnapshotTest, RelativeParentCanHideChild) {
+    reparentRelativeLayer(13, 11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 11, 13, 111, 12, 121, 122, 1221, 2});
+
+    hideLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 2});
+}
+
+TEST_F(LayerSnapshotTest, ReparentingToHiddenRelativeParentHidesChild) {
+    hideLayer(11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2});
+    reparentRelativeLayer(13, 11);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 2});
+}
+
+TEST_F(LayerSnapshotTest, AlphaInheritedByChildren) {
+    setAlpha(1, 0.5);
+    setAlpha(122, 0.5);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(12)->alpha, 0.5f);
+    EXPECT_EQ(getSnapshot(1221)->alpha, 0.25f);
+}
+
+// Change states
+TEST_F(LayerSnapshotTest, UpdateClearsPreviousChangeStates) {
+    setCrop(1, Rect(1, 2, 3, 4));
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_TRUE(getSnapshot(1)->changes.get() != 0);
+    EXPECT_TRUE(getSnapshot(11)->changes.get() != 0);
+    setCrop(2, Rect(1, 2, 3, 4));
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_TRUE(getSnapshot(2)->changes.get() != 0);
+    EXPECT_TRUE(getSnapshot(1)->changes.get() == 0);
+    EXPECT_TRUE(getSnapshot(11)->changes.get() == 0);
+}
+
+TEST_F(LayerSnapshotTest, FastPathClearsPreviousChangeStates) {
+    setColor(11, {1._hf, 0._hf, 0._hf});
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_TRUE(getSnapshot(11)->changes.get() != 0);
+    EXPECT_TRUE(getSnapshot(1)->changes.get() == 0);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_TRUE(getSnapshot(11)->changes.get() == 0);
+}
+
+TEST_F(LayerSnapshotTest, FastPathSetsChangeFlagToContent) {
+    setColor(1, {1._hf, 0._hf, 0._hf});
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(1)->changes, RequestedLayerState::Changes::Content);
+}
+
+} // namespace android::surfaceflinger::frontend
