Refactor HWC2on1Adapter

- Simply memory allocation with a single, consolidated calloc().
- Remove latch system which did not prove useful.
- Converted { to be before \n.

Change-Id: Id1daec2343225598160395bfecddc86955e2b610
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 1d2c178..d72139e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -34,33 +34,6 @@
 
 using namespace std::chrono_literals;
 
-static bool operator==(const hwc_color_t& lhs, const hwc_color_t& rhs) {
-    return lhs.r == rhs.r &&
-            lhs.g == rhs.g &&
-            lhs.b == rhs.b &&
-            lhs.a == rhs.a;
-}
-
-static bool operator==(const hwc_rect_t& lhs, const hwc_rect_t& rhs) {
-    return lhs.left == rhs.left &&
-            lhs.top == rhs.top &&
-            lhs.right == rhs.right &&
-            lhs.bottom == rhs.bottom;
-}
-
-static bool operator==(const hwc_frect_t& lhs, const hwc_frect_t& rhs) {
-    return lhs.left == rhs.left &&
-            lhs.top == rhs.top &&
-            lhs.right == rhs.right &&
-            lhs.bottom == rhs.bottom;
-}
-
-template <typename T>
-static inline bool operator!=(const T& lhs, const T& rhs)
-{
-    return !(lhs == rhs);
-}
-
 static uint8_t getMinorVersion(struct hwc_composer_device_1* device)
 {
     auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
@@ -80,19 +53,6 @@
 
 namespace android {
 
-void HWC2On1Adapter::DisplayContentsDeleter::operator()(
-        hwc_display_contents_1_t* contents)
-{
-    if (contents != nullptr) {
-        for (size_t l = 0; l < contents->numHwLayers; ++l) {
-            auto& layer = contents->hwLayers[l];
-            std::free(const_cast<hwc_rect_t*>(layer.visibleRegionScreen.rects));
-            std::free(const_cast<hwc_rect_t*>(layer.surfaceDamage.rects));
-        }
-    }
-    std::free(contents);
-}
-
 class HWC2On1Adapter::Callbacks : public hwc_procs_t {
     public:
         explicit Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) {
@@ -161,8 +121,7 @@
 }
 
 void HWC2On1Adapter::doGetCapabilities(uint32_t* outCount,
-        int32_t* outCapabilities)
-{
+        int32_t* outCapabilities) {
     if (outCapabilities == nullptr) {
         *outCount = mCapabilities.size();
         return;
@@ -179,8 +138,7 @@
 }
 
 hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
-        FunctionDescriptor descriptor)
-{
+        FunctionDescriptor descriptor) {
     switch (descriptor) {
         // Device functions
         case FunctionDescriptor::CreateVirtualDisplay:
@@ -350,8 +308,7 @@
 // Device functions
 
 Error HWC2On1Adapter::createVirtualDisplay(uint32_t width,
-        uint32_t height, hwc2_display_t* outDisplay)
-{
+        uint32_t height, hwc2_display_t* outDisplay) {
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
 
     if (mHwc1VirtualDisplay) {
@@ -381,8 +338,7 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId)
-{
+Error HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId) {
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
 
     if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
@@ -396,8 +352,7 @@
     return Error::None;
 }
 
-void HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer)
-{
+void HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer) {
     if (outBuffer != nullptr) {
         auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
         *outSize = static_cast<uint32_t>(copiedBytes);
@@ -450,8 +405,7 @@
     *outSize = static_cast<uint32_t>(mDumpString.size());
 }
 
-uint32_t HWC2On1Adapter::getMaxVirtualDisplayCount()
-{
+uint32_t HWC2On1Adapter::getMaxVirtualDisplayCount() {
     return mHwc1SupportsVirtualDisplays ? 1 : 0;
 }
 
@@ -465,8 +419,7 @@
 }
 
 Error HWC2On1Adapter::registerCallback(Callback descriptor,
-        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer)
-{
+        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
     if (!isValid(descriptor)) {
         return Error::BadParameter;
     }
@@ -553,11 +506,8 @@
 HWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
   : mId(sNextId++),
     mDevice(device),
-    mDirtyCount(0),
     mStateMutex(),
-    mZIsDirty(false),
     mHwc1RequestedContents(nullptr),
-    mHwc1ReceivedContents(nullptr),
     mRetireFence(),
     mChanges(),
     mHwc1Id(-1),
@@ -572,10 +522,13 @@
     mOutputBuffer(),
     mHasColorTransform(false),
     mLayers(),
-    mHwc1LayerMap() {}
+    mHwc1LayerMap(),
+    mNumAvailableRects(0),
+    mNextAvailableRect(nullptr),
+    mGeometryChanged(false)
+    {}
 
-Error HWC2On1Adapter::Display::acceptChanges()
-{
+Error HWC2On1Adapter::Display::acceptChanges() {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!mChanges) {
@@ -594,25 +547,21 @@
 
     mChanges->clearTypeChanges();
 
-    mHwc1RequestedContents = std::move(mHwc1ReceivedContents);
-
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId)
-{
+Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
     mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
     *outLayerId = layer->getId();
     ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
-    mZIsDirty = true;
+    markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId)
-{
+Error HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     const auto mapLayer = mDevice.mLayers.find(layerId);
@@ -631,12 +580,11 @@
         }
     }
     ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
-    mZIsDirty = true;
+    markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig)
-{
+Error HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!mActiveConfig) {
@@ -651,8 +599,7 @@
 }
 
 Error HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId,
-        Attribute attribute, int32_t* outValue)
-{
+        Attribute attribute, int32_t* outValue) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
@@ -667,8 +614,7 @@
 }
 
 Error HWC2On1Adapter::Display::getChangedCompositionTypes(
-        uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes)
-{
+        uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!mChanges) {
@@ -701,8 +647,7 @@
 }
 
 Error HWC2On1Adapter::Display::getColorModes(uint32_t* outNumModes,
-        int32_t* outModes)
-{
+        int32_t* outModes) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!outModes) {
@@ -717,8 +662,7 @@
 }
 
 Error HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs,
-        hwc2_config_t* outConfigs)
-{
+        hwc2_config_t* outConfigs) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!outConfigs) {
@@ -737,8 +681,7 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport)
-{
+Error HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
@@ -751,15 +694,13 @@
 
 Error HWC2On1Adapter::Display::getHdrCapabilities(uint32_t* outNumTypes,
         int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
-        float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/)
-{
+        float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
     // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
     *outNumTypes = 0;
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName)
-{
+Error HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!outName) {
@@ -772,8 +713,7 @@
 }
 
 Error HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements,
-        hwc2_layer_t* outLayers, int32_t* outFences)
-{
+        hwc2_layer_t* outLayers, int32_t* outFences) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     uint32_t numWritten = 0;
@@ -799,8 +739,7 @@
 
 Error HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests,
         uint32_t* outNumElements, hwc2_layer_t* outLayers,
-        int32_t* outLayerRequests)
-{
+        int32_t* outLayerRequests) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!mChanges) {
@@ -829,16 +768,14 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::getType(int32_t* outType)
-{
+Error HWC2On1Adapter::Display::getType(int32_t* outType) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     *outType = static_cast<int32_t>(mType);
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::present(int32_t* outRetireFence)
-{
+Error HWC2On1Adapter::Display::present(int32_t* outRetireFence) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (mChanges) {
@@ -857,8 +794,7 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId)
-{
+Error HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     auto config = getConfig(configId);
@@ -890,8 +826,7 @@
 }
 
 Error HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
-        int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/)
-{
+        int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
@@ -901,8 +836,7 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::setColorMode(android_color_mode_t mode)
-{
+Error HWC2On1Adapter::Display::setColorMode(android_color_mode_t mode) {
     std::unique_lock<std::recursive_mutex> lock (mStateMutex);
 
     ALOGV("[%" PRIu64 "] setColorMode(%d)", mId, mode);
@@ -933,8 +867,7 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint)
-{
+Error HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
@@ -944,8 +877,7 @@
 }
 
 Error HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
-        int32_t releaseFence)
-{
+        int32_t releaseFence) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
@@ -954,30 +886,25 @@
     return Error::None;
 }
 
-static bool isValid(PowerMode mode)
-{
+static bool isValid(PowerMode mode) {
     switch (mode) {
         case PowerMode::Off: // Fall-through
         case PowerMode::DozeSuspend: // Fall-through
         case PowerMode::Doze: // Fall-through
         case PowerMode::On: return true;
-        default: return false;
     }
 }
 
-static int getHwc1PowerMode(PowerMode mode)
-{
+static int getHwc1PowerMode(PowerMode mode) {
     switch (mode) {
         case PowerMode::Off: return HWC_POWER_MODE_OFF;
         case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
         case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
         case PowerMode::On: return HWC_POWER_MODE_NORMAL;
-        default: return HWC_POWER_MODE_OFF;
     }
 }
 
-Error HWC2On1Adapter::Display::setPowerMode(PowerMode mode)
-{
+Error HWC2On1Adapter::Display::setPowerMode(PowerMode mode) {
     if (!isValid(mode)) {
         return Error::BadParameter;
     }
@@ -1007,12 +934,11 @@
     switch (enable) {
         case Vsync::Enable: // Fall-through
         case Vsync::Disable: return true;
-        default: return false;
+        case Vsync::Invalid: return false;
     }
 }
 
-Error HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable)
-{
+Error HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable) {
     if (!isValid(enable)) {
         return Error::BadParameter;
     }
@@ -1032,8 +958,7 @@
 }
 
 Error HWC2On1Adapter::Display::validate(uint32_t* outNumTypes,
-        uint32_t* outNumRequests)
-{
+        uint32_t* outNumRequests) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     ALOGV("[%" PRIu64 "] Entering validate", mId);
@@ -1042,6 +967,8 @@
         if (!mDevice.prepareAllDisplays()) {
             return Error::BadDisplay;
         }
+    } else {
+        ALOGE("Validate was called more than once!");
     }
 
     *outNumTypes = mChanges->getNumTypes();
@@ -1055,10 +982,7 @@
     return *outNumTypes > 0 ? Error::HasChanges : Error::None;
 }
 
-// Display helpers
-
-Error HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z)
-{
+Error HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     const auto mapLayer = mDevice.mLayers.find(layerId);
@@ -1090,7 +1014,7 @@
 
     layer->setZ(z);
     mLayers.emplace(std::move(layer));
-    mZIsDirty = true;
+    markGeometryChanged();
 
     return Error::None;
 }
@@ -1159,8 +1083,7 @@
 static_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
         "Tables out of sync");
 
-void HWC2On1Adapter::Display::populateConfigs()
-{
+void HWC2On1Adapter::Display::populateConfigs() {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     ALOGV("[%" PRIu64 "] populateConfigs", mId);
@@ -1238,8 +1161,7 @@
     populateColorModes();
 }
 
-void HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height)
-{
+void HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     mConfigs.emplace_back(std::make_shared<Config>(*this));
@@ -1252,8 +1174,7 @@
     mActiveConfig = config;
 }
 
-bool HWC2On1Adapter::Display::prepare()
-{
+bool HWC2On1Adapter::Display::prepare() {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     // Only prepare display contents for displays HWC1 knows about
@@ -1270,86 +1191,45 @@
 
     ALOGV("[%" PRIu64 "] Entering prepare", mId);
 
-    auto currentCount = mHwc1RequestedContents ?
-            mHwc1RequestedContents->numHwLayers : 0;
-    auto requiredCount = mLayers.size() + 1;
-    ALOGV("[%" PRIu64 "]   Requires %zd layers, %zd allocated in %p", mId,
-            requiredCount, currentCount, mHwc1RequestedContents.get());
-
-    bool layerCountChanged = (currentCount != requiredCount);
-    if (layerCountChanged) {
-        reallocateHwc1Contents();
-    }
-
-    bool applyAllState = false;
-    if (layerCountChanged || mZIsDirty) {
-        assignHwc1LayerIds();
-        mZIsDirty = false;
-        applyAllState = true;
-    }
+    allocateRequestedContents();
+    assignHwc1LayerIds();
 
     mHwc1RequestedContents->retireFenceFd = -1;
     mHwc1RequestedContents->flags = 0;
-    if (isDirty() || applyAllState) {
+    if (mGeometryChanged) {
         mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
     }
+    mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
+    mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
 
+    // +1 is for framebuffer target layer.
+    mHwc1RequestedContents->numHwLayers = mLayers.size() + 1;
     for (auto& layer : mLayers) {
         auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
         hwc1Layer.releaseFenceFd = -1;
         hwc1Layer.acquireFenceFd = -1;
         ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
-        layer->applyState(hwc1Layer, applyAllState);
+        layer->applyState(hwc1Layer);
     }
 
-    mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
-    mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
-
     prepareFramebufferTarget();
 
+    resetGeometryMarker();
+
     return true;
 }
 
-static void cloneHWCRegion(hwc_region_t& region)
-{
-    auto size = sizeof(hwc_rect_t) * region.numRects;
-    auto newRects = static_cast<hwc_rect_t*>(std::malloc(size));
-    std::copy_n(region.rects, region.numRects, newRects);
-    region.rects = newRects;
-}
-
-HWC2On1Adapter::Display::HWC1Contents
-        HWC2On1Adapter::Display::cloneRequestedContents() const
-{
+void HWC2On1Adapter::Display::generateChanges() {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
-    size_t size = sizeof(hwc_display_contents_1_t) +
-            sizeof(hwc_layer_1_t) * (mHwc1RequestedContents->numHwLayers);
-    auto contents = static_cast<hwc_display_contents_1_t*>(std::malloc(size));
-    std::memcpy(contents, mHwc1RequestedContents.get(), size);
-    for (size_t layerId = 0; layerId < contents->numHwLayers; ++layerId) {
-        auto& layer = contents->hwLayers[layerId];
-        // Deep copy the regions to avoid double-frees
-        cloneHWCRegion(layer.visibleRegionScreen);
-        cloneHWCRegion(layer.surfaceDamage);
-    }
-    return HWC1Contents(contents);
-}
-
-void HWC2On1Adapter::Display::setReceivedContents(HWC1Contents contents)
-{
-    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
-
-    mHwc1ReceivedContents = std::move(contents);
-
     mChanges.reset(new Changes);
 
-    size_t numLayers = mHwc1ReceivedContents->numHwLayers;
+    size_t numLayers = mHwc1RequestedContents->numHwLayers;
     for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
-        const auto& receivedLayer = mHwc1ReceivedContents->hwLayers[hwc1Id];
+        const auto& receivedLayer = mHwc1RequestedContents->hwLayers[hwc1Id];
         if (mHwc1LayerMap.count(hwc1Id) == 0) {
             ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
-                    "setReceivedContents: HWC1 layer %zd doesn't have a"
+                    "generateChanges: HWC1 layer %zd doesn't have a"
                     " matching HWC2 layer, and isn't the framebuffer target",
                     hwc1Id);
             continue;
@@ -1361,14 +1241,12 @@
     }
 }
 
-bool HWC2On1Adapter::Display::hasChanges() const
-{
+bool HWC2On1Adapter::Display::hasChanges() const {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
     return mChanges != nullptr;
 }
 
-Error HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents)
-{
+Error HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     if (!mChanges || (mChanges->getNumTypes() > 0)) {
@@ -1404,15 +1282,13 @@
     return Error::None;
 }
 
-void HWC2On1Adapter::Display::addRetireFence(int fenceFd)
-{
+void HWC2On1Adapter::Display::addRetireFence(int fenceFd) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
     mRetireFence.add(fenceFd);
 }
 
 void HWC2On1Adapter::Display::addReleaseFences(
-        const hwc_display_contents_1_t& hwcContents)
-{
+        const hwc_display_contents_1_t& hwcContents) {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     size_t numLayers = hwcContents.numHwLayers;
@@ -1439,14 +1315,12 @@
     }
 }
 
-bool HWC2On1Adapter::Display::hasColorTransform() const
-{
+bool HWC2On1Adapter::Display::hasColorTransform() const {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
     return mHasColorTransform;
 }
 
-static std::string hwc1CompositionString(int32_t type)
-{
+static std::string hwc1CompositionString(int32_t type) {
     switch (type) {
         case HWC_FRAMEBUFFER: return "Framebuffer";
         case HWC_OVERLAY: return "Overlay";
@@ -1459,8 +1333,7 @@
     }
 }
 
-static std::string hwc1TransformString(int32_t transform)
-{
+static std::string hwc1TransformString(int32_t transform) {
     switch (transform) {
         case 0: return "None";
         case HWC_TRANSFORM_FLIP_H: return "FlipH";
@@ -1475,8 +1348,7 @@
     }
 }
 
-static std::string hwc1BlendModeString(int32_t mode)
-{
+static std::string hwc1BlendModeString(int32_t mode) {
     switch (mode) {
         case HWC_BLENDING_NONE: return "None";
         case HWC_BLENDING_PREMULT: return "Premultiplied";
@@ -1486,16 +1358,14 @@
     }
 }
 
-static std::string rectString(hwc_rect_t rect)
-{
+static std::string rectString(hwc_rect_t rect) {
     std::stringstream output;
     output << "[" << rect.left << ", " << rect.top << ", ";
     output << rect.right << ", " << rect.bottom << "]";
     return output.str();
 }
 
-static std::string approximateFloatString(float f)
-{
+static std::string approximateFloatString(float f) {
     if (static_cast<int32_t>(f) == f) {
         return std::to_string(static_cast<int32_t>(f));
     }
@@ -1508,8 +1378,7 @@
     return std::string(buffer, bytesWritten);
 }
 
-static std::string frectString(hwc_frect_t frect)
-{
+static std::string frectString(hwc_frect_t frect) {
     std::stringstream output;
     output << "[" << approximateFloatString(frect.left) << ", ";
     output << approximateFloatString(frect.top) << ", ";
@@ -1518,8 +1387,7 @@
     return output.str();
 }
 
-static std::string colorString(hwc_color_t color)
-{
+static std::string colorString(hwc_color_t color) {
     std::stringstream output;
     output << "RGBA [";
     output << static_cast<int32_t>(color.r) << ", ";
@@ -1529,8 +1397,7 @@
     return output.str();
 }
 
-static std::string alphaString(float f)
-{
+static std::string alphaString(float f) {
     const size_t BUFFER_SIZE = 8;
     char buffer[BUFFER_SIZE] = {};
     auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
@@ -1538,8 +1405,7 @@
 }
 
 static std::string to_string(const hwc_layer_1_t& hwcLayer,
-        int32_t hwc1MinorVersion)
-{
+        int32_t hwc1MinorVersion) {
     const char* fill = "          ";
 
     std::stringstream output;
@@ -1599,8 +1465,7 @@
 }
 
 static std::string to_string(const hwc_display_contents_1_t& hwcContents,
-        int32_t hwc1MinorVersion)
-{
+        int32_t hwc1MinorVersion) {
     const char* fill = "      ";
 
     std::stringstream output;
@@ -1622,8 +1487,7 @@
     return output.str();
 }
 
-std::string HWC2On1Adapter::Display::dump() const
-{
+std::string HWC2On1Adapter::Display::dump() const {
     std::unique_lock<std::recursive_mutex> lock(mStateMutex);
 
     std::stringstream output;
@@ -1663,10 +1527,7 @@
         output << "    Output buffer: " << mOutputBuffer.getBuffer() << '\n';
     }
 
-    if (mHwc1ReceivedContents) {
-        output << "    Last received HWC1 state\n";
-        output << to_string(*mHwc1ReceivedContents, mDevice.mHwc1MinorVersion);
-    } else if (mHwc1RequestedContents) {
+    if (mHwc1RequestedContents) {
         output << "    Last requested HWC1 state\n";
         output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
     }
@@ -1674,28 +1535,46 @@
     return output.str();
 }
 
+hwc_rect_t* HWC2On1Adapter::Display::GetRects(size_t numRects) {
+    if (numRects == 0) {
+        return nullptr;
+    }
+
+    if (numRects > mNumAvailableRects) {
+        // This should NEVER happen since we calculated how many rects the
+        // display would need.
+        ALOGE("Rect allocation failure! SF is likely to crash soon!");
+        return nullptr;
+
+    }
+    hwc_rect_t* rects = mNextAvailableRect;
+    mNextAvailableRect += numRects;
+    mNumAvailableRects -= numRects;
+    return rects;
+}
+
+hwc_display_contents_1* HWC2On1Adapter::Display::getDisplayContents() {
+    return mHwc1RequestedContents.get();
+}
+
 void HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
-        int32_t value)
-{
+        int32_t value) {
     mAttributes[attribute] = value;
 }
 
-int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const
-{
+int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const {
     if (mAttributes.count(attribute) == 0) {
         return -1;
     }
     return mAttributes.at(attribute);
 }
 
-void HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id)
-{
+void HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id) {
     android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
     mHwc1Ids.emplace(colorMode, id);
 }
 
-bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const
-{
+bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const {
     for (const auto& idPair : mHwc1Ids) {
         if (id == idPair.second) {
             return true;
@@ -1705,8 +1584,7 @@
 }
 
 Error HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
-        uint32_t id, android_color_mode_t* outMode) const
-{
+        uint32_t id, android_color_mode_t* outMode) const {
     for (const auto& idPair : mHwc1Ids) {
         if (id == idPair.second) {
             *outMode = idPair.first;
@@ -1718,8 +1596,7 @@
 }
 
 Error HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
-        uint32_t* outId) const
-{
+        uint32_t* outId) const {
     for (const auto& idPair : mHwc1Ids) {
         if (mode == idPair.first) {
             *outId = idPair.second;
@@ -1730,8 +1607,7 @@
     return Error::BadParameter;
 }
 
-bool HWC2On1Adapter::Display::Config::merge(const Config& other)
-{
+bool HWC2On1Adapter::Display::Config::merge(const Config& other) {
     auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
             HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
             HWC2::Attribute::DpiY};
@@ -1753,8 +1629,7 @@
     return true;
 }
 
-std::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const
-{
+std::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const {
     std::set<android_color_mode_t> colorModes;
     for (const auto& idPair : mHwc1Ids) {
         colorModes.emplace(idPair.first);
@@ -1762,8 +1637,7 @@
     return colorModes;
 }
 
-std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const
-{
+std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const {
     std::string output;
 
     const size_t BUFFER_SIZE = 100;
@@ -1819,16 +1693,14 @@
 }
 
 std::shared_ptr<const HWC2On1Adapter::Display::Config>
-        HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const
-{
+        HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const {
     if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
         return nullptr;
     }
     return mConfigs[configId];
 }
 
-void HWC2On1Adapter::Display::populateColorModes()
-{
+void HWC2On1Adapter::Display::populateColorModes() {
     mColorModes = mConfigs[0]->getColorModes();
     for (const auto& config : mConfigs) {
         std::set<android_color_mode_t> intersection;
@@ -1840,8 +1712,7 @@
     }
 }
 
-void HWC2On1Adapter::Display::initializeActiveConfig()
-{
+void HWC2On1Adapter::Display::initializeActiveConfig() {
     if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
         ALOGV("getActiveConfig is null, choosing config 0");
         mActiveConfig = mConfigs[0];
@@ -1886,22 +1757,40 @@
 
 }
 
-void HWC2On1Adapter::Display::reallocateHwc1Contents()
-{
-    // Allocate an additional layer for the framebuffer target
+void HWC2On1Adapter::Display::allocateRequestedContents() {
+    // What needs to be allocated:
+    // 1 hwc_display_contents_1_t
+    // 1 hwc_layer_1_t for each layer
+    // 1 hwc_rect_t for each layer's surfaceDamage
+    // 1 hwc_rect_t for each layer's visibleRegion
+    // 1 hwc_layer_1_t for the framebuffer
+    // 1 hwc_rect_t for the framebuffer's visibleRegion
+
+    // Count # of surfaceDamage
+    size_t numSurfaceDamages = 0;
+    for (const auto& layer : mLayers) {
+        numSurfaceDamages += layer->getNumSurfaceDamages();
+    }
+
+    // Count # of visibleRegions (start at 1 for mandatory framebuffer target
+    // region)
+    size_t numVisibleRegion = 1;
+    for (const auto& layer : mLayers) {
+        numVisibleRegion += layer->getNumVisibleRegions();
+    }
+
+    size_t numRects = numVisibleRegion + numSurfaceDamages;
     auto numLayers = mLayers.size() + 1;
     size_t size = sizeof(hwc_display_contents_1_t) +
-            sizeof(hwc_layer_1_t) * numLayers;
-    ALOGV("[%" PRIu64 "] reallocateHwc1Contents creating %zd layer%s", mId,
-            numLayers, numLayers != 1 ? "s" : "");
-    auto contents =
-            static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
-    contents->numHwLayers = numLayers;
+            sizeof(hwc_layer_1_t) * numLayers +
+            sizeof(hwc_rect_t) * numRects;
+    auto contents = static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
     mHwc1RequestedContents.reset(contents);
+    mNextAvailableRect = reinterpret_cast<hwc_rect_t*>(&contents->hwLayers[numLayers]);
+    mNumAvailableRects = numRects;
 }
 
-void HWC2On1Adapter::Display::assignHwc1LayerIds()
-{
+void HWC2On1Adapter::Display::assignHwc1LayerIds() {
     mHwc1LayerMap.clear();
     size_t nextHwc1Id = 0;
     for (auto& layer : mLayers) {
@@ -1911,8 +1800,7 @@
 }
 
 void HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
-        const Layer& layer)
-{
+        const Layer& layer) {
     auto layerId = layer.getId();
     switch (hwc1Layer.compositionType) {
         case HWC_FRAMEBUFFER:
@@ -1947,16 +1835,14 @@
 }
 
 void HWC2On1Adapter::Display::updateLayerRequests(
-        const hwc_layer_1_t& hwc1Layer, const Layer& layer)
-{
+        const hwc_layer_1_t& hwc1Layer, const Layer& layer) {
     if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
         mChanges->addLayerRequest(layer.getId(),
                 LayerRequest::ClearClientTarget);
     }
 }
 
-void HWC2On1Adapter::Display::prepareFramebufferTarget()
-{
+void HWC2On1Adapter::Display::prepareFramebufferTarget() {
     // We check that mActiveConfig is valid in Display::prepare
     int32_t width = mActiveConfig->getAttribute(Attribute::Width);
     int32_t height = mActiveConfig->getAttribute(Attribute::Height);
@@ -1976,8 +1862,9 @@
     }
     hwc1Target.displayFrame = {0, 0, width, height};
     hwc1Target.planeAlpha = 255;
+
     hwc1Target.visibleRegionScreen.numRects = 1;
-    auto rects = static_cast<hwc_rect_t*>(std::malloc(sizeof(hwc_rect_t)));
+    hwc_rect_t* rects = GetRects(1);
     rects[0].left = 0;
     rects[0].top = 0;
     rects[0].right = width;
@@ -1995,42 +1882,37 @@
 HWC2On1Adapter::Layer::Layer(Display& display)
   : mId(sNextId++),
     mDisplay(display),
-    mDirtyCount(0),
     mBuffer(),
     mSurfaceDamage(),
-    mBlendMode(*this, BlendMode::None),
-    mColor(*this, {0, 0, 0, 0}),
-    mCompositionType(*this, Composition::Invalid),
-    mDisplayFrame(*this, {0, 0, -1, -1}),
-    mPlaneAlpha(*this, 0.0f),
-    mSidebandStream(*this, nullptr),
-    mSourceCrop(*this, {0.0f, 0.0f, -1.0f, -1.0f}),
-    mTransform(*this, Transform::None),
-    mVisibleRegion(*this, std::vector<hwc_rect_t>()),
+    mBlendMode(BlendMode::None),
+    mColor({0, 0, 0, 0}),
+    mCompositionType(Composition::Invalid),
+    mDisplayFrame({0, 0, -1, -1}),
+    mPlaneAlpha(0.0f),
+    mSidebandStream(nullptr),
+    mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
+    mTransform(Transform::None),
+    mVisibleRegion(),
     mZ(0),
     mReleaseFence(),
     mHwc1Id(0),
-    mHasUnsupportedPlaneAlpha(false),
-    mHasUnsupportedBackgroundColor(false) {}
+    mHasUnsupportedPlaneAlpha(false) {}
 
 bool HWC2On1Adapter::SortLayersByZ::operator()(
-        const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs)
-{
+        const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs) {
     return lhs->getZ() < rhs->getZ();
 }
 
 Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
-        int32_t acquireFence)
-{
+        int32_t acquireFence) {
     ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
     mBuffer.setBuffer(buffer);
     mBuffer.setFence(acquireFence);
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y)
-{
-    if (mCompositionType.getValue() != Composition::Cursor) {
+Error HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y) {
+    if (mCompositionType != Composition::Cursor) {
         return Error::BadLayer;
     }
 
@@ -2044,8 +1926,7 @@
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage)
-{
+Error HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage) {
     // HWC1 supports surface damage starting only with version 1.5.
     if (mDisplay.getDevice().mHwc1MinorVersion < 5) {
         return Error::None;
@@ -2057,104 +1938,91 @@
 
 // Layer state functions
 
-Error HWC2On1Adapter::Layer::setBlendMode(BlendMode mode)
-{
-    mBlendMode.setPending(mode);
+Error HWC2On1Adapter::Layer::setBlendMode(BlendMode mode) {
+    mBlendMode = mode;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setColor(hwc_color_t color)
-{
-    mColor.setPending(color);
+Error HWC2On1Adapter::Layer::setColor(hwc_color_t color) {
+    mColor = color;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setCompositionType(Composition type)
-{
-    mCompositionType.setPending(type);
+Error HWC2On1Adapter::Layer::setCompositionType(Composition type) {
+    mCompositionType = type;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t)
-{
+Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t) {
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame)
-{
-    mDisplayFrame.setPending(frame);
+Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) {
+    mDisplayFrame = frame;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setPlaneAlpha(float alpha)
-{
-    mPlaneAlpha.setPending(alpha);
+Error HWC2On1Adapter::Layer::setPlaneAlpha(float alpha) {
+    mPlaneAlpha = alpha;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream)
-{
-    mSidebandStream.setPending(stream);
+Error HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream) {
+    mSidebandStream = stream;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop)
-{
-    mSourceCrop.setPending(crop);
+Error HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop) {
+    mSourceCrop = crop;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setTransform(Transform transform)
-{
-    mTransform.setPending(transform);
+Error HWC2On1Adapter::Layer::setTransform(Transform transform) {
+    mTransform = transform;
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t rawVisible)
-{
-    std::vector<hwc_rect_t> visible(rawVisible.rects,
-            rawVisible.rects + rawVisible.numRects);
-    mVisibleRegion.setPending(std::move(visible));
+Error HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t visible) {
+    mVisibleRegion.resize(visible.numRects);
+    std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
+    mDisplay.markGeometryChanged();
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setZ(uint32_t z)
-{
+Error HWC2On1Adapter::Layer::setZ(uint32_t z) {
     mZ = z;
     return Error::None;
 }
 
-void HWC2On1Adapter::Layer::addReleaseFence(int fenceFd)
-{
+void HWC2On1Adapter::Layer::addReleaseFence(int fenceFd) {
     ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
     mReleaseFence.add(fenceFd);
 }
 
-const sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const
-{
+const sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const {
     return mReleaseFence.get();
 }
 
-void HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer,
-        bool applyAllState)
-{
-    applyCommonState(hwc1Layer, applyAllState);
-    auto compositionType = mCompositionType.getPendingValue();
-    if (compositionType == Composition::SolidColor) {
-        applySolidColorState(hwc1Layer, applyAllState);
-    } else if (compositionType == Composition::Sideband) {
-        applySidebandState(hwc1Layer, applyAllState);
-    } else {
-        applyBufferState(hwc1Layer);
+void HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer) {
+    applyCommonState(hwc1Layer);
+    applyCompositionType(hwc1Layer);
+    switch (mCompositionType) {
+        case Composition::SolidColor : applySolidColorState(hwc1Layer); break;
+        case Composition::Sideband : applySidebandState(hwc1Layer); break;
+        default: applyBufferState(hwc1Layer); break;
     }
-    applyCompositionType(hwc1Layer, applyAllState);
 }
 
-// Layer dump helpers
-
 static std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
-        const std::vector<hwc_rect_t>& surfaceDamage)
-{
+        const std::vector<hwc_rect_t>& surfaceDamage) {
     std::string regions;
     regions += "        Visible Region";
     regions.resize(40, ' ');
@@ -2182,40 +2050,38 @@
     return regions;
 }
 
-std::string HWC2On1Adapter::Layer::dump() const
-{
+std::string HWC2On1Adapter::Layer::dump() const {
     std::stringstream output;
     const char* fill = "      ";
 
-    output << fill << to_string(mCompositionType.getPendingValue());
+    output << fill << to_string(mCompositionType);
     output << " Layer  HWC2/1: " << mId << "/" << mHwc1Id << "  ";
     output << "Z: " << mZ;
-    if (mCompositionType.getValue() == HWC2::Composition::SolidColor) {
-        output << "  " << colorString(mColor.getValue());
-    } else if (mCompositionType.getValue() == HWC2::Composition::Sideband) {
-        output << "  Handle: " << mSidebandStream.getValue() << '\n';
+    if (mCompositionType == HWC2::Composition::SolidColor) {
+        output << "  " << colorString(mColor);
+    } else if (mCompositionType == HWC2::Composition::Sideband) {
+        output << "  Handle: " << mSidebandStream << '\n';
     } else {
         output << "  Buffer: " << mBuffer.getBuffer() << "/" <<
                 mBuffer.getFence() << '\n';
         output << fill << "  Display frame [LTRB]: " <<
-                rectString(mDisplayFrame.getValue()) << '\n';
+                rectString(mDisplayFrame) << '\n';
         output << fill << "  Source crop: " <<
-                frectString(mSourceCrop.getValue()) << '\n';
-        output << fill << "  Transform: " << to_string(mTransform.getValue());
-        output << "  Blend mode: " << to_string(mBlendMode.getValue());
-        if (mPlaneAlpha.getValue() != 1.0f) {
+                frectString(mSourceCrop) << '\n';
+        output << fill << "  Transform: " << to_string(mTransform);
+        output << "  Blend mode: " << to_string(mBlendMode);
+        if (mPlaneAlpha != 1.0f) {
             output << "  Alpha: " <<
-                alphaString(mPlaneAlpha.getValue()) << '\n';
+                alphaString(mPlaneAlpha) << '\n';
         } else {
             output << '\n';
         }
-        output << regionStrings(mVisibleRegion.getValue(), mSurfaceDamage);
+        output << regionStrings(mVisibleRegion, mSurfaceDamage);
     }
     return output.str();
 }
 
-static int getHwc1Blending(HWC2::BlendMode blendMode)
-{
+static int getHwc1Blending(HWC2::BlendMode blendMode) {
     switch (blendMode) {
         case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
         case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
@@ -2223,168 +2089,124 @@
     }
 }
 
-void HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer,
-        bool applyAllState)
-{
+void HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer) {
     auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
-    if (applyAllState || mBlendMode.isDirty()) {
-        hwc1Layer.blending = getHwc1Blending(mBlendMode.getPendingValue());
-        mBlendMode.latch();
-    }
-    if (applyAllState || mDisplayFrame.isDirty()) {
-        hwc1Layer.displayFrame = mDisplayFrame.getPendingValue();
-        mDisplayFrame.latch();
-    }
-    if (applyAllState || mPlaneAlpha.isDirty()) {
-        auto pendingAlpha = mPlaneAlpha.getPendingValue();
-        if (minorVersion < 2) {
-            mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
-        } else {
-            hwc1Layer.planeAlpha =
-                    static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
-        }
-        mPlaneAlpha.latch();
-    }
-    if (applyAllState || mSourceCrop.isDirty()) {
-        if (minorVersion < 3) {
-            auto pending = mSourceCrop.getPendingValue();
-            hwc1Layer.sourceCropi.left =
-                    static_cast<int32_t>(std::ceil(pending.left));
-            hwc1Layer.sourceCropi.top =
-                    static_cast<int32_t>(std::ceil(pending.top));
-            hwc1Layer.sourceCropi.right =
-                    static_cast<int32_t>(std::floor(pending.right));
-            hwc1Layer.sourceCropi.bottom =
-                    static_cast<int32_t>(std::floor(pending.bottom));
-        } else {
-            hwc1Layer.sourceCropf = mSourceCrop.getPendingValue();
-        }
-        mSourceCrop.latch();
-    }
-    if (applyAllState || mTransform.isDirty()) {
-        hwc1Layer.transform =
-                static_cast<uint32_t>(mTransform.getPendingValue());
-        mTransform.latch();
-    }
-    if (applyAllState || mVisibleRegion.isDirty()) {
-        auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
+    hwc1Layer.blending = getHwc1Blending(mBlendMode);
+    hwc1Layer.displayFrame = mDisplayFrame;
 
-        std::free(const_cast<hwc_rect_t*>(hwc1VisibleRegion.rects));
+    auto pendingAlpha = mPlaneAlpha;
+    if (minorVersion < 2) {
+        mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
+    } else {
+        hwc1Layer.planeAlpha =
+                static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
+    }
 
-        auto pending = mVisibleRegion.getPendingValue();
-        hwc_rect_t* newRects = static_cast<hwc_rect_t*>(
-                std::malloc(sizeof(hwc_rect_t) * pending.size()));
-        std::copy(pending.begin(), pending.end(), newRects);
-        hwc1VisibleRegion.rects = const_cast<const hwc_rect_t*>(newRects);
-        hwc1VisibleRegion.numRects = pending.size();
-        mVisibleRegion.latch();
+    if (minorVersion < 3) {
+        auto pending = mSourceCrop;
+        hwc1Layer.sourceCropi.left =
+                static_cast<int32_t>(std::ceil(pending.left));
+        hwc1Layer.sourceCropi.top =
+                static_cast<int32_t>(std::ceil(pending.top));
+        hwc1Layer.sourceCropi.right =
+                static_cast<int32_t>(std::floor(pending.right));
+        hwc1Layer.sourceCropi.bottom =
+                static_cast<int32_t>(std::floor(pending.bottom));
+    } else {
+        hwc1Layer.sourceCropf = mSourceCrop;
+    }
+
+    hwc1Layer.transform = static_cast<uint32_t>(mTransform);
+
+    auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
+    hwc1VisibleRegion.numRects = mVisibleRegion.size();
+    hwc_rect_t* rects = mDisplay.GetRects(hwc1VisibleRegion.numRects);
+    hwc1VisibleRegion.rects = rects;
+    for (size_t i = 0; i < mVisibleRegion.size(); i++) {
+        rects[i] = mVisibleRegion[i];
     }
 }
 
-void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer,
-        bool applyAllState)
-{
-    if (applyAllState || mColor.isDirty()) {
-        // If the device does not support background color it is likely to make
-        // assumption regarding backgroundColor and handle (both fields occupy
-        // the same location in hwc_layer_1_t union).
-        // To not confuse these devices we don't set background color and we
-        // make sure handle is a null pointer.
-        if (mDisplay.getDevice().supportsBackgroundColor()) {
-            hwc1Layer.backgroundColor = mColor.getPendingValue();
-            mHasUnsupportedBackgroundColor = false;
-        } else {
-            hwc1Layer.handle = nullptr;
-            mHasUnsupportedBackgroundColor = true;
-        }
-        mColor.latch();
+void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer) {
+    // If the device does not support background color it is likely to make
+    // assumption regarding backgroundColor and handle (both fields occupy
+    // the same location in hwc_layer_1_t union).
+    // To not confuse these devices we don't set background color and we
+    // make sure handle is a null pointer.
+    if (hasUnsupportedBackgroundColor()) {
+        hwc1Layer.handle = nullptr;
+    } else {
+        hwc1Layer.backgroundColor = mColor;
     }
 }
 
-void HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer,
-        bool applyAllState)
-{
-    if (applyAllState || mSidebandStream.isDirty()) {
-        hwc1Layer.sidebandStream = mSidebandStream.getPendingValue();
-        mSidebandStream.latch();
-    }
+void HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer) {
+    hwc1Layer.sidebandStream = mSidebandStream;
 }
 
-void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer)
-{
+void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) {
     hwc1Layer.handle = mBuffer.getBuffer();
     hwc1Layer.acquireFenceFd = mBuffer.getFence();
 }
 
-void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
-        bool applyAllState)
-{
+void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer) {
     // HWC1 never supports color transforms or dataspaces and only sometimes
     // supports plane alpha (depending on the version). These require us to drop
     // some or all layers to client composition.
-    ALOGV("applyCompositionType");
-    ALOGV("mHasUnsupportedPlaneAlpha = %d", mHasUnsupportedPlaneAlpha);
-    ALOGV("mDisplay.hasColorTransform() = %d", mDisplay.hasColorTransform());
-    ALOGV("mHasUnsupportedBackgroundColor = %d", mHasUnsupportedBackgroundColor);
-
     if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
-        mHasUnsupportedBackgroundColor) {
+            hasUnsupportedBackgroundColor()) {
         hwc1Layer.compositionType = HWC_FRAMEBUFFER;
         hwc1Layer.flags = HWC_SKIP_LAYER;
         return;
     }
 
-    if (applyAllState || mCompositionType.isDirty()) {
-        hwc1Layer.flags = 0;
-        switch (mCompositionType.getPendingValue()) {
-            case Composition::Client:
+    hwc1Layer.flags = 0;
+    switch (mCompositionType) {
+        case Composition::Client:
+            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+            hwc1Layer.flags |= HWC_SKIP_LAYER;
+            break;
+        case Composition::Device:
+            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+            break;
+        case Composition::SolidColor:
+            // In theory the following line should work, but since the HWC1
+            // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
+            // devices may not work correctly. To be on the safe side, we
+            // fall back to client composition.
+            //
+            // hwc1Layer.compositionType = HWC_BACKGROUND;
+            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+            hwc1Layer.flags |= HWC_SKIP_LAYER;
+            break;
+        case Composition::Cursor:
+            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+            if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
+                hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
+            }
+            break;
+        case Composition::Sideband:
+            if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
+                hwc1Layer.compositionType = HWC_SIDEBAND;
+            } else {
                 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                 hwc1Layer.flags |= HWC_SKIP_LAYER;
-                break;
-            case Composition::Device:
-                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
-                break;
-            case Composition::SolidColor:
-                // In theory the following line should work, but since the HWC1
-                // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
-                // devices may not work correctly. To be on the safe side, we
-                // fall back to client composition.
-                //
-                // hwc1Layer.compositionType = HWC_BACKGROUND;
-                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
-                hwc1Layer.flags |= HWC_SKIP_LAYER;
-                break;
-            case Composition::Cursor:
-                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
-                if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
-                    hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
-                }
-                break;
-            case Composition::Sideband:
-                if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
-                    hwc1Layer.compositionType = HWC_SIDEBAND;
-                } else {
-                    hwc1Layer.compositionType = HWC_FRAMEBUFFER;
-                    hwc1Layer.flags |= HWC_SKIP_LAYER;
-                }
-                break;
-            default:
-                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
-                hwc1Layer.flags |= HWC_SKIP_LAYER;
-                break;
-        }
-        ALOGV("Layer %" PRIu64 " %s set to %d", mId,
-                to_string(mCompositionType.getPendingValue()).c_str(),
-                hwc1Layer.compositionType);
-        ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, "    and skipping");
-        mCompositionType.latch();
+            }
+            break;
+        default:
+            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+            hwc1Layer.flags |= HWC_SKIP_LAYER;
+            break;
     }
+    ALOGV("Layer %" PRIu64 " %s set to %d", mId,
+            to_string(mCompositionType).c_str(),
+            hwc1Layer.compositionType);
+    ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, "    and skipping");
 }
 
 // Adapter helpers
 
-void HWC2On1Adapter::populateCapabilities()
-{
+void HWC2On1Adapter::populateCapabilities() {
     ALOGV("populateCapabilities");
     if (mHwc1MinorVersion >= 3U) {
         int supportedTypes = 0;
@@ -2412,8 +2234,7 @@
     }
 }
 
-HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id)
-{
+HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) {
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
 
     auto display = mDisplays.find(id);
@@ -2425,8 +2246,7 @@
 }
 
 std::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
-        hwc2_display_t displayId, hwc2_layer_t layerId)
-{
+        hwc2_display_t displayId, hwc2_layer_t layerId) {
     auto display = getDisplay(displayId);
     if (!display) {
         return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
@@ -2444,22 +2264,19 @@
     return std::make_tuple(layer.get(), Error::None);
 }
 
-void HWC2On1Adapter::populatePrimary()
-{
+void HWC2On1Adapter::populatePrimary() {
     ALOGV("populatePrimary");
 
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
 
-    auto display =
-            std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
+    auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
     mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
     display->setHwc1Id(HWC_DISPLAY_PRIMARY);
     display->populateConfigs();
     mDisplays.emplace(display->getId(), std::move(display));
 }
 
-bool HWC2On1Adapter::prepareAllDisplays()
-{
+bool HWC2On1Adapter::prepareAllDisplays() {
     ATRACE_CALL();
 
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
@@ -2476,24 +2293,23 @@
         return false;
     }
 
+    // Build an array of hwc_display_contents_1 to call prepare() on HWC1.
+    mHwc1Contents.clear();
+
     // Always push the primary display
-    std::vector<HWC2On1Adapter::Display::HWC1Contents> requestedContents;
     auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
     auto& primaryDisplay = mDisplays[primaryDisplayId];
-    auto primaryDisplayContents = primaryDisplay->cloneRequestedContents();
-    requestedContents.push_back(std::move(primaryDisplayContents));
+    mHwc1Contents.push_back(primaryDisplay->getDisplayContents());
 
     // Push the external display, if present
     if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
         auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
         auto& externalDisplay = mDisplays[externalDisplayId];
-        auto externalDisplayContents =
-                externalDisplay->cloneRequestedContents();
-        requestedContents.push_back(std::move(externalDisplayContents));
+        mHwc1Contents.push_back(externalDisplay->getDisplayContents());
     } else {
         // Even if an external display isn't present, we still need to send
         // at least two displays down to HWC1
-        requestedContents.push_back(nullptr);
+        mHwc1Contents.push_back(nullptr);
     }
 
     // Push the hardware virtual display, if supported and present
@@ -2501,17 +2317,13 @@
         if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
             auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
             auto& virtualDisplay = mDisplays[virtualDisplayId];
-            auto virtualDisplayContents =
-                    virtualDisplay->cloneRequestedContents();
-            requestedContents.push_back(std::move(virtualDisplayContents));
+            mHwc1Contents.push_back(virtualDisplay->getDisplayContents());
         } else {
-            requestedContents.push_back(nullptr);
+            mHwc1Contents.push_back(nullptr);
         }
     }
 
-    mHwc1Contents.clear();
-    for (auto& displayContents : requestedContents) {
-        mHwc1Contents.push_back(displayContents.get());
+    for (auto& displayContents : mHwc1Contents) {
         if (!displayContents) {
             continue;
         }
@@ -2549,14 +2361,13 @@
 
         auto displayId = mHwc1DisplayMap[hwc1Id];
         auto& display = mDisplays[displayId];
-        display->setReceivedContents(std::move(requestedContents[hwc1Id]));
+        display->generateChanges();
     }
 
     return true;
 }
 
-Error HWC2On1Adapter::setAllDisplays()
-{
+Error HWC2On1Adapter::setAllDisplays() {
     ATRACE_CALL();
 
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
@@ -2602,14 +2413,13 @@
     return Error::None;
 }
 
-void HWC2On1Adapter::hwc1Invalidate()
-{
+void HWC2On1Adapter::hwc1Invalidate() {
     ALOGV("Received hwc1Invalidate");
 
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
 
     // If the HWC2-side callback hasn't been registered yet, buffer this until
-    // it is registered
+    // it is registered.
     if (mCallbacks.count(Callback::Refresh) == 0) {
         mHasPendingInvalidate = true;
         return;
@@ -2621,7 +2431,7 @@
         displays.emplace_back(displayPair.first);
     }
 
-    // Call back without the state lock held
+    // Call back without the state lock held.
     lock.unlock();
 
     auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
@@ -2630,14 +2440,13 @@
     }
 }
 
-void HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp)
-{
+void HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) {
     ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
 
     std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
 
     // If the HWC2-side callback hasn't been registered yet, buffer this until
-    // it is registered
+    // it is registered.
     if (mCallbacks.count(Callback::Vsync) == 0) {
         mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
         return;
@@ -2651,15 +2460,14 @@
     const auto& callbackInfo = mCallbacks[Callback::Vsync];
     auto displayId = mHwc1DisplayMap[hwc1DisplayId];
 
-    // Call back without the state lock held
+    // Call back without the state lock held.
     lock.unlock();
 
     auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
     vsync(callbackInfo.data, displayId, timestamp);
 }
 
-void HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected)
-{
+void HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected) {
     ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
 
     if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
@@ -2714,5 +2522,4 @@
             HWC2::Connection::Disconnected : HWC2::Connection::Connected;
     hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
 }
-
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
index df33ec3..408bc41 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
@@ -134,11 +134,6 @@
                     const std::shared_ptr<Layer>& rhs);
     };
 
-    class DisplayContentsDeleter {
-        public:
-            void operator()(struct hwc_display_contents_1* contents);
-    };
-
     // The semantics of the fences returned by the device differ between
     // hwc1.set() and hwc2.present(). Read hwcomposer.h and hwcomposer2.h
     // for more information.
@@ -193,9 +188,6 @@
 
     class Display {
         public:
-            typedef std::unique_ptr<hwc_display_contents_1,
-                    DisplayContentsDeleter> HWC1Contents;
-
             Display(HWC2On1Adapter& device, HWC2::DisplayType type);
 
             hwc2_display_t getId() const { return mId; }
@@ -206,10 +198,6 @@
             void setHwc1Id(int32_t id) { mHwc1Id = id; }
             int32_t getHwc1Id() const { return mHwc1Id; }
 
-            void incDirty() { ++mDirtyCount; }
-            void decDirty() { --mDirtyCount; }
-            bool isDirty() const { return mDirtyCount > 0 || mZIsDirty; }
-
             // HWC2 Display functions
             HWC2::Error acceptChanges();
             HWC2::Error createLayer(hwc2_layer_t* outLayerId);
@@ -233,7 +221,14 @@
                     uint32_t* outNumElements, hwc2_layer_t* outLayers,
                     int32_t* outLayerRequests);
             HWC2::Error getType(int32_t* outType);
+
+            // Since HWC1 "presents" (called "set" in HWC1) all Displays
+            // at once, the first call to any Display::present will trigger
+            // present() on all Displays in the Device. Subsequent calls without
+            // first calling validate() are noop (except for duping/returning
+            // the retire fence).
             HWC2::Error present(int32_t* outRetireFence);
+
             HWC2::Error setActiveConfig(hwc2_config_t configId);
             HWC2::Error setClientTarget(buffer_handle_t target,
                     int32_t acquireFence, int32_t dataspace,
@@ -244,6 +239,10 @@
                     int32_t releaseFence);
             HWC2::Error setPowerMode(HWC2::PowerMode mode);
             HWC2::Error setVsyncEnabled(HWC2::Vsync enabled);
+
+            // Since HWC1 "validates" (called "prepare" in HWC1) all Displays
+            // at once, the first call to any Display::validate() will trigger
+            // validate() on all other Displays in the Device.
             HWC2::Error validate(uint32_t* outNumTypes,
                     uint32_t* outNumRequests);
 
@@ -256,10 +255,9 @@
             void populateConfigs(uint32_t width, uint32_t height);
 
             bool prepare();
-            HWC1Contents cloneRequestedContents() const;
 
             // Called after hwc.prepare() with responses from the device.
-            void setReceivedContents(HWC1Contents contents);
+            void generateChanges();
 
             bool hasChanges() const;
             HWC2::Error set(hwc_display_contents_1& hwcContents);
@@ -270,6 +268,13 @@
 
             std::string dump() const;
 
+            // Return a rect from the pool allocated during validate()
+            hwc_rect_t* GetRects(size_t numRects);
+
+            hwc_display_contents_1* getDisplayContents();
+
+            void markGeometryChanged() { mGeometryChanged = true; }
+            void resetGeometryMarker() { mGeometryChanged = false;}
         private:
             class Config {
                 public:
@@ -314,7 +319,7 @@
                     std::unordered_map<android_color_mode_t, uint32_t> mHwc1Ids;
             };
 
-            // Store changes requested from the device upon calling prepare().
+            // Stores changes requested from the device upon calling prepare().
             // Handles change request to:
             //   - Layer composition type.
             //   - Layer hints.
@@ -363,7 +368,9 @@
             void populateColorModes();
             void initializeActiveConfig();
 
-            void reallocateHwc1Contents();
+            // Creates a bi-directional mapping between index in HWC1
+            // prepare/set array and Layer object. Stores mapping in
+            // mHwc1LayerMap and also updates Layer's attribute mHwc1Id.
             void assignHwc1LayerIds();
 
             // Called after a response to prepare() has been received:
@@ -376,13 +383,16 @@
             void updateLayerRequests(const struct hwc_layer_1& hwc1Layer,
                     const Layer& layer);
 
+            // Set all fields in HWC1 comm array for layer containing the
+            // HWC_FRAMEBUFFER_TARGET (always the last layer).
             void prepareFramebufferTarget();
 
+            // Display ID generator.
             static std::atomic<hwc2_display_t> sNextId;
             const hwc2_display_t mId;
-            HWC2On1Adapter& mDevice;
 
-            std::atomic<size_t> mDirtyCount;
+
+            HWC2On1Adapter& mDevice;
 
             // The state of this display should only be modified from
             // SurfaceFlinger's main loop, with the exception of when dump is
@@ -395,15 +405,18 @@
             // which require locking.
             mutable std::recursive_mutex mStateMutex;
 
-            bool mZIsDirty;
+            // Allocate RAM able to store all layers and rects used for
+            // communication with HWC1. Place allocated RAM in variable
+            // mHwc1RequestedContents.
+            void allocateRequestedContents();
 
             // Array of structs exchanged between client and hwc1 device.
-            HWC1Contents mHwc1RequestedContents; // Sent to device upon calling prepare().
-            HWC1Contents mHwc1ReceivedContents;  // Returned by device after prepare().
-
+            // Sent to device upon calling prepare().
+            std::unique_ptr<hwc_display_contents_1> mHwc1RequestedContents;
+    private:
             DeferredFence mRetireFence;
 
-            // Will only be non-null after the layer has been validated but
+            // Will only be non-null after the Display has been validated and
             // before it has been presented
             std::unique_ptr<Changes> mChanges;
 
@@ -418,15 +431,34 @@
             HWC2::PowerMode mPowerMode;
             HWC2::Vsync mVsyncEnabled;
 
+            // Used to populate HWC1 HWC_FRAMEBUFFER_TARGET layer
             FencedBuffer mClientTarget;
+
+
             FencedBuffer mOutputBuffer;
 
             bool mHasColorTransform;
 
+            // All layers this Display is aware of.
             std::multiset<std::shared_ptr<Layer>, SortLayersByZ> mLayers;
+
+            // Mapping between layer index in array of hwc_display_contents_1*
+            // passed to HWC1 during validate/set and Layer object.
             std::unordered_map<size_t, std::shared_ptr<Layer>> mHwc1LayerMap;
+
+            // All communication with HWC1 via prepare/set is done with one
+            // alloc. This pointer is pointing to a pool of hwc_rect_t.
+            size_t mNumAvailableRects;
+            hwc_rect_t* mNextAvailableRect;
+
+            // True if any of the Layers contained in this Display have been
+            // updated with anything other than a buffer since last call to
+            // Display::set()
+            bool mGeometryChanged;
     };
 
+    // Utility template calling a Display object method directly based on the
+    // hwc2_display_t displayId parameter.
     template <typename ...Args>
     static int32_t callDisplayFunction(hwc2_device_t* device,
             hwc2_display_t displayId, HWC2::Error (Display::*member)(Args...),
@@ -468,7 +500,8 @@
     static int32_t setColorModeHook(hwc2_device_t* device,
             hwc2_display_t display, int32_t /*android_color_mode_t*/ intMode) {
         auto mode = static_cast<android_color_mode_t>(intMode);
-        return callDisplayFunction(device, display, &Display::setColorMode, mode);
+        return callDisplayFunction(device, display, &Display::setColorMode,
+                mode);
     }
 
     static int32_t setPowerModeHook(hwc2_device_t* device,
@@ -485,46 +518,6 @@
                 enabled);
     }
 
-    // Layer functions
-
-    template <typename T>
-    class LatchedState {
-        public:
-            LatchedState(Layer& parent, T initialValue)
-              : mParent(parent),
-                mPendingValue(initialValue),
-                mValue(initialValue) {}
-
-            void setPending(T value) {
-                if (value == mPendingValue) {
-                    return;
-                }
-                if (mPendingValue == mValue) {
-                    mParent.incDirty();
-                } else if (value == mValue) {
-                    mParent.decDirty();
-                }
-                mPendingValue = value;
-            }
-
-            T getValue() const { return mValue; }
-            T getPendingValue() const { return mPendingValue; }
-
-            bool isDirty() const { return mPendingValue != mValue; }
-
-            void latch() {
-                if (isDirty()) {
-                    mValue = mPendingValue;
-                    mParent.decDirty();
-                }
-            }
-
-        private:
-            Layer& mParent;
-            T mPendingValue;
-            T mValue;
-    };
-
     class Layer {
         public:
             explicit Layer(Display& display);
@@ -535,10 +528,6 @@
             hwc2_layer_t getId() const { return mId; }
             Display& getDisplay() const { return mDisplay; }
 
-            void incDirty() { if (mDirtyCount++ == 0) mDisplay.incDirty(); }
-            void decDirty() { if (--mDirtyCount == 0) mDisplay.decDirty(); }
-            bool isDirty() const { return mDirtyCount > 0; }
-
             // HWC2 Layer functions
             HWC2::Error setBuffer(buffer_handle_t buffer, int32_t acquireFence);
             HWC2::Error setCursorPosition(int32_t x, int32_t y);
@@ -558,7 +547,7 @@
             HWC2::Error setZ(uint32_t z);
 
             HWC2::Composition getCompositionType() const {
-                return mCompositionType.getValue();
+                return mCompositionType;
             }
             uint32_t getZ() const { return mZ; }
 
@@ -568,47 +557,57 @@
             void setHwc1Id(size_t id) { mHwc1Id = id; }
             size_t getHwc1Id() const { return mHwc1Id; }
 
-            void applyState(struct hwc_layer_1& hwc1Layer, bool applyAllState);
+            // Write state to HWC1 communication struct.
+            void applyState(struct hwc_layer_1& hwc1Layer);
 
             std::string dump() const;
 
+            std::size_t getNumVisibleRegions() { return mVisibleRegion.size(); }
+
+            std::size_t getNumSurfaceDamages() { return mSurfaceDamage.size(); }
+
+            // True if a layer cannot be properly rendered by the device due
+            // to usage of SolidColor (a.k.a BackgroundColor in HWC1).
+            bool hasUnsupportedBackgroundColor() {
+                return (mCompositionType == HWC2::Composition::SolidColor &&
+                        !mDisplay.getDevice().supportsBackgroundColor());
+            }
         private:
-            void applyCommonState(struct hwc_layer_1& hwc1Layer,
-                    bool applyAllState);
-            void applySolidColorState(struct hwc_layer_1& hwc1Layer,
-                    bool applyAllState);
-            void applySidebandState(struct hwc_layer_1& hwc1Layer,
-                    bool applyAllState);
+            void applyCommonState(struct hwc_layer_1& hwc1Layer);
+            void applySolidColorState(struct hwc_layer_1& hwc1Layer);
+            void applySidebandState(struct hwc_layer_1& hwc1Layer);
             void applyBufferState(struct hwc_layer_1& hwc1Layer);
-            void applyCompositionType(struct hwc_layer_1& hwc1Layer,
-                    bool applyAllState);
+            void applyCompositionType(struct hwc_layer_1& hwc1Layer);
 
             static std::atomic<hwc2_layer_t> sNextId;
             const hwc2_layer_t mId;
             Display& mDisplay;
-            size_t mDirtyCount;
 
             FencedBuffer mBuffer;
             std::vector<hwc_rect_t> mSurfaceDamage;
 
-            LatchedState<HWC2::BlendMode> mBlendMode;
-            LatchedState<hwc_color_t> mColor;
-            LatchedState<HWC2::Composition> mCompositionType;
-            LatchedState<hwc_rect_t> mDisplayFrame;
-            LatchedState<float> mPlaneAlpha;
-            LatchedState<const native_handle_t*> mSidebandStream;
-            LatchedState<hwc_frect_t> mSourceCrop;
-            LatchedState<HWC2::Transform> mTransform;
-            LatchedState<std::vector<hwc_rect_t>> mVisibleRegion;
+            HWC2::BlendMode mBlendMode;
+            hwc_color_t mColor;
+            HWC2::Composition mCompositionType;
+            hwc_rect_t mDisplayFrame;
+            float mPlaneAlpha;
+            const native_handle_t* mSidebandStream;
+            hwc_frect_t mSourceCrop;
+            HWC2::Transform mTransform;
+            std::vector<hwc_rect_t> mVisibleRegion;
+
             uint32_t mZ;
 
             DeferredFence mReleaseFence;
 
             size_t mHwc1Id;
             bool mHasUnsupportedPlaneAlpha;
-            bool mHasUnsupportedBackgroundColor;
     };
 
+    // Utility tempate calling a Layer object method based on ID parameters:
+    // hwc2_display_t displayId
+    // and
+    // hwc2_layer_t layerId
     template <typename ...Args>
     static int32_t callLayerFunction(hwc2_device_t* device,
             hwc2_display_t displayId, hwc2_layer_t layerId,
@@ -677,6 +676,7 @@
     std::vector<struct hwc_display_contents_1*> mHwc1Contents;
     HWC2::Error setAllDisplays();
 
+    // Callbacks
     void hwc1Invalidate();
     void hwc1Vsync(int hwc1DisplayId, int64_t timestamp);
     void hwc1Hotplug(int hwc1DisplayId, int connected);
@@ -698,6 +698,8 @@
     // callbacks or dump
 
     std::map<hwc2_layer_t, std::shared_ptr<Layer>> mLayers;
+
+    // A HWC1 supports only one virtual display.
     std::shared_ptr<Display> mHwc1VirtualDisplay;
 
     // These are potentially accessed from multiple threads, and are protected
@@ -712,10 +714,19 @@
     };
     std::unordered_map<HWC2::Callback, CallbackInfo> mCallbacks;
     bool mHasPendingInvalidate;
+
+    // There is a small gap between the time the HWC1 module is started and
+    // when the callbacks for vsync and hotplugs are registered by the
+    // HWC2on1Adapter. To prevent losing events they are stored in these arrays
+    // and fed to the callback as soon as possible.
     std::vector<std::pair<int, int64_t>> mPendingVsyncs;
     std::vector<std::pair<int, int>> mPendingHotplugs;
 
+    // Mapping between HWC1 display id and Display objects.
     std::map<hwc2_display_t, std::shared_ptr<Display>> mDisplays;
+
+    // Map HWC1 display type (HWC_DISPLAY_PRIMARY, HWC_DISPLAY_EXTERNAL,
+    // HWC_DISPLAY_VIRTUAL) to Display IDs generated by HWC2on1Adapter objects.
     std::unordered_map<int, hwc2_display_t> mHwc1DisplayMap;
 };