// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_BASE_DEVTOOLS_INSTRUMENTATION_H_ #define CC_BASE_DEVTOOLS_INSTRUMENTATION_H_ #include #include #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" #include "cc/base/base_export.h" namespace cc { namespace devtools_instrumentation { namespace internal { struct CC_BASE_EXPORT CategoryName { // Put these strings into a struct to allow external linkage. static constexpr const char kTimeline[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline"); static constexpr const char kTimelineFrame[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame"); }; CC_BASE_EXPORT extern const char kData[]; CC_BASE_EXPORT extern const char kFrameId[]; CC_BASE_EXPORT extern const char kLayerId[]; CC_BASE_EXPORT extern const char kLayerTreeId[]; CC_BASE_EXPORT extern const char kPixelRefId[]; CC_BASE_EXPORT extern const char kImageDecodeTask[]; CC_BASE_EXPORT extern const char kBeginFrame[]; CC_BASE_EXPORT extern const char kNeedsBeginFrameChanged[]; CC_BASE_EXPORT extern const char kActivateLayerTree[]; CC_BASE_EXPORT extern const char kRequestMainThreadFrame[]; CC_BASE_EXPORT extern const char kBeginMainThreadFrame[]; CC_BASE_EXPORT extern const char kDrawFrame[]; CC_BASE_EXPORT extern const char kCompositeLayers[]; } // namespace internal extern const char kPaintSetup[]; CC_BASE_EXPORT extern const char kUpdateLayer[]; class CC_BASE_EXPORT ScopedLayerTask { public: ScopedLayerTask(const char* event_name, int layer_id) : event_name_(event_name) { TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline, event_name_, internal::kLayerId, layer_id); } ScopedLayerTask(const ScopedLayerTask&) = delete; ~ScopedLayerTask() { TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_); } ScopedLayerTask& operator=(const ScopedLayerTask&) = delete; private: const char* event_name_; }; class CC_BASE_EXPORT ScopedImageTask { public: enum ImageType { kAvif, kBmp, kGif, kIco, kJpeg, kPng, kWebP, kOther }; explicit ScopedImageTask(ImageType image_type) : image_type_(image_type), start_time_(base::TimeTicks::Now()) {} ScopedImageTask(const ScopedImageTask&) = delete; ~ScopedImageTask() = default; ScopedImageTask& operator=(const ScopedImageTask&) = delete; // Prevents logging duration metrics. Used in cases where a task performed // uninteresting work or was terminated early. void SuppressMetrics() { suppress_metrics_ = true; } protected: bool suppress_metrics_ = false; const ImageType image_type_; const base::TimeTicks start_time_; // UMA histogram parameters const uint32_t bucket_count_ = 50; base::TimeDelta hist_min_ = base::TimeDelta::FromMicroseconds(1); base::TimeDelta hist_max_ = base::TimeDelta::FromMilliseconds(1000); }; class CC_BASE_EXPORT ScopedImageUploadTask : public ScopedImageTask { public: ScopedImageUploadTask(const void* image_ptr, ImageType image_type); ScopedImageUploadTask(const ScopedImageUploadTask&) = delete; ~ScopedImageUploadTask(); ScopedImageUploadTask& operator=(const ScopedImageUploadTask&) = delete; }; class CC_BASE_EXPORT ScopedImageDecodeTask : public ScopedImageTask { public: enum TaskType { kInRaster, kOutOfRaster }; enum DecodeType { kSoftware, kGpu }; ScopedImageDecodeTask(const void* image_ptr, DecodeType decode_type, TaskType task_type, ImageType image_type); ScopedImageDecodeTask(const ScopedImageDecodeTask&) = delete; ~ScopedImageDecodeTask(); ScopedImageDecodeTask& operator=(const ScopedImageDecodeTask&) = delete; private: const DecodeType decode_type_; const TaskType task_type_; }; class CC_BASE_EXPORT ScopedLayerTreeTask { public: ScopedLayerTreeTask(const char* event_name, int layer_id, int layer_tree_host_id) : event_name_(event_name) { TRACE_EVENT_BEGIN2(internal::CategoryName::kTimeline, event_name_, internal::kLayerId, layer_id, internal::kLayerTreeId, layer_tree_host_id); } ScopedLayerTreeTask(const ScopedLayerTreeTask&) = delete; ~ScopedLayerTreeTask() { TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_); } ScopedLayerTreeTask& operator=(const ScopedLayerTreeTask&) = delete; private: const char* event_name_; }; struct CC_BASE_EXPORT ScopedCommitTrace { public: explicit ScopedCommitTrace(int layer_tree_host_id) { TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline, internal::kCompositeLayers, internal::kLayerTreeId, layer_tree_host_id); } ScopedCommitTrace(const ScopedCommitTrace&) = delete; ~ScopedCommitTrace() { TRACE_EVENT_END0(internal::CategoryName::kTimeline, internal::kCompositeLayers); } ScopedCommitTrace& operator=(const ScopedCommitTrace&) = delete; }; struct CC_BASE_EXPORT ScopedLayerObjectTracker : public base::trace_event:: TraceScopedTrackableObject { explicit ScopedLayerObjectTracker(int layer_id) : base::trace_event:: TraceScopedTrackableObject( internal::kLayerId, layer_id) {} ScopedLayerObjectTracker(const ScopedLayerObjectTracker&) = delete; ScopedLayerObjectTracker& operator=(const ScopedLayerObjectTracker&) = delete; }; inline void CC_BASE_EXPORT DidActivateLayerTree(int layer_tree_host_id, int frame_id) { TRACE_EVENT_INSTANT2(internal::CategoryName::kTimelineFrame, internal::kActivateLayerTree, TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id, internal::kFrameId, frame_id); } inline void CC_BASE_EXPORT DidBeginFrame(int layer_tree_host_id) { TRACE_EVENT_INSTANT1(internal::CategoryName::kTimelineFrame, internal::kBeginFrame, TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id); } inline void CC_BASE_EXPORT DidDrawFrame(int layer_tree_host_id) { TRACE_EVENT_INSTANT1(internal::CategoryName::kTimelineFrame, internal::kDrawFrame, TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id); } inline void CC_BASE_EXPORT DidRequestMainThreadFrame(int layer_tree_host_id) { TRACE_EVENT_INSTANT1( internal::CategoryName::kTimelineFrame, internal::kRequestMainThreadFrame, TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id); } inline std::unique_ptr BeginMainThreadFrameData(int frame_id) { std::unique_ptr value( new base::trace_event::TracedValue()); value->SetInteger("frameId", frame_id); return std::move(value); } inline void CC_BASE_EXPORT WillBeginMainThreadFrame(int layer_tree_host_id, int frame_id) { TRACE_EVENT_INSTANT2( internal::CategoryName::kTimelineFrame, internal::kBeginMainThreadFrame, TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id, internal::kData, BeginMainThreadFrameData(frame_id)); } inline std::unique_ptr NeedsBeginFrameData(bool needs_begin_frame) { std::unique_ptr value( new base::trace_event::TracedValue()); value->SetInteger("needsBeginFrame", needs_begin_frame); return std::move(value); } inline void CC_BASE_EXPORT NeedsBeginFrameChanged(int layer_tree_host_id, bool new_value) { TRACE_EVENT_INSTANT2( internal::CategoryName::kTimelineFrame, internal::kNeedsBeginFrameChanged, TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id, internal::kData, NeedsBeginFrameData(new_value)); } } // namespace devtools_instrumentation } // namespace cc #endif // CC_BASE_DEVTOOLS_INSTRUMENTATION_H_