/*
 * Copyright 2016 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_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H
#define ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H

#include <android-base/unique_fd.h>
#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <ComposerBase.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>

#include <mutex>
#include <unordered_map>

using namespace android::frameworks::vr::composer::V1_0;
using namespace android::hardware::graphics::common::V1_0;
using namespace android::hardware::graphics::composer::V2_1;

using android::hardware::hidl_handle;
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::Void;

namespace android {

class Fence;

namespace dvr {

class VrComposerClient;

using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::composer::V2_1::implementation::ComposerBase;

class ComposerView {
 public:
  struct ComposerLayer {
    using Recti = hardware::graphics::composer::V2_1::IComposerClient::Rect;
    using Rectf = hardware::graphics::composer::V2_1::IComposerClient::FRect;
    using BlendMode =
        hardware::graphics::composer::V2_1::IComposerClient::BlendMode;

    Layer id;
    sp<GraphicBuffer> buffer;
    sp<Fence> fence;
    Recti display_frame;
    Rectf crop;
    BlendMode blend_mode;
    float alpha;
    uint32_t type;
    uint32_t app_id;
    uint32_t z_order;
    int32_t cursor_x;
    int32_t cursor_y;
    IComposerClient::Color color;
    int32_t dataspace;
    int32_t transform;
    std::vector<hwc_rect_t> visible_regions;
    std::vector<hwc_rect_t> damaged_regions;
  };

  struct Frame {
    Display display_id;
    // This is set to true to notify the upper layer that the display is
    // being removed, or left false in the case of a normal frame. The upper
    // layer tracks display IDs and will handle new ones showing up.
    bool removed = false;
    int32_t display_width;
    int32_t display_height;
    Config active_config;
    ColorMode color_mode;
    IComposerClient::PowerMode power_mode;
    IComposerClient::Vsync vsync_enabled;
    float color_transform[16];
    int32_t color_transform_hint;
    std::vector<ComposerLayer> layers;
  };

  class Observer {
   public:
    virtual ~Observer() {}

    // Returns a list of layers that need to be shown together. Layers are
    // returned in z-order, with the lowest layer first.
    virtual base::unique_fd OnNewFrame(const Frame& frame) = 0;
  };

  virtual ~ComposerView() {}

  virtual void ForceDisplaysRefresh() = 0;
  virtual void RegisterObserver(Observer* observer) = 0;
  virtual void UnregisterObserver(Observer* observer) = 0;
};

struct HwcLayer {
  using Composition =
      hardware::graphics::composer::V2_1::IComposerClient::Composition;

  HwcLayer(Layer new_id) {
    info.id = new_id;
  }

  Composition composition_type;
  ComposerView::ComposerLayer info;
  IVrComposerClient::BufferMetadata buffer_metadata;
};

class HwcDisplay {
 public:
  HwcDisplay(int32_t width, int32_t height);
  ~HwcDisplay();

  int32_t width() const { return width_; }
  int32_t height() const { return height_; }

  HwcLayer* CreateLayer();
  bool DestroyLayer(Layer id);
  HwcLayer* GetLayer(Layer id);

  bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence);
  void SetClientTargetMetadata(
      const IVrComposerClient::BufferMetadata& metadata);

  void GetChangedCompositionTypes(
      std::vector<Layer>* layer_ids,
      std::vector<IComposerClient::Composition>* composition);

  Error GetFrame(std::vector<ComposerView::ComposerLayer>* out_frame);

  std::vector<Layer> UpdateLastFrameAndGetLastFrameLayers();

  Config active_config() const { return active_config_; }
  void set_active_config(Config config) { active_config_ = config; }

  ColorMode color_mode() const { return color_mode_; }
  void set_color_mode(ColorMode mode) { color_mode_ = mode; }

  IComposerClient::PowerMode power_mode() const { return power_mode_; }
  void set_power_mode(IComposerClient::PowerMode mode) { power_mode_ = mode; }

  IComposerClient::Vsync vsync_enabled() const { return vsync_enabled_; }
  void set_vsync_enabled(IComposerClient::Vsync vsync) {
    vsync_enabled_ = vsync;
  }

  const float* color_transform() const { return color_transform_; }
  int32_t color_transform_hint() const { return color_transform_hint_; }
  void SetColorTransform(const float* matrix, int32_t hint);

 private:
  // The client target buffer and the associated fence.
  sp<GraphicBuffer> buffer_;
  IVrComposerClient::BufferMetadata buffer_metadata_;
  sp<Fence> fence_;

  // List of currently active layers.
  std::vector<HwcLayer> layers_;

  std::vector<Layer> last_frame_layers_ids_;

  // Layer ID generator.
  uint64_t layer_ids_ = 1;

  int32_t width_;
  int32_t height_;

  Config active_config_;
  ColorMode color_mode_;
  IComposerClient::PowerMode power_mode_;
  IComposerClient::Vsync vsync_enabled_;
  float color_transform_[16];
  int32_t color_transform_hint_;

  HwcDisplay(const HwcDisplay&) = delete;
  void operator=(const HwcDisplay&) = delete;
};

class VrHwc : public IComposer, public ComposerBase, public ComposerView {
 public:
  VrHwc();
  ~VrHwc() override;

  bool hasCapability(Capability capability) const;

  Error setLayerInfo(Display display, Layer layer, uint32_t type,
                     uint32_t appId);
  Error setClientTargetMetadata(
      Display display, const IVrComposerClient::BufferMetadata& metadata);
  Error setLayerBufferMetadata(
      Display display, Layer layer,
      const IVrComposerClient::BufferMetadata& metadata);

  // ComposerBase
  void removeClient() override;
  void enableCallback(bool enable) override;

  uint32_t getMaxVirtualDisplayCount() override;
  Error createVirtualDisplay(uint32_t width, uint32_t height,
      PixelFormat* format, Display* outDisplay) override;
  Error destroyVirtualDisplay(Display display) override;

  Error createLayer(Display display, Layer* outLayer) override;
  Error destroyLayer(Display display, Layer layer) override;

  Error getActiveConfig(Display display, Config* outConfig) override;
  Error getClientTargetSupport(Display display,
          uint32_t width, uint32_t height,
          PixelFormat format, Dataspace dataspace) override;
  Error getColorModes(Display display, hidl_vec<ColorMode>* outModes) override;
  Error getDisplayAttribute(Display display, Config config,
          IComposerClient::Attribute attribute, int32_t* outValue) override;
  Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override;
  Error getDisplayName(Display display, hidl_string* outName) override;
  Error getDisplayType(Display display,
          IComposerClient::DisplayType* outType) override;
  Error getDozeSupport(Display display, bool* outSupport) override;
  Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
          float* outMaxLuminance, float* outMaxAverageLuminance,
          float* outMinLuminance) override;

  Error setActiveConfig(Display display, Config config) override;
  Error setColorMode(Display display, ColorMode mode) override;
  Error setPowerMode(Display display, IComposerClient::PowerMode mode) override;
  Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override;

  Error setColorTransform(Display display, const float* matrix,
          int32_t hint) override;
  Error setClientTarget(Display display, buffer_handle_t target,
          int32_t acquireFence, int32_t dataspace,
          const std::vector<hwc_rect_t>& damage) override;
  Error setOutputBuffer(Display display, buffer_handle_t buffer,
          int32_t releaseFence) override;
  Error validateDisplay(Display display,
          std::vector<Layer>* outChangedLayers,
          std::vector<IComposerClient::Composition>* outCompositionTypes,
          uint32_t* outDisplayRequestMask,
          std::vector<Layer>* outRequestedLayers,
          std::vector<uint32_t>* outRequestMasks) override;
  Error acceptDisplayChanges(Display display) override;
  Error presentDisplay(Display display, int32_t* outPresentFence,
          std::vector<Layer>* outLayers,
          std::vector<int32_t>* outReleaseFences) override;

  Error setLayerCursorPosition(Display display, Layer layer,
          int32_t x, int32_t y) override;
  Error setLayerBuffer(Display display, Layer layer,
          buffer_handle_t buffer, int32_t acquireFence) override;
  Error setLayerSurfaceDamage(Display display, Layer layer,
          const std::vector<hwc_rect_t>& damage) override;
  Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override;
  Error setLayerColor(Display display, Layer layer,
          IComposerClient::Color color) override;
  Error setLayerCompositionType(Display display, Layer layer,
          int32_t type) override;
  Error setLayerDataspace(Display display, Layer layer,
          int32_t dataspace) override;
  Error setLayerDisplayFrame(Display display, Layer layer,
          const hwc_rect_t& frame) override;
  Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
  Error setLayerSidebandStream(Display display, Layer layer,
          buffer_handle_t stream) override;
  Error setLayerSourceCrop(Display display, Layer layer,
          const hwc_frect_t& crop) override;
  Error setLayerTransform(Display display, Layer layer,
          int32_t transform) override;
  Error setLayerVisibleRegion(Display display, Layer layer,
          const std::vector<hwc_rect_t>& visible) override;
  Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;

  // IComposer:
  Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
  Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
  Return<void> createClient(createClient_cb hidl_cb) override;

  // ComposerView:
  void ForceDisplaysRefresh() override;
  void RegisterObserver(Observer* observer) override;
  void UnregisterObserver(Observer* observer) override;

 private:
  HwcDisplay* FindDisplay(Display display);

  wp<VrComposerClient> client_;

  // Guard access to internal state from binder threads.
  std::mutex mutex_;

  std::unordered_map<Display, std::unique_ptr<HwcDisplay>> displays_;
  Display display_count_ = 2;

  Observer* observer_ = nullptr;

  VrHwc(const VrHwc&) = delete;
  void operator=(const VrHwc&) = delete;
};

}  // namespace dvr
}  // namespace android

#endif  // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H
