SF: Use compositionInfo after HWC changedTypes

Bug: 112259502
Test: cts -m CtsViewTestCases
      SurfaceFlinger_test
      vrflinger_test

Change-Id: I908f439eedfab9ee8241f8ac594465527f93408a
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index d0ccabb..44305df 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -138,8 +138,6 @@
                          bool useIdentityTransform) {
     ATRACE_CALL();
 
-    CompositionInfo& compositionInfo = getBE().compositionInfo;
-
     if (CC_UNLIKELY(mActiveBuffer == 0)) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
@@ -221,7 +219,6 @@
         mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
         mTexture.setFiltering(useFiltering);
         mTexture.setMatrix(textureMatrix);
-        compositionInfo.re.texture = mTexture;
 
         engine.setupLayerTexturing(mTexture);
     } else {
@@ -231,23 +228,6 @@
     engine.disableTexturing();
 }
 
-void BufferLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) {
-    CompositionInfo& compositionInfo = getBE().compositionInfo;
-    auto& engine(mFlinger->getRenderEngine());
-
-    draw(renderArea, useIdentityTransform);
-
-    engine.setupLayerTexturing(compositionInfo.re.texture);
-    engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque,
-            false, compositionInfo.re.color);
-    engine.setSourceDataSpace(compositionInfo.hwc.dataspace);
-    engine.setSourceY410BT2020(compositionInfo.re.Y410BT2020);
-    engine.drawMesh(getBE().getMesh());
-    engine.disableBlending();
-    engine.disableTexturing();
-    engine.setSourceY410BT2020(false);
-}
-
 bool BufferLayer::isHdrY410() const {
     // pixel format is HDR Y410 masquerading as RGBA_1010102
     return (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ &&
@@ -340,6 +320,7 @@
 bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
                                     const std::shared_ptr<FenceTime>& presentFence,
                                     const CompositorTiming& compositorTiming) {
+
     // mFrameLatencyNeeded is true when a new frame was latched for the
     // composition.
     if (!mFrameLatencyNeeded) return false;
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 3319a98..3d06ded 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -77,7 +77,6 @@
     // onDraw - draws the surface.
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) override;
-    void drawNow(const RenderArea& renderArea, bool useIdentityTransform);
 
     bool isHdrY410() const override;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index c29698b..24e3d94 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -45,27 +45,17 @@
                         bool useIdentityTransform) {
     half4 color = getColor();
     if (color.a > 0) {
-        computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
-        getBE().compositionInfo.re.preMultipliedAlpha = getPremultipledAlpha();
-        getBE().compositionInfo.re.opaque = false;
-        getBE().compositionInfo.re.disableTexture = true;
-        getBE().compositionInfo.re.color = color;
+        Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
+        computeGeometry(renderArea, mesh, useIdentityTransform);
+        auto& engine(mFlinger->getRenderEngine());
+        engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
+                                  true /* disableTexture */, color);
+        engine.setSourceDataSpace(mCurrentDataSpace);
+        engine.drawMesh(mesh);
+        engine.disableBlending();
     }
 }
 
-void ColorLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) {
-    CompositionInfo& compositionInfo = getBE().compositionInfo;
-    auto& engine(mFlinger->getRenderEngine());
-
-    draw(renderArea, useIdentityTransform);
-
-    engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque,
-            compositionInfo.re.disableTexture, compositionInfo.re.color);
-    engine.setSourceDataSpace(compositionInfo.hwc.dataspace);
-    engine.drawMesh(getBE().getMesh());
-    engine.disableBlending();
-}
-
 bool ColorLayer::isVisible() const {
     return !isHiddenByPolicy() && getAlpha() > 0.0f;
 }
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 429ad79..aa6b049 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -32,7 +32,6 @@
     virtual const char* getTypeId() const { return "ColorLayer"; }
     virtual void onDraw(const RenderArea& renderArea, const Region& clip,
                         bool useIdentityTransform);
-    void drawNow(const RenderArea&, bool);
     bool isVisible() const override;
 
     void setPerFrameData(const sp<const DisplayDevice>& display) override;
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index 5ad5d56..e9f3059 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -30,8 +30,6 @@
 
 void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) {}
 
-void ContainerLayer::drawNow(const RenderArea&, bool) {}
-
 bool ContainerLayer::isVisible() const {
     return !isHiddenByPolicy();
 }
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 051e765..0b4a181 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -32,7 +32,6 @@
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) override;
-    void drawNow(const RenderArea& renderArea, bool useIdentityTransform) override;
     bool isVisible() const override;
 
     void setPerFrameData(const sp<const DisplayDevice>& display) override;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 0fbd459..aab6c22 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -334,8 +334,9 @@
     return mDisplaySurface->beginFrame(mustRecompose);
 }
 
-status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
-    status_t error = hwc.prepare(*this);
+status_t DisplayDevice::prepareFrame(HWComposer& hwc,
+        std::vector<CompositionInfo>& compositionData) {
+    status_t error = hwc.prepare(*this, compositionData);
     if (error != NO_ERROR) {
         return error;
     }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index da0931e..0ce56fe 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -50,6 +50,7 @@
 class Layer;
 class SurfaceFlinger;
 class HWComposer;
+struct CompositionInfo;
 
 class DisplayDevice : public LightRefBase<DisplayDevice>
 {
@@ -142,7 +143,7 @@
     // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
     // machine happy without actually queueing a buffer if nothing has changed
     status_t beginFrame(bool mustRecompose) const;
-    status_t prepareFrame(HWComposer& hwc);
+    status_t prepareFrame(HWComposer& hwc, std::vector<CompositionInfo>& compositionInfo);
 
     bool hasWideColorGamut() const { return mHasWideColorGamut; }
     // Whether h/w composer has native support for specific HDR type.
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 630cc0b..873de25 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -417,7 +417,8 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::prepare(DisplayDevice& display) {
+status_t HWComposer::prepare(DisplayDevice& display,
+        std::vector<CompositionInfo>& compositionData) {
     ATRACE_CALL();
 
     Mutex::Autolock _l(mDisplayLock);
@@ -488,18 +489,19 @@
 
     displayData.hasClientComposition = false;
     displayData.hasDeviceComposition = false;
-    for (auto& layer : display.getVisibleLayersSortedByZ()) {
-        auto hwcLayer = layer->getHwcLayer(displayId);
+    for (auto& compositionInfo : compositionData) {
+        auto hwcLayer = compositionInfo.hwc.hwcLayer;
 
-        if (changedTypes.count(hwcLayer) != 0) {
+        if (changedTypes.count(&*hwcLayer) != 0) {
             // We pass false so we only update our state and don't call back
             // into the HWC device
-            validateChange(layer->getCompositionType(displayId),
-                    changedTypes[hwcLayer]);
-            layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
+            validateChange(compositionInfo.compositionType,
+                    changedTypes[&*hwcLayer]);
+            compositionInfo.compositionType = changedTypes[&*hwcLayer];
+            compositionInfo.layer->mLayer->setCompositionType(displayId, compositionInfo.compositionType, false);
         }
 
-        switch (layer->getCompositionType(displayId)) {
+        switch (compositionInfo.compositionType) {
             case HWC2::Composition::Client:
                 displayData.hasClientComposition = true;
                 break;
@@ -513,17 +515,17 @@
                 break;
         }
 
-        if (layerRequests.count(hwcLayer) != 0 &&
-                layerRequests[hwcLayer] ==
+        if (layerRequests.count(&*hwcLayer) != 0 &&
+                layerRequests[&*hwcLayer] ==
                         HWC2::LayerRequest::ClearClientTarget) {
-            layer->setClearClientTarget(displayId, true);
+            compositionInfo.hwc.clearClientTarget = true;
         } else {
-            if (layerRequests.count(hwcLayer) != 0) {
+            if (layerRequests.count(&*hwcLayer) != 0) {
                 LOG_DISPLAY_ERROR(displayId,
-                                  ("Unknown layer request " + to_string(layerRequests[hwcLayer]))
+                                  ("Unknown layer request " + to_string(layerRequests[&*hwcLayer]))
                                           .c_str());
             }
-            layer->setClearClientTarget(displayId, false);
+            compositionInfo.hwc.clearClientTarget = false;
         }
     }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 9e01626..cca1f3b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -61,6 +61,7 @@
 class Region;
 class String8;
 class TestableSurfaceFlinger;
+struct CompositionInfo;
 
 namespace Hwc2 {
 class Composer;
@@ -92,7 +93,8 @@
     void destroyLayer(int32_t displayId, HWC2::Layer* layer);
 
     // Asks the HAL what it can do
-    status_t prepare(DisplayDevice& display);
+    status_t prepare(DisplayDevice& display,
+            std::vector<CompositionInfo>& compositionData);
 
     status_t setClientTarget(int32_t displayId, uint32_t slot,
             const sp<Fence>& acquireFence,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 443f410..604ec65 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -76,6 +76,7 @@
     static int32_t sSequence;
 
 public:
+    friend class LayerBE;
     LayerBE& getBE() { return mBE; }
     LayerBE& getBE() const { return mBE; }
     mutable bool contentDirty;
@@ -415,16 +416,6 @@
     void draw(const RenderArea& renderArea);
 
     /*
-     * drawNow uses the renderEngine to draw the layer.  This is different than the
-     * draw function as with the FE/BE split, the draw function runs in the FE and
-     * sets up state for the BE to do the actual drawing.  drawNow is used to tell
-     * the layer to skip the state setup and just go ahead and draw the layer.  This
-     * is used for screen captures which happens separately from the frame
-     * compositing path.
-     */
-    virtual void drawNow(const RenderArea& renderArea, bool useIdentityTransform) = 0;
-
-    /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index 3e04f26..9c6534e 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -46,6 +46,11 @@
     mLayer->onLayerDisplayed(releaseFence);
 }
 
+void LayerBE::clear(RE::RenderEngine& engine) {
+    engine.setupFillWithColor(0, 0, 0, 0);
+    engine.drawMesh(mMesh);
+}
+
 void CompositionInfo::dump(const char* tag) const
 {
     std::string logString;
@@ -89,22 +94,12 @@
         result += base::StringPrintf("[%s]RenderEngine parameters:\n", tag);
     }
 
-    Mesh& mesh = layer->getMesh();
     result += base::StringPrintf("\tblackoutLayer=%d\n", re.blackoutLayer);
     result += base::StringPrintf("\tclearArea=%d\n", re.clearArea);
     result += base::StringPrintf("\tpreMultipliedAlpha=%d\n", re.preMultipliedAlpha);
     result += base::StringPrintf("\topaque=%d\n", re.opaque);
     result += base::StringPrintf("\tdisableTexture=%d\n", re.disableTexture);
-    result += base::StringPrintf("\ttexture:name(%d), target(%d), size(%d/%d)\n", re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
     result += base::StringPrintf("\tuseIdentityTransform=%d\n", re.useIdentityTransform);
-    Mesh::VertexArray<vec2> positions(mesh.getPositionArray<vec2>());
-    result += base::StringPrintf("\tpositions[(%6.1f,%6.1f), (%6.1f,%6.1f), (%6.1f,%6.1f), (%6.1f,%6.1f)]\n",
-            positions[0][0], positions[0][1], positions[1][0], positions[1][1],
-            positions[2][0], positions[2][1], positions[3][0], positions[3][1]);
-    Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
-    result += base::StringPrintf("\ttexCoords[(%6.1f,%6.1f), (%6.1f,%6.1f),(%6.1f,%6.1f),(%6.1f,%6.1f)]\n",
-        texCoords[0][0], texCoords[0][1], texCoords[1][0], texCoords[1][1],
-        texCoords[2][0], texCoords[2][1], texCoords[3][0], texCoords[3][1]);
 }
 
 void CompositionInfo::dump(std::string& result, const char* tag) const
@@ -134,6 +129,4 @@
     }
 }
 
-
-
 }; // namespace android
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index e5110b7..21e7b5c 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 
 #include <renderengine/Mesh.h>
+#include <renderengine/RenderEngine.h>
 #include <renderengine/Texture.h>
 #include <ui/Region.h>
 
@@ -34,6 +35,7 @@
 struct CompositionInfo {
     std::string layerName;
     HWC2::Composition compositionType;
+    bool firstClear = false;
     sp<GraphicBuffer> mBuffer = nullptr;
     int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
     std::shared_ptr<LayerBE> layer;
@@ -59,14 +61,12 @@
         HdrMetadata hdrMetadata;
     } hwc;
     struct {
-        Mesh* mesh;
         bool blackoutLayer = false;
         bool clearArea = false;
         bool preMultipliedAlpha = false;
         bool opaque = false;
         bool disableTexture = false;
         half4 color;
-        Texture texture;
         bool useIdentityTransform = false;
         bool Y410BT2020 = false;
     } re;
@@ -90,10 +90,11 @@
     explicit LayerBE(const LayerBE& layer);
 
     void onLayerDisplayed(const sp<Fence>& releaseFence);
+    void clear(RE::RenderEngine& renderEngine);
     Mesh& getMesh() { return mMesh; }
 
-private:
     Layer*const mLayer;
+private:
     // The mesh used to draw the layer in GLES composition mode
     Mesh mMesh;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 37d0146..e4b7cb4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1594,6 +1594,7 @@
 
 void SurfaceFlinger::doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything)
 {
+    const auto displayId = display->getId();
     // is debugging enabled
     if (CC_LIKELY(!mDebugRegion))
         return;
@@ -1621,7 +1622,8 @@
     }
 
     if (display->isPoweredOn()) {
-        status_t result = display->prepareFrame(*getBE().mHwc);
+        status_t result = display->prepareFrame(
+                *getBE().mHwc, getBE().mCompositionInfo[displayId]);
         ALOGE_IF(result != NO_ERROR,
                  "prepareFrame for display %d failed:"
                  " %d (%s)",
@@ -2020,11 +2022,13 @@
 
 void SurfaceFlinger::prepareFrame(const sp<DisplayDevice>& display)
 {
+    const auto displayId = display->getId();
     if (!display->isPoweredOn()) {
         return;
     }
 
-    status_t result = display->prepareFrame(*getBE().mHwc);
+    status_t result = display->prepareFrame(
+            *getBE().mHwc, getBE().mCompositionInfo[displayId]);
     ALOGE_IF(result != NO_ERROR,
              "prepareFrame for display %d failed:"
              " %d (%s)",
@@ -2952,29 +2956,29 @@
     ALOGV("Rendering client layers");
     const ui::Transform& displayTransform = display->getTransform();
     bool firstLayer = true;
-    for (auto& layer : display->getVisibleLayersSortedByZ()) {
+    for (auto& compositionInfo : getBE().mCompositionInfo[displayId]) {
+        const Region bounds(display->bounds());
         const Region clip(bounds.intersect(
-                displayTransform.transform(layer->visibleRegion)));
-        ALOGV("Layer: %s", layer->getName().string());
-        ALOGV("  Composition type: %s", to_string(layer->getCompositionType(displayId)).c_str());
+                displayTransform.transform(compositionInfo.layer->mLayer->visibleRegion)));
+        ALOGV("Layer: %s", compositionInfo.layerName.c_str());
         if (!clip.isEmpty()) {
-            switch (layer->getCompositionType(displayId)) {
+            switch (compositionInfo.compositionType) {
                 case HWC2::Composition::Cursor:
                 case HWC2::Composition::Device:
                 case HWC2::Composition::Sideband:
                 case HWC2::Composition::SolidColor: {
-                    const Layer::State& state(layer->getDrawingState());
-                    if (layer->getClearClientTarget(displayId) && !firstLayer &&
-                        layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
-                        hasClientComposition) {
+                    const Layer::State& state(compositionInfo.layer->mLayer->getDrawingState());
+                    const bool opaque = compositionInfo.layer->mLayer->isOpaque(state);
+                    if (compositionInfo.hwc.clearClientTarget && !firstLayer &&
+                            opaque && (state.color.a == 1.0f) && hasClientComposition) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
-                        layer->clearWithOpenGL(renderArea);
+                        compositionInfo.layer->mLayer->clearWithOpenGL(renderArea);
                     }
                     break;
                 }
                 case HWC2::Composition::Client: {
-                    layer->draw(renderArea, clip);
+                    compositionInfo.layer->mLayer->draw(renderArea, clip);
                     break;
                 }
                 default:
@@ -5222,7 +5226,7 @@
 
     traverseLayers([&](Layer* layer) {
         if (filtering) layer->setFiltering(true);
-        layer->drawNow(renderArea, useIdentityTransform);
+        layer->draw(renderArea, useIdentityTransform);
         if (filtering) layer->setFiltering(false);
     });
 }