/*
 * Copyright (C) 2022 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 "src/trace_processor/importers/ftrace/drm_tracker.h"
#include "perfetto/ext/base/string_utils.h"
#include "protos/perfetto/trace/ftrace/dma_fence.pbzero.h"
#include "protos/perfetto/trace/ftrace/drm.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"

namespace perfetto {
namespace trace_processor {

namespace {

// There are meta-fences such as fence arrays or fence chains where a fence is
// a container of other fences.  These fences are on "unbound" timelines which
// are often dynamically created.  We want to ignore these timelines to avoid
// having tons of tracks for them.
constexpr char kUnboundFenceTimeline[] = "unbound";

}  // namespace

DrmTracker::DrmTracker(TraceProcessorContext* context)
    : context_(context),
      vblank_slice_signal_id_(context->storage->InternString("signal")),
      vblank_slice_deliver_id_(context->storage->InternString("deliver")),
      vblank_arg_seqno_id_(context->storage->InternString("vblank seqno")),
      sched_slice_schedule_id_(context->storage->InternString("drm_sched_job")),
      sched_slice_job_id_(context->storage->InternString("job")),
      sched_arg_ring_id_(context->storage->InternString("gpu sched ring")),
      sched_arg_job_id_(context->storage->InternString("gpu sched job")),
      fence_slice_fence_id_(context->storage->InternString("fence")),
      fence_slice_wait_id_(context->storage->InternString("dma_fence_wait")),
      fence_arg_context_id_(context->storage->InternString("fence context")),
      fence_arg_seqno_id_(context->storage->InternString("fence seqno")) {}

void DrmTracker::ParseDrm(int64_t timestamp,
                          int32_t field_id,
                          uint32_t pid,
                          protozero::ConstBytes blob) {
  using protos::pbzero::FtraceEvent;

  switch (field_id) {
    case FtraceEvent::kDrmVblankEventFieldNumber: {
      protos::pbzero::DrmVblankEventFtraceEvent::Decoder evt(blob.data,
                                                             blob.size);
      DrmVblankEvent(timestamp, evt.crtc(), evt.seq());
      break;
    }
    case FtraceEvent::kDrmVblankEventDeliveredFieldNumber: {
      protos::pbzero::DrmVblankEventDeliveredFtraceEvent::Decoder evt(
          blob.data, blob.size);
      DrmVblankEventDelivered(timestamp, evt.crtc(), evt.seq());
      break;
    }

    case FtraceEvent::kDrmSchedJobFieldNumber: {
      protos::pbzero::DrmSchedJobFtraceEvent::Decoder evt(blob.data, blob.size);
      DrmSchedJob(timestamp, pid, evt.name(), evt.id());
      break;
    }
    case FtraceEvent::kDrmRunJobFieldNumber: {
      protos::pbzero::DrmRunJobFtraceEvent::Decoder evt(blob.data, blob.size);
      DrmRunJob(timestamp, evt.name(), evt.id(), evt.fence());
      break;
    }
    case FtraceEvent::kDrmSchedProcessJobFieldNumber: {
      protos::pbzero::DrmSchedProcessJobFtraceEvent::Decoder evt(blob.data,
                                                                 blob.size);
      DrmSchedProcessJob(timestamp, evt.fence());
      break;
    }
    case FtraceEvent::kDmaFenceInitFieldNumber: {
      protos::pbzero::DmaFenceInitFtraceEvent::Decoder evt(blob.data,
                                                           blob.size);
      DmaFenceInit(timestamp, evt.timeline(), evt.context(), evt.seqno());
      break;
    }
    case FtraceEvent::kDmaFenceEmitFieldNumber: {
      protos::pbzero::DmaFenceEmitFtraceEvent::Decoder evt(blob.data,
                                                           blob.size);
      DmaFenceEmit(timestamp, evt.timeline(), evt.context(), evt.seqno());
      break;
    }
    case FtraceEvent::kDmaFenceSignaledFieldNumber: {
      protos::pbzero::DmaFenceSignaledFtraceEvent::Decoder evt(blob.data,
                                                               blob.size);
      DmaFenceSignaled(timestamp, evt.timeline(), evt.context(), evt.seqno());
      break;
    }
    case FtraceEvent::kDmaFenceWaitStartFieldNumber: {
      protos::pbzero::DmaFenceWaitStartFtraceEvent::Decoder evt(blob.data,
                                                                blob.size);
      DmaFenceWaitStart(timestamp, pid, evt.context(), evt.seqno());
      break;
    }
    case FtraceEvent::kDmaFenceWaitEndFieldNumber: {
      DmaFenceWaitEnd(timestamp, pid);
      break;
    }
    default:
      PERFETTO_DFATAL("Unexpected field id");
      break;
  }
}

TrackId DrmTracker::InternVblankTrack(int32_t crtc) {
  base::StackString<256> track_name("vblank-%d", crtc);
  StringId track_name_id =
      context_->storage->InternString(track_name.string_view());
  return context_->track_tracker->InternGpuTrack(
      tables::GpuTrackTable::Row(track_name_id));
}

void DrmTracker::DrmVblankEvent(int64_t timestamp,
                                int32_t crtc,
                                uint32_t seqno) {
  TrackId track_id = InternVblankTrack(crtc);
  auto args_inserter = [this, seqno](ArgsTracker::BoundInserter* inserter) {
    inserter->AddArg(vblank_arg_seqno_id_, Variadic::UnsignedInteger(seqno));
  };

  context_->slice_tracker->Scoped(timestamp, track_id, kNullStringId,
                                  vblank_slice_signal_id_, 0, args_inserter);
}

void DrmTracker::DrmVblankEventDelivered(int64_t timestamp,
                                         int32_t crtc,
                                         uint32_t seqno) {
  TrackId track_id = InternVblankTrack(crtc);
  auto args_inserter = [this, seqno](ArgsTracker::BoundInserter* inserter) {
    inserter->AddArg(vblank_arg_seqno_id_, Variadic::UnsignedInteger(seqno));
  };

  context_->slice_tracker->Scoped(timestamp, track_id, kNullStringId,
                                  vblank_slice_deliver_id_, 0, args_inserter);
}

DrmTracker::SchedRing& DrmTracker::GetSchedRingByName(base::StringView name) {
  auto* iter = sched_rings_.Find(name);
  if (iter)
    return **iter;

  // intern a gpu track
  base::StackString<64> track_name("sched-%.*s", int(name.size()), name.data());
  StringId track_name_id =
      context_->storage->InternString(track_name.string_view());
  TrackId track_id = context_->track_tracker->InternGpuTrack(
      tables::GpuTrackTable::Row(track_name_id));

  // no std::make_unique until C++14..
  auto ring = std::unique_ptr<SchedRing>(new SchedRing());
  ring->track_id = track_id;

  SchedRing& ret = *ring;
  sched_rings_.Insert(name, std::move(ring));

  return ret;
}

void DrmTracker::BeginSchedRingSlice(int64_t timestamp, SchedRing& ring) {
  PERFETTO_DCHECK(!ring.running_jobs.empty());
  uint64_t job_id = ring.running_jobs.front();

  auto args_inserter = [this, job_id](ArgsTracker::BoundInserter* inserter) {
    inserter->AddArg(sched_arg_job_id_, Variadic::UnsignedInteger(job_id));
  };

  std::optional<SliceId> slice_id =
      context_->slice_tracker->Begin(timestamp, ring.track_id, kNullStringId,
                                     sched_slice_job_id_, args_inserter);

  if (slice_id) {
    SliceId* out_slice_id = ring.out_slice_ids.Find(job_id);
    if (out_slice_id) {
      context_->flow_tracker->InsertFlow(*out_slice_id, *slice_id);
      ring.out_slice_ids.Erase(job_id);
    }
  }
}

void DrmTracker::DrmSchedJob(int64_t timestamp,
                             uint32_t pid,
                             base::StringView name,
                             uint64_t job_id) {
  UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
  TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
  StringId ring_id = context_->storage->InternString(name);
  auto args_inserter = [this, ring_id,
                        job_id](ArgsTracker::BoundInserter* inserter) {
    inserter->AddArg(sched_arg_ring_id_, Variadic::String(ring_id));
    inserter->AddArg(sched_arg_job_id_, Variadic::UnsignedInteger(job_id));
  };

  std::optional<SliceId> slice_id = context_->slice_tracker->Scoped(
      timestamp, track_id, kNullStringId, sched_slice_schedule_id_, 0,
      args_inserter);

  if (slice_id) {
    SchedRing& ring = GetSchedRingByName(name);
    ring.out_slice_ids[job_id] = *slice_id;
  }
}

void DrmTracker::DrmRunJob(int64_t timestamp,
                           base::StringView name,
                           uint64_t job_id,
                           uint64_t fence_id) {
  SchedRing& ring = GetSchedRingByName(name);

  ring.running_jobs.push_back(job_id);
  sched_pending_fences_.Insert(fence_id, &ring);

  if (ring.running_jobs.size() == 1)
    BeginSchedRingSlice(timestamp, ring);
}

void DrmTracker::DrmSchedProcessJob(int64_t timestamp, uint64_t fence_id) {
  // look up ring using fence_id
  auto* iter = sched_pending_fences_.Find(fence_id);
  if (!iter)
    return;
  SchedRing& ring = **iter;
  sched_pending_fences_.Erase(fence_id);

  ring.running_jobs.pop_front();
  context_->slice_tracker->End(timestamp, ring.track_id);

  if (!ring.running_jobs.empty())
    BeginSchedRingSlice(timestamp, ring);
}

DrmTracker::FenceTimeline& DrmTracker::GetFenceTimelineByContext(
    uint32_t context,
    base::StringView name) {
  auto* iter = fence_timelines_.Find(context);
  if (iter)
    return **iter;

  // intern a gpu track
  base::StackString<64> track_name("fence-%.*s-%u", int(name.size()),
                                   name.data(), context);
  StringId track_name_id =
      context_->storage->InternString(track_name.string_view());
  TrackId track_id = context_->track_tracker->InternGpuTrack(
      tables::GpuTrackTable::Row(track_name_id));

  // no std::make_unique until C++14..
  auto timeline = std::unique_ptr<FenceTimeline>(new FenceTimeline());
  timeline->track_id = track_id;

  FenceTimeline& ret = *timeline;
  fence_timelines_.Insert(context, std::move(timeline));

  return ret;
}

void DrmTracker::BeginFenceTimelineSlice(int64_t timestamp,
                                         const FenceTimeline& timeline) {
  PERFETTO_DCHECK(!timeline.pending_fences.empty());
  uint32_t seqno = timeline.pending_fences.front();

  auto args_inserter = [this, seqno](ArgsTracker::BoundInserter* inserter) {
    inserter->AddArg(fence_arg_seqno_id_, Variadic::UnsignedInteger(seqno));
  };

  context_->slice_tracker->Begin(timestamp, timeline.track_id, kNullStringId,
                                 fence_slice_fence_id_, args_inserter);
}

void DrmTracker::DmaFenceInit(int64_t timestamp,
                              base::StringView name,
                              uint32_t context,
                              uint32_t seqno) {
  if (name == kUnboundFenceTimeline)
    return;

  FenceTimeline& timeline = GetFenceTimelineByContext(context, name);
  // ignore dma_fence_init when the timeline has dma_fence_emit
  if (timeline.has_dma_fence_emit)
    return;

  timeline.pending_fences.push_back(seqno);

  if (timeline.pending_fences.size() == 1)
    BeginFenceTimelineSlice(timestamp, timeline);
}

void DrmTracker::DmaFenceEmit(int64_t timestamp,
                              base::StringView name,
                              uint32_t context,
                              uint32_t seqno) {
  if (name == kUnboundFenceTimeline)
    return;

  FenceTimeline& timeline = GetFenceTimelineByContext(context, name);

  // Most timelines do not have dma_fence_emit and we rely on the less
  // accurate dma_fence_init instead.  But for those who do, we will switch to
  // dma_fence_emit.
  if (!timeline.has_dma_fence_emit) {
    timeline.has_dma_fence_emit = true;

    if (!timeline.pending_fences.empty()) {
      context_->slice_tracker->End(timestamp, timeline.track_id);
      timeline.pending_fences.clear();
    }
  }

  timeline.pending_fences.push_back(seqno);

  if (timeline.pending_fences.size() == 1)
    BeginFenceTimelineSlice(timestamp, timeline);
}

void DrmTracker::DmaFenceSignaled(int64_t timestamp,
                                  base::StringView name,
                                  uint32_t context,
                                  uint32_t seqno) {
  if (name == kUnboundFenceTimeline)
    return;

  FenceTimeline& timeline = GetFenceTimelineByContext(context, name);
  if (timeline.pending_fences.empty() ||
      seqno < timeline.pending_fences.front()) {
    return;
  }

  timeline.pending_fences.pop_front();
  context_->slice_tracker->End(timestamp, timeline.track_id);

  if (!timeline.pending_fences.empty())
    BeginFenceTimelineSlice(timestamp, timeline);
}

void DrmTracker::DmaFenceWaitStart(int64_t timestamp,
                                   uint32_t pid,
                                   uint32_t context,
                                   uint32_t seqno) {
  UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
  TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
  auto args_inserter = [this, context,
                        seqno](ArgsTracker::BoundInserter* inserter) {
    inserter->AddArg(fence_arg_context_id_, Variadic::UnsignedInteger(context));
    inserter->AddArg(fence_arg_seqno_id_, Variadic::UnsignedInteger(seqno));
  };

  context_->slice_tracker->Begin(timestamp, track_id, kNullStringId,
                                 fence_slice_wait_id_, args_inserter);
}

void DrmTracker::DmaFenceWaitEnd(int64_t timestamp, uint32_t pid) {
  UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
  TrackId track_id = context_->track_tracker->InternThreadTrack(utid);

  context_->slice_tracker->End(timestamp, track_id);
}

}  // namespace trace_processor
}  // namespace perfetto
