Add display proto info

Currently display bounds are calculated in to layer bounds so when proto
files are uploaded, the display bounds are set at the root layer.
However, once display bounds are removed from layer bounds calculation,
the proto information will be missing display info and will be hard to
show a correct visual representation.

Add display proto info so winscope can properly show the display area.

Test: winscope works
Bug: 188792659
Change-Id: I445a892a855c302ab617a9c79bfbf5f217ac5349
Merged-In: I445a892a855c302ab617a9c79bfbf5f217ac5349
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 140436a..7cfc321 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2020,8 +2020,8 @@
         if (buffer != nullptr) {
             LayerProtoHelper::writeToProto(buffer,
                                            [&]() { return layerInfo->mutable_active_buffer(); });
-            LayerProtoHelper::writeToProto(ui::Transform(getBufferTransform()),
-                                           layerInfo->mutable_buffer_transform());
+            LayerProtoHelper::writeToProtoDeprecated(ui::Transform(getBufferTransform()),
+                                                     layerInfo->mutable_buffer_transform());
         }
         layerInfo->set_invalidate(contentDirty);
         layerInfo->set_is_protected(isProtected());
@@ -2035,7 +2035,7 @@
         layerInfo->set_corner_radius(getRoundedCornerState().radius);
         layerInfo->set_background_blur_radius(getBackgroundBlurRadius());
         layerInfo->set_is_trusted_overlay(isTrustedOverlay());
-        LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
+        LayerProtoHelper::writeToProtoDeprecated(transform, layerInfo->mutable_transform());
         LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
                                                [&]() { return layerInfo->mutable_position(); });
         LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
@@ -2110,8 +2110,8 @@
                                        [&]() { return layerInfo->mutable_requested_color(); });
         layerInfo->set_flags(state.flags);
 
-        LayerProtoHelper::writeToProto(requestedTransform,
-                                       layerInfo->mutable_requested_transform());
+        LayerProtoHelper::writeToProtoDeprecated(requestedTransform,
+                                                 layerInfo->mutable_requested_transform());
 
         auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
         if (parent != nullptr) {
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 79f7b1f..1062126 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -98,8 +98,8 @@
     }
 }
 
-void LayerProtoHelper::writeToProto(const ui::Transform& transform,
-                                    TransformProto* transformProto) {
+void LayerProtoHelper::writeToProtoDeprecated(const ui::Transform& transform,
+                                              TransformProto* transformProto) {
     const uint32_t type = transform.getType() | (transform.getOrientation() << 8);
     transformProto->set_type(type);
 
@@ -114,6 +114,22 @@
     }
 }
 
+void LayerProtoHelper::writeTransformToProto(const ui::Transform& transform,
+                                             TransformProto* transformProto) {
+    const uint32_t type = transform.getType() | (transform.getOrientation() << 8);
+    transformProto->set_type(type);
+
+    // Rotations that are 90/180/270 have their own type so the transform matrix can be
+    // reconstructed later. All other rotation have the type UNKNOWN so we need to save the
+    // transform values in that case.
+    if (type & (ui::Transform::SCALE | ui::Transform::UNKNOWN)) {
+        transformProto->set_dsdx(transform.dsdx());
+        transformProto->set_dtdx(transform.dtdx());
+        transformProto->set_dtdy(transform.dtdy());
+        transformProto->set_dsdy(transform.dsdy());
+    }
+}
+
 void LayerProtoHelper::writeToProto(const sp<GraphicBuffer>& buffer,
                                     std::function<ActiveBufferProto*()> getActiveBufferProto) {
     if (buffer->getWidth() != 0 || buffer->getHeight() != 0 || buffer->getStride() != 0 ||
@@ -154,7 +170,7 @@
     proto->set_has_wallpaper(inputInfo.hasWallpaper);
 
     proto->set_global_scale_factor(inputInfo.globalScaleFactor);
-    LayerProtoHelper::writeToProto(inputInfo.transform, proto->mutable_transform());
+    LayerProtoHelper::writeToProtoDeprecated(inputInfo.transform, proto->mutable_transform());
     proto->set_replace_touchable_region_with_crop(inputInfo.replaceTouchableRegionWithCrop);
     auto cropLayer = touchableRegionBounds.promote();
     if (cropLayer != nullptr) {
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index 187ce3d..36e0647 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -37,7 +37,12 @@
                              std::function<FloatRectProto*()> getFloatRectProto);
     static void writeToProto(const Region& region, std::function<RegionProto*()> getRegionProto);
     static void writeToProto(const half4 color, std::function<ColorProto*()> getColorProto);
-    static void writeToProto(const ui::Transform& transform, TransformProto* transformProto);
+    // This writeToProto for transform is incorrect, but due to backwards compatibility, we can't
+    // update Layers to use it. Use writeTransformToProto for any new transform proto data.
+    static void writeToProtoDeprecated(const ui::Transform& transform,
+                                       TransformProto* transformProto);
+    static void writeTransformToProto(const ui::Transform& transform,
+                                      TransformProto* transformProto);
     static void writeToProto(const sp<GraphicBuffer>& buffer,
                              std::function<ActiveBufferProto*()> getActiveBufferProto);
     static void writeToProto(const gui::WindowInfo& inputInfo,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0f7fada..e7456ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -114,6 +114,7 @@
 #include "FrameTracer/FrameTracer.h"
 #include "HdrLayerInfoReporter.h"
 #include "Layer.h"
+#include "LayerProtoHelper.h"
 #include "LayerRenderArea.h"
 #include "LayerVector.h"
 #include "MonitoredProducer.h"
@@ -4660,9 +4661,14 @@
         }
 
         if (dumpLayers) {
-            const LayersProto layersProto = dumpProtoFromMainThread();
+            LayersTraceFileProto traceFileProto = SurfaceTracing::createLayersTraceFileProto();
+            LayersTraceProto* layersTrace = traceFileProto.add_entry();
+            LayersProto layersProto = dumpProtoFromMainThread();
+            layersTrace->mutable_layers()->Swap(&layersProto);
+            dumpDisplayProto(*layersTrace);
+
             if (asProto) {
-                result.append(layersProto.SerializeAsString());
+                result.append(traceFileProto.SerializeAsString());
             } else {
                 // Dump info that we need to access from the main thread
                 const auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
@@ -4934,6 +4940,22 @@
     return layersProto;
 }
 
+void SurfaceFlinger::dumpDisplayProto(LayersTraceProto& layersTraceProto) const {
+    for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
+        DisplayProto* displayProto = layersTraceProto.add_displays();
+        displayProto->set_id(display->getId().value);
+        displayProto->set_name(display->getDisplayName());
+        displayProto->set_layer_stack(display->getLayerStack());
+        LayerProtoHelper::writeSizeToProto(display->getWidth(), display->getHeight(),
+                                           [&]() { return displayProto->mutable_size(); });
+        LayerProtoHelper::writeToProto(display->getLayerStackSpaceRect(), [&]() {
+            return displayProto->mutable_layer_stack_space_rect();
+        });
+        LayerProtoHelper::writeTransformToProto(display->getTransform(),
+                                                displayProto->mutable_transform());
+    }
+}
+
 void SurfaceFlinger::dumpHwc(std::string& result) const {
     getHwComposer().dump(result);
 }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ebc3e4a..e441e0c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1169,6 +1169,8 @@
     LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
     void dumpOffscreenLayersProto(LayersProto& layersProto,
                                   uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+    void dumpDisplayProto(LayersTraceProto& layersTraceProto) const;
+
     // Dumps state from HW Composer
     void dumpHwc(std::string& result) const;
     LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index b4d8a9a..5963737 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -137,14 +137,19 @@
     return writeToFile();
 }
 
+LayersTraceFileProto SurfaceTracing::createLayersTraceFileProto() {
+    LayersTraceFileProto fileProto;
+    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    return fileProto;
+}
+
 status_t SurfaceTracing::Runner::writeToFile() {
     ATRACE_CALL();
 
-    LayersTraceFileProto fileProto;
+    LayersTraceFileProto fileProto = createLayersTraceFileProto();
     std::string output;
 
-    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
-                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
     mBuffer.flush(&fileProto);
     mBuffer.reset(mConfig.bufferSize);
 
@@ -186,7 +191,7 @@
         entry.set_excludes_composition_state(true);
     }
     entry.set_missed_entries(mMissedTraceEntries);
-
+    mFlinger.dumpDisplayProto(entry);
     return entry;
 }
 
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 15a503d..d4cf6f3 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -73,6 +73,7 @@
     };
     void setTraceFlags(uint32_t flags) { mConfig.flags = flags; }
     bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }
+    static LayersTraceFileProto createLayersTraceFileProto();
 
 private:
     class Runner;
diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp
index c8a2b5e..973a439 100644
--- a/services/surfaceflinger/layerproto/Android.bp
+++ b/services/surfaceflinger/layerproto/Android.bp
@@ -13,8 +13,7 @@
 
     srcs: [
         "LayerProtoParser.cpp",
-        "layers.proto",
-        "layerstrace.proto",
+        "*.proto",
     ],
 
     shared_libs: [
diff --git a/services/surfaceflinger/layerproto/common.proto b/services/surfaceflinger/layerproto/common.proto
new file mode 100644
index 0000000..1c73a9f
--- /dev/null
+++ b/services/surfaceflinger/layerproto/common.proto
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+package android.surfaceflinger;
+
+message RectProto {
+  int32 left   = 1;
+  int32 top    = 2;
+  int32 right  = 3;
+  int32 bottom = 4;
+}
+
+message SizeProto {
+  int32 w = 1;
+  int32 h = 2;
+}
+
+message TransformProto {
+  float dsdx = 1;
+  float dtdx = 2;
+  float dsdy = 3;
+  float dtdy = 4;
+  int32 type = 5;
+}
\ No newline at end of file
diff --git a/services/surfaceflinger/layerproto/display.proto b/services/surfaceflinger/layerproto/display.proto
new file mode 100644
index 0000000..ee8830e
--- /dev/null
+++ b/services/surfaceflinger/layerproto/display.proto
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+
+import "frameworks/native/services/surfaceflinger/layerproto/common.proto";
+
+package android.surfaceflinger;
+
+message DisplayProto {
+    uint64 id = 1;
+
+    string name = 2;
+
+    uint32 layer_stack = 3;
+
+    SizeProto size = 4;
+
+    RectProto layer_stack_space_rect = 5;
+
+    TransformProto transform = 6;
+}
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 9f4e7d2..057eabb 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -2,6 +2,9 @@
 
 syntax = "proto3";
 option optimize_for = LITE_RUNTIME;
+
+import "frameworks/native/services/surfaceflinger/layerproto/common.proto";
+
 package android.surfaceflinger;
 
 // Contains a list of all layers.
@@ -140,31 +143,11 @@
   float y = 2;
 }
 
-message SizeProto {
-  int32 w = 1;
-  int32 h = 2;
-}
-
-message TransformProto {
-  float dsdx = 1;
-  float dtdx = 2;
-  float dsdy = 3;
-  float dtdy = 4;
-  int32 type = 5;
-}
-
 message RegionProto {
   reserved 1;  // Previously: uint64 id
   repeated RectProto rect = 2;
 }
 
-message RectProto {
-  int32 left   = 1;
-  int32 top    = 2;
-  int32 right  = 3;
-  int32 bottom = 4;
-}
-
 message FloatRectProto {
   float left = 1;
   float top = 2;
diff --git a/services/surfaceflinger/layerproto/layerstrace.proto b/services/surfaceflinger/layerproto/layerstrace.proto
index 990f3cf..13647b6 100644
--- a/services/surfaceflinger/layerproto/layerstrace.proto
+++ b/services/surfaceflinger/layerproto/layerstrace.proto
@@ -18,6 +18,7 @@
 option optimize_for = LITE_RUNTIME;
 
 import "frameworks/native/services/surfaceflinger/layerproto/layers.proto";
+import "frameworks/native/services/surfaceflinger/layerproto/display.proto";
 
 package android.surfaceflinger;
 
@@ -57,4 +58,6 @@
 
     /* Number of missed entries since the last entry was recorded. */
     optional uint32 missed_entries = 6;
+
+    repeated DisplayProto displays = 7;
 }