Add unit tests for planner's LayerState

Bug: 180639488
Test: libcompositionengine_test

Change-Id: I3660d58c0c8e17b5e9a6378e5c9a5ca5842f2cad
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 1c47691..d297d74 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -105,6 +105,7 @@
     srcs: [
         "tests/planner/CachedSetTest.cpp",
         "tests/planner/FlattenerTest.cpp",
+        "tests/planner/LayerStateTest.cpp",
         "tests/CompositionEngineTest.cpp",
         "tests/DisplayColorProfileTest.cpp",
         "tests/DisplayTest.cpp",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index d19ac62..7f8cb4e 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -40,6 +40,7 @@
 
 // clang-format off
 enum class LayerStateField : uint32_t {
+    None            = 0u,
     Id              = 1u << 0,
     Name            = 1u << 1,
     DisplayFrame    = 1u << 2,
@@ -173,8 +174,12 @@
     // Returns which fields were updated
     Flags<LayerStateField> update(compositionengine::OutputLayer*);
 
+    // Computes a hash for this LayerState.
+    // The hash is only computed from NonUniqueFields.
     size_t getHash(Flags<LayerStateField> skipFields) const;
 
+    // Returns the bit-set of differing fields between this LayerState and another LayerState.
+    // This bit-set is based on NonUniqueFields only
     Flags<LayerStateField> getDifferingFields(const LayerState& other,
                                               Flags<LayerStateField> skipFields) const;
 
@@ -280,19 +285,7 @@
 
     // Output-independent per-frame state
 
-    OutputLayerState<mat4, LayerStateField::ColorTransform>
-            mColorTransform{[](auto layer) {
-                                const auto state = layer->getLayerFE().getCompositionState();
-                                return state->colorTransformIsIdentity ? mat4{}
-                                                                       : state->colorTransform;
-                            },
-                            [](const mat4& mat) {
-                                using namespace std::string_literals;
-                                std::vector<std::string> split =
-                                        base::Split(std::string(mat.asString().string()), "\n"s);
-                                split.pop_back(); // Strip the last (empty) line
-                                return split;
-                            }};
+    OutputLayerState<mat4, LayerStateField::ColorTransform> mColorTransform;
 
     // TODO(b/180638831): Surface damage
 
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
index 7cf4819..f3746de 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
@@ -16,9 +16,28 @@
 
 #include <compositionengine/impl/planner/LayerState.h>
 
+namespace {
+extern "C" const char* __attribute__((unused)) __asan_default_options() {
+    return "detect_container_overflow=0";
+}
+} // namespace
+
 namespace android::compositionengine::impl::planner {
 
-LayerState::LayerState(compositionengine::OutputLayer* layer) : mOutputLayer(layer) {
+LayerState::LayerState(compositionengine::OutputLayer* layer)
+      : mOutputLayer(layer),
+        mColorTransform({[](auto layer) {
+                             const auto state = layer->getLayerFE().getCompositionState();
+                             return state->colorTransformIsIdentity ? mat4{}
+                                                                    : state->colorTransform;
+                         },
+                         [](const mat4& mat) {
+                             using namespace std::string_literals;
+                             std::vector<std::string> split =
+                                     base::Split(std::string(mat.asString().string()), "\n"s);
+                             split.pop_back(); // Strip the last (empty) line
+                             return split;
+                         }}) {
     update(layer);
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
new file mode 100644
index 0000000..8f235ab
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
@@ -0,0 +1,1020 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "LayerStateTest"
+
+#include <compositionengine/impl/OutputLayer.h>
+#include <compositionengine/impl/planner/LayerState.h>
+#include <compositionengine/mock/LayerFE.h>
+#include <compositionengine/mock/OutputLayer.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+
+namespace android::compositionengine::impl::planner {
+namespace {
+
+using testing::Return;
+using testing::ReturnRef;
+
+const std::string sDebugName = std::string("Test LayerFE");
+const std::string sDebugNameTwo = std::string("Test LayerFE2");
+const constexpr int32_t sSequenceId = 12345;
+const constexpr int32_t sSequenceIdTwo = 123456;
+const Rect sRectOne = Rect(10, 20, 30, 40);
+const Rect sRectTwo = Rect(40, 30, 20, 10);
+const FloatRect sFloatRectOne = FloatRect(100.f, 200.f, 300.f, 400.f);
+const FloatRect sFloatRectTwo = FloatRect(400.f, 300.f, 200.f, 100.f);
+const constexpr int32_t sZOne = 100;
+const constexpr int32_t sZTwo = 101;
+const constexpr float sAlphaOne = 0.25f;
+const constexpr float sAlphaTwo = 0.5f;
+const Region sRegionOne = Region(sRectOne);
+const Region sRegionTwo = Region(sRectTwo);
+const mat4 sMat4One = mat4::scale(vec4(2.f, 3.f, 1.f, 1.f));
+native_handle_t* const sFakeSidebandStreamOne = reinterpret_cast<native_handle_t*>(10);
+native_handle_t* const sFakeSidebandStreamTwo = reinterpret_cast<native_handle_t*>(11);
+const half4 sHalf4One = half4(0.2f, 0.3f, 0.4f, 0.5f);
+const half4 sHalf4Two = half4(0.5f, 0.4f, 0.43, 0.2f);
+
+struct LayerStateTest : public testing::Test {
+    LayerStateTest() {
+        const ::testing::TestInfo* const test_info =
+                ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+    }
+
+    ~LayerStateTest() {
+        const ::testing::TestInfo* const test_info =
+                ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
+    }
+
+    void setupMocksForLayer(mock::OutputLayer& layer, mock::LayerFE& layerFE,
+                            const OutputLayerCompositionState& outputLayerState,
+                            const LayerFECompositionState& layerFEState,
+                            int32_t sequenceId = sSequenceId,
+                            const std::string& debugName = sDebugName) {
+        EXPECT_CALL(layer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
+        EXPECT_CALL(layer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
+        EXPECT_CALL(layerFE, getSequence()).WillRepeatedly(Return(sequenceId));
+        EXPECT_CALL(layerFE, getDebugName()).WillRepeatedly(Return(debugName.c_str()));
+        EXPECT_CALL(layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
+    }
+
+    mock::LayerFE mLayerFE;
+    mock::OutputLayer mOutputLayer;
+    std::unique_ptr<LayerState> mLayerState;
+};
+
+TEST_F(LayerStateTest, getOutputLayer) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer());
+}
+
+TEST_F(LayerStateTest, getId) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(sSequenceId, mLayerState->getId());
+}
+
+TEST_F(LayerStateTest, updateId) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionState, sSequenceIdTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(sSequenceIdTwo, mLayerState->getId());
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Id), updates);
+}
+
+TEST_F(LayerStateTest, compareId) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionState, sSequenceIdTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getId(), otherLayerState->getId());
+
+    // Id is a unique field, so it's not computed in the hash for a layer state.
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::Id),
+              otherLayerState->getHash(LayerStateField::Id));
+
+    // Similarly, Id cannot be included in differing fields.
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::Id));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::Id));
+
+    EXPECT_FALSE(mLayerState->compare(*otherLayerState));
+    EXPECT_FALSE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, getName) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(sDebugName, mLayerState->getName());
+}
+
+TEST_F(LayerStateTest, updateName) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionState, sSequenceId, sDebugNameTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(sDebugNameTwo, mLayerState->getName());
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Name), updates);
+}
+
+TEST_F(LayerStateTest, compareName) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionState, sSequenceId, sDebugNameTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getName(), otherLayerState->getName());
+
+    // Name is a unique field, so it's not computed in the hash for a layer state.
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::Name),
+              otherLayerState->getHash(LayerStateField::Name));
+
+    // Similarly, Name cannot be included in differing fields.
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::Name));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::Name));
+
+    EXPECT_FALSE(mLayerState->compare(*otherLayerState));
+    EXPECT_FALSE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, getDisplayFrame) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.displayFrame = sRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(sRectOne, mLayerState->getDisplayFrame());
+}
+
+TEST_F(LayerStateTest, updateDisplayFrame) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.displayFrame = sRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.displayFrame = sRectTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(sRectTwo, mLayerState->getDisplayFrame());
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::DisplayFrame), updates);
+}
+
+TEST_F(LayerStateTest, compareDisplayFrame) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.displayFrame = sRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.displayFrame = sRectTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getDisplayFrame(), otherLayerState->getDisplayFrame());
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::DisplayFrame),
+              otherLayerState->getHash(LayerStateField::DisplayFrame));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::DisplayFrame),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::DisplayFrame));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::DisplayFrame),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::DisplayFrame));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, getCompositionType) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.compositionType =
+            hardware::graphics::composer::hal::Composition::DEVICE;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(hardware::graphics::composer::hal::Composition::DEVICE,
+              mLayerState->getCompositionType());
+}
+
+TEST_F(LayerStateTest, getCompositionType_forcedClient) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.forceClientComposition = true;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.compositionType =
+            hardware::graphics::composer::hal::Composition::DEVICE;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(hardware::graphics::composer::hal::Composition::CLIENT,
+              mLayerState->getCompositionType());
+}
+
+TEST_F(LayerStateTest, updateCompositionType) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.compositionType =
+            hardware::graphics::composer::hal::Composition::DEVICE;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.compositionType =
+            hardware::graphics::composer::hal::Composition::SOLID_COLOR;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(hardware::graphics::composer::hal::Composition::SOLID_COLOR,
+              mLayerState->getCompositionType());
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::CompositionType), updates);
+}
+
+TEST_F(LayerStateTest, compareCompositionType) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.compositionType =
+            hardware::graphics::composer::hal::Composition::DEVICE;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.compositionType =
+            hardware::graphics::composer::hal::Composition::SOLID_COLOR;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getCompositionType(), otherLayerState->getCompositionType());
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::CompositionType),
+              otherLayerState->getHash(LayerStateField::CompositionType));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::CompositionType),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::CompositionType));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::CompositionType),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::CompositionType));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, getBuffer) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.buffer = new GraphicBuffer();
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    EXPECT_EQ(layerFECompositionState.buffer, mLayerState->getBuffer());
+}
+
+TEST_F(LayerStateTest, updateBuffer) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.buffer = new GraphicBuffer();
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.buffer = new GraphicBuffer();
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(layerFECompositionStateTwo.buffer, mLayerState->getBuffer());
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer), updates);
+}
+
+TEST_F(LayerStateTest, compareBuffer) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.buffer = new GraphicBuffer();
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.buffer = new GraphicBuffer();
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getBuffer(), otherLayerState->getBuffer());
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::Buffer),
+              otherLayerState->getHash(LayerStateField::Buffer));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::Buffer));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::Buffer));
+
+    // Buffers are explicitly excluded from comparison
+    EXPECT_FALSE(mLayerState->compare(*otherLayerState));
+    EXPECT_FALSE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateSourceCrop) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.sourceCrop = sFloatRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.sourceCrop = sFloatRectTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SourceCrop), updates);
+}
+
+TEST_F(LayerStateTest, compareSourceCrop) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.sourceCrop = sFloatRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.sourceCrop = sFloatRectTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::SourceCrop),
+              otherLayerState->getHash(LayerStateField::SourceCrop));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SourceCrop),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::SourceCrop));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SourceCrop),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::SourceCrop));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateZOrder) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.z = sZOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.z = sZTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ZOrder), updates);
+}
+
+TEST_F(LayerStateTest, compareZOrder) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.z = sZOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.z = sZTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::ZOrder),
+              otherLayerState->getHash(LayerStateField::ZOrder));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ZOrder),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::ZOrder));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ZOrder),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::ZOrder));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateBufferTransform) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.bufferTransform = Hwc2::Transform::FLIP_H;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.bufferTransform = Hwc2::Transform::FLIP_V;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BufferTransform), updates);
+}
+
+TEST_F(LayerStateTest, compareBufferTransform) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.bufferTransform = Hwc2::Transform::FLIP_H;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.bufferTransform = Hwc2::Transform::FLIP_V;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::BufferTransform),
+              otherLayerState->getHash(LayerStateField::BufferTransform));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BufferTransform),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::BufferTransform));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BufferTransform),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::BufferTransform));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateBlendMode) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.blendMode = hal::BlendMode::COVERAGE;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlendMode), updates);
+}
+
+TEST_F(LayerStateTest, compareBlendMode) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.blendMode = hal::BlendMode::COVERAGE;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::BlendMode),
+              otherLayerState->getHash(LayerStateField::BlendMode));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlendMode),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::BlendMode));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::BlendMode),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::BlendMode));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateAlpha) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.alpha = sAlphaOne;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.alpha = sAlphaTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Alpha), updates);
+}
+
+TEST_F(LayerStateTest, compareAlpha) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.alpha = sAlphaOne;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.alpha = sAlphaTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::Alpha),
+              otherLayerState->getHash(LayerStateField::Alpha));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Alpha),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::Alpha));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Alpha),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::Alpha));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateVisibleRegion) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.visibleRegion = sRegionOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.visibleRegion = sRegionTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::VisibleRegion), updates);
+}
+
+TEST_F(LayerStateTest, compareVisibleRegion) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.visibleRegion = sRegionOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.visibleRegion = sRegionTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::VisibleRegion),
+              otherLayerState->getHash(LayerStateField::VisibleRegion));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::VisibleRegion),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::VisibleRegion));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::VisibleRegion),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::VisibleRegion));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateDataspace) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.dataspace = ui::Dataspace::SRGB;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.dataspace = ui::Dataspace::DISPLAY_P3;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Dataspace), updates);
+}
+
+TEST_F(LayerStateTest, compareDataspace) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.dataspace = ui::Dataspace::SRGB;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.dataspace = ui::Dataspace::DISPLAY_P3;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::Dataspace),
+              otherLayerState->getHash(LayerStateField::Dataspace));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Dataspace),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::Dataspace));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Dataspace),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::Dataspace));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateColorTransform) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.colorTransformIsIdentity = true;
+    layerFECompositionState.colorTransform = mat4();
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.colorTransformIsIdentity = false;
+    layerFECompositionStateTwo.colorTransform = sMat4One;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ColorTransform), updates);
+}
+
+TEST_F(LayerStateTest, compareColorTransform) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.colorTransformIsIdentity = true;
+    layerFECompositionState.colorTransform = mat4();
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.colorTransformIsIdentity = false;
+    layerFECompositionStateTwo.colorTransform = sMat4One;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::ColorTransform),
+              otherLayerState->getHash(LayerStateField::ColorTransform));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ColorTransform),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::ColorTransform));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::ColorTransform),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::ColorTransform));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateSidebandStream) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.sidebandStream = NativeHandle::create(sFakeSidebandStreamOne, false);
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.sidebandStream = NativeHandle::create(sFakeSidebandStreamTwo, false);
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SidebandStream), updates);
+}
+
+TEST_F(LayerStateTest, compareSidebandStream) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.sidebandStream = NativeHandle::create(sFakeSidebandStreamOne, false);
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.sidebandStream = NativeHandle::create(sFakeSidebandStreamTwo, false);
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::SidebandStream),
+              otherLayerState->getHash(LayerStateField::SidebandStream));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SidebandStream),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::SidebandStream));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SidebandStream),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::SidebandStream));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, updateSolidColor) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.color = sHalf4One;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.color = sHalf4Two;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SolidColor), updates);
+}
+
+TEST_F(LayerStateTest, compareSolidColor) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.color = sHalf4One;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.color = sHalf4Two;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(mLayerState->getHash(LayerStateField::None),
+              otherLayerState->getHash(LayerStateField::None));
+    EXPECT_EQ(mLayerState->getHash(LayerStateField::SolidColor),
+              otherLayerState->getHash(LayerStateField::SolidColor));
+
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SolidColor),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              mLayerState->getDifferingFields(*otherLayerState, LayerStateField::SolidColor));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SolidColor),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::None));
+    EXPECT_EQ(Flags<LayerStateField>(LayerStateField::None),
+              otherLayerState->getDifferingFields(*mLayerState, LayerStateField::SolidColor));
+
+    EXPECT_TRUE(mLayerState->compare(*otherLayerState));
+    EXPECT_TRUE(otherLayerState->compare(*mLayerState));
+}
+
+TEST_F(LayerStateTest, dumpDoesNotCrash) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    std::string dump;
+    mLayerState->dump(dump);
+    EXPECT_TRUE(dump.size() > 0);
+}
+
+TEST_F(LayerStateTest, framesSinceBufferUpdate) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    EXPECT_EQ(0, mLayerState->getFramesSinceBufferUpdate());
+    mLayerState->incrementFramesSinceBufferUpdate();
+    EXPECT_EQ(1, mLayerState->getFramesSinceBufferUpdate());
+    mLayerState->resetFramesSinceBufferUpdate();
+    EXPECT_EQ(0, mLayerState->getFramesSinceBufferUpdate());
+}
+
+TEST_F(LayerStateTest, getNonBufferHash_doesNotCommute) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.displayFrame = sRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.displayFrame = sRectTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_NE(getNonBufferHash({mLayerState.get(), otherLayerState.get()}),
+              getNonBufferHash({otherLayerState.get(), mLayerState.get()}));
+}
+
+TEST_F(LayerStateTest, getNonBufferHash_isIdempotent) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    outputLayerCompositionState.displayFrame = sRectOne;
+    LayerFECompositionState layerFECompositionState;
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    OutputLayerCompositionState outputLayerCompositionStateTwo;
+    outputLayerCompositionStateTwo.displayFrame = sRectTwo;
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
+                       layerFECompositionState);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_EQ(getNonBufferHash({mLayerState.get(), otherLayerState.get()}),
+              getNonBufferHash({mLayerState.get(), otherLayerState.get()}));
+}
+
+TEST_F(LayerStateTest, getNonBufferHash_filtersOutBuffers) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.buffer = new GraphicBuffer();
+    setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    mock::LayerFE newLayerFE;
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.buffer = new GraphicBuffer();
+    setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+    auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
+
+    EXPECT_EQ(getNonBufferHash({mLayerState.get()}), getNonBufferHash({otherLayerState.get()}));
+}
+
+} // namespace
+} // namespace android::compositionengine::impl::planner
\ No newline at end of file