Loading services/surfaceflinger/Tracing/TransactionProtoParser.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -585,7 +585,7 @@ frontend::DisplayInfo TransactionProtoParser::fromProto(const proto::DisplayInfo displayInfo.receivesInput = proto.receives_input(); displayInfo.isSecure = proto.is_secure(); displayInfo.isPrimary = proto.is_primary(); displayInfo.isPrimary = proto.is_virtual(); displayInfo.isVirtual = proto.is_virtual(); displayInfo.rotationFlags = (ui::Transform::RotationFlags)proto.rotation_flags(); displayInfo.transformHint = (ui::Transform::RotationFlags)proto.transform_hint(); return displayInfo; Loading @@ -593,7 +593,7 @@ frontend::DisplayInfo TransactionProtoParser::fromProto(const proto::DisplayInfo void TransactionProtoParser::fromProto( const google::protobuf::RepeatedPtrField<proto::DisplayInfo>& proto, display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> outDisplayInfos) { display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& outDisplayInfos) { outDisplayInfos.clear(); for (const proto::DisplayInfo& displayInfo : proto) { outDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(displayInfo.layer_stack()), Loading services/surfaceflinger/Tracing/TransactionProtoParser.h +5 −4 Original line number Diff line number Diff line Loading @@ -49,15 +49,16 @@ public: proto::TransactionState toProto(const std::map<uint32_t /* layerId */, TracingLayerState>&); proto::LayerCreationArgs toProto(const LayerCreationArgs& args); proto::LayerState toProto(const ResolvedComposerState&); proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack); static proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack); TransactionState fromProto(const proto::TransactionState&); void mergeFromProto(const proto::LayerState&, TracingLayerState& outState); void fromProto(const proto::LayerCreationArgs&, LayerCreationArgs& outArgs); std::unique_ptr<FlingerDataMapper> mMapper; frontend::DisplayInfo fromProto(const proto::DisplayInfo&); void fromProto(const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&, display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> outDisplayInfos); static frontend::DisplayInfo fromProto(const proto::DisplayInfo&); static void fromProto( const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&, display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& outDisplayInfos); private: proto::DisplayState toProto(const DisplayState&); Loading services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,16 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile, for (int j = 0; j < entry.transactions_size(); j++) { // apply transactions TransactionState transaction = parser.fromProto(entry.transactions(j)); for (auto& resolvedComposerState : transaction.states) { if (resolvedComposerState.state.what & layer_state_t::eInputInfoChanged) { if (!resolvedComposerState.state.windowInfoHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL)) { // create a fake token since the FE expects a valid token resolvedComposerState.state.windowInfoHandle->editInfo()->token = sp<BBinder>::make(); } } } transactions.emplace_back(std::move(transaction)); } Loading services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp +22 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <unordered_map> #include <LayerProtoHelper.h> #include <LayerTraceGenerator.h> #include <Tracing/TransactionProtoParser.h> #include <layerproto/LayerProtoHeader.h> Loading Loading @@ -94,11 +95,14 @@ struct LayerInfo { float y; uint32_t bufferWidth; uint32_t bufferHeight; Rect touchableRegionBounds; }; bool operator==(const LayerInfo& lh, const LayerInfo& rh) { return std::make_tuple(lh.id, lh.name, lh.parent, lh.z, lh.curr_frame) == std::make_tuple(rh.id, rh.name, rh.parent, rh.z, rh.curr_frame); return std::make_tuple(lh.id, lh.name, lh.parent, lh.z, lh.curr_frame, lh.bufferWidth, lh.bufferHeight, lh.touchableRegionBounds) == std::make_tuple(rh.id, rh.name, rh.parent, rh.z, rh.curr_frame, rh.bufferWidth, rh.bufferHeight, rh.touchableRegionBounds); } bool compareById(const LayerInfo& a, const LayerInfo& b) { Loading @@ -109,7 +113,9 @@ inline void PrintTo(const LayerInfo& info, ::std::ostream* os) { *os << "Layer [" << info.id << "] name=" << info.name << " parent=" << info.parent << " z=" << info.z << " curr_frame=" << info.curr_frame << " x=" << info.x << " y=" << info.y << " bufferWidth=" << info.bufferWidth << " bufferHeight=" << info.bufferHeight; << " bufferHeight=" << info.bufferHeight << "touchableRegionBounds={" << info.touchableRegionBounds.left << "," << info.touchableRegionBounds.top << "," << info.touchableRegionBounds.right << "," << info.touchableRegionBounds.bottom << "}"; } struct find_id : std::unary_function<LayerInfo, bool> { Loading @@ -119,6 +125,17 @@ struct find_id : std::unary_function<LayerInfo, bool> { }; static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& proto) { Rect touchableRegionBounds = Rect::INVALID_RECT; // ignore touchable region for layers without buffers, the new fe aggressively avoids // calculating state for layers that are not visible which could lead to mismatches if (proto.has_input_window_info() && proto.input_window_info().has_touchable_region() && proto.has_active_buffer()) { Region touchableRegion; LayerProtoHelper::readFromProto(proto.input_window_info().touchable_region(), touchableRegion); touchableRegionBounds = touchableRegion.bounds(); } return {proto.id(), proto.name(), proto.parent(), Loading @@ -127,7 +144,8 @@ static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& pr proto.has_position() ? proto.position().x() : -1, proto.has_position() ? proto.position().y() : -1, proto.has_active_buffer() ? proto.active_buffer().width() : 0, proto.has_active_buffer() ? proto.active_buffer().height() : 0}; proto.has_active_buffer() ? proto.active_buffer().height() : 0, touchableRegionBounds}; } TEST_P(TransactionTraceTestSuite, validateEndState) { Loading services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <limits> // std::numeric_limits #include <gui/SurfaceComposerClient.h> #include <ui/Rotation.h> #include "LayerProtoHelper.h" #include "Tracing/TransactionProtoParser.h" Loading Loading @@ -103,4 +104,48 @@ TEST(TransactionProtoParserTest, parse) { ASSERT_EQ(t1.displays[0].token, t2.displays[0].token); } TEST(TransactionProtoParserTest, parseDisplayInfo) { frontend::DisplayInfo d1; d1.info.displayId = 42; d1.info.logicalWidth = 43; d1.info.logicalHeight = 44; d1.info.transform.set(1, 2, 3, 4); d1.transform = d1.info.transform.inverse(); d1.receivesInput = true; d1.isSecure = false; d1.isPrimary = true; d1.isVirtual = false; d1.rotationFlags = ui::Transform::ROT_180; d1.transformHint = ui::Transform::ROT_90; const uint32_t layerStack = 2; google::protobuf::RepeatedPtrField<proto::DisplayInfo> displayProtos; auto displayInfoProto = displayProtos.Add(); *displayInfoProto = TransactionProtoParser::toProto(d1, layerStack); display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> displayInfos; TransactionProtoParser::fromProto(displayProtos, displayInfos); ASSERT_TRUE(displayInfos.contains(ui::LayerStack::fromValue(layerStack))); frontend::DisplayInfo d2 = displayInfos.get(ui::LayerStack::fromValue(layerStack))->get(); EXPECT_EQ(d1.info.displayId, d2.info.displayId); EXPECT_EQ(d1.info.logicalWidth, d2.info.logicalWidth); EXPECT_EQ(d1.info.logicalHeight, d2.info.logicalHeight); EXPECT_EQ(d1.info.transform.dsdx(), d2.info.transform.dsdx()); EXPECT_EQ(d1.info.transform.dsdy(), d2.info.transform.dsdy()); EXPECT_EQ(d1.info.transform.dtdx(), d2.info.transform.dtdx()); EXPECT_EQ(d1.info.transform.dtdy(), d2.info.transform.dtdy()); EXPECT_EQ(d1.transform.dsdx(), d2.transform.dsdx()); EXPECT_EQ(d1.transform.dsdy(), d2.transform.dsdy()); EXPECT_EQ(d1.transform.dtdx(), d2.transform.dtdx()); EXPECT_EQ(d1.transform.dtdy(), d2.transform.dtdy()); EXPECT_EQ(d1.receivesInput, d2.receivesInput); EXPECT_EQ(d1.isSecure, d2.isSecure); EXPECT_EQ(d1.isVirtual, d2.isVirtual); EXPECT_EQ(d1.rotationFlags, d2.rotationFlags); EXPECT_EQ(d1.transformHint, d2.transformHint); } } // namespace android Loading
services/surfaceflinger/Tracing/TransactionProtoParser.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -585,7 +585,7 @@ frontend::DisplayInfo TransactionProtoParser::fromProto(const proto::DisplayInfo displayInfo.receivesInput = proto.receives_input(); displayInfo.isSecure = proto.is_secure(); displayInfo.isPrimary = proto.is_primary(); displayInfo.isPrimary = proto.is_virtual(); displayInfo.isVirtual = proto.is_virtual(); displayInfo.rotationFlags = (ui::Transform::RotationFlags)proto.rotation_flags(); displayInfo.transformHint = (ui::Transform::RotationFlags)proto.transform_hint(); return displayInfo; Loading @@ -593,7 +593,7 @@ frontend::DisplayInfo TransactionProtoParser::fromProto(const proto::DisplayInfo void TransactionProtoParser::fromProto( const google::protobuf::RepeatedPtrField<proto::DisplayInfo>& proto, display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> outDisplayInfos) { display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& outDisplayInfos) { outDisplayInfos.clear(); for (const proto::DisplayInfo& displayInfo : proto) { outDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(displayInfo.layer_stack()), Loading
services/surfaceflinger/Tracing/TransactionProtoParser.h +5 −4 Original line number Diff line number Diff line Loading @@ -49,15 +49,16 @@ public: proto::TransactionState toProto(const std::map<uint32_t /* layerId */, TracingLayerState>&); proto::LayerCreationArgs toProto(const LayerCreationArgs& args); proto::LayerState toProto(const ResolvedComposerState&); proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack); static proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack); TransactionState fromProto(const proto::TransactionState&); void mergeFromProto(const proto::LayerState&, TracingLayerState& outState); void fromProto(const proto::LayerCreationArgs&, LayerCreationArgs& outArgs); std::unique_ptr<FlingerDataMapper> mMapper; frontend::DisplayInfo fromProto(const proto::DisplayInfo&); void fromProto(const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&, display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> outDisplayInfos); static frontend::DisplayInfo fromProto(const proto::DisplayInfo&); static void fromProto( const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&, display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& outDisplayInfos); private: proto::DisplayState toProto(const DisplayState&); Loading
services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,16 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile, for (int j = 0; j < entry.transactions_size(); j++) { // apply transactions TransactionState transaction = parser.fromProto(entry.transactions(j)); for (auto& resolvedComposerState : transaction.states) { if (resolvedComposerState.state.what & layer_state_t::eInputInfoChanged) { if (!resolvedComposerState.state.windowInfoHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL)) { // create a fake token since the FE expects a valid token resolvedComposerState.state.windowInfoHandle->editInfo()->token = sp<BBinder>::make(); } } } transactions.emplace_back(std::move(transaction)); } Loading
services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp +22 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <unordered_map> #include <LayerProtoHelper.h> #include <LayerTraceGenerator.h> #include <Tracing/TransactionProtoParser.h> #include <layerproto/LayerProtoHeader.h> Loading Loading @@ -94,11 +95,14 @@ struct LayerInfo { float y; uint32_t bufferWidth; uint32_t bufferHeight; Rect touchableRegionBounds; }; bool operator==(const LayerInfo& lh, const LayerInfo& rh) { return std::make_tuple(lh.id, lh.name, lh.parent, lh.z, lh.curr_frame) == std::make_tuple(rh.id, rh.name, rh.parent, rh.z, rh.curr_frame); return std::make_tuple(lh.id, lh.name, lh.parent, lh.z, lh.curr_frame, lh.bufferWidth, lh.bufferHeight, lh.touchableRegionBounds) == std::make_tuple(rh.id, rh.name, rh.parent, rh.z, rh.curr_frame, rh.bufferWidth, rh.bufferHeight, rh.touchableRegionBounds); } bool compareById(const LayerInfo& a, const LayerInfo& b) { Loading @@ -109,7 +113,9 @@ inline void PrintTo(const LayerInfo& info, ::std::ostream* os) { *os << "Layer [" << info.id << "] name=" << info.name << " parent=" << info.parent << " z=" << info.z << " curr_frame=" << info.curr_frame << " x=" << info.x << " y=" << info.y << " bufferWidth=" << info.bufferWidth << " bufferHeight=" << info.bufferHeight; << " bufferHeight=" << info.bufferHeight << "touchableRegionBounds={" << info.touchableRegionBounds.left << "," << info.touchableRegionBounds.top << "," << info.touchableRegionBounds.right << "," << info.touchableRegionBounds.bottom << "}"; } struct find_id : std::unary_function<LayerInfo, bool> { Loading @@ -119,6 +125,17 @@ struct find_id : std::unary_function<LayerInfo, bool> { }; static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& proto) { Rect touchableRegionBounds = Rect::INVALID_RECT; // ignore touchable region for layers without buffers, the new fe aggressively avoids // calculating state for layers that are not visible which could lead to mismatches if (proto.has_input_window_info() && proto.input_window_info().has_touchable_region() && proto.has_active_buffer()) { Region touchableRegion; LayerProtoHelper::readFromProto(proto.input_window_info().touchable_region(), touchableRegion); touchableRegionBounds = touchableRegion.bounds(); } return {proto.id(), proto.name(), proto.parent(), Loading @@ -127,7 +144,8 @@ static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& pr proto.has_position() ? proto.position().x() : -1, proto.has_position() ? proto.position().y() : -1, proto.has_active_buffer() ? proto.active_buffer().width() : 0, proto.has_active_buffer() ? proto.active_buffer().height() : 0}; proto.has_active_buffer() ? proto.active_buffer().height() : 0, touchableRegionBounds}; } TEST_P(TransactionTraceTestSuite, validateEndState) { Loading
services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <limits> // std::numeric_limits #include <gui/SurfaceComposerClient.h> #include <ui/Rotation.h> #include "LayerProtoHelper.h" #include "Tracing/TransactionProtoParser.h" Loading Loading @@ -103,4 +104,48 @@ TEST(TransactionProtoParserTest, parse) { ASSERT_EQ(t1.displays[0].token, t2.displays[0].token); } TEST(TransactionProtoParserTest, parseDisplayInfo) { frontend::DisplayInfo d1; d1.info.displayId = 42; d1.info.logicalWidth = 43; d1.info.logicalHeight = 44; d1.info.transform.set(1, 2, 3, 4); d1.transform = d1.info.transform.inverse(); d1.receivesInput = true; d1.isSecure = false; d1.isPrimary = true; d1.isVirtual = false; d1.rotationFlags = ui::Transform::ROT_180; d1.transformHint = ui::Transform::ROT_90; const uint32_t layerStack = 2; google::protobuf::RepeatedPtrField<proto::DisplayInfo> displayProtos; auto displayInfoProto = displayProtos.Add(); *displayInfoProto = TransactionProtoParser::toProto(d1, layerStack); display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> displayInfos; TransactionProtoParser::fromProto(displayProtos, displayInfos); ASSERT_TRUE(displayInfos.contains(ui::LayerStack::fromValue(layerStack))); frontend::DisplayInfo d2 = displayInfos.get(ui::LayerStack::fromValue(layerStack))->get(); EXPECT_EQ(d1.info.displayId, d2.info.displayId); EXPECT_EQ(d1.info.logicalWidth, d2.info.logicalWidth); EXPECT_EQ(d1.info.logicalHeight, d2.info.logicalHeight); EXPECT_EQ(d1.info.transform.dsdx(), d2.info.transform.dsdx()); EXPECT_EQ(d1.info.transform.dsdy(), d2.info.transform.dsdy()); EXPECT_EQ(d1.info.transform.dtdx(), d2.info.transform.dtdx()); EXPECT_EQ(d1.info.transform.dtdy(), d2.info.transform.dtdy()); EXPECT_EQ(d1.transform.dsdx(), d2.transform.dsdx()); EXPECT_EQ(d1.transform.dsdy(), d2.transform.dsdy()); EXPECT_EQ(d1.transform.dtdx(), d2.transform.dtdx()); EXPECT_EQ(d1.transform.dtdy(), d2.transform.dtdy()); EXPECT_EQ(d1.receivesInput, d2.receivesInput); EXPECT_EQ(d1.isSecure, d2.isSecure); EXPECT_EQ(d1.isVirtual, d2.isVirtual); EXPECT_EQ(d1.rotationFlags, d2.rotationFlags); EXPECT_EQ(d1.transformHint, d2.transformHint); } } // namespace android