/*
 * 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.
 */

#include "src/trace_processor/importers/proto/graphics_frame_event_parser.h"

#include <cinttypes>

#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/field.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/event_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"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"

#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"

namespace perfetto {
namespace trace_processor {

constexpr char kQueueLostMessage[] =
    "Missing queue event. The slice is now a bit extended than it might "
    "actually have been";
GraphicsFrameEventParser::GraphicsFrameEventParser(
    TraceProcessorContext* context)
    : context_(context),
      graphics_event_scope_id_(
          context->storage->InternString("graphics_frame_event")),
      unknown_event_name_id_(context->storage->InternString("unknown_event")),
      no_layer_name_name_id_(context->storage->InternString("no_layer_name")),
      layer_name_key_id_(context->storage->InternString("layer_name")),
      event_type_name_ids_{
          {context->storage->InternString(
               "unspecified_event") /* UNSPECIFIED */,
           context->storage->InternString("Dequeue") /* DEQUEUE */,
           context->storage->InternString("Queue") /* QUEUE */,
           context->storage->InternString("Post") /* POST */,
           context->storage->InternString(
               "AcquireFenceSignaled") /* ACQUIRE_FENCE */,
           context->storage->InternString("Latch") /* LATCH */,
           context->storage->InternString(
               "HWCCompositionQueued") /* HWC_COMPOSITION_QUEUED */,
           context->storage->InternString(
               "FallbackComposition") /* FALLBACK_COMPOSITION */,
           context->storage->InternString(
               "PresentFenceSignaled") /* PRESENT_FENCE */,
           context->storage->InternString(
               "ReleaseFenceSignaled") /* RELEASE_FENCE */,
           context->storage->InternString("Modify") /* MODIFY */,
           context->storage->InternString("Detach") /* DETACH */,
           context->storage->InternString("Attach") /* ATTACH */,
           context->storage->InternString("Cancel") /* CANCEL */}},
      queue_lost_message_id_(
          context->storage->InternString(kQueueLostMessage)) {}

bool GraphicsFrameEventParser::CreateBufferEvent(
    int64_t timestamp,
    GraphicsFrameEventDecoder& event) {
  if (!event.has_buffer_id()) {
    context_->storage->IncrementStats(
        stats::graphics_frame_event_parser_errors);
    PERFETTO_ELOG("GraphicsFrameEvent with missing buffer id field.");
    return false;
  }

  // Use buffer id + layer name as key because sometimes the same buffer can be
  // used by different layers.
  char event_key_buffer[4096];
  base::StringWriter event_key_str(event_key_buffer,
                                   base::ArraySize(event_key_buffer));
  const uint32_t buffer_id = event.buffer_id();
  StringId layer_name_id;
  event_key_str.AppendUnsignedInt(buffer_id);

  if (event.has_layer_name()) {
    layer_name_id = context_->storage->InternString(event.layer_name());
    event_key_str.AppendString(base::StringView(event.layer_name()));
  } else {
    layer_name_id = no_layer_name_name_id_;
  }
  StringId event_key =
      context_->storage->InternString(event_key_str.GetStringView());

  StringId event_name_id = unknown_event_name_id_;
  if (event.has_type()) {
    const auto type = static_cast<size_t>(event.type());
    if (type < event_type_name_ids_.size()) {
      event_name_id = event_type_name_ids_[type];
      graphics_frame_stats_map_[event_key][type] = timestamp;
    } else {
      context_->storage->IncrementStats(
          stats::graphics_frame_event_parser_errors);
      PERFETTO_ELOG("GraphicsFrameEvent with unknown type %zu.", type);
    }
  } else {
    context_->storage->IncrementStats(
        stats::graphics_frame_event_parser_errors);
    PERFETTO_ELOG("GraphicsFrameEvent with missing type field.");
  }

  char buffer[4096];
  base::StringWriter track_name(buffer, base::ArraySize(buffer));
  track_name.AppendLiteral("Buffer: ");
  track_name.AppendUnsignedInt(buffer_id);
  track_name.AppendLiteral(" ");
  track_name.AppendString(base::StringView(event.layer_name()));

  const StringId track_name_id =
      context_->storage->InternString(track_name.GetStringView());
  const int64_t duration =
      event.has_duration_ns() ? static_cast<int64_t>(event.duration_ns()) : 0;
  uint32_t frame_number = event.has_frame_number() ? event.frame_number() : 0;

  tables::GpuTrackTable::Row track(track_name_id);
  track.scope = graphics_event_scope_id_;
  TrackId track_id = context_->track_tracker->InternGpuTrack(track);

  auto* graphics_frame_slice_table =
      context_->storage->mutable_graphics_frame_slice_table();
  {
    tables::GraphicsFrameSliceTable::Row row;
    row.ts = timestamp;
    row.track_id = track_id;
    row.name = event_name_id;
    row.dur = duration;
    row.frame_number = frame_number;
    row.layer_name = layer_name_id;
    if (event.type() == GraphicsFrameEvent::PRESENT_FENCE) {
      auto acquire_ts =
          graphics_frame_stats_map_[event_key]
                                   [GraphicsFrameEvent::ACQUIRE_FENCE];
      auto queue_ts =
          graphics_frame_stats_map_[event_key][GraphicsFrameEvent::QUEUE];
      auto latch_ts =
          graphics_frame_stats_map_[event_key][GraphicsFrameEvent::LATCH];

      row.queue_to_acquire_time =
          std::max(acquire_ts - queue_ts, static_cast<int64_t>(0));
      row.acquire_to_latch_time = latch_ts - acquire_ts;
      row.latch_to_present_time = timestamp - latch_ts;
    }
    std::optional<SliceId> opt_slice_id =
        context_->slice_tracker->ScopedTyped(graphics_frame_slice_table, row);
    if (event.type() == GraphicsFrameEvent::DEQUEUE) {
      if (opt_slice_id) {
        dequeue_slice_ids_[event_key] = *opt_slice_id;
      }
    } else if (event.type() == GraphicsFrameEvent::QUEUE) {
      auto it = dequeue_slice_ids_.find(event_key);
      if (it != dequeue_slice_ids_.end()) {
        auto dequeue_slice_id = it->second;
        uint32_t row_idx =
            *graphics_frame_slice_table->id().IndexOf(dequeue_slice_id);
        graphics_frame_slice_table->mutable_frame_number()->Set(row_idx,
                                                                frame_number);
      }
    }
  }
  return true;
}

void GraphicsFrameEventParser::InvalidatePhaseEvent(int64_t timestamp,
                                                    TrackId track_id,
                                                    bool reset_name) {
  const auto opt_slice_id = context_->slice_tracker->End(timestamp, track_id);

  if (opt_slice_id) {
    auto* graphics_frame_slice_table =
        context_->storage->mutable_graphics_frame_slice_table();
    uint32_t row_idx = *graphics_frame_slice_table->id().IndexOf(*opt_slice_id);
    if (reset_name) {
      // Set the name (frame_number) to be 0 since there is no frame number
      // associated, example : dequeue event.
      StringId frame_name_id = context_->storage->InternString("0");
      graphics_frame_slice_table->mutable_name()->Set(row_idx, frame_name_id);
      graphics_frame_slice_table->mutable_frame_number()->Set(row_idx, 0);
    }

    // Set the duration to -1 so that this slice will be ignored by the
    // UI. Setting any other duration results in wrong data which we want
    // to avoid at all costs.
    graphics_frame_slice_table->mutable_dur()->Set(row_idx, -1);
  }
}

// Here we convert the buffer events into Phases(slices)
// APP: Dequeue to Queue
// Wait for GPU: Queue to Acquire
// SurfaceFlinger (SF): Latch to Present
// Display: Present to next Present (of the same layer)
void GraphicsFrameEventParser::CreatePhaseEvent(
    int64_t timestamp,
    GraphicsFrameEventDecoder& event) {
  // Use buffer id + layer name as key because sometimes the same buffer can be
  // used by different layers.
  char event_key_buffer[4096];
  base::StringWriter event_key_str(event_key_buffer,
                                   base::ArraySize(event_key_buffer));
  const uint32_t buffer_id = event.buffer_id();
  uint32_t frame_number = event.has_frame_number() ? event.frame_number() : 0;
  event_key_str.AppendUnsignedInt(buffer_id);
  StringId layer_name_id;
  if (event.has_layer_name()) {
    layer_name_id = context_->storage->InternString(event.layer_name());
    event_key_str.AppendString(base::StringView(event.layer_name()));
  } else {
    layer_name_id = no_layer_name_name_id_;
  }
  StringId event_key =
      context_->storage->InternString(event_key_str.GetStringView());

  char track_buffer[4096];
  char slice_buffer[4096];
  // We'll be using the name StringWriter and name_id for writing track names
  // and slice names.
  base::StringWriter track_name(track_buffer, base::ArraySize(track_buffer));
  base::StringWriter slice_name(slice_buffer, base::ArraySize(slice_buffer));
  StringId track_name_id;
  TrackId track_id;
  bool start_slice = true;

  // Close the previous phase before starting the new phase
  switch (event.type()) {
    case GraphicsFrameEvent::DEQUEUE: {
      track_name.reset();
      track_name.AppendLiteral("APP_");
      track_name.AppendUnsignedInt(buffer_id);
      track_name.AppendLiteral(" ");
      track_name.AppendString(base::StringView(event.layer_name()));
      track_name_id =
          context_->storage->InternString(track_name.GetStringView());
      tables::GpuTrackTable::Row app_track(track_name_id);
      app_track.scope = graphics_event_scope_id_;
      track_id = context_->track_tracker->InternGpuTrack(app_track);

      // Error handling
      auto dequeue_time = dequeue_map_.find(event_key);
      if (dequeue_time != dequeue_map_.end()) {
        InvalidatePhaseEvent(timestamp, dequeue_time->second, true);
        dequeue_map_.erase(dequeue_time);
      }
      auto queue_time = queue_map_.find(event_key);
      if (queue_time != queue_map_.end()) {
        InvalidatePhaseEvent(timestamp, queue_time->second);
        queue_map_.erase(queue_time);
      }

      dequeue_map_[event_key] = track_id;
      last_dequeued_[event_key] = timestamp;
      break;
    }

    case GraphicsFrameEvent::QUEUE: {
      auto dequeue_time = dequeue_map_.find(event_key);
      if (dequeue_time != dequeue_map_.end()) {
        const auto opt_slice_id =
            context_->slice_tracker->End(timestamp, dequeue_time->second);
        slice_name.reset();
        slice_name.AppendUnsignedInt(frame_number);
        if (opt_slice_id) {
          auto* graphics_frame_slice_table =
              context_->storage->mutable_graphics_frame_slice_table();
          // Set the name of the slice to be the frame number since dequeue did
          // not have a frame number at that time.
          uint32_t row_idx =
              *graphics_frame_slice_table->id().IndexOf(*opt_slice_id);
          StringId frame_name_id =
              context_->storage->InternString(slice_name.GetStringView());
          graphics_frame_slice_table->mutable_name()->Set(row_idx,
                                                          frame_name_id);
          graphics_frame_slice_table->mutable_frame_number()->Set(row_idx,
                                                                  frame_number);
          dequeue_map_.erase(dequeue_time);
        }
      }
      // The AcquireFence might be signaled before receiving a QUEUE event
      // sometimes. In that case, we shouldn't start a slice.
      if (last_acquired_[event_key] > last_dequeued_[event_key] &&
          last_acquired_[event_key] < timestamp) {
        start_slice = false;
        break;
      }
      track_name.reset();
      track_name.AppendLiteral("GPU_");
      track_name.AppendUnsignedInt(buffer_id);
      track_name.AppendLiteral(" ");
      track_name.AppendString(base::StringView(event.layer_name()));
      track_name_id =
          context_->storage->InternString(track_name.GetStringView());
      tables::GpuTrackTable::Row gpu_track(track_name_id);
      gpu_track.scope = graphics_event_scope_id_;
      track_id = context_->track_tracker->InternGpuTrack(gpu_track);
      queue_map_[event_key] = track_id;
      break;
    }
    case GraphicsFrameEvent::ACQUIRE_FENCE: {
      auto queue_time = queue_map_.find(event_key);
      if (queue_time != queue_map_.end()) {
        context_->slice_tracker->End(timestamp, queue_time->second);
        queue_map_.erase(queue_time);
      }
      last_acquired_[event_key] = timestamp;
      start_slice = false;
      break;
    }
    case GraphicsFrameEvent::LATCH: {
      // b/157578286 - Sometimes Queue event goes missing. To prevent having a
      // wrong slice info, we try to close any existing APP slice.
      auto dequeue_time = dequeue_map_.find(event_key);
      if (dequeue_time != dequeue_map_.end()) {
        InvalidatePhaseEvent(timestamp, dequeue_time->second, true);
        dequeue_map_.erase(dequeue_time);
      }
      track_name.reset();
      track_name.AppendLiteral("SF_");
      track_name.AppendUnsignedInt(buffer_id);
      track_name.AppendLiteral(" ");
      track_name.AppendString(base::StringView(event.layer_name()));
      track_name_id =
          context_->storage->InternString(track_name.GetStringView());
      tables::GpuTrackTable::Row sf_track(track_name_id);
      sf_track.scope = graphics_event_scope_id_;
      track_id = context_->track_tracker->InternGpuTrack(sf_track);
      latch_map_[event_key] = track_id;
      break;
    }

    case GraphicsFrameEvent::PRESENT_FENCE: {
      auto latch_time = latch_map_.find(event_key);
      if (latch_time != latch_map_.end()) {
        context_->slice_tracker->End(timestamp, latch_time->second);
        latch_map_.erase(latch_time);
      }
      auto display_time = display_map_.find(layer_name_id);
      if (display_time != display_map_.end()) {
        context_->slice_tracker->End(timestamp, display_time->second);
        display_map_.erase(display_time);
      }
      base::StringView layerName(event.layer_name());
      track_name.reset();
      track_name.AppendLiteral("Display_");
      track_name.AppendString(layerName.substr(0, 10));
      track_name_id =
          context_->storage->InternString(track_name.GetStringView());
      tables::GpuTrackTable::Row display_track(track_name_id);
      display_track.scope = graphics_event_scope_id_;
      track_id = context_->track_tracker->InternGpuTrack(display_track);
      display_map_[layer_name_id] = track_id;
      break;
    }

    default:
      start_slice = false;
  }

  // Start the new phase if needed.
  if (start_slice) {
    tables::GraphicsFrameSliceTable::Row slice;
    slice.ts = timestamp;
    slice.track_id = track_id;
    slice.layer_name = layer_name_id;
    slice_name.reset();
    // If the frame_number is known, set it as the name of the slice.
    // If not known (DEQUEUE), set the name as the timestamp.
    // Timestamp is chosen here because the stack_id is hashed based on the name
    // of the slice. To not have any conflicting stack_id with any of the
    // existing slices, we use timestamp as the temporary name.
    if (frame_number != 0) {
      slice_name.AppendUnsignedInt(frame_number);
    } else {
      slice_name.AppendInt(timestamp);
    }
    slice.name = context_->storage->InternString(slice_name.GetStringView());
    slice.frame_number = frame_number;
    context_->slice_tracker->BeginTyped(
        context_->storage->mutable_graphics_frame_slice_table(), slice);
  }
}

void GraphicsFrameEventParser::ParseGraphicsFrameEvent(int64_t timestamp,
                                                       ConstBytes blob) {
  protos::pbzero::GraphicsFrameEvent_Decoder frame_event(blob.data, blob.size);
  if (!frame_event.has_buffer_event()) {
    return;
  }

  ConstBytes bufferBlob = frame_event.buffer_event();
  protos::pbzero::GraphicsFrameEvent_BufferEvent_Decoder event(bufferBlob.data,
                                                               bufferBlob.size);
  if (CreateBufferEvent(timestamp, event)) {
    // Create a phase event only if the buffer event finishes successfully
    CreatePhaseEvent(timestamp, event);
  }
}

}  // namespace trace_processor
}  // namespace perfetto
