/*
 * Copyright (C) 2015 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 ANDROID_DRM_DISPLAY_COMPOSITOR_H_
#define ANDROID_DRM_DISPLAY_COMPOSITOR_H_

#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <pthread.h>

#include <memory>
#include <sstream>
#include <tuple>

#include "DrmDisplayComposition.h"
#include "DrmFramebuffer.h"
#include "Planner.h"
#include "drm/ResourceManager.h"
#include "drm/VSyncWorker.h"
#include "drmhwcomposer.h"

// One for the front, one for the back, and one for cases where we need to
// squash a frame that the hw can't display with hw overlays.
#define DRM_DISPLAY_BUFFERS 3

// If a scene is still for this number of vblanks flatten it to reduce power
// consumption.
#define FLATTEN_COUNTDOWN_INIT 60

namespace android {

enum class FlatteningState {
  kNone,
  kNotNeeded,
  kClientRequested,
  kClientDone,
  kSerial,
  kConcurrent
};

std::ostream &operator<<(std::ostream &str, FlatteningState state);

class DrmDisplayCompositor {
 public:
  DrmDisplayCompositor();
  ~DrmDisplayCompositor();

  int Init(ResourceManager *resource_manager, int display);

  hwc2_callback_data_t refresh_callback_data_ = NULL;
  HWC2_PFN_REFRESH refresh_callback_hook_ = NULL;
  std::mutex refresh_callback_lock;

  void SetRefreshCallback(hwc2_callback_data_t data,
                          hwc2_function_pointer_t hook) {
    const std::lock_guard<std::mutex> lock(refresh_callback_lock);
    refresh_callback_data_ = data;
    refresh_callback_hook_ = reinterpret_cast<HWC2_PFN_REFRESH>(hook);
  }

  std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
  std::unique_ptr<DrmDisplayComposition> CreateInitializedComposition() const;
  int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);
  int TestComposition(DrmDisplayComposition *composition);
  int Composite();
  void Dump(std::ostringstream *out) const;
  void Vsync(int display, int64_t timestamp);
  void ClearDisplay();
  int TakeOutFence() {
    if (!active_composition_)
      return -1;
    return active_composition_->take_out_fence();
  }

  FlatteningState GetFlatteningState() const;
  uint32_t GetFlattenedFramesCount() const;
  bool ShouldFlattenOnClient() const;

  std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();

 private:
  struct ModeState {
    bool needs_modeset = false;
    DrmMode mode;
    uint32_t blob_id = 0;
    uint32_t old_blob_id = 0;
  };

  DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;

  // We'll wait for acquire fences to fire for kAcquireWaitTimeoutMs,
  // kAcquireWaitTries times, logging a warning in between.
  static const int kAcquireWaitTries = 5;
  static const int kAcquireWaitTimeoutMs = 100;

  int CommitFrame(DrmDisplayComposition *display_comp, bool test_only,
                  DrmConnector *writeback_conn = NULL,
                  DrmHwcBuffer *writeback_buffer = NULL);
  int SetupWritebackCommit(drmModeAtomicReqPtr pset, uint32_t crtc_id,
                           DrmConnector *writeback_conn,
                           DrmHwcBuffer *writeback_buffer);
  int ApplyDpms(DrmDisplayComposition *display_comp);
  int DisablePlanes(DrmDisplayComposition *display_comp);

  void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
                  int status, bool writeback = false);

  void SetFlattening(FlatteningState new_state);
  bool IsFlatteningNeeded() const;
  int FlattenActiveComposition();
  int FlattenOnClient();
  int FlattenSerial(DrmConnector *writeback_conn);
  int FlattenConcurrent(DrmConnector *writeback_conn);
  int FlattenOnDisplay(std::unique_ptr<DrmDisplayComposition> &src,
                       DrmConnector *writeback_conn, DrmMode &src_mode,
                       DrmHwcLayer *writeback_layer);

  bool CountdownExpired() const;

  std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);

  ResourceManager *resource_manager_;
  int display_;

  std::unique_ptr<DrmDisplayComposition> active_composition_;

  bool initialized_;
  bool active_;
  bool use_hw_overlays_;

  ModeState mode_;

  int framebuffer_index_;
  DrmFramebuffer framebuffers_[DRM_DISPLAY_BUFFERS];

  // mutable since we need to acquire in Dump()
  mutable pthread_mutex_t lock_;

  // State tracking progress since our last Dump(). These are mutable since
  // we need to reset them on every Dump() call.
  mutable uint64_t dump_frames_composited_;
  mutable uint64_t dump_last_timestamp_ns_;
  VSyncWorker vsync_worker_;
  int64_t flatten_countdown_;
  std::unique_ptr<Planner> planner_;
  int writeback_fence_;

  FlatteningState flattening_state_;
  uint32_t frames_flattened_;

  std::function<void(int)> refresh_display_cb_;
};
}  // namespace android

#endif  // ANDROID_DRM_DISPLAY_COMPOSITOR_H_
