SF: Move config of HWComposer to setupHwComposer

Eliminate the setupFramebuffer function from Layer and
use setupHwComposer to actually setup the HWComposer.
Additionally, move preComposition and RebuildLayerStacks
into handleMessageInvalidate, as they are more frontend
processing.

Test: Compile/Run manually

Merged-In: Iffffbd8d044513ef3586ae2d25bdd76e077ed1af
Change-Id: Iffffbd8d044513ef3586ae2d25bdd76e077ed1af
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8d5c496..6552781 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1416,7 +1416,16 @@
             bool refreshNeeded = handleMessageTransaction();
             refreshNeeded |= handleMessageInvalidate();
             refreshNeeded |= mRepaintEverything;
+
+            const nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+            preComposition(refreshStartTime);
+            rebuildLayerStacks();
+
+            calculateWorkingSet();
+
             if (refreshNeeded) {
+
                 // Signal a refresh if a transaction modified the window state,
                 // a new buffer was latched, or if HWC has requested a full
                 // repaint
@@ -1445,6 +1454,101 @@
     return handlePageFlip();
 }
 
+void SurfaceFlinger::calculateWorkingSet() {
+    ATRACE_CALL();
+    ALOGV(__FUNCTION__);
+
+    // build the h/w work list
+    if (CC_UNLIKELY(mGeometryInvalid)) {
+        mGeometryInvalid = false;
+        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
+            const auto hwcId = displayDevice->getHwcDisplayId();
+            if (hwcId >= 0) {
+                const Vector<sp<Layer>>& currentLayers(
+                        displayDevice->getVisibleLayersSortedByZ());
+                for (size_t i = 0; i < currentLayers.size(); i++) {
+                    const auto& layer = currentLayers[i];
+
+                    if (!layer->hasHwcLayer(hwcId)) {
+                        if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
+                            layer->forceClientComposition(hwcId);
+                            continue;
+                        }
+                    }
+
+                    layer->setGeometry(displayDevice, i);
+                    if (mDebugDisableHWC || mDebugRegion) {
+                        layer->forceClientComposition(hwcId);
+                    }
+                }
+            }
+        }
+    }
+    mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();
+
+    // Set the per-frame data
+    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
+        auto& displayDevice = mDisplays[displayId];
+        const auto hwcId = displayDevice->getHwcDisplayId();
+
+        if (hwcId < 0) {
+            continue;
+        }
+        if (colorMatrix != mPreviousColorMatrix) {
+            status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix);
+            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
+                    "display %zd: %d", displayId, result);
+        }
+        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+            if ((layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ ||
+                 layer->getDataSpace() == HAL_DATASPACE_BT2020_ITU_PQ) &&
+                    !displayDevice->getHdrSupport()) {
+                layer->forceClientComposition(hwcId);
+            }
+
+            if (layer->getForceClientComposition(hwcId)) {
+                ALOGV("[%s] Requesting Client composition", layer->getName().string());
+                layer->setCompositionType(hwcId, HWC2::Composition::Client);
+                continue;
+            }
+
+            layer->setPerFrameData(displayDevice);
+        }
+
+        if (hasWideColorDisplay) {
+            ColorMode  newColorMode;
+            android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;
+
+            for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+                newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace,
+                        displayDevice->getHdrSupport());
+                ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)",
+                      layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(),
+                      layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace);
+            }
+            newColorMode = pickColorMode(newDataSpace);
+
+            setActiveColorModeInternal(displayDevice, newColorMode);
+        }
+    }
+
+    mPreviousColorMatrix = colorMatrix;
+    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
+        auto& displayDevice = mDisplays[displayId];
+        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+            auto hwcId = displayDevice->getHwcDisplayId();
+            layer->getBE().compositionInfo.compositionType = layer->getCompositionType(hwcId);
+            if (!layer->setHwcLayer(hwcId)) {
+                ALOGV("Need to create HWCLayer for %s", layer->getName().string());
+            }
+            layer->getBE().compositionInfo.hwc.hwid = hwcId;
+            getBE().mCompositionInfo.push_back(layer->getBE().compositionInfo);
+            layer->getBE().compositionInfo.hwc.hwcLayer = nullptr;
+        }
+    }
+}
+
 void SurfaceFlinger::handleMessageRefresh() {
     ATRACE_CALL();
 
@@ -1452,8 +1556,6 @@
 
     nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
-    preComposition(refreshStartTime);
-    rebuildLayerStacks();
     setUpHWComposer();
     doDebugFlashRegions();
     doTracing("handleRefresh");
@@ -1756,17 +1858,21 @@
                         if (!drawRegion.isEmpty()) {
                             layersSortedByZ.add(layer);
                         } else {
-                            // Clear out the HWC layer if this layer was
-                            // previously visible, but no longer is
+                            if (layer->hasHwcLayer(displayDevice->getHwcDisplayId())) {
+                                // Clear out the HWC layer if this layer was
+                                // previously visible, but no longer is
+                                hwcLayerDestroyed = layer->destroyHwcLayer(
+                                        displayDevice->getHwcDisplayId());
+                            }
+                        }
+                    } else {
+                        if (layer->hasHwcLayer(displayDevice->getHwcDisplayId())) {
+                            // WM changes displayDevice->layerStack upon sleep/awake.
+                            // Here we make sure we delete the HWC layers even if
+                            // WM changed their layer stack.
                             hwcLayerDestroyed = layer->destroyHwcLayer(
                                     displayDevice->getHwcDisplayId());
                         }
-                    } else {
-                        // WM changes displayDevice->layerStack upon sleep/awake.
-                        // Here we make sure we delete the HWC layers even if
-                        // WM changed their layer stack.
-                        hwcLayerDestroyed = layer->destroyHwcLayer(
-                                displayDevice->getHwcDisplayId());
                     }
 
                     // If a layer is not going to get a release fence because
@@ -1861,6 +1967,109 @@
     return HAL_DATASPACE_V0_SRGB;
 }
 
+void SurfaceFlinger::configureDeviceComposition(const CompositionInfo& compositionInfo) const
+{
+    HWC2::Error error;
+
+    if (!compositionInfo.hwc.skipGeometry) {
+        if (compositionInfo.hwc.blendMode != HWC2::BlendMode::Invalid) {
+            error = (*compositionInfo.hwc.hwcLayer)->setBlendMode(compositionInfo.hwc.blendMode);
+            ALOGE_IF(error != HWC2::Error::None,
+                     "[SF] Failed to set blend mode %s:"
+                     " %s (%d)",
+                     to_string(compositionInfo.hwc.blendMode).c_str(), to_string(error).c_str(),
+                     static_cast<int32_t>(error));
+        }
+
+        if (compositionInfo.hwc.displayFrame.isValid()) {
+            error = (*compositionInfo.hwc.hwcLayer)->setDisplayFrame(compositionInfo.hwc.displayFrame);
+            ALOGE_IF(error != HWC2::Error::None,
+                    "[SF] Failed to set the display frame [%d, %d, %d, %d] %s (%d)",
+                    compositionInfo.hwc.displayFrame.left,
+                    compositionInfo.hwc.displayFrame.right,
+                    compositionInfo.hwc.displayFrame.top,
+                    compositionInfo.hwc.displayFrame.bottom,
+                    to_string(error).c_str(), static_cast<int32_t>(error));
+        }
+
+        if ((compositionInfo.hwc.sourceCrop.getWidth() > 0) && (compositionInfo.hwc.sourceCrop.getHeight() > 0)) {
+            error = (*compositionInfo.hwc.hwcLayer)->setSourceCrop(compositionInfo.hwc.sourceCrop);
+            ALOGE_IF(error != HWC2::Error::None,
+                    "[SF] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: %s (%d)",
+                    compositionInfo.hwc.sourceCrop.left,
+                    compositionInfo.hwc.sourceCrop.right,
+                    compositionInfo.hwc.sourceCrop.top,
+                    compositionInfo.hwc.sourceCrop.bottom,
+                    to_string(error).c_str(), static_cast<int32_t>(error));
+        }
+
+        error = (*compositionInfo.hwc.hwcLayer)->setPlaneAlpha(compositionInfo.hwc.alpha);
+        ALOGE_IF(error != HWC2::Error::None,
+                 "[SF] Failed to set plane alpha %.3f: "
+                 "%s (%d)",
+                 compositionInfo.hwc.alpha,
+                 to_string(error).c_str(), static_cast<int32_t>(error));
+
+
+        error = (*compositionInfo.hwc.hwcLayer)->setZOrder(compositionInfo.hwc.z);
+        ALOGE_IF(error != HWC2::Error::None,
+                "[SF] Failed to set Z %u: %s (%d)",
+                compositionInfo.hwc.z,
+                to_string(error).c_str(), static_cast<int32_t>(error));
+
+        error = (*compositionInfo.hwc.hwcLayer)->setInfo(compositionInfo.hwc.type, compositionInfo.hwc.appId);
+        ALOGE_IF(error != HWC2::Error::None,
+                "[SF] Failed to set info (%d)",
+                static_cast<int32_t>(error));
+
+        if (compositionInfo.hwc.transform != HWC2::Transform::None) {
+            error = (*compositionInfo.hwc.hwcLayer)->setTransform(compositionInfo.hwc.transform);
+            ALOGE_IF(error != HWC2::Error::None,
+                     "[SF] Failed to set transform %s: "
+                     "%s (%d)",
+                     to_string(compositionInfo.hwc.transform).c_str(), to_string(error).c_str(),
+                     static_cast<int32_t>(error));
+        }
+    }
+
+    if (!compositionInfo.hwc.visibleRegion.isEmpty()) {
+        error = (*compositionInfo.hwc.hwcLayer)->setVisibleRegion(compositionInfo.hwc.visibleRegion);
+        ALOGE_IF(error != HWC2::Error::None,
+                "[SF] Failed to set visible region: %s (%d)",
+                to_string(error).c_str(), static_cast<int32_t>(error));
+    }
+
+    if (!compositionInfo.hwc.surfaceDamage.isEmpty()) {
+        error = (*compositionInfo.hwc.hwcLayer)->setSurfaceDamage(compositionInfo.hwc.surfaceDamage);
+        ALOGE_IF(error != HWC2::Error::None,
+                "[SF] Failed to set surface damage: %s (%d)",
+                to_string(error).c_str(), static_cast<int32_t>(error));
+    }
+
+    error = (*compositionInfo.hwc.hwcLayer)->setCompositionType(compositionInfo.compositionType);
+    ALOGE_IF(error != HWC2::Error::None,
+            "[SF] Failed to set composition type: %s (%d)",
+            to_string(error).c_str(), static_cast<int32_t>(error));
+
+    error = (*compositionInfo.hwc.hwcLayer)->setDataspace(compositionInfo.hwc.dataspace);
+    ALOGE_IF(error != HWC2::Error::None,
+            "[SF] Failed to set dataspace: %s (%d)",
+            to_string(error).c_str(), static_cast<int32_t>(error));
+
+    error = (*compositionInfo.hwc.hwcLayer)->setHdrMetadata(compositionInfo.hwc.hdrMetadata);
+    ALOGE_IF(error != HWC2::Error::None && error != HWC2::Error::Unsupported,
+            "[SF] Failed to set hdrMetadata: %s (%d)",
+            to_string(error).c_str(), static_cast<int32_t>(error));
+
+    if (compositionInfo.updateBuffer) {
+        error = (*compositionInfo.hwc.hwcLayer)->setBuffer(compositionInfo.mBufferSlot,
+                compositionInfo.mBuffer, compositionInfo.hwc.fence);
+        ALOGE_IF(error != HWC2::Error::None,
+                "[SF] Failed to set buffer: %s (%d)",
+                to_string(error).c_str(), static_cast<int32_t>(error));
+    }
+}
+
 void SurfaceFlinger::setUpHWComposer() {
     ATRACE_CALL();
     ALOGV("setUpHWComposer");
@@ -1894,94 +2103,36 @@
         }
     }
 
-    // build the h/w work list
-    if (CC_UNLIKELY(mGeometryInvalid)) {
-        mGeometryInvalid = false;
-        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
-            const auto hwcId = displayDevice->getHwcDisplayId();
-            if (hwcId >= 0) {
-                const Vector<sp<Layer>>& currentLayers(
-                        displayDevice->getVisibleLayersSortedByZ());
-                for (size_t i = 0; i < currentLayers.size(); i++) {
-                    const auto& layer = currentLayers[i];
-                    if (!layer->hasHwcLayer(hwcId)) {
-                        if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
-                            layer->forceClientComposition(hwcId);
-                            continue;
-                        }
-                    }
+    {
+        ATRACE_NAME("Programming_HWCOMPOSER");
+        for (auto compositionInfo : getBE().mCompositionInfo) {
+            ALOGV("[SF] hwcLayer=%p(%lu), compositionType=%d",
+                  static_cast<HWC2::Layer*>(*compositionInfo.hwc.hwcLayer),
+                  compositionInfo.hwc.hwcLayer.use_count(), compositionInfo.compositionType);
 
-                    layer->setGeometry(displayDevice, i);
-                    if (mDebugDisableHWC || mDebugRegion) {
-                        layer->forceClientComposition(hwcId);
-                    }
-                }
+            switch (compositionInfo.compositionType)
+            {
+                case HWC2::Composition::Invalid:
+                    break;
+
+                case HWC2::Composition::Client:
+                    break;
+
+                case HWC2::Composition::SolidColor:
+                    break;
+
+                case HWC2::Composition::Cursor:
+                    break;
+
+                case HWC2::Composition::Sideband:
+                    break;
+
+                case HWC2::Composition::Device:
+                    configureDeviceComposition(compositionInfo);
+                break;
             }
         }
-    }
-
-
-    mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();
-
-    // Set the per-frame data
-    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
-        auto& displayDevice = mDisplays[displayId];
-        const auto hwcId = displayDevice->getHwcDisplayId();
-
-        if (hwcId < 0) {
-            continue;
-        }
-        if (colorMatrix != mPreviousColorMatrix) {
-            status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix);
-            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
-                    "display %zd: %d", displayId, result);
-        }
-        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
-            if ((layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ ||
-                 layer->getDataSpace() == HAL_DATASPACE_BT2020_ITU_PQ) &&
-                    !displayDevice->getHdrSupport()) {
-                layer->forceClientComposition(hwcId);
-            }
-
-            if (layer->getForceClientComposition(hwcId)) {
-                ALOGV("[%s] Requesting Client composition", layer->getName().string());
-                layer->setCompositionType(hwcId, HWC2::Composition::Client);
-                continue;
-            }
-
-            layer->setPerFrameData(displayDevice);
-        }
-
-        if (hasWideColorDisplay) {
-            ColorMode newColorMode;
-            android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;
-
-            for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
-                newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace,
-                        displayDevice->getHdrSupport());
-                ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)",
-                      layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(),
-                      layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace);
-            }
-            newColorMode = pickColorMode(newDataSpace);
-
-            setActiveColorModeInternal(displayDevice, newColorMode);
-        }
-    }
-
-    mPreviousColorMatrix = colorMatrix;
-
-    for (size_t dpy = 0; dpy < mDisplays.size(); dpy++) {
-        sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
-        const auto hwcId = displayDevice->getHwcDisplayId();
-        if (hwcId >= 0) {
-            const Vector<sp<Layer>>& currentLayers(
-                    displayDevice->getVisibleLayersSortedByZ());
-            for (auto& layer : currentLayers) {
-                layer->configureHwcLayer(displayDevice);
-            }
-        }
+        getBE().mCompositionInfo.clear();
     }
 
     for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {