SF: Add frame-composition info dumping

Add frame-composition info as part of command-line option and
as part of dumpAll

Bug: 112259502
Test: manual test
Change-Id: I8dbb4d31918415779f909df658a3c7f32b11452d
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1bb7232..1a2566e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1533,6 +1533,12 @@
     const FloatRect& crop = hwcInfo.sourceCrop;
     result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom);
 
+    result.append("- - - - - - - - - - - - - - - -\n");
+
+    std::string compositionInfoStr;
+    getBE().compositionInfo.dump(compositionInfoStr, "compositionInfo");
+    result.append(compositionInfoStr.c_str());
+
     result.append("- - - - - - - - - - - - - - - -");
     result.append("- - - - - - - - - - - - - - - -");
     result.append("- - - - - - - - - - - - - - -\n");
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index b936b3f..6381a44 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -20,6 +20,11 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include "Layer.h"
+#include "RenderEngine/RenderEngine.h"
+
+#include "android-base/stringprintf.h"
+
+#include <string>
 
 namespace android {
 
@@ -41,50 +46,94 @@
     mLayer->onLayerDisplayed(releaseFence);
 }
 
-void CompositionInfo::dumpHwc(const char* tag) const {
-    ALOGV("[%s]\thwcLayer=%p", tag, hwc.hwcLayer.get());
-    ALOGV("[%s]\tfence=%p", tag, hwc.fence.get());
-    ALOGV("[%s]\ttransform=%d", tag, hwc.transform);
-    ALOGV("[%s]\tz=%d", tag, hwc.z);
-    ALOGV("[%s]\ttype=%d", tag, hwc.type);
-    ALOGV("[%s]\tappId=%d", tag, hwc.appId);
-    ALOGV("[%s]\tdisplayFrame=%4d %4d %4d %4d", tag, hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
-    ALOGV("[%s]\talpha=%.3f", tag, hwc.alpha);
-    ALOGV("[%s]\tsourceCrop=%6.1f %6.1f %6.1f %6.1f", tag, hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
-
-    std::string label = tag;
-    label+=":visibleRegion";
-    hwc.visibleRegion.dump(label.c_str());
-    label = tag;
-    label+=":surfaceDamage";
-    hwc.surfaceDamage.dump(label.c_str());
+void CompositionInfo::dump(const char* tag) const
+{
+    std::string logString;
+    dump(logString, tag);
+    ALOGV("%s", logString.c_str());
 }
 
-void CompositionInfo::dumpRe(const char* tag) const {
-    ALOGV("[%s]\tblackoutLayer=%d", tag, re.blackoutLayer);
-    ALOGV("[%s]\tclearArea=%d", tag, re.clearArea);
-    ALOGV("[%s]\tpreMultipliedAlpha=%d", tag, re.preMultipliedAlpha);
-    ALOGV("[%s]\topaque=%d", tag, re.opaque);
-    ALOGV("[%s]\tdisableTexture=%d", tag, re.disableTexture);
-    ALOGV("[%s]\ttexture:name(%d), target(%d), size(%d/%d)", tag, re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
-    ALOGV("[%s]\tuseIdentityTransform=%d\n", tag, re.useIdentityTransform);
+void CompositionInfo::dumpHwc(std::string& result, const char* tag) const {
+    if (tag == nullptr) {
+        result += base::StringPrintf("HWC parameters\n");
+    } else {
+        result += base::StringPrintf("[%s]HWC parameters\n", tag);
+    }
+
+    result += base::StringPrintf("\thwcLayer=%p\n", static_cast<HWC2::Layer*>(&*hwc.hwcLayer));
+    result += base::StringPrintf("\tfence=%p\n", hwc.fence.get());
+    result += base::StringPrintf("\tblendMode=%d\n", hwc.blendMode);
+    result += base::StringPrintf("\ttransform=%d\n", hwc.transform);
+    result += base::StringPrintf("\tz=%d\n", hwc.z);
+    result += base::StringPrintf("\ttype=%d\n", hwc.type);
+    result += base::StringPrintf("\tappId=%d\n", hwc.appId);
+    result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
+    result += base::StringPrintf("\talpha=%.3f", hwc.alpha);
+    result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
+
+    {
+        //
+        // Keep a conversion from std::string to String8 and back until Region can use std::string
+        //
+        String8 regionString;
+        hwc.visibleRegion.dump(regionString, "visibleRegion");
+        hwc.surfaceDamage.dump(regionString, "surfaceDamage");
+        result += regionString.string();
+    }
 }
 
-void CompositionInfo::dump(const char* tag) const {
-    ALOGV("[%s] CompositionInfo", tag);
-    ALOGV("[%s]\tLayerName: %s", tag, layerName.c_str());
-    ALOGV("[%s]\tCompositionType: %d", tag, compositionType);
-    ALOGV("[%s]\tmBuffer = %p", tag, mBuffer.get());
-    ALOGV("[%s]\tmBufferSlot=%d", tag, mBufferSlot);
+void CompositionInfo::dumpRe(std::string& result, const char* tag) const {
+    if (tag == nullptr) {
+        result += base::StringPrintf("RenderEngine parameters:\n");
+    } else {
+        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
+{
+    if (tag == nullptr) {
+        result += base::StringPrintf("CompositionInfo\n");
+    } else {
+        result += base::StringPrintf("[%s]CompositionInfo\n", tag);
+    }
+    result += base::StringPrintf("\tLayerName: %s\n", layerName.c_str());
+    result += base::StringPrintf("\tCompositionType: %d\n", compositionType);
+    result += base::StringPrintf("\tmBuffer = %p\n", mBuffer.get());
+    result += base::StringPrintf("\tmBufferSlot=%d\n", mBufferSlot);
+    result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
+    result += base::StringPrintf("\talpha=%f\n", hwc.alpha);
+    result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
+
     switch (compositionType) {
         case HWC2::Composition::Device:
-            dumpHwc(tag);
+            dumpHwc(result, tag);
             break;
         case HWC2::Composition::Client:
-            dumpRe(tag);
+            dumpRe(result, tag);
+            break;
         default:
             break;
     }
 }
 
+
+
 }; // namespace android
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index dacdc06..86d4ac4 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -73,8 +73,9 @@
     } re;
 
     void dump(const char* tag) const;
-    void dumpHwc(const char* tag) const;
-    void dumpRe(const char* tag) const;
+    void dump(std::string& result, const char* tag = nullptr) const;
+    void dumpHwc(std::string& result, const char* tag = nullptr) const;
+    void dumpRe(std::string& result, const char* tag = nullptr) const;
 };
 
 class LayerBE {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8cee8d7..4df62af 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -91,6 +91,8 @@
 
 #include <cutils/compiler.h>
 
+#include "android-base/stringprintf.h"
+
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/types.h>
@@ -1463,13 +1465,15 @@
 
     mVsyncModulator.onRefreshed(mHadClientComposition);
 
-    mLayersWithQueuedFrames.clear();
+    getBE().mEndOfFrameCompositionInfo = std::move(getBE().mCompositionInfo);
     for (const auto& [token, display] : mDisplays) {
         const auto displayId = display->getId();
-        for (auto& compositionInfo : getBE().mCompositionInfo[displayId]) {
+        for (auto& compositionInfo : getBE().mEndOfFrameCompositionInfo[displayId]) {
             compositionInfo.hwc.hwcLayer = nullptr;
         }
     }
+
+    mLayersWithQueuedFrames.clear();
 }
 
 
@@ -3911,6 +3915,13 @@
             }
 
             if ((index < numArgs) &&
+                    (args[index] == String16("--frame-composition"))) {
+                index++;
+                dumpFrameCompositionInfo(result);
+                dumpAll = false;
+            }
+
+            if ((index < numArgs) &&
                 (args[index] == String16("--display-identification"))) {
                 index++;
                 dumpDisplayIdentificationData(result);
@@ -4167,6 +4178,31 @@
     result.append("\n");
 }
 
+void SurfaceFlinger::dumpFrameCompositionInfo(String8& result) const {
+    std::string stringResult;
+
+    for (const auto& [token, display] : mDisplays) {
+        const auto displayId = display->getId();
+        if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
+            continue;
+        }
+
+        const auto& compositionInfoIt = getBE().mEndOfFrameCompositionInfo.find(displayId);
+        if (compositionInfoIt == getBE().mEndOfFrameCompositionInfo.end()) {
+            break;
+        }
+        const auto& compositionInfoList = compositionInfoIt->second;
+        stringResult += base::StringPrintf("Display: %d\n", displayId);
+        stringResult += base::StringPrintf("numComponents: %zu\n", compositionInfoList.size());
+        for (const auto& compositionInfo : compositionInfoList) {
+            compositionInfo.dump(stringResult, nullptr);
+            stringResult += base::StringPrintf("\n");
+        }
+    }
+
+    result.append(stringResult.c_str());
+}
+
 LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const {
     LayersProto layersProto;
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
@@ -4293,6 +4329,10 @@
     result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
     result.append("\n");
 
+    result.append("\nFrame-Composition information:\n");
+    dumpFrameCompositionInfo(result);
+    result.append("\n");
+
     /*
      * Dump Display state
      */
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index bdbd6ab..572f5d0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -227,6 +227,7 @@
     int32_t mComposerSequenceId;
 
     std::unordered_map<int32_t, std::vector<CompositionInfo>> mCompositionInfo;
+    std::unordered_map<int32_t, std::vector<CompositionInfo>> mEndOfFrameCompositionInfo;
 };
 
 
@@ -753,6 +754,7 @@
     void dumpBufferingStats(String8& result) const;
     void dumpDisplayIdentificationData(String8& result) const;
     void dumpWideColorInfo(String8& result) const;
+    void dumpFrameCompositionInfo(String8& result) const;
     LayersProto dumpProtoInfo(LayerVector::StateSet stateSet) const;
     LayersProto dumpVisibleLayersProtoInfo(const DisplayDevice& display) const;