/*
 * 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 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 RegisterObserver(Observer* observer) override;
  void UnregisterObserver(Observer* observer) override;

 private:
  HwcDisplay* FindDisplay(Display display);

  wp<VrComposerClient> client_;
  sp<IComposerCallback> callbacks_;

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