diff options
39 files changed, 1184 insertions, 1255 deletions
| diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index eda52bfcb5..1718e0b10f 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -198,9 +198,12 @@ filegroup {          "StartPropertySetThread.cpp",          "SurfaceFlinger.cpp",          "SurfaceFlingerDefaultFactory.cpp", +        "Tracing/LayerDataSource.cpp",          "Tracing/LayerTracing.cpp", +        "Tracing/TransactionDataSource.cpp",          "Tracing/TransactionTracing.cpp",          "Tracing/TransactionProtoParser.cpp", +        "Tracing/tools/LayerTraceGenerator.cpp",          "TransactionCallbackInvoker.cpp",          "TunnelModeEnabledReporter.cpp",      ], diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index cdf7cff76d..9a5173ba9b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -139,7 +139,7 @@ using gui::WindowInfo;  using PresentState = frametimeline::SurfaceFrame::PresentState; -Layer::Layer(const LayerCreationArgs& args) +Layer::Layer(const surfaceflinger::LayerCreationArgs& args)        : sequence(args.sequence),          mFlinger(sp<SurfaceFlinger>::fromExisting(args.flinger)),          mName(base::StringPrintf("%s#%d", args.name.c_str(), sequence)), @@ -1000,8 +1000,8 @@ bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace da          uint32_t flags = ISurfaceComposerClient::eFXSurfaceEffect;          std::string name = mName + "BackgroundColorLayer";          mDrawingState.bgColorLayer = mFlinger->getFactory().createEffectLayer( -                LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), flags, -                                  LayerMetadata())); +                surfaceflinger::LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), flags, +                                                  LayerMetadata()));          // add to child list          addChild(mDrawingState.bgColorLayer); @@ -2203,8 +2203,9 @@ void Layer::setInputInfo(const WindowInfo& info) {      setTransactionFlags(eTransactionNeeded);  } -LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) { -    LayerProto* layerProto = layersProto.add_layers(); +perfetto::protos::LayerProto* Layer::writeToProto(perfetto::protos::LayersProto& layersProto, +                                                  uint32_t traceFlags) { +    perfetto::protos::LayerProto* layerProto = layersProto.add_layers();      writeToProtoDrawingState(layerProto);      writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags); @@ -2221,20 +2222,22 @@ LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) {      return layerProto;  } -void Layer::writeCompositionStateToProto(LayerProto* layerProto, ui::LayerStack layerStack) { +void Layer::writeCompositionStateToProto(perfetto::protos::LayerProto* layerProto, +                                         ui::LayerStack layerStack) {      ftl::FakeGuard guard(mFlinger->mStateLock); // Called from the main thread.      ftl::FakeGuard mainThreadGuard(kMainThreadContext);      // Only populate for the primary display.      if (const auto display = mFlinger->getDisplayFromLayerStack(layerStack)) {          const auto compositionType = getCompositionType(*display); -        layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType)); +        layerProto->set_hwc_composition_type( +                static_cast<perfetto::protos::HwcCompositionType>(compositionType));          LayerProtoHelper::writeToProto(getVisibleRegion(display),                                         [&]() { return layerProto->mutable_visible_region(); });      }  } -void Layer::writeToProtoDrawingState(LayerProto* layerInfo) { +void Layer::writeToProtoDrawingState(perfetto::protos::LayerProto* layerInfo) {      const ui::Transform transform = getTransform();      auto buffer = getExternalTexture();      if (buffer != nullptr) { @@ -2273,8 +2276,8 @@ void Layer::writeToProtoDrawingState(LayerProto* layerInfo) {      layerInfo->set_shadow_radius(mEffectiveShadowRadius);  } -void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet stateSet, -                                    uint32_t traceFlags) { +void Layer::writeToProtoCommonState(perfetto::protos::LayerProto* layerInfo, +                                    LayerVector::StateSet stateSet, uint32_t traceFlags) {      const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;      const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;      const State& state = useDrawing ? mDrawingState : mDrawingState; @@ -2322,15 +2325,11 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet      auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();      if (parent != nullptr) {          layerInfo->set_parent(parent->sequence); -    } else { -        layerInfo->set_parent(-1);      }      auto zOrderRelativeOf = state.zOrderRelativeOf.promote();      if (zOrderRelativeOf != nullptr) {          layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); -    } else { -        layerInfo->set_z_order_relative_of(-1);      }      layerInfo->set_is_relative_of(state.isRelativeOf); @@ -3630,7 +3629,8 @@ Rect Layer::computeBufferCrop(const State& s) {  }  sp<Layer> Layer::createClone(uint32_t mirrorRootId) { -    LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, LayerMetadata()); +    surfaceflinger::LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, +                                           LayerMetadata());      sp<Layer> layer = mFlinger->getFactory().createBufferStateLayer(args);      layer->setInitialValuesForClone(sp<Layer>::fromExisting(this), mirrorRootId);      return layer; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 7b6c56b6a8..dc4ceb0bfa 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -235,7 +235,7 @@ public:          bool useVsyncIdForRefreshRateSelection = false;      }; -    explicit Layer(const LayerCreationArgs& args); +    explicit Layer(const surfaceflinger::LayerCreationArgs& args);      virtual ~Layer();      static bool isLayerFocusedBasedOnPriority(int32_t priority); @@ -634,17 +634,19 @@ public:      bool isRemovedFromCurrentState() const; -    LayerProto* writeToProto(LayersProto& layersProto, uint32_t traceFlags); -    void writeCompositionStateToProto(LayerProto* layerProto, ui::LayerStack layerStack); +    perfetto::protos::LayerProto* writeToProto(perfetto::protos::LayersProto& layersProto, +                                               uint32_t traceFlags); +    void writeCompositionStateToProto(perfetto::protos::LayerProto* layerProto, +                                      ui::LayerStack layerStack);      // Write states that are modified by the main thread. This includes drawing      // state as well as buffer data. This should be called in the main or tracing      // thread. -    void writeToProtoDrawingState(LayerProto* layerInfo); +    void writeToProtoDrawingState(perfetto::protos::LayerProto* layerInfo);      // Write drawing or current state. If writing current state, the caller should hold the      // external mStateLock. If writing drawing state, this function should be called on the      // main or tracing thread. -    void writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet, +    void writeToProtoCommonState(perfetto::protos::LayerProto* layerInfo, LayerVector::StateSet,                                   uint32_t traceFlags = LayerTracing::TRACE_ALL);      gui::WindowInfo::Type getWindowType() const { return mWindowType; } diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp index 341f041086..144e1f5abf 100644 --- a/services/surfaceflinger/LayerProtoHelper.cpp +++ b/services/surfaceflinger/LayerProtoHelper.cpp @@ -29,28 +29,30 @@ using gui::WindowInfo;  namespace surfaceflinger { -void LayerProtoHelper::writePositionToProto(const float x, const float y, -                                            std::function<PositionProto*()> getPositionProto) { +void LayerProtoHelper::writePositionToProto( +        const float x, const float y, +        std::function<perfetto::protos::PositionProto*()> getPositionProto) {      if (x != 0 || y != 0) {          // Use a lambda do avoid writing the object header when the object is empty -        PositionProto* position = getPositionProto(); +        perfetto::protos::PositionProto* position = getPositionProto();          position->set_x(x);          position->set_y(y);      }  } -void LayerProtoHelper::writeSizeToProto(const uint32_t w, const uint32_t h, -                                        std::function<SizeProto*()> getSizeProto) { +void LayerProtoHelper::writeSizeToProto( +        const uint32_t w, const uint32_t h, +        std::function<perfetto::protos::SizeProto*()> getSizeProto) {      if (w != 0 || h != 0) {          // Use a lambda do avoid writing the object header when the object is empty -        SizeProto* size = getSizeProto(); +        perfetto::protos::SizeProto* size = getSizeProto();          size->set_w(w);          size->set_h(h);      }  } -void LayerProtoHelper::writeToProto(const Region& region, -                                    std::function<RegionProto*()> getRegionProto) { +void LayerProtoHelper::writeToProto( +        const Region& region, std::function<perfetto::protos::RegionProto*()> getRegionProto) {      if (region.isEmpty()) {          return;      } @@ -58,7 +60,8 @@ void LayerProtoHelper::writeToProto(const Region& region,      writeToProto(region, getRegionProto());  } -void LayerProtoHelper::writeToProto(const Region& region, RegionProto* regionProto) { +void LayerProtoHelper::writeToProto(const Region& region, +                                    perfetto::protos::RegionProto* regionProto) {      if (region.isEmpty()) {          return;      } @@ -72,7 +75,8 @@ void LayerProtoHelper::writeToProto(const Region& region, RegionProto* regionPro      }  } -void LayerProtoHelper::readFromProto(const RegionProto& regionProto, Region& outRegion) { +void LayerProtoHelper::readFromProto(const perfetto::protos::RegionProto& regionProto, +                                     Region& outRegion) {      for (int i = 0; i < regionProto.rect_size(); i++) {          Rect rect;          readFromProto(regionProto.rect(i), rect); @@ -80,32 +84,34 @@ void LayerProtoHelper::readFromProto(const RegionProto& regionProto, Region& out      }  } -void LayerProtoHelper::writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto) { +void LayerProtoHelper::writeToProto(const Rect& rect, +                                    std::function<perfetto::protos::RectProto*()> getRectProto) {      if (rect.left != 0 || rect.right != 0 || rect.top != 0 || rect.bottom != 0) {          // Use a lambda do avoid writing the object header when the object is empty          writeToProto(rect, getRectProto());      }  } -void LayerProtoHelper::writeToProto(const Rect& rect, RectProto* rectProto) { +void LayerProtoHelper::writeToProto(const Rect& rect, perfetto::protos::RectProto* rectProto) {      rectProto->set_left(rect.left);      rectProto->set_top(rect.top);      rectProto->set_bottom(rect.bottom);      rectProto->set_right(rect.right);  } -void LayerProtoHelper::readFromProto(const RectProto& proto, Rect& outRect) { +void LayerProtoHelper::readFromProto(const perfetto::protos::RectProto& proto, Rect& outRect) {      outRect.left = proto.left();      outRect.top = proto.top();      outRect.bottom = proto.bottom();      outRect.right = proto.right();  } -void LayerProtoHelper::writeToProto(const FloatRect& rect, -                                    std::function<FloatRectProto*()> getFloatRectProto) { +void LayerProtoHelper::writeToProto( +        const FloatRect& rect, +        std::function<perfetto::protos::FloatRectProto*()> getFloatRectProto) {      if (rect.left != 0 || rect.right != 0 || rect.top != 0 || rect.bottom != 0) {          // Use a lambda do avoid writing the object header when the object is empty -        FloatRectProto* rectProto = getFloatRectProto(); +        perfetto::protos::FloatRectProto* rectProto = getFloatRectProto();          rectProto->set_left(rect.left);          rectProto->set_top(rect.top);          rectProto->set_bottom(rect.bottom); @@ -113,10 +119,11 @@ void LayerProtoHelper::writeToProto(const FloatRect& rect,      }  } -void LayerProtoHelper::writeToProto(const half4 color, std::function<ColorProto*()> getColorProto) { +void LayerProtoHelper::writeToProto(const half4 color, +                                    std::function<perfetto::protos::ColorProto*()> getColorProto) {      if (color.r != 0 || color.g != 0 || color.b != 0 || color.a != 0) {          // Use a lambda do avoid writing the object header when the object is empty -        ColorProto* colorProto = getColorProto(); +        perfetto::protos::ColorProto* colorProto = getColorProto();          colorProto->set_r(color.r);          colorProto->set_g(color.g);          colorProto->set_b(color.b); @@ -125,7 +132,7 @@ void LayerProtoHelper::writeToProto(const half4 color, std::function<ColorProto*  }  void LayerProtoHelper::writeToProtoDeprecated(const ui::Transform& transform, -                                              TransformProto* transformProto) { +                                              perfetto::protos::TransformProto* transformProto) {      const uint32_t type = transform.getType() | (transform.getOrientation() << 8);      transformProto->set_type(type); @@ -141,7 +148,7 @@ void LayerProtoHelper::writeToProtoDeprecated(const ui::Transform& transform,  }  void LayerProtoHelper::writeTransformToProto(const ui::Transform& transform, -                                             TransformProto* transformProto) { +                                             perfetto::protos::TransformProto* transformProto) {      const uint32_t type = transform.getType() | (transform.getOrientation() << 8);      transformProto->set_type(type); @@ -156,12 +163,13 @@ void LayerProtoHelper::writeTransformToProto(const ui::Transform& transform,      }  } -void LayerProtoHelper::writeToProto(const renderengine::ExternalTexture& buffer, -                                    std::function<ActiveBufferProto*()> getActiveBufferProto) { +void LayerProtoHelper::writeToProto( +        const renderengine::ExternalTexture& buffer, +        std::function<perfetto::protos::ActiveBufferProto*()> getActiveBufferProto) {      if (buffer.getWidth() != 0 || buffer.getHeight() != 0 || buffer.getUsage() != 0 ||          buffer.getPixelFormat() != 0) {          // Use a lambda do avoid writing the object header when the object is empty -        ActiveBufferProto* activeBufferProto = getActiveBufferProto(); +        auto* activeBufferProto = getActiveBufferProto();          activeBufferProto->set_width(buffer.getWidth());          activeBufferProto->set_height(buffer.getHeight());          activeBufferProto->set_stride(buffer.getUsage()); @@ -171,12 +179,12 @@ void LayerProtoHelper::writeToProto(const renderengine::ExternalTexture& buffer,  void LayerProtoHelper::writeToProto(          const WindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds, -        std::function<InputWindowInfoProto*()> getInputWindowInfoProto) { +        std::function<perfetto::protos::InputWindowInfoProto*()> getInputWindowInfoProto) {      if (inputInfo.token == nullptr) {          return;      } -    InputWindowInfoProto* proto = getInputWindowInfoProto(); +    perfetto::protos::InputWindowInfoProto* proto = getInputWindowInfoProto();      proto->set_layout_params_flags(inputInfo.layoutParamsFlags.get());      proto->set_input_config(inputInfo.inputConfig.get());      using U = std::underlying_type_t<WindowInfo::Type>; @@ -209,7 +217,8 @@ void LayerProtoHelper::writeToProto(      }  } -void LayerProtoHelper::writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto) { +void LayerProtoHelper::writeToProto(const mat4 matrix, +                                    perfetto::protos::ColorTransformProto* colorTransformProto) {      for (int i = 0; i < mat4::ROW_SIZE; i++) {          for (int j = 0; j < mat4::COL_SIZE; j++) {              colorTransformProto->add_val(matrix[i][j]); @@ -217,7 +226,8 @@ void LayerProtoHelper::writeToProto(const mat4 matrix, ColorTransformProto* colo      }  } -void LayerProtoHelper::readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix) { +void LayerProtoHelper::readFromProto( +        const perfetto::protos::ColorTransformProto& colorTransformProto, mat4& matrix) {      for (int i = 0; i < mat4::ROW_SIZE; i++) {          for (int j = 0; j < mat4::COL_SIZE; j++) {              matrix[i][j] = colorTransformProto.val(i * mat4::COL_SIZE + j); @@ -225,7 +235,8 @@ void LayerProtoHelper::readFromProto(const ColorTransformProto& colorTransformPr      }  } -void LayerProtoHelper::writeToProto(const android::BlurRegion region, BlurRegion* proto) { +void LayerProtoHelper::writeToProto(const android::BlurRegion region, +                                    perfetto::protos::BlurRegion* proto) {      proto->set_blur_radius(region.blurRadius);      proto->set_corner_radius_tl(region.cornerRadiusTL);      proto->set_corner_radius_tr(region.cornerRadiusTR); @@ -238,7 +249,8 @@ void LayerProtoHelper::writeToProto(const android::BlurRegion region, BlurRegion      proto->set_bottom(region.bottom);  } -void LayerProtoHelper::readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion) { +void LayerProtoHelper::readFromProto(const perfetto::protos::BlurRegion& proto, +                                     android::BlurRegion& outRegion) {      outRegion.blurRadius = proto.blur_radius();      outRegion.cornerRadiusTL = proto.corner_radius_tl();      outRegion.cornerRadiusTR = proto.corner_radius_tr(); @@ -251,7 +263,8 @@ void LayerProtoHelper::readFromProto(const BlurRegion& proto, android::BlurRegio      outRegion.bottom = proto.bottom();  } -LayersProto LayerProtoFromSnapshotGenerator::generate(const frontend::LayerHierarchy& root) { +perfetto::protos::LayersProto LayerProtoFromSnapshotGenerator::generate( +        const frontend::LayerHierarchy& root) {      mLayersProto.clear_layers();      std::unordered_set<uint64_t> stackIdsToSkip;      if ((mTraceFlags & LayerTracing::TRACE_VIRTUAL_DISPLAYS) == 0) { @@ -310,7 +323,7 @@ frontend::LayerSnapshot* LayerProtoFromSnapshotGenerator::getSnapshot(  void LayerProtoFromSnapshotGenerator::writeHierarchyToProto(          const frontend::LayerHierarchy& root, frontend::LayerHierarchy::TraversalPath& path) {      using Variant = frontend::LayerHierarchy::Variant; -    LayerProto* layerProto = mLayersProto.add_layers(); +    perfetto::protos::LayerProto* layerProto = mLayersProto.add_layers();      const frontend::RequestedLayerState& layer = *root.getLayer();      frontend::LayerSnapshot* snapshot = getSnapshot(path, layer);      LayerProtoHelper::writeSnapshotToProto(layerProto, layer, *snapshot, mTraceFlags); @@ -349,7 +362,7 @@ void LayerProtoFromSnapshotGenerator::writeHierarchyToProto(      }  } -void LayerProtoHelper::writeSnapshotToProto(LayerProto* layerInfo, +void LayerProtoHelper::writeSnapshotToProto(perfetto::protos::LayerProto* layerInfo,                                              const frontend::RequestedLayerState& requestedState,                                              const frontend::LayerSnapshot& snapshot,                                              uint32_t traceFlags) { @@ -446,9 +459,9 @@ void LayerProtoHelper::writeSnapshotToProto(LayerProto* layerInfo,                                     [&]() { return layerInfo->mutable_destination_frame(); });  } -google::protobuf::RepeatedPtrField<DisplayProto> LayerProtoHelper::writeDisplayInfoToProto( -        const frontend::DisplayInfos& displayInfos) { -    google::protobuf::RepeatedPtrField<DisplayProto> displays; +google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> +LayerProtoHelper::writeDisplayInfoToProto(const frontend::DisplayInfos& displayInfos) { +    google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> displays;      displays.Reserve(displayInfos.size());      for (const auto& [layerStack, displayInfo] : displayInfos) {          auto displayProto = displays.Add(); diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h index 346685f259..20c226006c 100644 --- a/services/surfaceflinger/LayerProtoHelper.h +++ b/services/surfaceflinger/LayerProtoHelper.h @@ -35,39 +35,47 @@ namespace android {  namespace surfaceflinger {  class LayerProtoHelper {  public: -    static void writePositionToProto(const float x, const float y, -                                     std::function<PositionProto*()> getPositionProto); +    static void writePositionToProto( +            const float x, const float y, +            std::function<perfetto::protos::PositionProto*()> getPositionProto);      static void writeSizeToProto(const uint32_t w, const uint32_t h, -                                 std::function<SizeProto*()> getSizeProto); -    static void writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto); -    static void writeToProto(const Rect& rect, RectProto* rectProto); -    static void readFromProto(const RectProto& proto, Rect& outRect); +                                 std::function<perfetto::protos::SizeProto*()> getSizeProto); +    static void writeToProto(const Rect& rect, +                             std::function<perfetto::protos::RectProto*()> getRectProto); +    static void writeToProto(const Rect& rect, perfetto::protos::RectProto* rectProto); +    static void readFromProto(const perfetto::protos::RectProto& proto, Rect& outRect);      static void writeToProto(const FloatRect& rect, -                             std::function<FloatRectProto*()> getFloatRectProto); -    static void writeToProto(const Region& region, std::function<RegionProto*()> getRegionProto); -    static void writeToProto(const Region& region, RegionProto* regionProto); -    static void readFromProto(const RegionProto& regionProto, Region& outRegion); -    static void writeToProto(const half4 color, std::function<ColorProto*()> getColorProto); +                             std::function<perfetto::protos::FloatRectProto*()> getFloatRectProto); +    static void writeToProto(const Region& region, +                             std::function<perfetto::protos::RegionProto*()> getRegionProto); +    static void writeToProto(const Region& region, perfetto::protos::RegionProto* regionProto); +    static void readFromProto(const perfetto::protos::RegionProto& regionProto, Region& outRegion); +    static void writeToProto(const half4 color, +                             std::function<perfetto::protos::ColorProto*()> getColorProto);      // 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); +                                       perfetto::protos::TransformProto* transformProto);      static void writeTransformToProto(const ui::Transform& transform, -                                      TransformProto* transformProto); -    static void writeToProto(const renderengine::ExternalTexture& buffer, -                             std::function<ActiveBufferProto*()> getActiveBufferProto); -    static void writeToProto(const gui::WindowInfo& inputInfo, -                             const wp<Layer>& touchableRegionBounds, -                             std::function<InputWindowInfoProto*()> getInputWindowInfoProto); -    static void writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto); -    static void readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix); -    static void writeToProto(const android::BlurRegion region, BlurRegion*); -    static void readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion); -    static void writeSnapshotToProto(LayerProto* outProto, +                                      perfetto::protos::TransformProto* transformProto); +    static void writeToProto( +            const renderengine::ExternalTexture& buffer, +            std::function<perfetto::protos::ActiveBufferProto*()> getActiveBufferProto); +    static void writeToProto( +            const gui::WindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds, +            std::function<perfetto::protos::InputWindowInfoProto*()> getInputWindowInfoProto); +    static void writeToProto(const mat4 matrix, +                             perfetto::protos::ColorTransformProto* colorTransformProto); +    static void readFromProto(const perfetto::protos::ColorTransformProto& colorTransformProto, +                              mat4& matrix); +    static void writeToProto(const android::BlurRegion region, perfetto::protos::BlurRegion*); +    static void readFromProto(const perfetto::protos::BlurRegion& proto, +                              android::BlurRegion& outRegion); +    static void writeSnapshotToProto(perfetto::protos::LayerProto* outProto,                                       const frontend::RequestedLayerState& requestedState,                                       const frontend::LayerSnapshot& snapshot, uint32_t traceFlags); -    static google::protobuf::RepeatedPtrField<DisplayProto> writeDisplayInfoToProto( -            const frontend::DisplayInfos&); +    static google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> +    writeDisplayInfoToProto(const frontend::DisplayInfos&);  };  class LayerProtoFromSnapshotGenerator { @@ -80,7 +88,7 @@ public:              mLegacyLayers(legacyLayers),              mDisplayInfos(displayInfos),              mTraceFlags(traceFlags) {} -    LayersProto generate(const frontend::LayerHierarchy& root); +    perfetto::protos::LayersProto generate(const frontend::LayerHierarchy& root);  private:      void writeHierarchyToProto(const frontend::LayerHierarchy& root, @@ -92,7 +100,7 @@ private:      const std::unordered_map<uint32_t, sp<Layer>>& mLegacyLayers;      const frontend::DisplayInfos& mDisplayInfos;      uint32_t mTraceFlags; -    LayersProto mLayersProto; +    perfetto::protos::LayersProto mLayersProto;      // winscope expects all the layers, so provide a snapshot even if it not currently drawing      std::unordered_map<frontend::LayerHierarchy::TraversalPath, frontend::LayerSnapshot,                         frontend::LayerHierarchy::TraversalPathHash> diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index bc626f3030..38188c05b5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -320,8 +320,6 @@ const String16 sWakeupSurfaceFlinger("android.permission.WAKEUP_SURFACE_FLINGER"  const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled"; -static const int MAX_TRACING_MEMORY = 1024 * 1024 * 1024; // 1GB -  // ---------------------------------------------------------------------------  int64_t SurfaceFlinger::dispSyncPresentTimeOffset;  bool SurfaceFlinger::useHwcForRgbToYuv; @@ -483,6 +481,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI      if (!mIsUserBuild && base::GetBoolProperty("debug.sf.enable_transaction_tracing"s, true)) {          mTransactionTracing.emplace(); +        mLayerTracing.setTransactionTracing(*mTransactionTracing);      }      mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false); @@ -827,6 +826,17 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {      initScheduler(display);      dispatchDisplayHotplugEvent(display->getPhysicalId(), true); +    mLayerTracing.setTakeLayersSnapshotProtoFunction([&](uint32_t traceFlags) { +        auto snapshot = perfetto::protos::LayersSnapshotProto{}; +        mScheduler +                ->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) { +                    snapshot = takeLayersSnapshotProto(traceFlags, TimePoint::now(), +                                                       mLastCommittedVsyncId, true); +                }) +                .wait(); +        return snapshot; +    }); +      // Commit secondary display(s).      processDisplayChangesLocked(); @@ -2378,11 +2388,6 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId,          mTimeStats->incrementMissedFrames();      } -    if (mTracingEnabledChanged) { -        mLayerTracingEnabled = mLayerTracing.isEnabled(); -        mTracingEnabledChanged = false; -    } -      // If a mode set is pending and the fence hasn't fired yet, wait for the next commit.      if (std::any_of(frameTargets.begin(), frameTargets.end(),                      [this](const auto& pair) FTL_FAKE_GUARD(mStateLock) @@ -2509,11 +2514,9 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId,      if (!mustComposite) {          updateInputFlinger(vsyncId, pacesetterFrameTarget.frameBeginTime());      } +    doActiveLayersTracingIfNeeded(false, mVisibleRegionsDirty, +                                  pacesetterFrameTarget.frameBeginTime(), vsyncId); -    if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) { -        // This will block and tracing should only be enabled for debugging. -        addToLayerTracing(mVisibleRegionsDirty, pacesetterFrameTarget.frameBeginTime(), vsyncId); -    }      mLastCommittedVsyncId = vsyncId;      persistDisplayBrightness(mustComposite); @@ -2735,10 +2738,8 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(      mLayersWithQueuedFrames.clear();      mLayersIdsWithQueuedFrames.clear(); -    if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) { -        // This will block and should only be used for debugging. -        addToLayerTracing(mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(), vsyncId); -    } +    doActiveLayersTracingIfNeeded(true, mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(), +                                  vsyncId);      updateInputFlinger(vsyncId, pacesetterTarget.frameBeginTime()); @@ -5889,9 +5890,10 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {          }          if (dumpLayers) { -            LayersTraceFileProto traceFileProto = mLayerTracing.createTraceFileProto(); -            LayersTraceProto* layersTrace = traceFileProto.add_entry(); -            LayersProto layersProto = dumpProtoFromMainThread(); +            perfetto::protos::LayersTraceFileProto traceFileProto = +                    mLayerTracing.createTraceFileProto(); +            perfetto::protos::LayersSnapshotProto* layersTrace = traceFileProto.add_entry(); +            perfetto::protos::LayersProto layersProto = dumpProtoFromMainThread();              layersTrace->mutable_layers()->Swap(&layersProto);              auto displayProtos = dumpDisplayProto();              layersTrace->mutable_displays()->Swap(&displayProtos); @@ -6117,7 +6119,7 @@ void SurfaceFlinger::dumpHdrInfo(std::string& result) const {      }  } -LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const { +perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {      std::unordered_set<uint64_t> stackIdsToSkip;      // Determine if virtual layers display should be skipped @@ -6130,7 +6132,7 @@ LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {      }      if (mLegacyFrontEndEnabled) { -        LayersProto layersProto; +        perfetto::protos::LayersProto layersProto;          for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {              if (stackIdsToSkip.find(layer->getLayerStack().id) != stackIdsToSkip.end()) {                  continue; @@ -6145,10 +6147,11 @@ LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {              .generate(mLayerHierarchyBuilder.getHierarchy());  } -google::protobuf::RepeatedPtrField<DisplayProto> SurfaceFlinger::dumpDisplayProto() const { -    google::protobuf::RepeatedPtrField<DisplayProto> displays; +google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> +SurfaceFlinger::dumpDisplayProto() const { +    google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> displays;      for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) { -        DisplayProto* displayProto = displays.Add(); +        perfetto::protos::DisplayProto* displayProto = displays.Add();          displayProto->set_id(display->getId().value);          displayProto->set_name(display->getDisplayName());          displayProto->set_layer_stack(display->getLayerStack().id); @@ -6175,10 +6178,11 @@ void SurfaceFlinger::dumpHwc(std::string& result) const {      getHwComposer().dump(result);  } -void SurfaceFlinger::dumpOffscreenLayersProto(LayersProto& layersProto, uint32_t traceFlags) const { +void SurfaceFlinger::dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto, +                                              uint32_t traceFlags) const {      // Add a fake invisible root layer to the proto output and parent all the offscreen layers to      // it. -    LayerProto* rootProto = layersProto.add_layers(); +    perfetto::protos::LayerProto* rootProto = layersProto.add_layers();      const int32_t offscreenRootLayerId = INT32_MAX - 2;      rootProto->set_id(offscreenRootLayerId);      rootProto->set_name("Offscreen Root"); @@ -6189,12 +6193,12 @@ void SurfaceFlinger::dumpOffscreenLayersProto(LayersProto& layersProto, uint32_t          rootProto->add_children(offscreenLayer->sequence);          // Add layer -        LayerProto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags); +        auto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags);          layerProto->set_parent(offscreenRootLayerId);      }  } -LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) { +perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {      return mScheduler->schedule([=] { return dumpDrawingStateProto(traceFlags); }).get();  } @@ -6363,11 +6367,6 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, const std::string& comp      StringAppendF(&result, "  transaction time: %f us\n", inTransactionDuration / 1000.0); -    /* -     * Tracing state -     */ -    mLayerTracing.dump(result); -      result.append("\nTransaction tracing: ");      if (mTransactionTracing) {          result.append("enabled\n"); @@ -6719,42 +6718,13 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r              case 1024: {                  return NAME_NOT_FOUND;              } -            case 1025: { // Set layer tracing -                n = data.readInt32(); -                bool tracingEnabledChanged; -                if (n == 1) { -                    int64_t fixedStartingTime = data.readInt64(); -                    ALOGD("LayerTracing enabled"); -                    tracingEnabledChanged = mLayerTracing.enable(); -                    if (tracingEnabledChanged) { -                        const TimePoint startingTime = fixedStartingTime -                                ? TimePoint::fromNs(fixedStartingTime) -                                : TimePoint::now(); - -                        mScheduler -                                ->schedule([this, startingTime]() FTL_FAKE_GUARD( -                                                   mStateLock) FTL_FAKE_GUARD(kMainThreadContext) { -                                    constexpr bool kVisibleRegionDirty = true; -                                    addToLayerTracing(kVisibleRegionDirty, startingTime, -                                                      mLastCommittedVsyncId); -                                }) -                                .wait(); -                    } -                } else if (n == 2) { -                    std::string filename = std::string(data.readCString()); -                    ALOGD("LayerTracing disabled. Trace wrote to %s", filename.c_str()); -                    tracingEnabledChanged = mLayerTracing.disable(filename.c_str()); -                } else { -                    ALOGD("LayerTracing disabled"); -                    tracingEnabledChanged = mLayerTracing.disable(); -                } -                mTracingEnabledChanged = tracingEnabledChanged; -                reply->writeInt32(NO_ERROR); -                return NO_ERROR; +            // Deprecated, use perfetto to start/stop the layer tracing +            case 1025: { +                return NAME_NOT_FOUND;              } -            case 1026: { // Get layer tracing status -                reply->writeBool(mLayerTracing.isEnabled()); -                return NO_ERROR; +            // Deprecated, execute "adb shell perfetto --query" to see the ongoing tracing sessions +            case 1026: { +                return NAME_NOT_FOUND;              }              // Is a DisplayColorSetting supported?              case 1027: { @@ -6782,19 +6752,9 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r              case 1028: { // Unused.                  return NAME_NOT_FOUND;              } -            // Set buffer size for SF tracing (value in KB) +            // Deprecated, use perfetto to set the active layer tracing buffer size              case 1029: { -                n = data.readInt32(); -                if (n <= 0 || n > MAX_TRACING_MEMORY) { -                    ALOGW("Invalid buffer size: %d KB", n); -                    reply->writeInt32(BAD_VALUE); -                    return BAD_VALUE; -                } - -                ALOGD("Updating trace buffer to %d KB", n); -                mLayerTracing.setBufferSize(n * 1024); -                reply->writeInt32(NO_ERROR); -                return NO_ERROR; +                return NAME_NOT_FOUND;              }              // Is device color managed?              case 1030: { @@ -6834,13 +6794,9 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r                  }                  return NO_ERROR;              } -            // Set trace flags +            // Deprecated, use perfetto to set layer trace flags              case 1033: { -                n = data.readUint32(); -                ALOGD("Updating trace flags to 0x%x", n); -                mLayerTracing.setTraceFlags(n); -                reply->writeInt32(NO_ERROR); -                return NO_ERROR; +                return NAME_NOT_FOUND;              }              case 1034: {                  n = data.readInt32(); @@ -6985,7 +6941,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r                          // Transaction tracing is always running but allow the user to temporarily                          // increase the buffer when actively debugging.                          mTransactionTracing->setBufferSize( -                                TransactionTracing::ACTIVE_TRACING_BUFFER_SIZE); +                                TransactionTracing::LEGACY_ACTIVE_TRACING_BUFFER_SIZE);                      } else {                          TransactionTraceWriter::getInstance().invoke("", /* overwrite= */ true);                          mTransactionTracing->setBufferSize( @@ -6995,13 +6951,10 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r                  reply->writeInt32(NO_ERROR);                  return NO_ERROR;              } -            case 1042: { // Write layers trace or transaction trace to file +            case 1042: { // Write transaction trace to file                  if (mTransactionTracing) {                      mTransactionTracing->writeToFile();                  } -                if (mLayerTracingEnabled) { -                    mLayerTracing.writeToFile(); -                }                  reply->writeInt32(NO_ERROR);                  return NO_ERROR;              } @@ -8788,19 +8741,50 @@ frontend::Update SurfaceFlinger::flushLifecycleUpdates() {      return update;  } -void SurfaceFlinger::addToLayerTracing(bool visibleRegionDirty, TimePoint time, VsyncId vsyncId) { -    const uint32_t tracingFlags = mLayerTracing.getFlags(); -    LayersProto layers(dumpDrawingStateProto(tracingFlags)); -    if (tracingFlags & LayerTracing::TRACE_EXTRA) { +void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed, +                                                   bool visibleRegionDirty, TimePoint time, +                                                   VsyncId vsyncId) { +    if (!mLayerTracing.isActiveTracingStarted()) { +        return; +    } +    if (isCompositionComputed != +        mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_COMPOSITION)) { +        return; +    } +    if (!visibleRegionDirty && +        !mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_BUFFERS)) { +        return; +    } +    auto snapshot = takeLayersSnapshotProto(mLayerTracing.getActiveTracingFlags(), time, vsyncId, +                                            visibleRegionDirty); +    mLayerTracing.addProtoSnapshotToOstream(std::move(snapshot), LayerTracing::Mode::MODE_ACTIVE); +} + +perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto( +        uint32_t traceFlags, TimePoint time, VsyncId vsyncId, bool visibleRegionDirty) { +    ATRACE_CALL(); +    perfetto::protos::LayersSnapshotProto snapshot; +    snapshot.set_elapsed_realtime_nanos(time.ns()); +    snapshot.set_vsync_id(ftl::to_underlying(vsyncId)); +    snapshot.set_where(visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched"); +    snapshot.set_excludes_composition_state((traceFlags & LayerTracing::Flag::TRACE_COMPOSITION) == +                                            0); + +    auto layers = dumpDrawingStateProto(traceFlags); +    if (traceFlags & LayerTracing::Flag::TRACE_EXTRA) {          dumpOffscreenLayersProto(layers);      } -    std::string hwcDump; -    if (tracingFlags & LayerTracing::TRACE_HWC) { +    *snapshot.mutable_layers() = std::move(layers); + +    if (traceFlags & LayerTracing::Flag::TRACE_HWC) { +        std::string hwcDump;          dumpHwc(hwcDump); +        snapshot.set_hwc_blob(std::move(hwcDump));      } -    auto displays = dumpDisplayProto(); -    mLayerTracing.notify(visibleRegionDirty, time.ns(), ftl::to_underlying(vsyncId), &layers, -                         std::move(hwcDump), &displays); + +    *snapshot.mutable_displays() = dumpDisplayProto(); + +    return snapshot;  }  // sfdo functions diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 79dcd0d1b2..dc4e7cf2fe 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -368,7 +368,6 @@ private:      friend class RefreshRateOverlay;      friend class RegionSamplingThread;      friend class LayerRenderArea; -    friend class LayerTracing;      friend class SurfaceComposerAIDL;      friend class DisplayRenderArea; @@ -1092,17 +1091,20 @@ private:      void dumpWideColorInfo(std::string& result) const REQUIRES(mStateLock);      void dumpHdrInfo(std::string& result) const REQUIRES(mStateLock); -    LayersProto dumpDrawingStateProto(uint32_t traceFlags) const; -    void dumpOffscreenLayersProto(LayersProto& layersProto, +    perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const; +    void dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto,                                    uint32_t traceFlags = LayerTracing::TRACE_ALL) const; -    google::protobuf::RepeatedPtrField<DisplayProto> dumpDisplayProto() const; -    void addToLayerTracing(bool visibleRegionDirty, TimePoint, VsyncId) +    google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> dumpDisplayProto() const; +    void doActiveLayersTracingIfNeeded(bool isCompositionComputed, bool visibleRegionDirty, +                                       TimePoint, VsyncId) REQUIRES(kMainThreadContext); +    perfetto::protos::LayersSnapshotProto takeLayersSnapshotProto(uint32_t flags, TimePoint, +                                                                  VsyncId, bool visibleRegionDirty)              REQUIRES(kMainThreadContext);      // Dumps state from HW Composer      void dumpHwc(std::string& result) const; -    LayersProto dumpProtoFromMainThread(uint32_t traceFlags = LayerTracing::TRACE_ALL) -            EXCLUDES(mStateLock); +    perfetto::protos::LayersProto dumpProtoFromMainThread( +            uint32_t traceFlags = LayerTracing::TRACE_ALL) EXCLUDES(mStateLock);      void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);      void dumpPlannerInfo(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); @@ -1261,10 +1263,7 @@ private:      bool mBackpressureGpuComposition = false;      LayerTracing mLayerTracing; -    bool mLayerTracingEnabled = false; -      std::optional<TransactionTracing> mTransactionTracing; -    std::atomic<bool> mTracingEnabledChanged = false;      const std::shared_ptr<TimeStats> mTimeStats;      const std::unique_ptr<FrameTracer> mFrameTracer; diff --git a/services/surfaceflinger/Tracing/LayerDataSource.cpp b/services/surfaceflinger/Tracing/LayerDataSource.cpp new file mode 100644 index 0000000000..474fef89a0 --- /dev/null +++ b/services/surfaceflinger/Tracing/LayerDataSource.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2023 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. + */ + +#undef LOG_TAG +#define LOG_TAG "LayerTracing" + +#include "LayerDataSource.h" + +#include <log/log.h> +#include <perfetto/config/android/surfaceflinger_layers_config.pbzero.h> + +namespace android { + +void LayerDataSource::Initialize(LayerTracing& layerTracing) { +    mLayerTracing.store(&layerTracing); + +    auto args = perfetto::TracingInitArgs{}; +    args.backends = perfetto::kSystemBackend; +    // We are tracing ~50kb/entry and the default shmem buffer size (256kb) could be overrun. +    // A shmem buffer overrun typically just stalls layer tracing, however when the stall +    // lasts for too long perfetto assumes there is a deadlock and aborts surfaceflinger. +    args.shmem_size_hint_kb = 1024; +    perfetto::Tracing::Initialize(args); + +    perfetto::DataSourceDescriptor descriptor; +    descriptor.set_name(android::LayerDataSource::kName); +    LayerDataSource::Register(descriptor); +} + +void LayerDataSource::UnregisterLayerTracing() { +    mLayerTracing.store(nullptr); +} + +void LayerDataSource::OnSetup(const LayerDataSource::SetupArgs& args) { +    const auto configRaw = args.config->surfaceflinger_layers_config_raw(); +    const auto config = perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Decoder{configRaw}; + +    if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) { +        mMode = static_cast<LayerTracing::Mode>(config.mode()); +    } else { +        mMode = LayerTracing::Mode::MODE_GENERATED; +        ALOGV("Received config with unspecified 'mode'. Using 'GENERATED' as default"); +    } + +    mFlags = 0; +    for (auto it = config.trace_flags(); it; ++it) { +        mFlags |= static_cast<uint32_t>(*it); +    } +} + +void LayerDataSource::OnStart(const LayerDataSource::StartArgs&) { +    ALOGV("Received OnStart event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags); +    if (auto* p = mLayerTracing.load()) { +        p->onStart(mMode, mFlags); +    } +} + +void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs&) { +    ALOGV("Received OnFlush event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags); +    if (auto* p = mLayerTracing.load()) { +        p->onFlush(mMode, mFlags); +    } +} + +void LayerDataSource::OnStop(const LayerDataSource::StopArgs&) { +    ALOGV("Received OnStop event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags); +    if (auto* p = mLayerTracing.load()) { +        p->onStop(mMode); +    } +} + +LayerTracing::Mode LayerDataSource::GetMode() const { +    return mMode; +} + +std::atomic<LayerTracing*> LayerDataSource::mLayerTracing = nullptr; + +} // namespace android + +PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::LayerDataSource); diff --git a/services/surfaceflinger/Tracing/LayerDataSource.h b/services/surfaceflinger/Tracing/LayerDataSource.h new file mode 100644 index 0000000000..7944092993 --- /dev/null +++ b/services/surfaceflinger/Tracing/LayerDataSource.h @@ -0,0 +1,77 @@ +/* + * Copyright 2023 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. + */ + +#pragma once + +#include "LayerTracing.h" + +#include <perfetto/tracing.h> + +#include <atomic> + +namespace android { + +/* + * Thread local storage used for fast (lock free) read of data source's properties. + * + */ +struct LayerDataSourceTlsState { +    template <typename TraceContext> +    explicit LayerDataSourceTlsState(const TraceContext& trace_context) { +        auto dataSource = trace_context.GetDataSourceLocked(); +        mMode = dataSource.valid() +                ? dataSource->GetMode() +                : perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Mode::MODE_GENERATED; +    } + +    LayerTracing::Mode mMode; +}; + +struct LayerDataSourceTraits : public perfetto::DefaultDataSourceTraits { +    using TlsStateType = LayerDataSourceTlsState; +}; + +/* + * Defines the Perfetto custom data source 'android.surfaceflinger.layers'. + * + * Registers the data source with Perfetto, listens to Perfetto events (setup/start/flush/stop) + * and writes trace packets to Perfetto. + * + */ +class LayerDataSource : public perfetto::DataSource<LayerDataSource, LayerDataSourceTraits> { +public: +    static void Initialize(LayerTracing&); +    static void UnregisterLayerTracing(); +    void OnSetup(const SetupArgs&) override; +    void OnStart(const StartArgs&) override; +    void OnFlush(const FlushArgs&) override; +    void OnStop(const StopArgs&) override; +    LayerTracing::Mode GetMode() const; + +    static constexpr auto* kName = "android.surfaceflinger.layers"; +    static constexpr perfetto::BufferExhaustedPolicy kBufferExhaustedPolicy = +            perfetto::BufferExhaustedPolicy::kStall; +    static constexpr bool kRequiresCallbacksUnderLock = false; + +private: +    static std::atomic<LayerTracing*> mLayerTracing; +    LayerTracing::Mode mMode; +    std::uint32_t mFlags; +}; + +} // namespace android + +PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(android::LayerDataSource); diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp index b92d50b423..e55b4c2ce8 100644 --- a/services/surfaceflinger/Tracing/LayerTracing.cpp +++ b/services/surfaceflinger/Tracing/LayerTracing.cpp @@ -18,131 +18,177 @@  #define LOG_TAG "LayerTracing"  #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include <filesystem> +#include "LayerTracing.h" + +#include "LayerDataSource.h" +#include "Tracing/tools/LayerTraceGenerator.h" +#include "TransactionTracing.h" -#include <SurfaceFlinger.h> -#include <android-base/stringprintf.h>  #include <log/log.h> -#include <utils/SystemClock.h> +#include <perfetto/tracing.h> +#include <utils/Timers.h>  #include <utils/Trace.h> -#include "LayerTracing.h" -#include "TransactionRingBuffer.h" -  namespace android { -LayerTracing::LayerTracing() -      : mBuffer(std::make_unique<TransactionRingBuffer<LayersTraceFileProto, LayersTraceProto>>()) { +LayerTracing::LayerTracing() { +    mTakeLayersSnapshotProto = [](uint32_t) { return perfetto::protos::LayersSnapshotProto{}; }; +    LayerDataSource::Initialize(*this);  } -LayerTracing::~LayerTracing() = default; +LayerTracing::~LayerTracing() { +    LayerDataSource::UnregisterLayerTracing(); +} + +void LayerTracing::setTakeLayersSnapshotProtoFunction( +        const std::function<perfetto::protos::LayersSnapshotProto(uint32_t)>& callback) { +    mTakeLayersSnapshotProto = callback; +} -bool LayerTracing::enable() { -    std::scoped_lock lock(mTraceLock); -    if (mEnabled) { -        return false; +void LayerTracing::setTransactionTracing(TransactionTracing& transactionTracing) { +    mTransactionTracing = &transactionTracing; +} + +void LayerTracing::setOutputStream(std::ostream& outStream) { +    mOutStream = std::ref(outStream); +} + +void LayerTracing::onStart(Mode mode, uint32_t flags) { +    switch (mode) { +        case Mode::MODE_ACTIVE: { +            mActiveTracingFlags.store(flags); +            mIsActiveTracingStarted.store(true); +            ALOGV("Starting active tracing (waiting for initial snapshot)"); +            // It might take a while before a layers change occurs and a "spontaneous" snapshot is +            // taken. Let's manually take a snapshot, so that the trace's first entry will contain +            // the current layers state. +            addProtoSnapshotToOstream(mTakeLayersSnapshotProto(flags), Mode::MODE_ACTIVE); +            ALOGV("Started active tracing (traced initial snapshot)"); +            break; +        } +        case Mode::MODE_GENERATED: { +            ALOGV("Started generated tracing (waiting for OnFlush event to generated layers)"); +            break; +        } +        case Mode::MODE_DUMP: { +            ALOGV("Starting dump tracing (dumping single snapshot)"); +            auto snapshot = mTakeLayersSnapshotProto(flags); +            addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP); +            ALOGV("Started dump tracing (dumped single snapshot)"); +            break; +        } +        default: { +            ALOGE("Started unknown tracing mode (0x%02x)", mode); +        }      } -    mBuffer->setSize(mBufferSizeInBytes); -    mEnabled = true; -    return true;  } -bool LayerTracing::disable(std::string filename, bool writeToFile) { -    std::scoped_lock lock(mTraceLock); -    if (!mEnabled) { -        return false; +void LayerTracing::onFlush(Mode mode, uint32_t flags) { +    // In "generated" mode process the buffer of transactions (owned by TransactionTracing), +    // generate a sequence of layers snapshots and write them to perfetto. +    if (mode != Mode::MODE_GENERATED) { +        return;      } -    mEnabled = false; -    if (writeToFile) { -        LayersTraceFileProto fileProto = createTraceFileProto(); -        mBuffer->writeToFile(fileProto, filename); + +    if (!mTransactionTracing) { +        ALOGV("Skipping layers trace generation (transactions tracing disabled)"); +        return;      } -    mBuffer->reset(); -    return true; -} -void LayerTracing::appendToStream(std::ofstream& out) { -    std::scoped_lock lock(mTraceLock); -    LayersTraceFileProto fileProto = createTraceFileProto(); -    mBuffer->appendToStream(fileProto, out); -    mBuffer->reset(); +    auto transactionTrace = mTransactionTracing->writeToProto(); +    LayerTraceGenerator{}.generate(transactionTrace, flags); +    ALOGV("Flushed generated tracing");  } -bool LayerTracing::isEnabled() const { -    std::scoped_lock lock(mTraceLock); -    return mEnabled; +void LayerTracing::onStop(Mode mode) { +    if (mode == Mode::MODE_ACTIVE) { +        mIsActiveTracingStarted.store(false); +        ALOGV("Stopped active tracing"); +    }  } -status_t LayerTracing::writeToFile(std::string filename) { -    std::scoped_lock lock(mTraceLock); -    if (!mEnabled) { -        return STATUS_OK; +void LayerTracing::addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto&& snapshot, +                                             Mode mode) { +    ATRACE_CALL(); +    if (mOutStream) { +        writeSnapshotToStream(std::move(snapshot)); +    } else { +        writeSnapshotToPerfetto(snapshot, mode);      } -    LayersTraceFileProto fileProto = createTraceFileProto(); -    return mBuffer->writeToFile(fileProto, filename);  } -void LayerTracing::setTraceFlags(uint32_t flags) { -    std::scoped_lock lock(mTraceLock); -    mFlags = flags; +bool LayerTracing::isActiveTracingStarted() const { +    return mIsActiveTracingStarted.load();  } -void LayerTracing::setBufferSize(size_t bufferSizeInBytes) { -    std::scoped_lock lock(mTraceLock); -    mBufferSizeInBytes = bufferSizeInBytes; +uint32_t LayerTracing::getActiveTracingFlags() const { +    return mActiveTracingFlags.load();  } -bool LayerTracing::flagIsSet(uint32_t flags) const { -    return (mFlags & flags) == flags; -} -uint32_t LayerTracing::getFlags() const { -    return mFlags; +bool LayerTracing::isActiveTracingFlagSet(Flag flag) const { +    return (mActiveTracingFlags.load() & flag) != 0;  } -LayersTraceFileProto LayerTracing::createTraceFileProto() { -    LayersTraceFileProto fileProto; -    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 | -                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L); -    auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) - -                                                   systemTime(SYSTEM_TIME_MONOTONIC)); +perfetto::protos::LayersTraceFileProto LayerTracing::createTraceFileProto() { +    perfetto::protos::LayersTraceFileProto fileProto; +    fileProto.set_magic_number( +            static_cast<uint64_t>(perfetto::protos::LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) +                    << 32 | +            perfetto::protos::LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L); +    auto timeOffsetNs = static_cast<uint64_t>(systemTime(SYSTEM_TIME_REALTIME) - +                                              systemTime(SYSTEM_TIME_MONOTONIC));      fileProto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);      return fileProto;  } -void LayerTracing::dump(std::string& result) const { -    std::scoped_lock lock(mTraceLock); -    base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled"); -    mBuffer->dump(result); +void LayerTracing::writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& snapshot) const { +    auto fileProto = createTraceFileProto(); +    *fileProto.add_entry() = std::move(snapshot); +    mOutStream->get() << fileProto.SerializeAsString();  } -void LayerTracing::notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId, -                          LayersProto* layers, std::string hwcDump, -                          google::protobuf::RepeatedPtrField<DisplayProto>* displays) { -    std::scoped_lock lock(mTraceLock); -    if (!mEnabled) { -        return; -    } +void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot, +                                           Mode mode) { +    const auto snapshotBytes = snapshot.SerializeAsString(); + +    LayerDataSource::Trace([&](LayerDataSource::TraceContext context) { +        if (mode != context.GetCustomTlsState()->mMode) { +            return; +        } +        if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(mode, snapshot.vsync_id())) { +            return; +        } +        { +            auto packet = context.NewTracePacket(); +            packet->set_timestamp(static_cast<uint64_t>(snapshot.elapsed_realtime_nanos())); +            packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC); +            auto* snapshotProto = packet->set_surfaceflinger_layers_snapshot(); +            snapshotProto->AppendRawProtoBytes(snapshotBytes.data(), snapshotBytes.size()); +        } +        { +            // TODO (b/162206162): remove empty packet when perfetto bug is fixed. +            //  It is currently needed in order not to lose the last trace entry. +            context.NewTracePacket(); +        } +    }); +} -    if (!visibleRegionDirty && !flagIsSet(LayerTracing::TRACE_BUFFERS)) { -        return; +bool LayerTracing::checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::int64_t vsyncId) { +    // In some situations (e.g. two bugreports taken shortly one after the other) the generated +    // sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make +    // sure that in generated tracing mode a given snapshot is written only once to perfetto. +    if (mode != Mode::MODE_GENERATED) { +        return true;      } -    ATRACE_CALL(); -    LayersTraceProto entry; -    entry.set_elapsed_realtime_nanos(time); -    const char* where = visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched"; -    entry.set_where(where); -    entry.mutable_layers()->Swap(layers); - -    if (flagIsSet(LayerTracing::TRACE_HWC)) { -        entry.set_hwc_blob(hwcDump); -    } -    if (!flagIsSet(LayerTracing::TRACE_COMPOSITION)) { -        entry.set_excludes_composition_state(true); +    auto lastVsyncId = mLastVsyncIdWrittenToPerfetto.load(); +    while (lastVsyncId < vsyncId) { +        if (mLastVsyncIdWrittenToPerfetto.compare_exchange_strong(lastVsyncId, vsyncId)) { +            return true; +        }      } -    entry.mutable_displays()->Swap(displays); -    entry.set_vsync_id(vsyncId); -    mBuffer->emplace(std::move(entry)); + +    return false;  }  } // namespace android diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h index 7c0d23d5b6..349cc40073 100644 --- a/services/surfaceflinger/Tracing/LayerTracing.h +++ b/services/surfaceflinger/Tracing/LayerTracing.h @@ -16,42 +16,77 @@  #pragma once -#include <android-base/thread_annotations.h>  #include <layerproto/LayerProtoHeader.h> -#include <utils/Errors.h> -#include <utils/StrongPointer.h> -#include <utils/Timers.h> -#include <memory> -#include <mutex> - -using namespace android::surfaceflinger; +#include <atomic> +#include <functional> +#include <optional> +#include <ostream>  namespace android { -template <typename FileProto, typename EntryProto> -class TransactionRingBuffer; - -class SurfaceFlinger; +class TransactionTracing;  /*   * LayerTracing records layer states during surface flinging. Manages tracing state and   * configuration. + * + * The traced data can then be collected with Perfetto. + * + * The Perfetto custom data source LayerDataSource is registered with perfetto. The data source + * is used to listen to perfetto events (setup, start, stop, flush) and to write trace packets + * to perfetto. + * + * The user can configure/start/stop tracing via /system/bin/perfetto. + * + * Tracing can operate in the following modes. + * + * ACTIVE mode: + * A layers snapshot is taken and written to perfetto for each vsyncid commit. + * + * GENERATED mode: + * Listens to the perfetto 'flush' event (e.g. when a bugreport is taken). + * When a 'flush' event is received, the ring buffer of transactions (hold by TransactionTracing) + * is processed by LayerTraceGenerator, a sequence of layers snapshots is generated + * and written to perfetto. + * + * DUMP mode: + * When the 'start' event is received a single layers snapshot is taken + * and written to perfetto. + * + * + * E.g. start active mode tracing: + * +   adb shell -t perfetto \ +     -c - --txt \ +     -o /data/misc/perfetto-traces/trace \ +   <<EOF +   unique_session_name: "surfaceflinger_layers_active" +   buffers: { +       size_kb: 63488 +       fill_policy: RING_BUFFER +   } +   data_sources: { +       config { +           name: "android.surfaceflinger.layers" +           surfaceflinger_layers_config: { +               mode: MODE_ACTIVE +               trace_flags: TRACE_FLAG_INPUT +               trace_flags: TRACE_FLAG_COMPOSITION +               trace_flags: TRACE_FLAG_HWC +               trace_flags: TRACE_FLAG_BUFFERS +               trace_flags: TRACE_FLAG_VIRTUAL_DISPLAYS +           } +       } +   } +   EOF + *   */  class LayerTracing {  public: -    LayerTracing(); -    ~LayerTracing(); -    bool enable(); -    bool disable(std::string filename = FILE_NAME, bool writeToFile = true); -    void appendToStream(std::ofstream& out); -    bool isEnabled() const; -    status_t writeToFile(std::string filename = FILE_NAME); -    static LayersTraceFileProto createTraceFileProto(); -    void notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId, LayersProto* layers, -                std::string hwcDump, google::protobuf::RepeatedPtrField<DisplayProto>* displays); +    using Mode = perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Mode; -    enum : uint32_t { +    enum Flag : uint32_t {          TRACE_INPUT = 1 << 1,          TRACE_COMPOSITION = 1 << 2,          TRACE_EXTRA = 1 << 3, @@ -60,20 +95,39 @@ public:          TRACE_VIRTUAL_DISPLAYS = 1 << 6,          TRACE_ALL = TRACE_INPUT | TRACE_COMPOSITION | TRACE_EXTRA,      }; -    void setTraceFlags(uint32_t flags); -    bool flagIsSet(uint32_t flags) const; -    uint32_t getFlags() const; -    void setBufferSize(size_t bufferSizeInBytes); -    void dump(std::string&) const; + +    LayerTracing(); +    ~LayerTracing(); +    void setTakeLayersSnapshotProtoFunction( +            const std::function<perfetto::protos::LayersSnapshotProto(uint32_t)>&); +    void setTransactionTracing(TransactionTracing&); +    void setOutputStream(std::ostream&); + +    // Start event from perfetto data source +    void onStart(Mode mode, uint32_t flags); +    // Flush event from perfetto data source +    void onFlush(Mode mode, uint32_t flags); +    // Stop event from perfetto data source +    void onStop(Mode mode); + +    void addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto&& snapshot, Mode mode); +    bool isActiveTracingStarted() const; +    uint32_t getActiveTracingFlags() const; +    bool isActiveTracingFlagSet(Flag flag) const; +    static perfetto::protos::LayersTraceFileProto createTraceFileProto();  private: -    static constexpr auto FILE_NAME = "/data/misc/wmtrace/layers_trace.winscope"; -    uint32_t mFlags = TRACE_INPUT; -    mutable std::mutex mTraceLock; -    bool mEnabled GUARDED_BY(mTraceLock) = false; -    std::unique_ptr<TransactionRingBuffer<LayersTraceFileProto, LayersTraceProto>> mBuffer -            GUARDED_BY(mTraceLock); -    size_t mBufferSizeInBytes GUARDED_BY(mTraceLock) = 20 * 1024 * 1024; +    void writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& snapshot) const; +    void writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot, Mode mode); +    bool checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::int64_t vsyncId); + +    std::function<perfetto::protos::LayersSnapshotProto(uint32_t)> mTakeLayersSnapshotProto; +    TransactionTracing* mTransactionTracing; + +    std::atomic<bool> mIsActiveTracingStarted{false}; +    std::atomic<uint32_t> mActiveTracingFlags{0}; +    std::atomic<std::int64_t> mLastVsyncIdWrittenToPerfetto{-1}; +    std::optional<std::reference_wrapper<std::ostream>> mOutStream;  };  } // namespace android diff --git a/services/surfaceflinger/Tracing/TransactionDataSource.cpp b/services/surfaceflinger/Tracing/TransactionDataSource.cpp new file mode 100644 index 0000000000..05b89b84ad --- /dev/null +++ b/services/surfaceflinger/Tracing/TransactionDataSource.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2023 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. + */ + +#include "TransactionDataSource.h" +#include "TransactionTracing.h" + +#undef LOG_TAG +#define LOG_TAG "TransactionTracing" + +#include <log/log.h> + +namespace android { + +void TransactionDataSource::Initialize(TransactionTracing& transactionTracing) { +    mTransactionTracing.store(&transactionTracing); + +    auto args = perfetto::TracingInitArgs{}; +    args.backends = perfetto::kSystemBackend; +    perfetto::Tracing::Initialize(args); + +    perfetto::DataSourceDescriptor descriptor; +    descriptor.set_name(kName); +    TransactionDataSource::Register(descriptor); +} + +void TransactionDataSource::UnregisterTransactionTracing() { +    mTransactionTracing.store(nullptr); +} + +void TransactionDataSource::OnSetup(const TransactionDataSource::SetupArgs& args) { +    const auto configRaw = args.config->surfaceflinger_transactions_config_raw(); +    const auto config = +            perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig::Decoder{configRaw}; + +    if (config.has_mode() && config.mode() != TransactionTracing::Mode::MODE_UNSPECIFIED) { +        mMode = static_cast<TransactionTracing::Mode>(config.mode()); +    } else { +        mMode = TransactionTracing::Mode::MODE_CONTINUOUS; +        ALOGV("Received config with unspecified 'mode'. Using 'CONTINUOUS' as default"); +    } +} + +void TransactionDataSource::OnStart(const StartArgs&) { +    ALOGV("Received OnStart event"); +    if (auto* p = mTransactionTracing.load()) { +        p->onStart(mMode); +    } +} + +void TransactionDataSource::OnFlush(const FlushArgs&) { +    ALOGV("Received OnFlush event"); +    if (auto* p = mTransactionTracing.load()) { +        p->onFlush(mMode); +    } +} + +void TransactionDataSource::OnStop(const StopArgs&) { +    ALOGV("Received OnStop event"); +} + +TransactionTracing::Mode TransactionDataSource::GetMode() const { +    return mMode; +} + +std::atomic<TransactionTracing*> TransactionDataSource::mTransactionTracing = nullptr; + +} // namespace android + +PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::TransactionDataSource); diff --git a/services/surfaceflinger/Tracing/TransactionDataSource.h b/services/surfaceflinger/Tracing/TransactionDataSource.h new file mode 100644 index 0000000000..be8373b4ac --- /dev/null +++ b/services/surfaceflinger/Tracing/TransactionDataSource.h @@ -0,0 +1,74 @@ +/* + * Copyright 2023 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. + */ + +#pragma once + +#include "TransactionTracing.h" + +#include <perfetto/tracing.h> + +namespace android { + +/* + * Thread local storage used for fast (lock free) read of data source's properties. + * + */ +struct TransactionDataSourceTlsState { +    template <typename TraceContext> +    explicit TransactionDataSourceTlsState(const TraceContext& trace_context) { +        auto dataSource = trace_context.GetDataSourceLocked(); +        mMode = dataSource.valid() ? dataSource->GetMode() +                                   : TransactionTracing::Mode::MODE_CONTINUOUS; +    } + +    TransactionTracing::Mode mMode; +}; + +struct TransactionDataSourceTraits : public perfetto::DefaultDataSourceTraits { +    using TlsStateType = TransactionDataSourceTlsState; +}; + +/* + * Defines the Perfetto custom data source 'android.surfaceflinger.transactions'. + * + * Registers the data source with Perfetto, listens to Perfetto events (setup/start/flush/stop) + * and writes trace packets to Perfetto. + * + */ +class TransactionDataSource +      : public perfetto::DataSource<TransactionDataSource, TransactionDataSourceTraits> { +public: +    static void Initialize(TransactionTracing&); +    static void UnregisterTransactionTracing(); +    void OnSetup(const SetupArgs&) override; +    void OnStart(const StartArgs&) override; +    void OnFlush(const FlushArgs&) override; +    void OnStop(const StopArgs&) override; +    TransactionTracing::Mode GetMode() const; + +    static constexpr auto* kName = "android.surfaceflinger.transactions"; +    static constexpr perfetto::BufferExhaustedPolicy kBufferExhaustedPolicy = +            perfetto::BufferExhaustedPolicy::kStall; +    static constexpr bool kRequiresCallbacksUnderLock = false; + +private: +    static std::atomic<TransactionTracing*> mTransactionTracing; +    TransactionTracing::Mode mMode; +}; + +} // namespace android + +PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(android::TransactionDataSource); diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp index b1e3d6378a..2dc89b55ba 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp @@ -51,8 +51,8 @@ public:      ~FakeExternalTexture() = default;  }; -proto::TransactionState TransactionProtoParser::toProto(const TransactionState& t) { -    proto::TransactionState proto; +perfetto::protos::TransactionState TransactionProtoParser::toProto(const TransactionState& t) { +    perfetto::protos::TransactionState proto;      proto.set_pid(t.originPid);      proto.set_uid(t.originUid);      proto.set_vsync_id(t.frameTimelineInfo.vsyncId); @@ -79,21 +79,21 @@ proto::TransactionState TransactionProtoParser::toProto(const TransactionState&      return proto;  } -proto::TransactionState TransactionProtoParser::toProto( +perfetto::protos::TransactionState TransactionProtoParser::toProto(          const std::map<uint32_t /* layerId */, TracingLayerState>& states) { -    proto::TransactionState proto; +    perfetto::protos::TransactionState proto;      proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(states.size()));      for (auto& [layerId, state] : states) { -        proto::LayerState layerProto = toProto(state); +        perfetto::protos::LayerState layerProto = toProto(state);          layerProto.set_has_sideband_stream(state.hasSidebandStream);          proto.mutable_layer_changes()->Add(std::move(layerProto));      }      return proto;  } -proto::LayerState TransactionProtoParser::toProto( +perfetto::protos::LayerState TransactionProtoParser::toProto(          const ResolvedComposerState& resolvedComposerState) { -    proto::LayerState proto; +    perfetto::protos::LayerState proto;      auto& layer = resolvedComposerState.state;      proto.set_layer_id(resolvedComposerState.layerId);      proto.set_what(layer.what); @@ -114,7 +114,7 @@ proto::LayerState TransactionProtoParser::toProto(          proto.set_mask(layer.mask);      }      if (layer.what & layer_state_t::eMatrixChanged) { -        proto::LayerState_Matrix22* matrixProto = proto.mutable_matrix(); +        perfetto::protos::LayerState_Matrix22* matrixProto = proto.mutable_matrix();          matrixProto->set_dsdx(layer.matrix.dsdx);          matrixProto->set_dsdy(layer.matrix.dsdy);          matrixProto->set_dtdx(layer.matrix.dtdx); @@ -132,7 +132,7 @@ proto::LayerState TransactionProtoParser::toProto(      }      if (layer.what & layer_state_t::eColorChanged) { -        proto::LayerState_Color3* colorProto = proto.mutable_color(); +        perfetto::protos::LayerState_Color3* colorProto = proto.mutable_color();          colorProto->set_r(layer.color.r);          colorProto->set_g(layer.color.g);          colorProto->set_b(layer.color.b); @@ -150,13 +150,14 @@ proto::LayerState TransactionProtoParser::toProto(          LayerProtoHelper::writeToProto(layer.crop, proto.mutable_crop());      }      if (layer.what & layer_state_t::eBufferChanged) { -        proto::LayerState_BufferData* bufferProto = proto.mutable_buffer_data(); +        perfetto::protos::LayerState_BufferData* bufferProto = proto.mutable_buffer_data();          if (resolvedComposerState.externalTexture) {              bufferProto->set_buffer_id(resolvedComposerState.externalTexture->getId());              bufferProto->set_width(resolvedComposerState.externalTexture->getWidth());              bufferProto->set_height(resolvedComposerState.externalTexture->getHeight()); -            bufferProto->set_pixel_format(static_cast<proto::LayerState_BufferData_PixelFormat>( -                    resolvedComposerState.externalTexture->getPixelFormat())); +            bufferProto->set_pixel_format( +                    static_cast<perfetto::protos::LayerState_BufferData_PixelFormat>( +                            resolvedComposerState.externalTexture->getPixelFormat()));              bufferProto->set_usage(resolvedComposerState.externalTexture->getUsage());          }          bufferProto->set_frame_number(layer.bufferData->frameNumber); @@ -191,7 +192,8 @@ proto::LayerState TransactionProtoParser::toProto(      if (layer.what & layer_state_t::eInputInfoChanged) {          if (layer.windowInfoHandle) {              const gui::WindowInfo* inputInfo = layer.windowInfoHandle->getInfo(); -            proto::LayerState_WindowInfo* windowInfoProto = proto.mutable_window_info_handle(); +            perfetto::protos::LayerState_WindowInfo* windowInfoProto = +                    proto.mutable_window_info_handle();              windowInfoProto->set_layout_params_flags(inputInfo->layoutParamsFlags.get());              windowInfoProto->set_layout_params_type(                      static_cast<int32_t>(inputInfo->layoutParamsType)); @@ -204,7 +206,7 @@ proto::LayerState TransactionProtoParser::toProto(              windowInfoProto->set_has_wallpaper(inputInfo->inputConfig.test(                      gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));              windowInfoProto->set_global_scale_factor(inputInfo->globalScaleFactor); -            proto::Transform* transformProto = windowInfoProto->mutable_transform(); +            perfetto::protos::Transform* transformProto = windowInfoProto->mutable_transform();              transformProto->set_dsdx(inputInfo->transform.dsdx());              transformProto->set_dtdx(inputInfo->transform.dtdx());              transformProto->set_dtdy(inputInfo->transform.dtdy()); @@ -219,7 +221,7 @@ proto::LayerState TransactionProtoParser::toProto(      if (layer.what & layer_state_t::eBackgroundColorChanged) {          proto.set_bg_color_alpha(layer.bgColor.a);          proto.set_bg_color_dataspace(static_cast<int32_t>(layer.bgColorDataspace)); -        proto::LayerState_Color3* colorProto = proto.mutable_color(); +        perfetto::protos::LayerState_Color3* colorProto = proto.mutable_color();          colorProto->set_r(layer.bgColor.r);          colorProto->set_g(layer.bgColor.g);          colorProto->set_b(layer.bgColor.b); @@ -255,13 +257,13 @@ proto::LayerState TransactionProtoParser::toProto(      }      if (layer.what & layer_state_t::eDropInputModeChanged) {          proto.set_drop_input_mode( -                static_cast<proto::LayerState_DropInputMode>(layer.dropInputMode)); +                static_cast<perfetto::protos::LayerState_DropInputMode>(layer.dropInputMode));      }      return proto;  } -proto::DisplayState TransactionProtoParser::toProto(const DisplayState& display) { -    proto::DisplayState proto; +perfetto::protos::DisplayState TransactionProtoParser::toProto(const DisplayState& display) { +    perfetto::protos::DisplayState proto;      proto.set_what(display.what);      proto.set_id(mMapper->getDisplayId(display.token)); @@ -285,8 +287,8 @@ proto::DisplayState TransactionProtoParser::toProto(const DisplayState& display)      return proto;  } -proto::LayerCreationArgs TransactionProtoParser::toProto(const LayerCreationArgs& args) { -    proto::LayerCreationArgs proto; +perfetto::protos::LayerCreationArgs TransactionProtoParser::toProto(const LayerCreationArgs& args) { +    perfetto::protos::LayerCreationArgs proto;      proto.set_layer_id(args.sequence);      proto.set_name(args.name);      proto.set_flags(args.flags); @@ -297,7 +299,8 @@ proto::LayerCreationArgs TransactionProtoParser::toProto(const LayerCreationArgs      return proto;  } -TransactionState TransactionProtoParser::fromProto(const proto::TransactionState& proto) { +TransactionState TransactionProtoParser::fromProto( +        const perfetto::protos::TransactionState& proto) {      TransactionState t;      t.originPid = proto.pid();      t.originUid = proto.uid(); @@ -323,7 +326,7 @@ TransactionState TransactionProtoParser::fromProto(const proto::TransactionState      return t;  } -void TransactionProtoParser::fromProto(const proto::LayerCreationArgs& proto, +void TransactionProtoParser::fromProto(const perfetto::protos::LayerCreationArgs& proto,                                         LayerCreationArgs& outArgs) {      outArgs.sequence = proto.layer_id(); @@ -335,7 +338,7 @@ void TransactionProtoParser::fromProto(const proto::LayerCreationArgs& proto,      outArgs.layerStackToMirror.id = proto.layer_stack_to_mirror();  } -void TransactionProtoParser::mergeFromProto(const proto::LayerState& proto, +void TransactionProtoParser::mergeFromProto(const perfetto::protos::LayerState& proto,                                              TracingLayerState& outState) {      ResolvedComposerState resolvedComposerState;      fromProto(proto, resolvedComposerState); @@ -360,7 +363,7 @@ void TransactionProtoParser::mergeFromProto(const proto::LayerState& proto,      }  } -void TransactionProtoParser::fromProto(const proto::LayerState& proto, +void TransactionProtoParser::fromProto(const perfetto::protos::LayerState& proto,                                         ResolvedComposerState& resolvedComposerState) {      auto& layer = resolvedComposerState.state;      resolvedComposerState.layerId = proto.layer_id(); @@ -381,7 +384,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,          layer.mask = proto.mask();      }      if (proto.what() & layer_state_t::eMatrixChanged) { -        const proto::LayerState_Matrix22& matrixProto = proto.matrix(); +        const perfetto::protos::LayerState_Matrix22& matrixProto = proto.matrix();          layer.matrix.dsdx = matrixProto.dsdx();          layer.matrix.dsdy = matrixProto.dsdy();          layer.matrix.dtdx = matrixProto.dtdx(); @@ -399,7 +402,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,      }      if (proto.what() & layer_state_t::eColorChanged) { -        const proto::LayerState_Color3& colorProto = proto.color(); +        const perfetto::protos::LayerState_Color3& colorProto = proto.color();          layer.color.r = colorProto.r();          layer.color.g = colorProto.g();          layer.color.b = colorProto.b(); @@ -417,7 +420,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,          LayerProtoHelper::readFromProto(proto.crop(), layer.crop);      }      if (proto.what() & layer_state_t::eBufferChanged) { -        const proto::LayerState_BufferData& bufferProto = proto.buffer_data(); +        const perfetto::protos::LayerState_BufferData& bufferProto = proto.buffer_data();          layer.bufferData =                  std::make_shared<fake::BufferData>(bufferProto.buffer_id(), bufferProto.width(),                                                     bufferProto.height(), bufferProto.pixel_format(), @@ -460,7 +463,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,      if ((proto.what() & layer_state_t::eInputInfoChanged) && proto.has_window_info_handle()) {          gui::WindowInfo inputInfo; -        const proto::LayerState_WindowInfo& windowInfoProto = proto.window_info_handle(); +        const perfetto::protos::LayerState_WindowInfo& windowInfoProto = proto.window_info_handle();          inputInfo.layoutParamsFlags =                  static_cast<gui::WindowInfo::Flag>(windowInfoProto.layout_params_flags()); @@ -472,7 +475,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,                  ftl::Flags<gui::WindowInfo::InputConfig>(windowInfoProto.input_config());          inputInfo.surfaceInset = windowInfoProto.surface_inset();          inputInfo.globalScaleFactor = windowInfoProto.global_scale_factor(); -        const proto::Transform& transformProto = windowInfoProto.transform(); +        const perfetto::protos::Transform& transformProto = windowInfoProto.transform();          inputInfo.transform.set(transformProto.dsdx(), transformProto.dtdx(), transformProto.dtdy(),                                  transformProto.dsdy());          inputInfo.transform.set(transformProto.tx(), transformProto.ty()); @@ -485,7 +488,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,      if (proto.what() & layer_state_t::eBackgroundColorChanged) {          layer.bgColor.a = proto.bg_color_alpha();          layer.bgColorDataspace = static_cast<ui::Dataspace>(proto.bg_color_dataspace()); -        const proto::LayerState_Color3& colorProto = proto.color(); +        const perfetto::protos::LayerState_Color3& colorProto = proto.color();          layer.bgColor.r = colorProto.r();          layer.bgColor.g = colorProto.g();          layer.bgColor.b = colorProto.b(); @@ -525,7 +528,7 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto,      }  } -DisplayState TransactionProtoParser::fromProto(const proto::DisplayState& proto) { +DisplayState TransactionProtoParser::fromProto(const perfetto::protos::DisplayState& proto) {      DisplayState display;      display.what = proto.what();      display.token = mMapper->getDisplayHandle(proto.id()); @@ -550,7 +553,7 @@ DisplayState TransactionProtoParser::fromProto(const proto::DisplayState& proto)      return display;  } -void asProto(proto::Transform* proto, const ui::Transform& transform) { +void asProto(perfetto::protos::Transform* proto, const ui::Transform& transform) {      proto->set_dsdx(transform.dsdx());      proto->set_dtdx(transform.dtdx());      proto->set_dtdy(transform.dtdy()); @@ -559,9 +562,9 @@ void asProto(proto::Transform* proto, const ui::Transform& transform) {      proto->set_ty(transform.ty());  } -proto::DisplayInfo TransactionProtoParser::toProto(const frontend::DisplayInfo& displayInfo, -                                                   uint32_t layerStack) { -    proto::DisplayInfo proto; +perfetto::protos::DisplayInfo TransactionProtoParser::toProto( +        const frontend::DisplayInfo& displayInfo, uint32_t layerStack) { +    perfetto::protos::DisplayInfo proto;      proto.set_layer_stack(layerStack);      proto.set_display_id(displayInfo.info.displayId);      proto.set_logical_width(displayInfo.info.logicalWidth); @@ -577,12 +580,13 @@ proto::DisplayInfo TransactionProtoParser::toProto(const frontend::DisplayInfo&      return proto;  } -void fromProto2(ui::Transform& outTransform, const proto::Transform& proto) { +void fromProto2(ui::Transform& outTransform, const perfetto::protos::Transform& proto) {      outTransform.set(proto.dsdx(), proto.dtdx(), proto.dtdy(), proto.dsdy());      outTransform.set(proto.tx(), proto.ty());  } -frontend::DisplayInfo TransactionProtoParser::fromProto(const proto::DisplayInfo& proto) { +frontend::DisplayInfo TransactionProtoParser::fromProto( +        const perfetto::protos::DisplayInfo& proto) {      frontend::DisplayInfo displayInfo;      displayInfo.info.displayId = proto.display_id();      displayInfo.info.logicalWidth = proto.logical_width(); @@ -599,10 +603,10 @@ frontend::DisplayInfo TransactionProtoParser::fromProto(const proto::DisplayInfo  }  void TransactionProtoParser::fromProto( -        const google::protobuf::RepeatedPtrField<proto::DisplayInfo>& proto, +        const google::protobuf::RepeatedPtrField<perfetto::protos::DisplayInfo>& proto,          frontend::DisplayInfos& outDisplayInfos) {      outDisplayInfos.clear(); -    for (const proto::DisplayInfo& displayInfo : proto) { +    for (const perfetto::protos::DisplayInfo& displayInfo : proto) {          outDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(displayInfo.layer_stack()),                                             fromProto(displayInfo));      } diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.h b/services/surfaceflinger/Tracing/TransactionProtoParser.h index 457c3bec40..b3ab71cfb5 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.h +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.h @@ -44,25 +44,25 @@ public:      TransactionProtoParser(std::unique_ptr<FlingerDataMapper> provider)            : mMapper(std::move(provider)) {} -    proto::TransactionState toProto(const TransactionState&); -    proto::TransactionState toProto(const std::map<uint32_t /* layerId */, TracingLayerState>&); -    proto::LayerCreationArgs toProto(const LayerCreationArgs& args); -    proto::LayerState toProto(const ResolvedComposerState&); -    static proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack); +    perfetto::protos::TransactionState toProto(const TransactionState&); +    perfetto::protos::TransactionState toProto( +            const std::map<uint32_t /* layerId */, TracingLayerState>&); +    perfetto::protos::LayerCreationArgs toProto(const LayerCreationArgs& args); +    perfetto::protos::LayerState toProto(const ResolvedComposerState&); +    static perfetto::protos::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); +    TransactionState fromProto(const perfetto::protos::TransactionState&); +    void mergeFromProto(const perfetto::protos::LayerState&, TracingLayerState& outState); +    void fromProto(const perfetto::protos::LayerCreationArgs&, LayerCreationArgs& outArgs);      std::unique_ptr<FlingerDataMapper> mMapper; -    static frontend::DisplayInfo fromProto(const proto::DisplayInfo&); -    static void fromProto(const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&, +    static frontend::DisplayInfo fromProto(const perfetto::protos::DisplayInfo&); +    static void fromProto(const google::protobuf::RepeatedPtrField<perfetto::protos::DisplayInfo>&,                            frontend::DisplayInfos& outDisplayInfos);  private: -    proto::DisplayState toProto(const DisplayState&); -    void fromProto(const proto::LayerState&, ResolvedComposerState& out); -    DisplayState fromProto(const proto::DisplayState&); - +    perfetto::protos::DisplayState toProto(const DisplayState&); +    void fromProto(const perfetto::protos::LayerState&, ResolvedComposerState& out); +    DisplayState fromProto(const perfetto::protos::DisplayState&);  };  } // namespace android::surfaceflinger diff --git a/services/surfaceflinger/Tracing/TransactionRingBuffer.h b/services/surfaceflinger/Tracing/TransactionRingBuffer.h index e6f85ca4a5..7d1d3fd7f2 100644 --- a/services/surfaceflinger/Tracing/TransactionRingBuffer.h +++ b/services/surfaceflinger/Tracing/TransactionRingBuffer.h @@ -47,7 +47,7 @@ public:          mUsedInBytes = 0U;      } -    void writeToProto(FileProto& fileProto) { +    void writeToProto(FileProto& fileProto) const {          fileProto.mutable_entry()->Reserve(static_cast<int>(mStorage.size()) +                                             fileProto.entry().size());          for (const std::string& entry : mStorage) { @@ -56,24 +56,6 @@ public:          }      } -    status_t writeToFile(FileProto& fileProto, std::string filename) { -        ATRACE_CALL(); -        writeToProto(fileProto); -        std::string output; -        if (!fileProto.SerializeToString(&output)) { -            ALOGE("Could not serialize proto."); -            return UNKNOWN_ERROR; -        } - -        // -rw-r--r-- -        const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; -        if (!android::base::WriteStringToFile(output, filename, mode, getuid(), getgid(), true)) { -            ALOGE("Could not save the proto file %s", filename.c_str()); -            return PERMISSION_DENIED; -        } -        return NO_ERROR; -    } -      status_t appendToStream(FileProto& fileProto, std::ofstream& out) {          ATRACE_CALL();          writeToProto(fileProto); diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp index bc69191cc1..0517984dab 100644 --- a/services/surfaceflinger/Tracing/TransactionTracing.cpp +++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp @@ -25,6 +25,7 @@  #include "Client.h"  #include "FrontEnd/LayerCreationArgs.h" +#include "TransactionDataSource.h"  #include "TransactionTracing.h"  namespace android { @@ -34,15 +35,20 @@ TransactionTracing::TransactionTracing()        : mProtoParser(std::make_unique<TransactionProtoParser::FlingerDataMapper>()) {      std::scoped_lock lock(mTraceLock); -    mBuffer.setSize(mBufferSizeInBytes); +    mBuffer.setSize(CONTINUOUS_TRACING_BUFFER_SIZE); +      mStartingTimestamp = systemTime(); +      {          std::scoped_lock lock(mMainThreadLock);          mThread = std::thread(&TransactionTracing::loop, this);      } + +    TransactionDataSource::Initialize(*this);  }  TransactionTracing::~TransactionTracing() { +    TransactionDataSource::UnregisterTransactionTracing();      std::thread thread;      {          std::scoped_lock lock(mMainThreadLock); @@ -53,29 +59,103 @@ TransactionTracing::~TransactionTracing() {      if (thread.joinable()) {          thread.join();      } +} + +void TransactionTracing::onStart(TransactionTracing::Mode mode) { +    // In "active" mode write the ring buffer (starting state + following sequence of transactions) +    // to perfetto when tracing starts (only once). +    if (mode != Mode::MODE_ACTIVE) { +        return; +    } + +    writeRingBufferToPerfetto(TransactionTracing::Mode::MODE_ACTIVE); + +    ALOGV("Started active mode tracing (wrote initial transactions ring buffer to perfetto)"); +} -    writeToFile(); +void TransactionTracing::onFlush(TransactionTracing::Mode mode) { +    // In "continuous" mode write the ring buffer (starting state + following sequence of +    // transactions) to perfetto when a "flush" event is received (bugreport is taken or tracing is +    // stopped). +    if (mode != Mode::MODE_CONTINUOUS) { +        return; +    } + +    writeRingBufferToPerfetto(TransactionTracing::Mode::MODE_CONTINUOUS); + +    ALOGV("Flushed continuous mode tracing (wrote transactions ring buffer to perfetto"); +} + +void TransactionTracing::writeRingBufferToPerfetto(TransactionTracing::Mode mode) { +    // Write the ring buffer (starting state + following sequence of transactions) to perfetto +    // tracing sessions with the specified mode. +    const auto fileProto = writeToProto(); + +    TransactionDataSource::Trace([&](TransactionDataSource::TraceContext context) { +        // Write packets only to tracing sessions with specified mode +        if (context.GetCustomTlsState()->mMode != mode) { +            return; +        } +        for (const auto& entryProto : fileProto.entry()) { +            const auto entryBytes = entryProto.SerializeAsString(); + +            auto packet = context.NewTracePacket(); +            packet->set_timestamp(static_cast<uint64_t>(entryProto.elapsed_realtime_nanos())); +            packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC); + +            auto* transactionsProto = packet->set_surfaceflinger_transactions(); +            transactionsProto->AppendRawProtoBytes(entryBytes.data(), entryBytes.size()); +        } +        { +            // TODO (b/162206162): remove empty packet when perfetto bug is fixed. +            //  It is currently needed in order not to lose the last trace entry. +            context.NewTracePacket(); +        } +    });  }  status_t TransactionTracing::writeToFile(const std::string& filename) { -    std::scoped_lock lock(mTraceLock); -    proto::TransactionTraceFile fileProto = createTraceFileProto(); -    addStartingStateToProtoLocked(fileProto); -    return mBuffer.writeToFile(fileProto, filename); +    auto fileProto = writeToProto(); + +    std::string output; +    if (!fileProto.SerializeToString(&output)) { +        ALOGE("Could not serialize proto."); +        return UNKNOWN_ERROR; +    } + +    // -rw-r--r-- +    const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; +    if (!android::base::WriteStringToFile(output, filename, mode, getuid(), getgid(), true)) { +        ALOGE("Could not save the proto file %s", filename.c_str()); +        return PERMISSION_DENIED; +    } + +    return NO_ERROR; +} + +perfetto::protos::TransactionTraceFile TransactionTracing::writeToProto() { +    std::scoped_lock<std::mutex> lock(mTraceLock); +    perfetto::protos::TransactionTraceFile fileProto = createTraceFileProto(); +    const auto startingStateProto = createStartingStateProtoLocked(); +    if (startingStateProto) { +        *fileProto.add_entry() = std::move(*startingStateProto); +    } +    mBuffer.writeToProto(fileProto); +    return fileProto;  }  void TransactionTracing::setBufferSize(size_t bufferSizeInBytes) {      std::scoped_lock lock(mTraceLock); -    mBufferSizeInBytes = bufferSizeInBytes; -    mBuffer.setSize(mBufferSizeInBytes); +    mBuffer.setSize(bufferSizeInBytes);  } -proto::TransactionTraceFile TransactionTracing::createTraceFileProto() const { -    proto::TransactionTraceFile proto; -    proto.set_magic_number(uint64_t(proto::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_H) << 32 | -                           proto::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_L); -    auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) - -                                                   systemTime(SYSTEM_TIME_MONOTONIC)); +perfetto::protos::TransactionTraceFile TransactionTracing::createTraceFileProto() const { +    perfetto::protos::TransactionTraceFile proto; +    proto.set_magic_number( +            uint64_t(perfetto::protos::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_H) << 32 | +            perfetto::protos::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_L); +    auto timeOffsetNs = static_cast<uint64_t>(systemTime(SYSTEM_TIME_REALTIME) - +                                              systemTime(SYSTEM_TIME_MONOTONIC));      proto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);      proto.set_version(TRACING_VERSION);      return proto; @@ -89,7 +169,8 @@ void TransactionTracing::dump(std::string& result) const {  }  void TransactionTracing::addQueuedTransaction(const TransactionState& transaction) { -    proto::TransactionState* state = new proto::TransactionState(mProtoParser.toProto(transaction)); +    perfetto::protos::TransactionState* state = +            new perfetto::protos::TransactionState(mProtoParser.toProto(transaction));      mTransactionQueue.push(state);  } @@ -152,7 +233,7 @@ void TransactionTracing::addEntry(const std::vector<CommittedUpdates>& committed      ATRACE_CALL();      std::scoped_lock lock(mTraceLock);      std::vector<std::string> removedEntries; -    proto::TransactionTraceEntry entryProto; +    perfetto::protos::TransactionTraceEntry entryProto;      while (auto incomingTransaction = mTransactionQueue.pop()) {          auto transaction = *incomingTransaction; @@ -204,14 +285,37 @@ void TransactionTracing::addEntry(const std::vector<CommittedUpdates>& committed          std::string serializedProto;          entryProto.SerializeToString(&serializedProto); -        entryProto.Clear(); + +        TransactionDataSource::Trace([&](TransactionDataSource::TraceContext context) { +            // In "active" mode write each committed transaction to perfetto. +            // Note: the starting state is written (once) when the perfetto "start" event is +            // received. +            if (context.GetCustomTlsState()->mMode != Mode::MODE_ACTIVE) { +                return; +            } +            { +                auto packet = context.NewTracePacket(); +                packet->set_timestamp(static_cast<uint64_t>(entryProto.elapsed_realtime_nanos())); +                packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC); +                auto* transactions = packet->set_surfaceflinger_transactions(); +                transactions->AppendRawProtoBytes(serializedProto.data(), serializedProto.size()); +            } +            { +                // TODO (b/162206162): remove empty packet when perfetto bug is fixed. +                //  It is currently needed in order not to lose the last trace entry. +                context.NewTracePacket(); +            } +        }); +          std::vector<std::string> entries = mBuffer.emplace(std::move(serializedProto));          removedEntries.reserve(removedEntries.size() + entries.size());          removedEntries.insert(removedEntries.end(), std::make_move_iterator(entries.begin()),                                std::make_move_iterator(entries.end())); + +        entryProto.Clear();      } -    proto::TransactionTraceEntry removedEntryProto; +    perfetto::protos::TransactionTraceEntry removedEntryProto;      for (const std::string& removedEntry : removedEntries) {          removedEntryProto.ParseFromString(removedEntry);          updateStartingStateLocked(removedEntryProto); @@ -236,7 +340,7 @@ void TransactionTracing::flush() {      base::ScopedLockAssertion assumeLocked(mTraceLock);      mTransactionsAddedToBufferCv.wait_for(lock, std::chrono::milliseconds(100),                                            [&]() REQUIRES(mTraceLock) { -                                              proto::TransactionTraceEntry entry; +                                              perfetto::protos::TransactionTraceEntry entry;                                                if (mBuffer.used() > 0) {                                                    entry.ParseFromString(mBuffer.back());                                                } @@ -268,19 +372,19 @@ void TransactionTracing::tryPushToTracingThread() {  }  void TransactionTracing::updateStartingStateLocked( -        const proto::TransactionTraceEntry& removedEntry) { +        const perfetto::protos::TransactionTraceEntry& removedEntry) {      mStartingTimestamp = removedEntry.elapsed_realtime_nanos();      // Keep track of layer starting state so we can reconstruct the layer state as we purge      // transactions from the buffer. -    for (const proto::LayerCreationArgs& addedLayer : removedEntry.added_layers()) { +    for (const perfetto::protos::LayerCreationArgs& addedLayer : removedEntry.added_layers()) {          TracingLayerState& startingState = mStartingStates[addedLayer.layer_id()];          startingState.layerId = addedLayer.layer_id();          mProtoParser.fromProto(addedLayer, startingState.args);      }      // Merge layer states to starting transaction state. -    for (const proto::TransactionState& transaction : removedEntry.transactions()) { -        for (const proto::LayerState& layerState : transaction.layer_changes()) { +    for (const perfetto::protos::TransactionState& transaction : removedEntry.transactions()) { +        for (const perfetto::protos::LayerState& layerState : transaction.layer_changes()) {              auto it = mStartingStates.find(layerState.layer_id());              if (it == mStartingStates.end()) {                  // TODO(b/238781169) make this log fatal when we switch over to using new fe @@ -307,43 +411,38 @@ void TransactionTracing::updateStartingStateLocked(      }  } -void TransactionTracing::addStartingStateToProtoLocked(proto::TransactionTraceFile& proto) { -    if (mStartingStates.size() == 0) { -        return; +std::optional<perfetto::protos::TransactionTraceEntry> +TransactionTracing::createStartingStateProtoLocked() { +    if (mStartingStates.empty()) { +        return std::nullopt;      } -    proto::TransactionTraceEntry* entryProto = proto.add_entry(); -    entryProto->set_elapsed_realtime_nanos(mStartingTimestamp); -    entryProto->set_vsync_id(0); +    perfetto::protos::TransactionTraceEntry entryProto; +    entryProto.set_elapsed_realtime_nanos(mStartingTimestamp); +    entryProto.set_vsync_id(0); -    entryProto->mutable_added_layers()->Reserve(static_cast<int32_t>(mStartingStates.size())); +    entryProto.mutable_added_layers()->Reserve(static_cast<int32_t>(mStartingStates.size()));      for (auto& [layerId, state] : mStartingStates) { -        entryProto->mutable_added_layers()->Add(mProtoParser.toProto(state.args)); +        entryProto.mutable_added_layers()->Add(mProtoParser.toProto(state.args));      } -    proto::TransactionState transactionProto = mProtoParser.toProto(mStartingStates); +    perfetto::protos::TransactionState transactionProto = mProtoParser.toProto(mStartingStates);      transactionProto.set_vsync_id(0);      transactionProto.set_post_time(mStartingTimestamp); -    entryProto->mutable_transactions()->Add(std::move(transactionProto)); +    entryProto.mutable_transactions()->Add(std::move(transactionProto)); -    entryProto->mutable_destroyed_layer_handles()->Reserve( +    entryProto.mutable_destroyed_layer_handles()->Reserve(              static_cast<int32_t>(mRemovedLayerHandlesAtStart.size()));      for (const uint32_t destroyedLayerHandleId : mRemovedLayerHandlesAtStart) { -        entryProto->mutable_destroyed_layer_handles()->Add(destroyedLayerHandleId); +        entryProto.mutable_destroyed_layer_handles()->Add(destroyedLayerHandleId);      } -    entryProto->mutable_displays()->Reserve(static_cast<int32_t>(mStartingDisplayInfos.size())); +    entryProto.mutable_displays()->Reserve(static_cast<int32_t>(mStartingDisplayInfos.size()));      for (auto& [layerStack, displayInfo] : mStartingDisplayInfos) { -        entryProto->mutable_displays()->Add(mProtoParser.toProto(displayInfo, layerStack.id)); +        entryProto.mutable_displays()->Add(mProtoParser.toProto(displayInfo, layerStack.id));      } -} -proto::TransactionTraceFile TransactionTracing::writeToProto() { -    std::scoped_lock<std::mutex> lock(mTraceLock); -    proto::TransactionTraceFile proto = createTraceFileProto(); -    addStartingStateToProtoLocked(proto); -    mBuffer.writeToProto(proto); -    return proto; +    return entryProto;  }  } // namespace android diff --git a/services/surfaceflinger/Tracing/TransactionTracing.h b/services/surfaceflinger/Tracing/TransactionTracing.h index 422b5f3689..ddbf3e4873 100644 --- a/services/surfaceflinger/Tracing/TransactionTracing.h +++ b/services/surfaceflinger/Tracing/TransactionTracing.h @@ -22,8 +22,8 @@  #include <utils/Singleton.h>  #include <utils/Timers.h> -#include <memory>  #include <mutex> +#include <optional>  #include <thread>  #include "FrontEnd/DisplayInfo.h" @@ -41,7 +41,7 @@ class SurfaceFlinger;  class TransactionTracingTest;  /* - * Records all committed transactions into a ring bufffer. + * Records all committed transactions into a ring buffer.   *   * Transactions come in via the binder thread. They are serialized to proto   * and stored in a map using the transaction id as key. Main thread will @@ -49,26 +49,104 @@ class TransactionTracingTest;   * the tracing thread. The tracing thread will then wake up and add the   * committed transactions to the ring buffer.   * - * When generating SF dump state, we will flush the buffer to a file which - * will then be included in the bugreport. + * The traced data can then be collected via: + * - Perfetto (preferred). + * - File system, after triggering the disk write through SF backdoor. This is legacy and is going + *   to be phased out. + * + * The Perfetto custom data source TransactionDataSource is registered with perfetto and is used + * to listen to perfetto events (setup, start, stop, flush) and to write trace packets to perfetto. + * + * The user can configure/start/stop tracing via /system/bin/perfetto. + * + * Tracing can operate in the following modes. + * + * ACTIVE mode: + * The transactions ring buffer (starting state + following committed transactions) is written + * (only once) to perfetto when the 'start' event is received. + * Transactions are then written to perfetto each time they are committed. + * On the receiver side, the data source is to be configured to periodically + * flush data to disk providing virtually infinite storage. + * + * CONTINUOUS mode: + * Listens to the perfetto 'flush' event (e.g. when a bugreport is taken). + * When a 'flush' event is received, the ring buffer of transactions (starting state + following + * committed transactions) is written to perfetto. On the receiver side, the data source is to be + * configured with a dedicated buffer large enough to store all the flushed data. + * + * + * E.g. start active mode tracing: + * +   adb shell perfetto \ +     -c - --txt \ +     -o /data/misc/perfetto-traces/trace \ +   <<EOF +   unique_session_name: "surfaceflinger_transactions_active" +   buffers: { +       size_kb: 1024 +       fill_policy: RING_BUFFER +   } +   data_sources: { +       config { +           name: "android.surfaceflinger.transactions" +           surfaceflinger_transactions_config: { +               mode: MODE_ACTIVE +           } +       } +   } +   write_into_file: true +   file_write_period_ms: 100 +   EOF + * + * + * E.g. start continuous mode tracing: + * +   adb shell perfetto \ +     -c - --txt \ +     -o /data/misc/perfetto-traces/trace \ +   <<EOF +   unique_session_name: "surfaceflinger_transactions_continuous" +   buffers: { +       size_kb: 1024 +       fill_policy: RING_BUFFER +   } +   data_sources: { +       config { +           name: "android.surfaceflinger.transactions" +           surfaceflinger_transactions_config: { +               mode: MODE_CONTINUOUS +           } +       } +   } +   EOF   *   */  class TransactionTracing {  public: +    using Mode = perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig::Mode; +      TransactionTracing();      ~TransactionTracing(); +    // Start event from perfetto data source +    void onStart(Mode mode); +    // Flush event from perfetto data source +    void onFlush(Mode mode); +      void addQueuedTransaction(const TransactionState&);      void addCommittedTransactions(int64_t vsyncId, nsecs_t commitTime, frontend::Update& update,                                    const frontend::DisplayInfos&, bool displayInfoChanged);      status_t writeToFile(const std::string& filename = FILE_PATH); +    // Return buffer contents as trace file proto +    perfetto::protos::TransactionTraceFile writeToProto() EXCLUDES(mMainThreadLock);      void setBufferSize(size_t bufferSizeInBytes);      void onLayerRemoved(int layerId);      void dump(std::string&) const;      // Wait until all the committed transactions for the specified vsync id are added to the buffer.      void flush() EXCLUDES(mMainThreadLock); +      static constexpr auto CONTINUOUS_TRACING_BUFFER_SIZE = 512 * 1024; -    static constexpr auto ACTIVE_TRACING_BUFFER_SIZE = 100 * 1024 * 1024; +    static constexpr auto LEGACY_ACTIVE_TRACING_BUFFER_SIZE = 100 * 1024 * 1024;      // version 1 - switching to support new frontend      static constexpr auto TRACING_VERSION = 1; @@ -85,14 +163,15 @@ private:      }      mutable std::mutex mTraceLock; -    TransactionRingBuffer<proto::TransactionTraceFile, proto::TransactionTraceEntry> mBuffer -            GUARDED_BY(mTraceLock); -    size_t mBufferSizeInBytes GUARDED_BY(mTraceLock) = CONTINUOUS_TRACING_BUFFER_SIZE; -    std::unordered_map<uint64_t, proto::TransactionState> mQueuedTransactions +    TransactionRingBuffer<perfetto::protos::TransactionTraceFile, +                          perfetto::protos::TransactionTraceEntry> +            mBuffer GUARDED_BY(mTraceLock); +    std::unordered_map<uint64_t, perfetto::protos::TransactionState> mQueuedTransactions              GUARDED_BY(mTraceLock); -    LocklessStack<proto::TransactionState> mTransactionQueue; +    LocklessStack<perfetto::protos::TransactionState> mTransactionQueue;      nsecs_t mStartingTimestamp GUARDED_BY(mTraceLock); -    std::unordered_map<int, proto::LayerCreationArgs> mCreatedLayers GUARDED_BY(mTraceLock); +    std::unordered_map<int, perfetto::protos::LayerCreationArgs> mCreatedLayers +            GUARDED_BY(mTraceLock);      std::map<uint32_t /* layerId */, TracingLayerState> mStartingStates GUARDED_BY(mTraceLock);      frontend::DisplayInfos mStartingDisplayInfos GUARDED_BY(mTraceLock); @@ -122,17 +201,17 @@ private:      std::vector<uint32_t /* layerId */> mPendingDestroyedLayers; // only accessed by main thread      int64_t mLastUpdatedVsyncId = -1; -    proto::TransactionTraceFile createTraceFileProto() const; +    void writeRingBufferToPerfetto(TransactionTracing::Mode mode); +    perfetto::protos::TransactionTraceFile createTraceFileProto() const;      void loop();      void addEntry(const std::vector<CommittedUpdates>& committedTransactions,                    const std::vector<uint32_t>& removedLayers) EXCLUDES(mTraceLock);      int32_t getLayerIdLocked(const sp<IBinder>& layerHandle) REQUIRES(mTraceLock);      void tryPushToTracingThread() EXCLUDES(mMainThreadLock); -    void addStartingStateToProtoLocked(proto::TransactionTraceFile& proto) REQUIRES(mTraceLock); -    void updateStartingStateLocked(const proto::TransactionTraceEntry& entry) REQUIRES(mTraceLock); -    // TEST -    // Return buffer contents as trace file proto -    proto::TransactionTraceFile writeToProto() EXCLUDES(mMainThreadLock); +    std::optional<perfetto::protos::TransactionTraceEntry> createStartingStateProtoLocked() +            REQUIRES(mTraceLock); +    void updateStartingStateLocked(const perfetto::protos::TransactionTraceEntry& entry) +            REQUIRES(mTraceLock);  };  class TransactionTraceWriter : public Singleton<TransactionTraceWriter> { diff --git a/services/surfaceflinger/Tracing/tools/Android.bp b/services/surfaceflinger/Tracing/tools/Android.bp index b6435a8a13..2ff09c3f4c 100644 --- a/services/surfaceflinger/Tracing/tools/Android.bp +++ b/services/surfaceflinger/Tracing/tools/Android.bp @@ -31,7 +31,6 @@ cc_binary {      srcs: [          ":libsurfaceflinger_sources",          ":libsurfaceflinger_mock_sources", -        ":layertracegenerator_sources",          "main.cpp",      ],      static_libs: [ @@ -41,15 +40,3 @@ cc_binary {          "libsurfaceflinger_mocks_headers",      ],  } - -filegroup { -    name: "layertracegenerator_sources", -    srcs: [ -        "LayerTraceGenerator.cpp", -    ], -} - -cc_library_headers { -    name: "layertracegenerator_headers", -    export_include_dirs: ["."], -} diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp index 321b8baccc..62c362eb2d 100644 --- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp +++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp @@ -40,8 +40,10 @@  namespace android {  using namespace ftl::flag_operators; -bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile, -                                   const char* outputLayersTracePath, bool onlyLastEntry) { +bool LayerTraceGenerator::generate(const perfetto::protos::TransactionTraceFile& traceFile, +                                   std::uint32_t traceFlags, +                                   std::optional<std::reference_wrapper<std::ostream>> outStream, +                                   bool onlyLastEntry) {      if (traceFile.entry_size() == 0) {          ALOGD("Trace file is empty");          return false; @@ -49,6 +51,11 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile,      TransactionProtoParser parser(std::make_unique<TransactionProtoParser::FlingerDataMapper>()); +    LayerTracing layerTracing; +    if (outStream) { +        layerTracing.setOutputStream(outStream->get()); +    } +      // frontend      frontend::LayerLifecycleManager lifecycleManager;      frontend::LayerHierarchyBuilder hierarchyBuilder{{}}; @@ -60,18 +67,10 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile,      property_get("ro.surface_flinger.supports_background_blur", value, "0");      bool supportsBlur = atoi(value); -    LayerTracing layerTracing; -    layerTracing.setTraceFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS); -    // 10MB buffer size (large enough to hold a single entry) -    layerTracing.setBufferSize(10 * 1024 * 1024); -    layerTracing.enable(); -    layerTracing.writeToFile(outputLayersTracePath); -    std::ofstream out(outputLayersTracePath, std::ios::binary | std::ios::app); -      ALOGD("Generating %d transactions...", traceFile.entry_size());      for (int i = 0; i < traceFile.entry_size(); i++) {          // parse proto -        proto::TransactionTraceEntry entry = traceFile.entry(i); +        perfetto::protos::TransactionTraceEntry entry = traceFile.entry(i);          ALOGV("    Entry %04d/%04d for time=%" PRId64 " vsyncid=%" PRId64                " layers +%d -%d handles -%d transactions=%d",                i, traceFile.entry_size(), entry.elapsed_realtime_nanos(), entry.vsync_id(), @@ -154,19 +153,26 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile,          lifecycleManager.commitChanges(); -        LayersProto layersProto = LayerProtoFromSnapshotGenerator(snapshotBuilder, displayInfos, {}, -                                                                  layerTracing.getFlags()) -                                          .generate(hierarchyBuilder.getHierarchy()); +        auto layersProto = +                LayerProtoFromSnapshotGenerator(snapshotBuilder, displayInfos, {}, traceFlags) +                        .generate(hierarchyBuilder.getHierarchy());          auto displayProtos = LayerProtoHelper::writeDisplayInfoToProto(displayInfos);          if (!onlyLastEntry || (i == traceFile.entry_size() - 1)) { -            layerTracing.notify(visibleRegionsDirty, entry.elapsed_realtime_nanos(), -                                entry.vsync_id(), &layersProto, {}, &displayProtos); -            layerTracing.appendToStream(out); +            perfetto::protos::LayersSnapshotProto snapshotProto{}; +            snapshotProto.set_vsync_id(entry.vsync_id()); +            snapshotProto.set_elapsed_realtime_nanos(entry.elapsed_realtime_nanos()); +            snapshotProto.set_where(visibleRegionsDirty ? "visibleRegionsDirty" : "bufferLatched"); +            *snapshotProto.mutable_layers() = std::move(layersProto); +            if ((traceFlags & LayerTracing::TRACE_COMPOSITION) == 0) { +                snapshotProto.set_excludes_composition_state(true); +            } +            *snapshotProto.mutable_displays() = std::move(displayProtos); + +            layerTracing.addProtoSnapshotToOstream(std::move(snapshotProto), +                                                   LayerTracing::Mode::MODE_GENERATED);          }      } -    layerTracing.disable("", /*writeToFile=*/false); -    out.close(); -    ALOGD("End of generating trace file. File written to %s", outputLayersTracePath); +    ALOGD("End of generating trace file");      return true;  } diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h index e41d1e6e0b..2bb6f5129c 100644 --- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h +++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h @@ -18,10 +18,19 @@  #include <Tracing/TransactionTracing.h> +#include <functional> +#include <optional> +#include <ostream> +#include <string> +  namespace android { + +class LayerTracing; +  class LayerTraceGenerator {  public: -    bool generate(const proto::TransactionTraceFile&, const char* outputLayersTracePath, -                  bool onlyLastEntry); +    bool generate(const perfetto::protos::TransactionTraceFile&, std::uint32_t traceFlags, +                  std::optional<std::reference_wrapper<std::ostream>> outStream = std::nullopt, +                  bool onlyLastEntry = false);  }; -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/Tracing/tools/main.cpp b/services/surfaceflinger/Tracing/tools/main.cpp index 5ca87e4cb3..a8ac36a422 100644 --- a/services/surfaceflinger/Tracing/tools/main.cpp +++ b/services/surfaceflinger/Tracing/tools/main.cpp @@ -21,6 +21,7 @@  #include <iostream>  #include <string> +#include <Tracing/LayerTracing.h>  #include "LayerTraceGenerator.h"  using namespace android; @@ -41,25 +42,28 @@ int main(int argc, char** argv) {          return -1;      } -    proto::TransactionTraceFile transactionTraceFile; +    perfetto::protos::TransactionTraceFile transactionTraceFile;      if (!transactionTraceFile.ParseFromIstream(&input)) {          std::cout << "Error: Failed to parse " << transactionTracePath;          return -1;      } -    const char* outputLayersTracePath = -            (argc >= 3) ? argv[2] : "/data/misc/wmtrace/layers_trace.winscope"; +    const auto* outputLayersTracePath = +            (argc == 3) ? argv[2] : "/data/misc/wmtrace/layers_trace.winscope"; +    auto outStream = std::ofstream{outputLayersTracePath, std::ios::binary | std::ios::app};      const bool generateLastEntryOnly =              argc >= 4 && std::string_view(argv[3]) == "--last-entry-only"; +    auto traceFlags = LayerTracing::Flag::TRACE_INPUT | LayerTracing::Flag::TRACE_BUFFERS; +      ALOGD("Generating %s...", outputLayersTracePath);      std::cout << "Generating " << outputLayersTracePath << "\n"; -    if (!LayerTraceGenerator().generate(transactionTraceFile, outputLayersTracePath, +    if (!LayerTraceGenerator().generate(transactionTraceFile, traceFlags, outStream,                                          generateLastEntryOnly)) {          std::cout << "Error: Failed to generate layers trace " << outputLayersTracePath;          return -1;      }      return 0; -}
\ No newline at end of file +} diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h index 8a050fdab5..437fd35c15 100644 --- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h +++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h @@ -455,7 +455,8 @@ public:          result = fdp->ConsumeRandomLengthString().c_str();          mFlinger->dumpRawDisplayIdentificationData(dumpArgs, result); -        LayersProto layersProto = mFlinger->dumpDrawingStateProto(fdp->ConsumeIntegral<uint32_t>()); +        perfetto::protos::LayersProto layersProto = +                mFlinger->dumpDrawingStateProto(fdp->ConsumeIntegral<uint32_t>());          mFlinger->dumpOffscreenLayersProto(layersProto);          mFlinger->dumpDisplayProto(); diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp index 7287dd0103..a4dc8a058e 100644 --- a/services/surfaceflinger/layerproto/Android.bp +++ b/services/surfaceflinger/layerproto/Android.bp @@ -13,7 +13,20 @@ cc_library {      srcs: [          "LayerProtoParser.cpp", -        "*.proto", +    ], + +    static_libs: [ +        "libperfetto_client_experimental", +    ], + +    whole_static_libs: [ +        // TODO(b/169779783): move  into "static_libs" when the soong issue is fixed +        "perfetto_trace_protos", +    ], + +    export_static_lib_headers: [ +        "libperfetto_client_experimental", +        "perfetto_trace_protos",      ],      shared_libs: [ @@ -24,10 +37,6 @@ cc_library {          "libbase",      ], -    proto: { -        export_proto_headers: true, -    }, -      cppflags: [          "-Werror",          "-Wno-unused-parameter", @@ -42,22 +51,3 @@ cc_library {          "-Wno-undef",      ],  } - -java_library_static { -    name: "layersprotoslite", -    host_supported: true, -    proto: { -        type: "lite", -        include_dirs: ["external/protobuf/src"], -    }, -    srcs: ["*.proto"], -    sdk_version: "core_platform", -    target: { -        android: { -            jarjar_rules: "jarjar-rules.txt", -        }, -        host: { -            static_libs: ["libprotobuf-java-lite"], -        }, -    }, -} diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp index 854084e7f9..c3d0a40261 100644 --- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp +++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp @@ -37,7 +37,8 @@ bool sortLayers(LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs      return lhs->id < rhs->id;  } -LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree(const LayersProto& layersProto) { +LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree( +        const perfetto::protos::LayersProto& layersProto) {      LayerTree layerTree;      layerTree.allLayers = generateLayerList(layersProto); @@ -53,7 +54,7 @@ LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree(const LayersProt  }  std::vector<LayerProtoParser::Layer> LayerProtoParser::generateLayerList( -        const LayersProto& layersProto) { +        const perfetto::protos::LayersProto& layersProto) {      std::vector<Layer> layerList;      std::unordered_map<int32_t, Layer*> layerMap; @@ -74,7 +75,8 @@ std::vector<LayerProtoParser::Layer> LayerProtoParser::generateLayerList(      return layerList;  } -LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerProto) { +LayerProtoParser::Layer LayerProtoParser::generateLayer( +        const perfetto::protos::LayerProto& layerProto) {      Layer layer;      layer.id = layerProto.id();      layer.name = layerProto.name(); @@ -120,17 +122,19 @@ LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerP      return layer;  } -LayerProtoParser::Region LayerProtoParser::generateRegion(const RegionProto& regionProto) { +LayerProtoParser::Region LayerProtoParser::generateRegion( +        const perfetto::protos::RegionProto& regionProto) {      LayerProtoParser::Region region;      for (int i = 0; i < regionProto.rect_size(); i++) { -        const RectProto& rectProto = regionProto.rect(i); +        const perfetto::protos::RectProto& rectProto = regionProto.rect(i);          region.rects.push_back(generateRect(rectProto));      }      return region;  } -LayerProtoParser::Rect LayerProtoParser::generateRect(const RectProto& rectProto) { +LayerProtoParser::Rect LayerProtoParser::generateRect( +        const perfetto::protos::RectProto& rectProto) {      LayerProtoParser::Rect rect;      rect.left = rectProto.left();      rect.top = rectProto.top(); @@ -140,7 +144,8 @@ LayerProtoParser::Rect LayerProtoParser::generateRect(const RectProto& rectProto      return rect;  } -LayerProtoParser::FloatRect LayerProtoParser::generateFloatRect(const FloatRectProto& rectProto) { +LayerProtoParser::FloatRect LayerProtoParser::generateFloatRect( +        const perfetto::protos::FloatRectProto& rectProto) {      LayerProtoParser::FloatRect rect;      rect.left = rectProto.left();      rect.top = rectProto.top(); @@ -151,7 +156,7 @@ LayerProtoParser::FloatRect LayerProtoParser::generateFloatRect(const FloatRectP  }  LayerProtoParser::Transform LayerProtoParser::generateTransform( -        const TransformProto& transformProto) { +        const perfetto::protos::TransformProto& transformProto) {      LayerProtoParser::Transform transform;      transform.dsdx = transformProto.dsdx();      transform.dtdx = transformProto.dtdx(); @@ -162,7 +167,7 @@ LayerProtoParser::Transform LayerProtoParser::generateTransform(  }  LayerProtoParser::ActiveBuffer LayerProtoParser::generateActiveBuffer( -        const ActiveBufferProto& activeBufferProto) { +        const perfetto::protos::ActiveBufferProto& activeBufferProto) {      LayerProtoParser::ActiveBuffer activeBuffer;      activeBuffer.width = activeBufferProto.width();      activeBuffer.height = activeBufferProto.height(); @@ -172,7 +177,7 @@ LayerProtoParser::ActiveBuffer LayerProtoParser::generateActiveBuffer(      return activeBuffer;  } -void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto, +void LayerProtoParser::updateChildrenAndRelative(const perfetto::protos::LayerProto& layerProto,                                                   std::unordered_map<int32_t, Layer*>& layerMap) {      auto currLayer = layerMap[layerProto.id()]; @@ -188,13 +193,13 @@ void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto,          }      } -    if (layerProto.parent() != -1) { +    if (layerProto.has_parent()) {          if (layerMap.count(layerProto.parent()) > 0) {              currLayer->parent = layerMap[layerProto.parent()];          }      } -    if (layerProto.z_order_relative_of() != -1) { +    if (layerProto.has_z_order_relative_of()) {          if (layerMap.count(layerProto.z_order_relative_of()) > 0) {              currLayer->zOrderRelativeOf = layerMap[layerProto.z_order_relative_of()];          } diff --git a/services/surfaceflinger/layerproto/common.proto b/services/surfaceflinger/layerproto/common.proto deleted file mode 100644 index 5e20d4d0f5..0000000000 --- a/services/surfaceflinger/layerproto/common.proto +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 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 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 ColorProto { -    float r = 1; -    float g = 2; -    float b = 3; -    float a = 4; -} - -message InputWindowInfoProto { -    uint32 layout_params_flags = 1; -    int32 layout_params_type = 2; -    RectProto frame = 3; -    RegionProto touchable_region = 4; - -    int32 surface_inset = 5; -    bool visible = 6; -    bool can_receive_keys = 7 [deprecated = true]; -    bool focusable = 8; -    bool has_wallpaper = 9; - -    float global_scale_factor = 10; -    float window_x_scale = 11 [deprecated = true]; -    float window_y_scale = 12 [deprecated = true]; - -    int32 crop_layer_id = 13; -    bool replace_touchable_region_with_crop = 14; -    RectProto touchable_region_crop = 15; -    TransformProto transform = 16; -    uint32 input_config = 17; -} - -message BlurRegion { -    uint32 blur_radius = 1; -    uint32 corner_radius_tl = 2; -    uint32 corner_radius_tr = 3; -    uint32 corner_radius_bl = 4; -    float corner_radius_br = 5; -    float alpha = 6; -    int32 left = 7; -    int32 top = 8; -    int32 right = 9; -    int32 bottom = 10; -} - -message ColorTransformProto { -    // This will be a 4x4 matrix of float values -    repeated float val = 1; -} diff --git a/services/surfaceflinger/layerproto/display.proto b/services/surfaceflinger/layerproto/display.proto deleted file mode 100644 index 64de775b8b..0000000000 --- a/services/surfaceflinger/layerproto/display.proto +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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; - -    bool is_virtual = 7; - -    double dpi_x = 8; - -    double dpi_y = 9; -} diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoHeader.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoHeader.h index f560562c94..4a2ef3ddf8 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoHeader.h +++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoHeader.h @@ -14,11 +14,14 @@   * limitations under the License.   */ +#pragma once +  // pragma is used here to disable the warnings emitted from the protobuf  // headers. By adding #pragma before including layer.pb.h, it supresses  // protobuf warnings, but allows the rest of the files to continuing using  // the current flags.  // This file should be included instead of directly including layer.b.h  #pragma GCC system_header -#include <layers.pb.h> -#include <layerstrace.pb.h> +#include <perfetto/config/android/surfaceflinger_layers_config.pbzero.h> +#include <perfetto/trace/android/surfaceflinger_layers.pb.h> +#include <perfetto/trace/android/surfaceflinger_layers.pbzero.h> diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h index cdc2706ee2..79c3982dbd 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h @@ -131,19 +131,22 @@ public:          std::vector<Layer*> topLevelLayers;      }; -    static LayerTree generateLayerTree(const LayersProto& layersProto); +    static LayerTree generateLayerTree(const perfetto::protos::LayersProto& layersProto);      static std::string layerTreeToString(const LayerTree& layerTree);  private: -    static std::vector<Layer> generateLayerList(const LayersProto& layersProto); -    static LayerProtoParser::Layer generateLayer(const LayerProto& layerProto); -    static LayerProtoParser::Region generateRegion(const RegionProto& regionProto); -    static LayerProtoParser::Rect generateRect(const RectProto& rectProto); -    static LayerProtoParser::FloatRect generateFloatRect(const FloatRectProto& rectProto); -    static LayerProtoParser::Transform generateTransform(const TransformProto& transformProto); +    static std::vector<Layer> generateLayerList(const perfetto::protos::LayersProto& layersProto); +    static LayerProtoParser::Layer generateLayer(const perfetto::protos::LayerProto& layerProto); +    static LayerProtoParser::Region generateRegion( +            const perfetto::protos::RegionProto& regionProto); +    static LayerProtoParser::Rect generateRect(const perfetto::protos::RectProto& rectProto); +    static LayerProtoParser::FloatRect generateFloatRect( +            const perfetto::protos::FloatRectProto& rectProto); +    static LayerProtoParser::Transform generateTransform( +            const perfetto::protos::TransformProto& transformProto);      static LayerProtoParser::ActiveBuffer generateActiveBuffer( -            const ActiveBufferProto& activeBufferProto); -    static void updateChildrenAndRelative(const LayerProto& layerProto, +            const perfetto::protos::ActiveBufferProto& activeBufferProto); +    static void updateChildrenAndRelative(const perfetto::protos::LayerProto& layerProto,                                            std::unordered_map<int32_t, Layer*>& layerMap);      static std::string layerToString(const LayerProtoParser::Layer* layer); diff --git a/services/surfaceflinger/layerproto/include/layerproto/TransactionProto.h b/services/surfaceflinger/layerproto/include/layerproto/TransactionProto.h index 3e9ca52fff..ea80ad8f33 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/TransactionProto.h +++ b/services/surfaceflinger/layerproto/include/layerproto/TransactionProto.h @@ -14,7 +14,11 @@   * limitations under the License.   */ +#pragma once +  // disable the warnings emitted from the protobuf headers. This file should be included instead of  // directly including the generated header file  #pragma GCC system_header -#include <transactions.pb.h> +#include <perfetto/config/android/surfaceflinger_transactions_config.pbzero.h> +#include <perfetto/trace/android/surfaceflinger_transactions.pb.h> +#include <perfetto/trace/android/surfaceflinger_transactions.pbzero.h> diff --git a/services/surfaceflinger/layerproto/jarjar-rules.txt b/services/surfaceflinger/layerproto/jarjar-rules.txt deleted file mode 100644 index 40043a861c..0000000000 --- a/services/surfaceflinger/layerproto/jarjar-rules.txt +++ /dev/null @@ -1 +0,0 @@ -rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1 diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto deleted file mode 100644 index e9add2e1a4..0000000000 --- a/services/surfaceflinger/layerproto/layers.proto +++ /dev/null @@ -1,171 +0,0 @@ -// Definitions for SurfaceFlinger layers. - -syntax = "proto3"; -option optimize_for = LITE_RUNTIME; - -import "frameworks/native/services/surfaceflinger/layerproto/common.proto"; - -package android.surfaceflinger; - -// Contains a list of all layers. -message LayersProto { -  repeated LayerProto layers = 1; -} - -// Must match definition in the IComposerClient HAL -enum HwcCompositionType { -    // Invalid composition type -    INVALID = 0; -    // Layer was composited by the client into the client target buffer -    CLIENT = 1; -    // Layer was composited by the device through hardware overlays -    DEVICE = 2; -    // Layer was composited by the device using a color -    SOLID_COLOR = 3; -    // Similar to DEVICE, but the layer position may have been asynchronously set -    // through setCursorPosition -    CURSOR = 4; -    // Layer was composited by the device via a sideband stream. -    SIDEBAND = 5; -} - -// Information about each layer. -message LayerProto { -  // unique id per layer. -  int32 id = 1; -  // unique name per layer. -  string name = 2; -  // list of children this layer may have. May be empty. -  repeated int32 children = 3; -  // list of layers that are z order relative to this layer. -  repeated int32 relatives = 4; -  // The type of layer, ex Color, Layer -  string type = 5; -  RegionProto transparent_region = 6; -  RegionProto visible_region = 7; -  RegionProto damage_region = 8; -  uint32 layer_stack = 9; -  // The layer's z order. Can be z order in layer stack, relative to parent, -  // or relative to another layer specified in zOrderRelative. -  int32 z = 10; -  // The layer's position on the display. -  PositionProto position = 11; -  // The layer's requested position. -  PositionProto requested_position = 12; -  // The layer's size. -  SizeProto size = 13; -  // The layer's crop in it's own bounds. -  RectProto crop = 14; -  // The layer's crop in it's parent's bounds. -  RectProto final_crop = 15 [deprecated=true]; -  bool is_opaque = 16; -  bool invalidate = 17; -  string dataspace = 18; -  string pixel_format = 19; -  // The layer's actual color. -  ColorProto color = 20; -  // The layer's requested color. -  ColorProto requested_color = 21; -  // Can be any combination of -  //    hidden = 0x01 -  //    opaque = 0x02, -  //    secure = 0x80, -  uint32 flags = 22; -  // The layer's actual transform -  TransformProto transform = 23; -  // The layer's requested transform. -  TransformProto requested_transform = 24; -  // The parent layer. This value can be null if there is no parent. -  int32 parent = 25; -  // The layer that this layer has a z order relative to. This value can be null. -  int32 z_order_relative_of = 26; -  // This value can be null if there's nothing to draw. -  ActiveBufferProto active_buffer = 27; -  // The number of frames available. -  int32 queued_frames = 28; -  bool refresh_pending = 29; -  // The layer's composer backend destination frame -  RectProto hwc_frame = 30; -  // The layer's composer backend source crop -  FloatRectProto hwc_crop = 31; -  // The layer's composer backend transform -  int32 hwc_transform = 32; -  int32 window_type = 33 [deprecated=true]; -  int32 app_id = 34 [deprecated=true]; -  // The layer's composition type -  HwcCompositionType hwc_composition_type = 35; -  // If it's a buffer layer, indicate if the content is protected -  bool is_protected = 36; -  // Current frame number being rendered. -  uint64 curr_frame = 37; -  // A list of barriers that the layer is waiting to update state. -  repeated BarrierLayerProto barrier_layer = 38; -  // If active_buffer is not null, record its transform. -  TransformProto buffer_transform = 39; -  int32 effective_scaling_mode = 40; -  // Layer's corner radius. -  float corner_radius = 41; -  // Metadata map. May be empty. -  map<int32, bytes> metadata = 42; - -  TransformProto effective_transform = 43; -  FloatRectProto source_bounds = 44; -  FloatRectProto bounds = 45; -  FloatRectProto screen_bounds = 46; - -  InputWindowInfoProto input_window_info = 47; - -  // Crop used to draw the rounded corner. -  FloatRectProto corner_radius_crop = 48; - -  // length of the shadow to draw around the layer, it may be set on the -  // layer or set by a parent layer. -  float shadow_radius = 49; -  ColorTransformProto color_transform = 50; - -  bool is_relative_of = 51; -  // Layer's background blur radius in pixels. -  int32 background_blur_radius = 52; - -  uint32 owner_uid = 53; - -  // Regions of a layer, where blur should be applied. -  repeated BlurRegion blur_regions = 54; - -  bool is_trusted_overlay = 55; - -  // Corner radius explicitly set on layer rather than inherited -  float requested_corner_radius = 56; - -  RectProto destination_frame = 57; - -  uint32 original_id = 58; -} - -message PositionProto { -  float x = 1; -  float y = 2; -} - -message FloatRectProto { -  float left = 1; -  float top = 2; -  float right = 3; -  float bottom = 4; -} - -message ActiveBufferProto { -  uint32 width = 1; -  uint32 height = 2; -  uint32 stride = 3; -  int32 format = 4; -  uint64 usage = 5; -} - -message BarrierLayerProto { -  // layer id the barrier is waiting on. -  int32 id = 1; -  // frame number the barrier is waiting on. -  uint64 frame_number = 2; -} - diff --git a/services/surfaceflinger/layerproto/layerstrace.proto b/services/surfaceflinger/layerproto/layerstrace.proto deleted file mode 100644 index 804a4994ee..0000000000 --- a/services/surfaceflinger/layerproto/layerstrace.proto +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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 = "proto2"; -option optimize_for = LITE_RUNTIME; - -import "frameworks/native/services/surfaceflinger/layerproto/layers.proto"; -import "frameworks/native/services/surfaceflinger/layerproto/display.proto"; - -package android.surfaceflinger; - -/* represents a file full of surface flinger trace entries. -   Encoded, it should start with 0x4c 0x59 0x52 0x54 0x52 0x41 0x43 0x45 (.LYRTRACE), such -   that they can be easily identified. */ -message LayersTraceFileProto { - -    /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L -       (this is needed because enums have to be 32 bits and there's no nice way to put 64bit -        constants into .proto files. */ -    enum MagicNumber { -        INVALID = 0; -        MAGIC_NUMBER_L = 0x5452594c;  /* LYRT (little-endian ASCII) */ -        MAGIC_NUMBER_H = 0x45434152;  /* RACE (little-endian ASCII) */ -    } - -    optional fixed64 magic_number = 1;  /* Must be the first field, set to value in MagicNumber */ -    repeated LayersTraceProto entry = 2; - -    /* offset between real-time clock and elapsed time clock in nanoseconds. -       Calculated as: systemTime(SYSTEM_TIME_REALTIME) - systemTime(SYSTEM_TIME_MONOTONIC) */ -    optional fixed64 real_to_elapsed_time_offset_nanos = 3; -} - -/* one layers trace entry. */ -message LayersTraceProto { -    /* required: elapsed realtime in nanos since boot of when this entry was logged */ -    optional sfixed64 elapsed_realtime_nanos = 1; - -    /* where the trace originated */ -    optional string where = 2; - -    optional LayersProto layers = 3; - -    // Blob for the current HWC information for all layers, reported by dumpsys. -    optional string hwc_blob = 4; - -    /* Includes state sent during composition like visible region and composition type. */ -    optional bool excludes_composition_state = 5; - -    /* Number of missed entries since the last entry was recorded. */ -    optional uint32 missed_entries = 6; - -    repeated DisplayProto displays = 7; - -    optional int64 vsync_id = 8; -} diff --git a/services/surfaceflinger/layerproto/transactions.proto b/services/surfaceflinger/layerproto/transactions.proto deleted file mode 100644 index d03afa05ab..0000000000 --- a/services/surfaceflinger/layerproto/transactions.proto +++ /dev/null @@ -1,310 +0,0 @@ -/* - * 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.proto; - -/* Represents a file full of surface flinger transactions. -   Encoded, it should start with 0x54 0x4E 0x58 0x54 0x52 0x41 0x43 0x45 (.TNXTRACE), such -   that they can be easily identified. */ -message TransactionTraceFile { -    /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L -       (this is needed because enums have to be 32 bits and there's no nice way to put 64bit -        constants into .proto files. */ -    enum MagicNumber { -        INVALID = 0; -        MAGIC_NUMBER_L = 0x54584E54; /* TNXT (little-endian ASCII) */ -        MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */ -    } - -    fixed64 magic_number = 1; /* Must be the first field, set to value in MagicNumber */ -    repeated TransactionTraceEntry entry = 2; - -    /* offset between real-time clock and elapsed time clock in nanoseconds. -       Calculated as: systemTime(SYSTEM_TIME_REALTIME) - systemTime(SYSTEM_TIME_MONOTONIC) */ -    fixed64 real_to_elapsed_time_offset_nanos = 3; -    uint32 version = 4; -} - -message TransactionTraceEntry { -    int64 elapsed_realtime_nanos = 1; -    int64 vsync_id = 2; -    repeated TransactionState transactions = 3; -    repeated LayerCreationArgs added_layers = 4; -    repeated uint32 destroyed_layers = 5; -    repeated DisplayState added_displays = 6; -    repeated int32 removed_displays = 7; -    repeated uint32 destroyed_layer_handles = 8; -    bool displays_changed = 9; -    repeated DisplayInfo displays = 10; -} - -message DisplayInfo { -    uint32 layer_stack = 1; -    int32 display_id = 2; -    int32 logical_width = 3; -    int32 logical_height = 4; -    Transform transform_inverse = 5; -    Transform transform = 6; -    bool receives_input = 7; -    bool is_secure = 8; -    bool is_primary = 9; -    bool is_virtual = 10; -    int32 rotation_flags = 11; -    int32 transform_hint = 12; - -} - -message LayerCreationArgs { -    uint32 layer_id = 1; -    string name = 2; -    uint32 flags = 3; -    uint32 parent_id = 4; -    uint32 mirror_from_id = 5; -    bool add_to_root = 6; -    uint32 layer_stack_to_mirror = 7; -} - -message Transform { -    float dsdx = 1; -    float dtdx = 2; -    float dtdy = 3; -    float dsdy = 4; -    float tx = 5; -    float ty = 6; -} - -message TransactionState { -    int32 pid = 1; -    int32 uid = 2; -    int64 vsync_id = 3; -    int32 input_event_id = 4; -    int64 post_time = 5; -    uint64 transaction_id = 6; -    repeated LayerState layer_changes = 7; -    repeated DisplayState display_changes = 8; -    repeated uint64 merged_transaction_ids = 9; -} - -// Keep insync with layer_state_t -message LayerState { -    uint32 layer_id = 1; -    // Changes are split into ChangesLsb and ChangesMsb. First 32 bits are in ChangesLsb -    // and the next 32 bits are in ChangesMsb. This is needed because enums have to be -    // 32 bits and there's no nice way to put 64bit constants into .proto files. -    enum ChangesLsb { -        eChangesLsbNone = 0; -        ePositionChanged = 0x00000001; -        eLayerChanged = 0x00000002; -        // unused = 0x00000004; -        eAlphaChanged = 0x00000008; - -        eMatrixChanged = 0x00000010; -        eTransparentRegionChanged = 0x00000020; -        eFlagsChanged = 0x00000040; -        eLayerStackChanged = 0x00000080; - -        eReleaseBufferListenerChanged = 0x00000400; -        eShadowRadiusChanged = 0x00000800; - -        eBufferCropChanged = 0x00002000; -        eRelativeLayerChanged = 0x00004000; -        eReparent = 0x00008000; - -        eColorChanged = 0x00010000; -        eBufferTransformChanged = 0x00040000; -        eTransformToDisplayInverseChanged = 0x00080000; - -        eCropChanged = 0x00100000; -        eBufferChanged = 0x00200000; -        eAcquireFenceChanged = 0x00400000; -        eDataspaceChanged = 0x00800000; - -        eHdrMetadataChanged = 0x01000000; -        eSurfaceDamageRegionChanged = 0x02000000; -        eApiChanged = 0x04000000; -        eSidebandStreamChanged = 0x08000000; - -        eColorTransformChanged = 0x10000000; -        eHasListenerCallbacksChanged = 0x20000000; -        eInputInfoChanged = 0x40000000; -        eCornerRadiusChanged = -2147483648; // 0x80000000; (proto stores enums as signed int) -    }; -    enum ChangesMsb { -        eChangesMsbNone = 0; -        eDestinationFrameChanged = 0x1; -        eCachedBufferChanged = 0x2; -        eBackgroundColorChanged = 0x4; -        eMetadataChanged = 0x8; -        eColorSpaceAgnosticChanged = 0x10; -        eFrameRateSelectionPriority = 0x20; -        eFrameRateChanged = 0x40; -        eBackgroundBlurRadiusChanged = 0x80; -        eProducerDisconnect = 0x100; -        eFixedTransformHintChanged = 0x200; -        eFrameNumberChanged = 0x400; -        eBlurRegionsChanged = 0x800; -        eAutoRefreshChanged = 0x1000; -        eStretchChanged = 0x2000; -        eTrustedOverlayChanged = 0x4000; -        eDropInputModeChanged = 0x8000; -    }; -    uint64 what = 2; -    float x = 3; -    float y = 4; -    int32 z = 5; -    uint32 w = 6; -    uint32 h = 7; -    uint32 layer_stack = 8; - -    enum Flags { -        eFlagsNone = 0; -        eLayerHidden = 0x01; -        eLayerOpaque = 0x02; -        eLayerSkipScreenshot = 0x40; -        eLayerSecure = 0x80; -        eEnableBackpressure = 0x100; -        eLayerIsDisplayDecoration = 0x200; -    }; -    uint32 flags = 9; -    uint32 mask = 10; - -    message Matrix22 { -        float dsdx = 1; -        float dtdx = 2; -        float dtdy = 3; -        float dsdy = 4; -    }; -    Matrix22 matrix = 11; -    float corner_radius = 12; -    uint32 background_blur_radius = 13; -    uint32 parent_id = 14; -    uint32 relative_parent_id = 15; - -    float alpha = 16; -    message Color3 { -        float r = 1; -        float g = 2; -        float b = 3; -    } -    Color3 color = 17; -    RegionProto transparent_region = 18; -    uint32 transform = 19; -    bool transform_to_display_inverse = 20; -    RectProto crop = 21; - -    message BufferData { -        uint64 buffer_id = 1; -        uint32 width = 2; -        uint32 height = 3; -        uint64 frame_number = 4; - -        enum BufferDataChange { -            BufferDataChangeNone = 0; -            fenceChanged = 0x01; -            frameNumberChanged = 0x02; -            cachedBufferChanged = 0x04; -        } -        uint32 flags = 5; -        uint64 cached_buffer_id = 6; - -        enum PixelFormat { -            PIXEL_FORMAT_UNKNOWN = 0; -            PIXEL_FORMAT_CUSTOM = -4; -            PIXEL_FORMAT_TRANSLUCENT = -3; -            PIXEL_FORMAT_TRANSPARENT = -2; -            PIXEL_FORMAT_OPAQUE = -1; -            PIXEL_FORMAT_RGBA_8888 = 1; -            PIXEL_FORMAT_RGBX_8888 = 2; -            PIXEL_FORMAT_RGB_888 = 3; -            PIXEL_FORMAT_RGB_565 = 4; -            PIXEL_FORMAT_BGRA_8888 = 5; -            PIXEL_FORMAT_RGBA_5551 = 6; -            PIXEL_FORMAT_RGBA_4444 = 7; -            PIXEL_FORMAT_RGBA_FP16 = 22; -            PIXEL_FORMAT_RGBA_1010102 = 43; -            PIXEL_FORMAT_R_8 = 0x38; -        } -        PixelFormat pixel_format = 7; -        uint64 usage = 8; -    } -    BufferData buffer_data = 22; -    int32 api = 23; -    bool has_sideband_stream = 24; -    ColorTransformProto color_transform = 25; -    repeated BlurRegion blur_regions = 26; - -    message WindowInfo { -        uint32 layout_params_flags = 1; -        int32 layout_params_type = 2; -        RegionProto touchable_region = 3; -        int32 surface_inset = 4; -        bool focusable = 5; // unused -        bool has_wallpaper = 6; // unused -        float global_scale_factor = 7; -        uint32 crop_layer_id = 8; -        bool replace_touchable_region_with_crop = 9; -        RectProto touchable_region_crop = 10; -        Transform transform = 11; -        uint32 input_config = 12; -    } -    WindowInfo window_info_handle = 27; -    float bg_color_alpha = 28; -    int32 bg_color_dataspace = 29; -    bool color_space_agnostic = 30; -    float shadow_radius = 31; -    int32 frame_rate_selection_priority = 32; -    float frame_rate = 33; -    int32 frame_rate_compatibility = 34; -    int32 change_frame_rate_strategy = 35; -    uint32 fixed_transform_hint = 36; -    uint64 frame_number = 37; -    bool auto_refresh = 38; -    bool is_trusted_overlay = 39; -    RectProto buffer_crop = 40; -    RectProto destination_frame = 41; - -    enum DropInputMode { -        NONE = 0; -        ALL = 1; -        OBSCURED = 2; -    }; -    DropInputMode drop_input_mode = 42; -} - -message DisplayState { -    enum Changes { -        eChangesNone = 0; -        eSurfaceChanged = 0x01; -        eLayerStackChanged = 0x02; -        eDisplayProjectionChanged = 0x04; -        eDisplaySizeChanged = 0x08; -        eFlagsChanged = 0x10; -    }; -    int32 id = 1; -    uint32 what = 2; -    uint32 flags = 3; -    uint32 layer_stack = 4; -    uint32 orientation = 5; -    RectProto layer_stack_space_rect = 6; -    RectProto oriented_display_space_rect = 7; -    uint32 width = 8; -    uint32 height = 9; -} diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp index 03201f7937..b30df5ef15 100644 --- a/services/surfaceflinger/tests/Stress_test.cpp +++ b/services/surfaceflinger/tests/Stress_test.cpp @@ -51,9 +51,9 @@ TEST(SurfaceFlingerStress, create_and_destroy) {      }  } -surfaceflinger::LayersProto generateLayerProto() { -    surfaceflinger::LayersProto layersProto; -    std::array<surfaceflinger::LayerProto*, 10> layers = {}; +perfetto::protos::LayersProto generateLayerProto() { +    perfetto::protos::LayersProto layersProto; +    std::array<perfetto::protos::LayerProto*, 10> layers = {};      for (size_t i = 0; i < layers.size(); ++i) {          layers[i] = layersProto.add_layers();          layers[i]->set_id(i); @@ -103,7 +103,7 @@ TEST(LayerProtoStress, mem_info) {      cmd += std::to_string(getpid());      system(cmd.c_str());      for (int i = 0; i < 100000; i++) { -        surfaceflinger::LayersProto layersProto = generateLayerProto(); +        perfetto::protos::LayersProto layersProto = generateLayerProto();          auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);          surfaceflinger::LayerProtoParser::layerTreeToString(layerTree);      } diff --git a/services/surfaceflinger/tests/tracing/Android.bp b/services/surfaceflinger/tests/tracing/Android.bp index 21ebaea8ad..b6cd7b8b7f 100644 --- a/services/surfaceflinger/tests/tracing/Android.bp +++ b/services/surfaceflinger/tests/tracing/Android.bp @@ -35,7 +35,6 @@ cc_test {      srcs: [          ":libsurfaceflinger_sources",          ":libsurfaceflinger_mock_sources", -        ":layertracegenerator_sources",          "TransactionTraceTestSuite.cpp",      ],      static_libs: [ @@ -43,7 +42,6 @@ cc_test {      ],      header_libs: [          "libsurfaceflinger_mocks_headers", -        "layertracegenerator_headers",      ],      data: ["testdata/*"],  } diff --git a/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp b/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp index b8a5e79a38..7a076347bb 100644 --- a/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp +++ b/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp @@ -23,8 +23,8 @@  #include <unordered_map>  #include <LayerProtoHelper.h> -#include <LayerTraceGenerator.h>  #include <Tracing/TransactionProtoParser.h> +#include <Tracing/tools/LayerTraceGenerator.h>  #include <layerproto/LayerProtoHeader.h>  #include <log/log.h> @@ -40,9 +40,9 @@ public:      static constexpr std::string_view sLayersTracePrefix = "layers_trace_";      static constexpr std::string_view sTracePostfix = ".winscope"; -    proto::TransactionTraceFile mTransactionTrace; -    LayersTraceFileProto mExpectedLayersTraceProto; -    LayersTraceFileProto mActualLayersTraceProto; +    perfetto::protos::TransactionTraceFile mTransactionTrace; +    perfetto::protos::LayersTraceFileProto mExpectedLayersTraceProto; +    perfetto::protos::LayersTraceFileProto mActualLayersTraceProto;  protected:      void SetUp() override { @@ -56,18 +56,23 @@ protected:          EXPECT_TRUE(std::filesystem::exists(std::filesystem::path(expectedLayersTracePath)));          parseLayersTraceFromFile(expectedLayersTracePath.c_str(), mExpectedLayersTraceProto);          TemporaryDir temp_dir; +          std::string actualLayersTracePath =                  std::string(temp_dir.path) + "/" + expectedLayersFilename + "_actual"; +        { +            auto traceFlags = LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS; +            std::ofstream outStream{actualLayersTracePath, std::ios::binary | std::ios::app}; +            EXPECT_TRUE(LayerTraceGenerator().generate(mTransactionTrace, traceFlags, outStream, +                                                       /*onlyLastEntry=*/true)) +                    << "Failed to generate layers trace from " << transactionTracePath; +        } -        EXPECT_TRUE(LayerTraceGenerator().generate(mTransactionTrace, actualLayersTracePath.c_str(), -                                                   /*onlyLastEntry=*/true)) -                << "Failed to generate layers trace from " << transactionTracePath;          EXPECT_TRUE(std::filesystem::exists(std::filesystem::path(actualLayersTracePath)));          parseLayersTraceFromFile(actualLayersTracePath.c_str(), mActualLayersTraceProto);      }      void parseTransactionTraceFromFile(const char* transactionTracePath, -                                       proto::TransactionTraceFile& outProto) { +                                       perfetto::protos::TransactionTraceFile& outProto) {          ALOGD("Parsing file %s...", transactionTracePath);          std::fstream input(transactionTracePath, std::ios::in | std::ios::binary);          EXPECT_TRUE(input) << "Error could not open " << transactionTracePath; @@ -75,7 +80,8 @@ protected:                  << "Failed to parse " << transactionTracePath;      } -    void parseLayersTraceFromFile(const char* layersTracePath, LayersTraceFileProto& outProto) { +    void parseLayersTraceFromFile(const char* layersTracePath, +                                  perfetto::protos::LayersTraceFileProto& outProto) {          ALOGD("Parsing file %s...", layersTracePath);          std::fstream input(layersTracePath, std::ios::in | std::ios::binary);          EXPECT_TRUE(input) << "Error could not open " << layersTracePath; @@ -124,7 +130,7 @@ struct find_id : std::unary_function<LayerInfo, bool> {      bool operator()(LayerInfo const& m) const { return m.id == id; }  }; -static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& proto) { +static LayerInfo getLayerInfoFromProto(perfetto::protos::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 @@ -148,8 +154,7 @@ static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& pr              touchableRegionBounds};  } -static std::vector<LayerInfo> getLayerInfosFromProto( -        android::surfaceflinger::LayersTraceProto& entry) { +static std::vector<LayerInfo> getLayerInfosFromProto(perfetto::protos::LayersSnapshotProto& entry) {      std::unordered_map<uint64_t /* snapshotId*/, uint64_t /*layerId*/> snapshotIdToLayerId;      std::vector<LayerInfo> layers;      layers.reserve(static_cast<size_t>(entry.layers().layers_size())); @@ -267,4 +272,4 @@ int main(int argc, char** argv) {      }      ::testing::InitGoogleTest(&argc, argv);      return RUN_ALL_TESTS(); -}
\ No newline at end of file +} diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp index a95a6453d5..cbb597af69 100644 --- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp @@ -85,7 +85,7 @@ TEST(TransactionProtoParserTest, parse) {      TransactionProtoParser parser(std::make_unique<TestMapper>(displayHandle)); -    proto::TransactionState proto = parser.toProto(t1); +    perfetto::protos::TransactionState proto = parser.toProto(t1);      TransactionState t2 = parser.fromProto(proto);      ASSERT_EQ(t1.originPid, t2.originPid); @@ -119,7 +119,7 @@ TEST(TransactionProtoParserTest, parseDisplayInfo) {      d1.transformHint = ui::Transform::ROT_90;      const uint32_t layerStack = 2; -    google::protobuf::RepeatedPtrField<proto::DisplayInfo> displayProtos; +    google::protobuf::RepeatedPtrField<perfetto::protos::DisplayInfo> displayProtos;      auto displayInfoProto = displayProtos.Add();      *displayInfoProto = TransactionProtoParser::toProto(d1, layerStack);      frontend::DisplayInfos displayInfos; diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp index 71a2d2b9a6..7981224b5c 100644 --- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp @@ -37,11 +37,11 @@ protected:      TransactionTracing mTracing;      void flush() { mTracing.flush(); } -    proto::TransactionTraceFile writeToProto() { return mTracing.writeToProto(); } +    perfetto::protos::TransactionTraceFile writeToProto() { return mTracing.writeToProto(); } -    proto::TransactionTraceEntry bufferFront() { +    perfetto::protos::TransactionTraceEntry bufferFront() {          std::scoped_lock<std::mutex> lock(mTracing.mTraceLock); -        proto::TransactionTraceEntry entry; +        perfetto::protos::TransactionTraceEntry entry;          entry.ParseFromString(mTracing.mBuffer.front());          return entry;      } @@ -59,7 +59,7 @@ protected:          flush();      } -    void verifyEntry(const proto::TransactionTraceEntry& actualProto, +    void verifyEntry(const perfetto::protos::TransactionTraceEntry& actualProto,                       const std::vector<TransactionState>& expectedTransactions,                       int64_t expectedVsyncId) {          EXPECT_EQ(actualProto.vsync_id(), expectedVsyncId); @@ -117,7 +117,7 @@ TEST_F(TransactionTracingTest, addTransactions) {      mTracing.addCommittedTransactions(secondTransactionSetVsyncId, 0, secondUpdate, {}, false);      flush(); -    proto::TransactionTraceFile proto = writeToProto(); +    perfetto::protos::TransactionTraceFile proto = writeToProto();      ASSERT_EQ(proto.entry().size(), 2);      verifyEntry(proto.entry(0), firstUpdate.transactions, firstTransactionSetVsyncId);      verifyEntry(proto.entry(1), secondUpdate.transactions, secondTransactionSetVsyncId); @@ -203,7 +203,7 @@ TEST_F(TransactionTracingLayerHandlingTest, addStartingState) {      while (bufferFront().vsync_id() <= VSYNC_ID_FIRST_LAYER_CHANGE) {          queueAndCommitTransaction(++mVsyncId);      } -    proto::TransactionTraceFile proto = writeToProto(); +    perfetto::protos::TransactionTraceFile proto = writeToProto();      // verify we can still retrieve the layer change from the first entry containing starting      // states.      EXPECT_GT(proto.entry().size(), 0); @@ -221,7 +221,7 @@ TEST_F(TransactionTracingLayerHandlingTest, updateStartingState) {      while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {          queueAndCommitTransaction(++mVsyncId);      } -    proto::TransactionTraceFile proto = writeToProto(); +    perfetto::protos::TransactionTraceFile proto = writeToProto();      // verify starting states are updated correctly      EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 41);  } @@ -231,7 +231,7 @@ TEST_F(TransactionTracingLayerHandlingTest, removeStartingState) {      while (bufferFront().vsync_id() <= VSYNC_ID_CHILD_LAYER_REMOVED) {          queueAndCommitTransaction(++mVsyncId);      } -    proto::TransactionTraceFile proto = writeToProto(); +    perfetto::protos::TransactionTraceFile proto = writeToProto();      // verify the child layer has been removed from the trace      EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 1);      EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId); @@ -242,7 +242,7 @@ TEST_F(TransactionTracingLayerHandlingTest, startingStateSurvivesBufferFlush) {      while (bufferFront().vsync_id() <= VSYNC_ID_SECOND_LAYER_CHANGE) {          queueAndCommitTransaction(++mVsyncId);      } -    proto::TransactionTraceFile proto = writeToProto(); +    perfetto::protos::TransactionTraceFile proto = writeToProto();      // verify we have two starting states      EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2); @@ -302,7 +302,7 @@ protected:  };  TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) { -    proto::TransactionTraceFile proto = writeToProto(); +    perfetto::protos::TransactionTraceFile proto = writeToProto();      // We don't have any starting states since no layer was removed from.      EXPECT_EQ(proto.entry().size(), 1); @@ -317,18 +317,18 @@ TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) {  // Verify we can write the layers traces by entry to reduce mem pressure  // on the system when generating large traces.  TEST(LayerTraceTest, canStreamLayersTrace) { -    LayersTraceFileProto inProto = LayerTracing::createTraceFileProto(); +    perfetto::protos::LayersTraceFileProto inProto = LayerTracing::createTraceFileProto();      inProto.add_entry();      inProto.add_entry();      std::string output;      inProto.SerializeToString(&output); -    LayersTraceFileProto inProto2 = LayerTracing::createTraceFileProto(); +    perfetto::protos::LayersTraceFileProto inProto2 = LayerTracing::createTraceFileProto();      inProto2.add_entry();      std::string output2;      inProto2.SerializeToString(&output2); -    LayersTraceFileProto outProto; +    perfetto::protos::LayersTraceFileProto outProto;      outProto.ParseFromString(output + output2);      // magic?      EXPECT_EQ(outProto.entry().size(), 3); |