/*
* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*    * Redistributions of source code must retain the above copyright notice, this list of
*      conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of
*      conditions and the following disclaimer in the documentation and/or other materials provided
*      with the distribution.
*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
*      endorse or promote products derived from this software without specific prior written
*      permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <math.h>
#include <utils/constants.h>
#include <utils/debug.h>
#include <dlfcn.h>

#include "res_manager.h"

#define __CLASS__ "ResManager"

namespace sde {

ResManager::ResManager()
  : num_pipe_(0), vig_pipes_(NULL), rgb_pipes_(NULL), dma_pipes_(NULL), virtual_count_(0),
    buffer_allocator_(NULL), buffer_sync_handler_(NULL), scalar_(NULL) {
}

DisplayError ResManager::Init(const HWResourceInfo &hw_res_info) {
  DisplayError error = kErrorNone;
  uint32_t num_pipe = 0;

  num_pipe = hw_res_info.num_vig_pipe + hw_res_info.num_rgb_pipe + hw_res_info.num_dma_pipe;

  if (num_pipe > kPipeIdMax) {
    DLOGE("Number of pipe is over the limit! %d", num_pipe);
    return kErrorParameters;
  }

  num_pipe_ = num_pipe;
  hw_res_info_ = hw_res_info;
  // Init pipe info
  vig_pipes_ = &src_pipes_[0];
  rgb_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe];
  dma_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe];

  for (uint32_t i = 0; i < hw_res_info_.num_vig_pipe; i++) {
    vig_pipes_[i].type = kPipeTypeVIG;
    vig_pipes_[i].index = i;
    vig_pipes_[i].mdss_pipe_id = GetMdssPipeId(vig_pipes_[i].type, i);
  }

  for (uint32_t i = 0; i < hw_res_info_.num_rgb_pipe; i++) {
    rgb_pipes_[i].type = kPipeTypeRGB;
    rgb_pipes_[i].index = i + hw_res_info_.num_vig_pipe;
    rgb_pipes_[i].mdss_pipe_id = GetMdssPipeId(rgb_pipes_[i].type, i);
  }

  for (uint32_t i = 0; i < hw_res_info_.num_dma_pipe; i++) {
    dma_pipes_[i].type = kPipeTypeDMA;
    dma_pipes_[i].index = i + hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe;
    dma_pipes_[i].mdss_pipe_id = GetMdssPipeId(dma_pipes_[i].type, i);
  }

  for (uint32_t i = 0; i < num_pipe_; i++) {
    src_pipes_[i].priority = i;
  }

  DLOGI("hw_rev=%x, DMA=%d RGB=%d VIG=%d", hw_res_info_.hw_revision, hw_res_info_.num_dma_pipe,
    hw_res_info_.num_rgb_pipe, hw_res_info_.num_vig_pipe);

  // TODO(user): Need to get it from HW capability
  hw_res_info_.num_rotator = 2;

  if (hw_res_info_.num_rotator > kMaxNumRotator) {
    DLOGE("Number of rotator is over the limit! %d", hw_res_info_.num_rotator);
    hw_res_info_.num_rotator = kMaxNumRotator;
  }

  if (hw_res_info_.max_scale_down < 1 || hw_res_info_.max_scale_up < 1) {
    DLOGE("Max scaling setting is invalid! max_scale_down = %d, max_scale_up = %d",
          hw_res_info_.max_scale_down, hw_res_info_.max_scale_up);
    hw_res_info_.max_scale_down = 1;
    hw_res_info_.max_scale_up = 1;
  }

  if (hw_res_info_.num_rotator > 0) {
    rotators_[0].pipe_index = dma_pipes_[0].index;
    rotators_[0].writeback_id = kHWWriteback0;
  }
  if (hw_res_info_.num_rotator > 1) {
    rotators_[1].pipe_index = dma_pipes_[1].index;
    rotators_[1].writeback_id = kHWWriteback1;
  }

  // Used by splash screen
  rgb_pipes_[0].state = kPipeStateOwnedByKernel;
  rgb_pipes_[1].state = kPipeStateOwnedByKernel;

  error = Scalar::CreateScalar(&scalar_);
  if (error != kErrorNone) {
    DLOGE("Failed to create Scalar object!");
  }

  max_system_bw_ = FLOAT(hw_res_info_.max_bandwidth_high);
  return error;
}

DisplayError ResManager::Deinit() {
  Scalar::Destroy(scalar_);
  return kErrorNone;
}

DisplayError ResManager::RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
                                         const HWPanelInfo &hw_panel_info, Handle *display_ctx) {
  DisplayError error = kErrorNone;

  HWBlockType hw_block_id = kHWBlockMax;
  switch (type) {
  case kPrimary:
    if (!hw_block_ctx_[kHWPrimary].is_in_use) {
      hw_block_id = kHWPrimary;
    }
    break;

  case kHDMI:
    if (!hw_block_ctx_[kHWHDMI].is_in_use) {
      hw_block_id = kHWHDMI;
    }
    break;

  case kVirtual:
    // TODO(user): read this block id from kernel
    virtual_count_++;
    hw_block_id = kHWWriteback2;
    break;

  default:
    DLOGW("RegisterDisplay, invalid type %d", type);
    return kErrorParameters;
  }

  if (hw_block_id == kHWBlockMax) {
    return kErrorResources;
  }

  DisplayResourceContext *display_resource_ctx = new DisplayResourceContext();
  if (!display_resource_ctx) {
    return kErrorMemory;
  }

  display_resource_ctx->hw_panel_info_ = hw_panel_info;
  hw_block_ctx_[hw_block_id].is_in_use = true;

  display_resource_ctx->display_attributes = attributes;
  display_resource_ctx->display_type = type;
  display_resource_ctx->hw_block_id = hw_block_id;
  if (!display_resource_ctx->display_attributes.is_device_split)
    display_resource_ctx->display_attributes.split_left =
      display_resource_ctx->display_attributes.x_pixels;

  display_resource_ctx->max_mixer_stages = hw_res_info_.num_blending_stages;

  *display_ctx = display_resource_ctx;
  return error;
}

DisplayError ResManager::UnregisterDisplay(Handle display_ctx) {
  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);

  if (display_resource_ctx->hw_block_id == kHWWriteback2) {
    virtual_count_--;
    if (!virtual_count_)
      hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
  } else {
    hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
  }

  if (!hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use)
    Purge(display_ctx);

  delete display_resource_ctx;

  return kErrorNone;
}

void ResManager::ReconfigureDisplay(Handle display_ctx, const HWDisplayAttributes &attributes,
                                    const HWPanelInfo &hw_panel_info) {
  SCOPE_LOCK(locker_);

  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);

  display_resource_ctx->display_attributes = attributes;
  display_resource_ctx->hw_panel_info_ = hw_panel_info;
}

DisplayError ResManager::Start(Handle display_ctx) {
  locker_.Lock();

  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);

  if (display_resource_ctx->frame_start) {
    return kErrorNone;  // keep context locked.
  }

  // First call in the cycle
  display_resource_ctx->frame_start = true;
  display_resource_ctx->frame_count++;

  // Release the pipes not used in the previous cycle
  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
  for (uint32_t i = 0; i < num_pipe_; i++) {
    if ((src_pipes_[i].hw_block_id == hw_block_id) &&
        (src_pipes_[i].state == kPipeStateToRelease)) {
      src_pipes_[i].state = kPipeStateIdle;
    }
  }

  // Clear rotator usage
  for (uint32_t i = 0; i < hw_res_info_.num_rotator; i++) {
    uint32_t pipe_index;
    pipe_index = rotators_[i].pipe_index;
    rotators_[i].ClearState(display_resource_ctx->hw_block_id);
    if (rotators_[i].client_bit_mask == 0 &&
        src_pipes_[pipe_index].state == kPipeStateToRelease &&
        src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id) {
      src_pipes_[pipe_index].dedicated_hw_block = kHWBlockMax;
      src_pipes_[pipe_index].state = kPipeStateIdle;
    }
  }

  property_setting_.disable_rotator_downscaling = Debug::IsRotatorDownScaleDisabled();
  property_setting_.disable_decimation = Debug::IsDecimationDisabled();

  return kErrorNone;
}

DisplayError ResManager::Stop(Handle display_ctx) {
  locker_.Unlock();

  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);

  return kErrorNone;
}

DisplayError ResManager::Acquire(Handle display_ctx, HWLayers *hw_layers) {
  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);

  DisplayError error = kErrorNone;
  const struct HWLayersInfo &layer_info = hw_layers->info;
  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;

  DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);

  if (layer_info.count > num_pipe_) {
    DLOGV_IF(kTagResources, "layer count exceeds pipe limit of %d, layer count %d", num_pipe_,
             layer_info.count);
    return kErrorResources;
  }

  if (layer_info.count > display_resource_ctx->max_mixer_stages) {
    DLOGV_IF(kTagResources, "layer count exceeds max mixer stage limit of %d, layer count %d",
             display_resource_ctx->max_mixer_stages, layer_info.count);
    return kErrorResources;
  }

  uint32_t rotate_count = 0;
  error = Config(display_resource_ctx, hw_layers, &rotate_count);
  if (error != kErrorNone) {
    DLOGV_IF(kTagResources, "Resource config failed");
    return error;
  }

  uint32_t left_index = kPipeIdMax;
  bool need_scale = false;
  HWBlockType rotator_block = kHWBlockMax;

  // Clear reserved marking
  for (uint32_t i = 0; i < num_pipe_; i++) {
    if (src_pipes_[i].reserved_hw_block == hw_block_id)
      src_pipes_[i].reserved_hw_block = kHWBlockMax;
  }

  // allocate rotator
  error = AcquireRotator(display_resource_ctx, rotate_count);
  if (error != kErrorNone) {
    return error;
  }

  rotate_count = 0;
  for (uint32_t i = 0; i < layer_info.count; i++) {
    Layer &layer = layer_info.stack->layers[layer_info.index[i]];
    struct HWLayerConfig &layer_config = hw_layers->config[i];
    HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
    bool use_non_dma_pipe = layer_config.use_non_dma_pipe;

    // TODO(user): set this from comp_manager
    if (hw_block_id == kHWPrimary) {
      use_non_dma_pipe = true;
    }

    for (uint32_t j = 0; j < hw_rotator_session.hw_block_count; j++) {
      AssignRotator(&hw_rotator_session.hw_rotate_info[j], &rotate_count);
    }

    HWPipeInfo *pipe_info = &layer_config.left_pipe;

    bool is_yuv = !IS_RGB_FORMAT(layer.input_buffer->format);

    // left pipe is needed
    if (pipe_info->valid) {
      need_scale = IsScalingNeeded(pipe_info);
      left_index = GetPipe(hw_block_id, is_yuv, need_scale, false, use_non_dma_pipe);
      if (left_index >= num_pipe_) {
        DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, is_yuv = %d, " \
                 "need_scale = %d, use_non_dma_pipe= %d",
                 hw_block_id, is_yuv, need_scale, use_non_dma_pipe);
        ResourceStateLog();
        goto CleanupOnError;
      }
      src_pipes_[left_index].reserved_hw_block = hw_block_id;
    }

    error = SetDecimationFactor(pipe_info);
    if (error != kErrorNone) {
      goto CleanupOnError;
    }

    pipe_info =  &layer_config.right_pipe;
    if (!pipe_info->valid) {
      // assign single pipe
      if (left_index < num_pipe_) {
        layer_config.left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
        src_pipes_[left_index].at_right = false;
      }
      DLOGV_IF(kTagResources, "1 pipe acquired, layer index = %d, left_pipe = %x",
               i, layer_config.left_pipe.pipe_id);
      continue;
    }

    need_scale = IsScalingNeeded(pipe_info);

    uint32_t right_index;
    right_index = GetPipe(hw_block_id, is_yuv, need_scale, true, use_non_dma_pipe);
    if (right_index >= num_pipe_) {
      DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, is_yuv = %d, " \
               "need_scale = %d, use_non_dma_pipe= %d",
               hw_block_id, is_yuv, need_scale, use_non_dma_pipe);
      ResourceStateLog();
      goto CleanupOnError;
    }

    if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) {
      // Swap pipe based on priority
      Swap(left_index, right_index);
    }

    // assign dual pipes
    pipe_info->pipe_id = src_pipes_[right_index].mdss_pipe_id;
    src_pipes_[right_index].reserved_hw_block = hw_block_id;
    src_pipes_[right_index].at_right = true;
    src_pipes_[left_index].reserved_hw_block = hw_block_id;
    src_pipes_[left_index].at_right = false;
    layer_config.left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
    error = SetDecimationFactor(pipe_info);
    if (error != kErrorNone) {
      goto CleanupOnError;
    }

    DLOGV_IF(kTagResources, "2 pipes acquired, layer index = %d, left_pipe = %x, right_pipe = %x",
             i, layer_config.left_pipe.pipe_id,  pipe_info->pipe_id);
  }

  if (scalar_->ConfigureScale(hw_layers) != kErrorNone) {
    DLOGV_IF(kTagResources, "Scale data configuration has failed!");
    goto CleanupOnError;
  }

  if (!CheckBandwidth(display_resource_ctx, hw_layers)) {
    DLOGV_IF(kTagResources, "Bandwidth check failed!");
    goto CleanupOnError;
  }

  return kErrorNone;

CleanupOnError:
  DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id);
  for (uint32_t i = 0; i < num_pipe_; i++) {
    if (src_pipes_[i].reserved_hw_block == hw_block_id)
      src_pipes_[i].reserved_hw_block = kHWBlockMax;
  }
  return kErrorResources;
}

bool ResManager::CheckBandwidth(DisplayResourceContext *display_ctx, HWLayers *hw_layers) {
  // No need to check bandwidth for virtual displays
  if (display_ctx->display_type == kVirtual) {
    return true;
  }

  float max_pipe_bw = FLOAT(hw_res_info_.max_pipe_bw) / 1000000;  // KBps to GBps
  float max_sde_clk = FLOAT(hw_res_info_.max_sde_clk) / 1000000;  // Hz to MHz
  const struct HWLayersInfo &layer_info = hw_layers->info;

  float left_pipe_bw[kMaxSDELayers] = {0};
  float right_pipe_bw[kMaxSDELayers] = {0};
  float left_max_clk = 0;
  float right_max_clk = 0;

  for (uint32_t i = 0; i < layer_info.count; i++) {
    Layer &layer = layer_info.stack->layers[layer_info.index[i]];
    float bpp = GetBpp(layer.input_buffer->format);
    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;

    left_pipe_bw[i] = left_pipe->valid ? GetPipeBw(display_ctx, left_pipe, bpp) : 0;
    right_pipe_bw[i] = right_pipe->valid ? GetPipeBw(display_ctx, right_pipe, bpp) : 0;

    if ((left_pipe_bw[i] > max_pipe_bw) || (right_pipe_bw[i] > max_pipe_bw)) {
      DLOGV_IF(kTagResources, "Pipe bandwidth exceeds limit for layer index=%d !" \
               " left_pipe_bw=%f, right_pipe_bw=%f, max_pipe_bw=%f",
               i, left_pipe_bw[i], right_pipe_bw[i], max_pipe_bw);
      return false;
    }

    float left_clk = left_pipe->valid ? GetClockForPipe(display_ctx, left_pipe) : 0;
    float right_clk = right_pipe->valid ? GetClockForPipe(display_ctx, right_pipe) : 0;

    left_max_clk = MAX(left_clk, left_max_clk);
    right_max_clk = MAX(right_clk, right_max_clk);
  }

  float left_mixer_bw = GetOverlapBw(hw_layers, left_pipe_bw, true);
  float right_mixer_bw = GetOverlapBw(hw_layers, right_pipe_bw, false);
  float display_bw = left_mixer_bw + right_mixer_bw;

  // Check system bandwidth (nth External + max(nth, n-1th) Primary)
  if (display_ctx->hw_block_id == kHWPrimary) {
    display_bw = MAX(display_bw, last_primary_bw_);
    last_primary_bw_ = left_mixer_bw + right_mixer_bw;
  }

  // If system has Video mode panel, then bw limit is max_bandwidth_low
  if (display_ctx->hw_panel_info_.mode == kModeVideo) {
    max_system_bw_ = FLOAT(hw_res_info_.max_bandwidth_low);
  }

  if ((display_bw + bw_claimed_) > (max_system_bw_ / 1000000)) {
    DLOGV_IF(kTagResources, "Overlap bandwidth: %f exceeds system limit: %f (GBps)!",
             (display_bw + bw_claimed_), (max_system_bw_ / 1000000));
    return false;
  }

  // Max clock requirement of display
  float display_clk = MAX(left_max_clk, right_max_clk);

  // Check max clock requirement of system
  float system_clk = MAX(display_clk, clk_claimed_);

  // Apply fudge factor to consider in-efficieny
  if ((system_clk * hw_res_info_.clk_fudge_factor) > max_sde_clk) {
    DLOGV_IF(kTagResources, "Clock requirement: %f exceeds system limit: %f (MHz)!",
             (system_clk * hw_res_info_.clk_fudge_factor), max_sde_clk);
    return false;
  }

  // If Primary display, reset claimed bw & clk for next cycle
  if (display_ctx->hw_block_id == kHWPrimary) {
    bw_claimed_ = 0.0f;
    clk_claimed_ = 0.0f;
  } else {
    bw_claimed_ = display_bw;
    clk_claimed_ = display_clk;
  }

  return true;
}

float ResManager::GetPipeBw(DisplayResourceContext *display_ctx, HWPipeInfo *pipe, float bpp) {
  HWDisplayAttributes &display_attributes = display_ctx->display_attributes;
  float src_w = pipe->src_roi.right - pipe->src_roi.left;
  float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
  float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;

  // Adjust src_h with pipe decimation
  float decimation = powf(2.0f, pipe->vertical_decimation);
  src_h /= decimation;

  float bw = src_w * src_h * bpp * FLOAT(display_attributes.fps);

  // Consider panel dimension
  // (v_total / v_active) * (v_active / dst_h)
  bw *= FLOAT(display_attributes.v_total) / dst_h;

  // Bandwidth is the rate at which data needs to be fetched from source to MDP (bytes/time).
  // On Video mode panel, there is no transfer of data from MDP to panel in horizontal blanking
  // time (hBP + hFP + hPW). So MDP gets this extra time to fetch data from source. But on the
  // Command mode panel, data gets transferred from MDP to panel during blanking time as well,
  // which means MDP needs to fetch the data faster. So pipe bandwidth needs to be adjusted.
  if (display_ctx->hw_panel_info_.mode == kModeCommand) {
    uint32_t h_total = display_attributes.h_total;
    uint32_t h_active = display_attributes.x_pixels;
    // On split-panel device, h_active is left split
    if (display_attributes.is_device_split) {
      uint32_t h_blanking = (h_total - h_active) / 2;
      h_active = display_attributes.split_left;
      h_total = h_active + h_blanking;
    }
    bw *= FLOAT(h_total) / FLOAT(h_active);
  }

  // Bandwidth in GBps
  return (bw / 1000000000.0f);
}

float ResManager::GetClockForPipe(DisplayResourceContext *display_ctx, HWPipeInfo *pipe) {
  HWDisplayAttributes &display_attributes = display_ctx->display_attributes;
  float v_total = FLOAT(display_attributes.v_total);
  float fps = FLOAT(display_attributes.fps);

  float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
  float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
  float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;

  // Adjust src_h with pipe decimation
  float decimation = powf(2.0f, pipe->vertical_decimation);
  src_h /= decimation;


  // SDE Clock requirement in MHz
  float clk = (dst_w * v_total * fps) / 1000000.0f;

  // Consider down-scaling
  if (src_h > dst_h)
    clk *= (src_h / dst_h);

  return clk;
}

float ResManager::GetOverlapBw(HWLayers *hw_layers, float *pipe_bw, bool left_mixer) {
  uint32_t count = hw_layers->info.count;
  float overlap_bw[count][count];
  float overall_max = 0;

  memset(overlap_bw, 0, sizeof(overlap_bw));

  // Algorithm:
  // 1.Create an 'n' by 'n' sized 2D array, overlap_bw[n][n] (n = # of layers).
  // 2.Get overlap_bw between two layers, i and j, and account for other overlaps (prev_max) if any.
  //   This will fill the bottom-left half of the array including diagonal (0 <= i < n, 0 <= j <= i)
  //                      {1. pipe_bw[i],                         where i == j
  //   overlap_bw[i][j] = {2. 0,                                  where i != j && !Overlap(i, j)
  //                      {3. pipe_bw[i] + pipe_bw[j] + prev_max, where i != j && Overlap(i, j)
  //
  //   Overlap(i, j) = !(bottom_i <= top_j || top_i >= bottom_j)
  //   prev_max = max(prev_max, overlap_bw[j, k]), where 0 <= k < j and prev_max initially 0
  //   prev_max = prev_max ? (prev_max - pipe_bw[j]) : 0; (to account for "double counting")
  // 3.Get the max value in 2D array, overlap_bw[n][n], for the final overall_max bandwidth.
  //   overall_max = max(overlap_bw[i, j]), where 0 <= i < n, 0 <= j <= i

  for (uint32_t i = 0; i < count; i++) {
    HWPipeInfo &pipe1 = left_mixer ? hw_layers->config[i].left_pipe :
                        hw_layers->config[i].right_pipe;

    // Non existing pipe never overlaps
    if (pipe_bw[i] == 0)
      continue;

    float top1 = pipe1.dst_roi.top;
    float bottom1 = pipe1.dst_roi.bottom;
    float row_max = 0;

    for (uint32_t j = 0; j <= i; j++) {
      HWPipeInfo &pipe2 = left_mixer ? hw_layers->config[j].left_pipe :
                          hw_layers->config[j].right_pipe;

      if ((pipe_bw[j] == 0) || (i == j)) {
        overlap_bw[i][j] = pipe_bw[j];
        row_max = MAX(pipe_bw[j], row_max);
        continue;
      }

      float top2 = pipe2.dst_roi.top;
      float bottom2 = pipe2.dst_roi.bottom;

      if ((bottom1 <= top2) || (top1 >= bottom2)) {
        overlap_bw[i][j] = 0;
        continue;
      }

      overlap_bw[i][j] = pipe_bw[i] + pipe_bw[j];

      float prev_max = 0;
      for (uint32_t k = 0; k < j; k++) {
        if (overlap_bw[j][k])
          prev_max = MAX(overlap_bw[j][k], prev_max);
      }
      overlap_bw[i][j] += (prev_max > 0) ? (prev_max - pipe_bw[j]) : 0;
      row_max = MAX(overlap_bw[i][j], row_max);
    }

    overall_max = MAX(row_max, overall_max);
  }

  return overall_max;
}

float ResManager::GetBpp(LayerBufferFormat format) {
  switch (format) {
    case kFormatARGB8888:
    case kFormatRGBA8888:
    case kFormatBGRA8888:
    case kFormatXRGB8888:
    case kFormatRGBX8888:
    case kFormatBGRX8888:
    case kFormatRGBA8888Ubwc:
    case kFormatRGBX8888Ubwc:
      return 4.0f;
    case kFormatRGB888:
    case kFormatBGR888:
      return 3.0f;
    case kFormatRGB565:
    case kFormatRGBA5551:
    case kFormatRGBA4444:
    case kFormatRGB565Ubwc:
    case kFormatYCbCr422H2V1Packed:
    case kFormatYCrCb422H2V1SemiPlanar:
    case kFormatYCrCb422H1V2SemiPlanar:
    case kFormatYCbCr422H2V1SemiPlanar:
    case kFormatYCbCr422H1V2SemiPlanar:
      return 2.0f;
    case kFormatYCbCr420Planar:
    case kFormatYCrCb420Planar:
    case kFormatYCbCr420SemiPlanar:
    case kFormatYCrCb420SemiPlanar:
    case kFormatYCbCr420SemiPlanarVenus:
    case kFormatYCbCr420SPVenusUbwc:
      return 1.5f;
    default:
      DLOGE("GetBpp: Invalid buffer format: %x", format);
      return 0.0f;
  }
}

DisplayError ResManager::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
  SCOPE_LOCK(locker_);

  return kErrorNone;
}

DisplayError ResManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
  SCOPE_LOCK(locker_);
  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
  uint64_t frame_count = display_resource_ctx->frame_count;
  DisplayError error = kErrorNone;

  DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %d", hw_block_id, frame_count);

  for (uint32_t i = 0; i < num_pipe_; i++) {
    if (src_pipes_[i].reserved_hw_block == hw_block_id) {
      src_pipes_[i].hw_block_id = hw_block_id;
      src_pipes_[i].state = kPipeStateAcquired;
      src_pipes_[i].state_frame_count = frame_count;
      DLOGV_IF(kTagResources, "Pipe acquired index = %d, type = %d, pipe_id = %x", i,
               src_pipes_[i].type, src_pipes_[i].mdss_pipe_id);
    } else if ((src_pipes_[i].hw_block_id == hw_block_id) &&
               (src_pipes_[i].state == kPipeStateAcquired)) {
      src_pipes_[i].state = kPipeStateToRelease;
      src_pipes_[i].state_frame_count = frame_count;
      DLOGV_IF(kTagResources, "Pipe to release index = %d, type = %d, pipe_id = %x", i,
               src_pipes_[i].type, src_pipes_[i].mdss_pipe_id);
    }
  }

  // handoff pipes which are used by splash screen
  if ((frame_count == 1) && (hw_block_id == kHWPrimary)) {
    for (uint32_t i = 0; i < num_pipe_; i++) {
      if ((src_pipes_[i].state == kPipeStateOwnedByKernel)) {
        src_pipes_[i].state = kPipeStateToRelease;
        src_pipes_[i].hw_block_id = kHWPrimary;
      }
    }
  }
  // set rotator pipes
  for (uint32_t i = 0; i < hw_res_info_.num_rotator; i++) {
    uint32_t pipe_index = rotators_[i].pipe_index;

    if (IS_BIT_SET(rotators_[i].client_bit_mask, hw_block_id)) {
      src_pipes_[pipe_index].hw_block_id = rotators_[i].writeback_id;
      src_pipes_[pipe_index].state = kPipeStateAcquired;
    } else if (!rotators_[i].client_bit_mask &&
               src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id &&
               src_pipes_[pipe_index].state == kPipeStateAcquired) {
      src_pipes_[pipe_index].state = kPipeStateToRelease;
      src_pipes_[pipe_index].state_frame_count = frame_count;
    }
    // If no request on the rotation, release the pipe.
    if (!rotators_[i].request_bit_mask) {
      src_pipes_[pipe_index].dedicated_hw_block = kHWBlockMax;
    }
  }
  display_resource_ctx->frame_start = false;

  return kErrorNone;
}

void ResManager::Purge(Handle display_ctx) {
  SCOPE_LOCK(locker_);

  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);
  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;

  for (uint32_t i = 0; i < num_pipe_; i++) {
    if (src_pipes_[i].hw_block_id == hw_block_id)
      src_pipes_[i].ResetState();
  }
  ClearRotator(display_resource_ctx);
  DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
}

DisplayError ResManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
  SCOPE_LOCK(locker_);

  if (max_mixer_stages < 1 || max_mixer_stages > hw_res_info_.num_blending_stages) {
    DLOGE("Max mixer stages = %d and that should be in between 1 to %d", max_mixer_stages,
          hw_res_info_.num_blending_stages);

    return kErrorParameters;
  }

  DisplayResourceContext *display_resource_ctx =
                          reinterpret_cast<DisplayResourceContext *>(display_ctx);

  if (display_resource_ctx) {
    display_resource_ctx->max_mixer_stages = max_mixer_stages;
  }

  return kErrorNone;
}

uint32_t ResManager::GetMdssPipeId(PipeType type, uint32_t index) {
  uint32_t mdss_id = kPipeIdMax;
  switch (type) {
  case kPipeTypeVIG:
    if (index < 3) {
      mdss_id = kPipeIdVIG0 + index;
    } else if (index == 3) {
      mdss_id = kPipeIdVIG3;
    } else {
      DLOGE("vig pipe index is over the limit! %d", index);
    }
    break;
  case kPipeTypeRGB:
    if (index < 3) {
      mdss_id = kPipeIdRGB0 + index;
    } else if (index == 3) {
      mdss_id = kPipeIdRGB3;
    } else {
      DLOGE("rgb pipe index is over the limit! %d", index);
    }
    break;
  case kPipeTypeDMA:
    if (index < 2) {
      mdss_id = kPipeIdDMA0 + index;
    } else {
      DLOGE("dma pipe index is over the limit! %d", index);
    }
    break;
  default:
    DLOGE("wrong pipe type! %d", type);
    break;
  }

  return (1 << mdss_id);
}

uint32_t ResManager::SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes,
                                uint32_t num_pipe, bool at_right) {
  uint32_t index = kPipeIdMax;
  SourcePipe *src_pipe;
  HWBlockType dedicated_block;

  // search dedicated idle pipes
  for (uint32_t i = 0; i < num_pipe; i++) {
    src_pipe = &src_pipes[i];
    if (src_pipe->reserved_hw_block == kHWBlockMax &&
        src_pipe->state == kPipeStateIdle &&
        src_pipe->dedicated_hw_block == hw_block_id) {
      index = src_pipe->index;
      break;
    }
  }

  // found
  if (index < num_pipe_) {
    return index;
  }

  // search the pipe being used
  for (uint32_t i = 0; i < num_pipe; i++) {
    src_pipe = &src_pipes[i];
    dedicated_block = src_pipe->dedicated_hw_block;
    if (src_pipe->reserved_hw_block == kHWBlockMax &&
        (src_pipe->state == kPipeStateAcquired) &&
        (src_pipe->hw_block_id == hw_block_id) &&
        (src_pipe->at_right == at_right) &&
        (dedicated_block == hw_block_id || dedicated_block == kHWBlockMax)) {
      index = src_pipe->index;
      break;
    }
  }

  // found
  if (index < num_pipe_) {
    return index;
  }

  // search the pipes idle or being used but not at the same side
  for (uint32_t i = 0; i < num_pipe; i++) {
    src_pipe = &src_pipes[i];
    dedicated_block = src_pipe->dedicated_hw_block;
    if (src_pipe->reserved_hw_block == kHWBlockMax &&
        ((src_pipe->state == kPipeStateIdle) ||
         (src_pipe->state == kPipeStateAcquired && src_pipe->hw_block_id == hw_block_id)) &&
         (dedicated_block == hw_block_id || dedicated_block == kHWBlockMax)) {
      index = src_pipe->index;
      break;
    }
  }
  return index;
}

uint32_t ResManager::NextPipe(PipeType type, HWBlockType hw_block_id, bool at_right) {
  uint32_t num_pipe = 0;
  SourcePipe *src_pipes = NULL;

  switch (type) {
  case kPipeTypeVIG:
    src_pipes = vig_pipes_;
    num_pipe = hw_res_info_.num_vig_pipe;
    break;
  case kPipeTypeRGB:
    src_pipes = rgb_pipes_;
    num_pipe = hw_res_info_.num_rgb_pipe;
    break;
  case kPipeTypeDMA:
  default:
    src_pipes = dma_pipes_;
    num_pipe = hw_res_info_.num_dma_pipe;
    break;
  }

  return SearchPipe(hw_block_id, src_pipes, num_pipe, at_right);
}

uint32_t ResManager::GetPipe(HWBlockType hw_block_id, bool is_yuv, bool need_scale, bool at_right,
                             bool use_non_dma_pipe) {
  uint32_t index = kPipeIdMax;

  // The default behavior is to assume RGB and VG pipes have scalars
  if (is_yuv) {
    return NextPipe(kPipeTypeVIG, hw_block_id, at_right);
  } else {
    if (!need_scale && !use_non_dma_pipe) {
      index = NextPipe(kPipeTypeDMA, hw_block_id, at_right);
    }

    if ((index >= num_pipe_) && (!need_scale || !hw_res_info_.has_non_scalar_rgb)) {
      index = NextPipe(kPipeTypeRGB, hw_block_id, at_right);
    }

    if (index >= num_pipe_) {
      index = NextPipe(kPipeTypeVIG, hw_block_id, at_right);
    }
  }

  return index;
}

bool ResManager::IsScalingNeeded(const HWPipeInfo *pipe_info) {
  const LayerRect &src_roi = pipe_info->src_roi;
  const LayerRect &dst_roi = pipe_info->dst_roi;

  return ((dst_roi.right - dst_roi.left) != (src_roi.right - src_roi.left)) ||
          ((dst_roi.bottom - dst_roi.top) != (src_roi.bottom - src_roi.top));
}

void ResManager::AppendDump(char *buffer, uint32_t length) {
  SCOPE_LOCK(locker_);
  AppendString(buffer, length, "\nresource manager pipe state");
  uint32_t i;
  for (i = 0; i < num_pipe_; i++) {
    SourcePipe *src_pipe = &src_pipes_[i];
    AppendString(buffer, length,
                 "\nindex = %d, id = %x, reserved = %d, state = %d, hw_block = %d, dedicated = %d",
                 src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->reserved_hw_block,
                 src_pipe->state, src_pipe->hw_block_id, src_pipe->dedicated_hw_block);
  }

  for (i = 0; i < hw_res_info_.num_rotator; i++) {
    if (rotators_[i].client_bit_mask || rotators_[i].request_bit_mask) {
      AppendString(buffer, length,
                   "\nrotator = %d, pipe index = %x, client_bit_mask = %x, request_bit_mask = %x",
                   i, rotators_[i].pipe_index, rotators_[i].client_bit_mask,
                   rotators_[i].request_bit_mask);
    }
  }
}

void ResManager::ResourceStateLog() {
  DLOGV_IF(kTagResources, "==== resource manager pipe state ====");
  uint32_t i;
  for (i = 0; i < num_pipe_; i++) {
    SourcePipe *src_pipe = &src_pipes_[i];
    DLOGV_IF(kTagResources,
             "index = %d, id = %x, reserved = %d, state = %d, hw_block = %d, dedicated = %d",
             src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->reserved_hw_block,
             src_pipe->state, src_pipe->hw_block_id, src_pipe->dedicated_hw_block);
  }

  for (i = 0; i < hw_res_info_.num_rotator; i++) {
    if (rotators_[i].client_bit_mask || rotators_[i].request_bit_mask) {
      DLOGV_IF(kTagResources,
               "rotator = %d, pipe index = %x, client_bit_mask = %x, request_bit_mask = %x",
               i, rotators_[i].pipe_index, rotators_[i].client_bit_mask,
               rotators_[i].request_bit_mask);
    }
  }
}

DisplayError ResManager::AcquireRotator(DisplayResourceContext *display_resource_ctx,
                                        const uint32_t rotate_count) {
  if (rotate_count == 0)
    return kErrorNone;
  if (hw_res_info_.num_rotator == 0) {
    DLOGV_IF(kTagResources, "Rotator hardware is not available");
    return kErrorResources;
  }

  uint32_t i, j, pipe_index, num_rotator;
  if (rotate_count > hw_res_info_.num_rotator)
    num_rotator = hw_res_info_.num_rotator;
  else
    num_rotator = rotate_count;

  for (i = 0; i < num_rotator; i++) {
    uint32_t rotate_pipe_index = rotators_[i].pipe_index;
    SourcePipe *src_pipe = &src_pipes_[rotate_pipe_index];

    if (src_pipe->dedicated_hw_block != kHWBlockMax)
      DLOGV_IF(kTagResources, "Overwrite dedicated block %d", src_pipe->dedicated_hw_block);
    src_pipe->dedicated_hw_block = rotators_[i].writeback_id;
    SET_BIT(rotators_[i].request_bit_mask, display_resource_ctx->hw_block_id);
  }

  for (i = 0; i < num_rotator; i++) {
    uint32_t rotate_pipe_index = rotators_[i].pipe_index;
    if (src_pipes_[rotate_pipe_index].reserved_hw_block != kHWBlockMax) {
      DLOGV_IF(kTagResources, "pipe %x is reserved by block:%d",
               src_pipes_[rotate_pipe_index].mdss_pipe_id,
               src_pipes_[rotate_pipe_index].reserved_hw_block);
      return kErrorResources;
    }
    pipe_index = SearchPipe(rotators_[i].writeback_id, &src_pipes_[rotate_pipe_index], 1, false);
    if (pipe_index >= num_pipe_) {
      DLOGV_IF(kTagResources, "pipe %x is not ready for rotator",
               src_pipes_[rotate_pipe_index].mdss_pipe_id);
      return kErrorResources;
    }
  }

  for (i = 0; i < num_rotator; i++)
    SET_BIT(rotators_[i].client_bit_mask, display_resource_ctx->hw_block_id);

  return kErrorNone;
}

void ResManager::AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_count) {
  if (!rotate->valid)
    return;
  // Interleave rotator assignment
  if ((*rotate_count & 0x1) && (hw_res_info_.num_rotator > 1)) {
    rotate->pipe_id = src_pipes_[rotators_[1].pipe_index].mdss_pipe_id;
    rotate->writeback_id = rotators_[1].writeback_id;
  } else {
    rotate->pipe_id = src_pipes_[rotators_[0].pipe_index].mdss_pipe_id;
    rotate->writeback_id = rotators_[0].writeback_id;
  }
  (*rotate_count)++;
}

void ResManager::ClearRotator(DisplayResourceContext *display_resource_ctx) {
  for (uint32_t i = 0; i < hw_res_info_.num_rotator; i++) {
    uint32_t pipe_index;
    pipe_index = rotators_[i].pipe_index;
    rotators_[i].ClearState(display_resource_ctx->hw_block_id);
    if (rotators_[i].client_bit_mask)
      continue;

    if (src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id) {
      src_pipes_[pipe_index].ResetState();
    } else if (src_pipes_[pipe_index].dedicated_hw_block == rotators_[i].writeback_id) {
      src_pipes_[pipe_index].dedicated_hw_block = kHWBlockMax;
    }
  }
}

void ResManager::SetRotatorOutputFormat(const LayerBufferFormat &input_format,
                                        const bool &is_opaque, const bool &rot90,
                                        const bool &downscale, LayerBufferFormat *output_format) {
  // Initialize the output format with input format by default.
  *output_format = input_format;

  switch (input_format) {
  case kFormatARGB8888:
  case kFormatRGBA8888:
    if (is_opaque) {
      *output_format = kFormatRGB888;
    }
    break;
  case kFormatBGRA8888:
    if (is_opaque) {
      *output_format = kFormatBGR888;
    }
    break;
  case kFormatBGRX8888:
    *output_format = kFormatBGR888;
    break;
  case kFormatXRGB8888:
  case kFormatRGBX8888:
    *output_format = kFormatRGB888;
    break;
  case kFormatYCrCb420SemiPlanar:
  case kFormatYCbCr420SemiPlanar:
  case kFormatYCbCr420SemiPlanarVenus:
    *output_format = kFormatYCbCr420SemiPlanar;
    break;
  default:
    break;
  }

  if (downscale) {
    switch (input_format) {
    case kFormatRGBA8888Ubwc:
      *output_format = is_opaque ? kFormatRGB888 : kFormatRGBA8888;
      break;
    case kFormatRGBX8888Ubwc:
      *output_format = kFormatRGB888;
      break;
    case kFormatRGB565Ubwc:
      *output_format = kFormatRGB565;
      break;
    case kFormatYCbCr420SPVenusUbwc:
      *output_format = kFormatYCbCr420SemiPlanar;
      break;
    default:
      break;
    }
  } else {
    if (hw_res_info_.has_ubwc) {
      switch (input_format) {
      case kFormatRGBA8888:
        *output_format = kFormatRGBA8888Ubwc;
        break;
      case kFormatRGBX8888:
        *output_format = kFormatRGBX8888Ubwc;
        break;
      case kFormatRGB565:
        *output_format = kFormatRGB565Ubwc;
        break;
      case kFormatYCrCb420SemiPlanar:
      case kFormatYCbCr420SemiPlanar:
      case kFormatYCbCr420SemiPlanarVenus:
        *output_format = kFormatYCbCr420SPVenusUbwc;
        break;
      default:
        break;
      }
    }
  }

  if (rot90) {
    if (input_format == kFormatYCbCr422H2V1SemiPlanar) {
      *output_format = kFormatYCbCr422H1V2SemiPlanar;
    } else if (input_format == kFormatYCbCr422H1V2SemiPlanar) {
      *output_format = kFormatYCbCr422H2V1SemiPlanar;
    } else if (input_format == kFormatYCrCb422H2V1SemiPlanar) {
      *output_format = kFormatYCrCb422H1V2SemiPlanar;
    } else if (input_format == kFormatYCrCb422H1V2SemiPlanar) {
      *output_format = kFormatYCrCb422H2V1SemiPlanar;
    }
  }

  DLOGV_IF(kTagResources, "Input format = %x, Output format = %x, rot90 = %d, ubwc = %d,"
           "downscale = %d", input_format, *output_format, rot90, hw_res_info_.has_ubwc,
           downscale);

  return;
}

}  // namespace sde

