blob: 9c4e75e7d661814394730fc0a6080490b40c3d00 [file] [log] [blame]
/*
* Copyright (C) 2019 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.
*/
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_FRAME_TIMELINE_EVENT_PARSER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_FRAME_TIMELINE_EVENT_PARSER_H_
#include "perfetto/protozero/field.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/async_track_set_tracker.h"
#include "src/trace_processor/importers/proto/proto_incremental_state.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "protos/perfetto/trace/android/frame_timeline_event.pbzero.h"
#include <map>
#include <unordered_map>
#include <unordered_set>
namespace perfetto {
namespace trace_processor {
using FrameTimelineEvent = protos::pbzero::FrameTimelineEvent;
using FrameTimelineEventDecoder = protos::pbzero::FrameTimelineEvent_Decoder;
class TraceProcessorContext;
// Class for parsing graphics frame related events.
class FrameTimelineEventParser {
public:
using ConstBytes = protozero::ConstBytes;
using TrackSetId = AsyncTrackSetTracker::TrackSetId;
explicit FrameTimelineEventParser(TraceProcessorContext*);
void ParseFrameTimelineEvent(int64_t timestamp, ConstBytes);
private:
void ParseExpectedDisplayFrameStart(int64_t timestamp, ConstBytes);
void ParseActualDisplayFrameStart(int64_t timestamp, ConstBytes);
void ParseExpectedSurfaceFrameStart(int64_t timestamp, ConstBytes);
void ParseActualSurfaceFrameStart(int64_t timestamp, ConstBytes);
void ParseFrameEnd(int64_t timestamp, ConstBytes);
TraceProcessorContext* const context_;
// Cookie -> TrackSetId map. Since cookies are globally unique per slice, this
// helps in allowing the producer to send only the cookie as the End marker
// without the need for any other fields. The TrackSets could be interned
// based on any number of fields in the Start marker but the global uniqueness
// of the cookie makes it so that we can end a slice with just the cookie and
// the TrackSetId.
std::map<int64_t, TrackSetId> cookie_track_set_id_map_;
std::array<StringId, 6> present_type_ids_;
std::array<StringId, 4> prediction_type_ids_;
StringId expected_timeline_track_name_;
StringId actual_timeline_track_name_;
StringId surface_frame_token_id_;
StringId display_frame_token_id_;
StringId present_type_id_;
StringId on_time_finish_id_;
StringId gpu_composition_id_;
StringId jank_type_id_;
StringId layer_name_id_;
StringId prediction_type_id_;
StringId is_buffer_id_;
StringId jank_tag_none_id_;
StringId jank_tag_self_id_;
StringId jank_tag_other_id_;
StringId jank_tag_dropped_id_;
StringId jank_tag_buffer_stuffing_id_;
StringId jank_tag_sf_stuffing_id_;
// upid -> set of tokens map. The expected timeline is the same for a given
// token no matter how many times its seen. We can safely ignore duplicates
// for the expected timeline slices by caching the set of tokens seen so far
// per upid. upid is used as a dimension here because we show the timeline
// tracks for every process group.
// This map is used only for SurfaceFrames because there is no way two
// DisplayFrames use the same token unless there is something wrong with
// SurfaceFlinger.
std::unordered_map<UniquePid, std::unordered_set<int64_t>>
expected_timeline_token_map_;
std::multimap<int64_t, SliceId> display_token_to_surface_slice_;
};
} // namespace trace_processor
} // namespace perfetto
#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_FRAME_TIMELINE_EVENT_PARSER_H_