/*
* 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 <utils/rect.h>
#include <dlfcn.h>

#include "resource_default.h"

#define __CLASS__ "ResourceDefault"

namespace sdm {

ResourceDefault::ResourceDefault()
  : num_pipe_(0), vig_pipes_(NULL), rgb_pipes_(NULL), dma_pipes_(NULL) {
}

DisplayError ResourceDefault::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);

  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;
  }

  rgb_pipes_[0].owner = kPipeOwnerKernelMode;
  rgb_pipes_[1].owner = kPipeOwnerKernelMode;

  return error;
}

DisplayError ResourceDefault::Deinit() {
  return kErrorNone;
}

DisplayError ResourceDefault::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;

  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;
  }

  hw_block_ctx_[hw_block_id].is_in_use = true;

  display_resource_ctx->display_attributes = attributes;
  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 = attributes.x_pixels;
  }

  *display_ctx = display_resource_ctx;
  return error;
}

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

  hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;

  delete display_resource_ctx;

  return kErrorNone;
}

void ResourceDefault::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;
}

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

  return kErrorNone;
}

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

  return kErrorNone;
}

DisplayError ResourceDefault::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 > 1) {
    DLOGV_IF(kTagResources, "More than one FB layers");
    return kErrorResources;
  }

  Layer &layer = layer_info.stack->layers[layer_info.index[0]];

  if (layer.composition != kCompositionGPUTarget) {
    DLOGV_IF(kTagResources, "Not an FB layer");
    return kErrorParameters;
  }

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

  for (uint32_t i = 0; i < num_pipe_; i++) {
    if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
      src_pipes_[i].ResetState();
    }
  }

  uint32_t left_index = kPipeIdMax;
  uint32_t right_index = kPipeIdMax;
  bool need_scale = false;

  struct HWLayerConfig &layer_config = hw_layers->config[0];

  HWPipeInfo *left_pipe = &layer_config.left_pipe;
  HWPipeInfo *right_pipe = &layer_config.right_pipe;

  // left pipe is needed
  if (left_pipe->valid) {
    need_scale = IsScalingNeeded(left_pipe);
    left_index = GetPipe(hw_block_id, need_scale);
    if (left_index >= num_pipe_) {
      DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, need_scale = %d",
               hw_block_id, need_scale);
      ResourceStateLog();
      goto CleanupOnError;
    }
  }

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

  if (!right_pipe->valid) {
    // assign single pipe
    if (left_index < num_pipe_) {
      left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
    }
    DLOGV_IF(kTagResources, "1 pipe acquired for FB layer, left_pipe = %x", left_pipe->pipe_id);
    return kErrorNone;
  }

  need_scale = IsScalingNeeded(right_pipe);

  right_index = GetPipe(hw_block_id, need_scale);
  if (right_index >= num_pipe_) {
    DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id,
             need_scale);
    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
  left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
  right_pipe->pipe_id = src_pipes_[right_index].mdss_pipe_id;

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

  DLOGV_IF(kTagResources, "2 pipes acquired for FB layer, left_pipe = %x, right_pipe = %x",
           left_pipe->pipe_id,  right_pipe->pipe_id);

  return kErrorNone;

CleanupOnError:
  DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id);

  return kErrorResources;
}

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

  return kErrorNone;
}

DisplayError ResourceDefault::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);

  // handoff pipes which are used by splash screen
  if ((frame_count == 0) && (hw_block_id == kHWPrimary)) {
    for (uint32_t i = 0; i < num_pipe_; i++) {
      if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerKernelMode) {
        src_pipes_[i].owner = kPipeOwnerUserMode;
      }
    }
  }

  display_resource_ctx->frame_count++;

  return kErrorNone;
}

void ResourceDefault::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].owner == kPipeOwnerUserMode) {
      src_pipes_[i].ResetState();
    }
  }
  DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
}

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

  return kErrorNone;
}

uint32_t ResourceDefault::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 ResourceDefault::SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes,
                                uint32_t num_pipe) {
  uint32_t index = kPipeIdMax;
  SourcePipe *src_pipe;

  // search the pipe being used
  for (uint32_t i = 0; i < num_pipe; i++) {
    src_pipe = &src_pipes[i];
    if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_id == kHWBlockMax) {
      index = src_pipe->index;
      src_pipe->hw_block_id = hw_block_id;
      break;
    }
  }

  return index;
}

uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_id) {
  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);
}

uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_id, bool need_scale) {
  uint32_t index = kPipeIdMax;

  // The default behavior is to assume RGB and VG pipes have scalars
  if (!need_scale) {
    index = NextPipe(kPipeTypeDMA, hw_block_id);
  }

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

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

  return index;
}

bool ResourceDefault::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 ResourceDefault::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, hw_block = %d, owner = %s",
                 src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->hw_block_id,
                 (src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
  }
}

DisplayError ResourceDefault::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
                                        const LayerRect &src_rect, const LayerRect &dst_rect,
                                        HWLayerConfig *layer_config) {
  HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
  HWPipeInfo *left_pipe = &layer_config->left_pipe;
  HWPipeInfo *right_pipe = &layer_config->right_pipe;
  float src_width = src_rect.right - src_rect.left;
  float dst_width = dst_rect.right - dst_rect.left;
  float src_height = src_rect.bottom - src_rect.top;
  float dst_height = dst_rect.bottom - dst_rect.top;
  float left_mixer_width = FLOAT(display_attributes.split_left);

  // Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
  // For perf/power optimization, even if "always_src_split" is enabled, use 2 pipes only if:
  // Source width is greater than split_left (left_mixer_width)
  if ((src_width > hw_res_info_.max_pipe_width) || (dst_width > hw_res_info_.max_pipe_width) ||
      (display_resource_ctx->display_attributes.always_src_split && src_width > left_mixer_width)) {
    SplitRect(src_rect, dst_rect, &left_pipe->src_roi, &left_pipe->dst_roi, &right_pipe->src_roi,
              &right_pipe->dst_roi);
    left_pipe->valid = true;
    right_pipe->valid = true;
  } else {
    left_pipe->src_roi = src_rect;
    left_pipe->dst_roi = dst_rect;
    left_pipe->valid = true;
    right_pipe->Reset();
  }

  return kErrorNone;
}

DisplayError ResourceDefault::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
                                            const LayerRect &src_rect, const LayerRect &dst_rect,
                                            HWLayerConfig *layer_config) {
  HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;

  // for display split case
  HWPipeInfo *left_pipe = &layer_config->left_pipe;
  HWPipeInfo *right_pipe = &layer_config->right_pipe;
  LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;

  scissor_left.right = FLOAT(display_attributes.split_left);
  scissor_left.bottom = FLOAT(display_attributes.y_pixels);

  scissor_right.left = FLOAT(display_attributes.split_left);
  scissor_right.top = 0.0f;
  scissor_right.right = FLOAT(display_attributes.x_pixels);
  scissor_right.bottom = FLOAT(display_attributes.y_pixels);

  crop_left = src_rect;
  dst_left = dst_rect;
  crop_right = crop_left;
  dst_right = dst_left;

  bool crop_left_valid = CalculateCropRects(scissor_left, &crop_left, &dst_left);
  bool crop_right_valid = false;

  if (IsValid(scissor_right)) {
    crop_right_valid = CalculateCropRects(scissor_right, &crop_right, &dst_right);
  }

  // Reset left_pipe and right_pipe to invalid by default
  left_pipe->Reset();
  right_pipe->Reset();

  if (crop_left_valid) {
    // assign left pipe
    left_pipe->src_roi = crop_left;
    left_pipe->dst_roi = dst_left;
    left_pipe->valid = true;
  }

  // assign right pipe if needed
  if (crop_right_valid) {
    right_pipe->src_roi = crop_right;
    right_pipe->dst_roi = dst_right;
    right_pipe->valid = true;
  }

  return kErrorNone;
}

DisplayError ResourceDefault::Config(DisplayResourceContext *display_resource_ctx,
                                HWLayers *hw_layers) {
  HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
  HWLayersInfo &layer_info = hw_layers->info;
  DisplayError error = kErrorNone;
  uint32_t z_order = 0;

  Layer& layer = layer_info.stack->layers[layer_info.index[0]];

  error = ValidateLayerDimensions(layer);
  if (error != kErrorNone) {
    return error;
  }

  struct HWLayerConfig *layer_config = &hw_layers->config[0];
  HWPipeInfo &left_pipe = layer_config->left_pipe;
  HWPipeInfo &right_pipe = layer_config->right_pipe;

  LayerRect src_rect = layer.src_rect;
  LayerRect dst_rect = layer.dst_rect;

  error = ValidateDimensions(src_rect, dst_rect);
  if (error != kErrorNone) {
    return error;
  }

  error = ValidateScaling(src_rect, dst_rect, false);
  if (error != kErrorNone) {
    return error;
  }

  if (hw_res_info_.is_src_split) {
    error = SrcSplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
  } else {
    error = DisplaySplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
  }

  if (error != kErrorNone) {
    return error;
  }

  error = AlignPipeConfig(layer, &left_pipe, &right_pipe);
  if (error != kErrorNone) {
    return error;
  }

  // set z_order, left_pipe should always be valid
  left_pipe.z_order = 0;

  DLOGV_IF(kTagResources, "==== FB layer Config ====");
  Log(kTagResources, "input layer src_rect", layer.src_rect);
  Log(kTagResources, "input layer dst_rect", layer.dst_rect);
  Log(kTagResources, "cropped src_rect", src_rect);
  Log(kTagResources, "cropped dst_rect", dst_rect);
  Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
  Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
  if (right_pipe.valid) {
    right_pipe.z_order = 0;
    Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
    Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
  }

  return error;
}

bool ResourceDefault::CalculateCropRects(const LayerRect &scissor, LayerRect *crop,
                                         LayerRect *dst) {
  float &crop_left = crop->left;
  float &crop_top = crop->top;
  float &crop_right = crop->right;
  float &crop_bottom = crop->bottom;
  float crop_width = crop->right - crop->left;
  float crop_height = crop->bottom - crop->top;

  float &dst_left = dst->left;
  float &dst_top = dst->top;
  float &dst_right = dst->right;
  float &dst_bottom = dst->bottom;
  float dst_width = dst->right - dst->left;
  float dst_height = dst->bottom - dst->top;

  const float &sci_left = scissor.left;
  const float &sci_top = scissor.top;
  const float &sci_right = scissor.right;
  const float &sci_bottom = scissor.bottom;

  float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
  bool need_cut = false;

  if (dst_left < sci_left) {
    left_cut_ratio = (sci_left - dst_left) / dst_width;
    dst_left = sci_left;
    need_cut = true;
  }

  if (dst_right > sci_right) {
    right_cut_ratio = (dst_right - sci_right) / dst_width;
    dst_right = sci_right;
    need_cut = true;
  }

  if (dst_top < sci_top) {
    top_cut_ratio = (sci_top - dst_top) / (dst_height);
    dst_top = sci_top;
    need_cut = true;
  }

  if (dst_bottom > sci_bottom) {
    bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
    dst_bottom = sci_bottom;
    need_cut = true;
  }

  if (!need_cut)
    return true;

  crop_left += crop_width * left_cut_ratio;
  crop_top += crop_height * top_cut_ratio;
  crop_right -= crop_width * right_cut_ratio;
  crop_bottom -= crop_height * bottom_cut_ratio;
  Normalize(1, 1, crop);
  Normalize(1, 1, dst);
  if (IsValid(*crop) && IsValid(*dst))
    return true;
  else
    return false;
}

DisplayError ResourceDefault::ValidateLayerDimensions(const Layer &layer) {
  const LayerRect &src = layer.src_rect;
  const LayerRect &dst = layer.dst_rect;
  LayerBuffer *input_buffer = layer.input_buffer;

  if (!IsValid(src) || !IsValid(dst)) {
    Log(kTagResources, "input layer src_rect", src);
    Log(kTagResources, "input layer dst_rect", dst);
    return kErrorNotSupported;
  }

  // Make sure source in integral only if it is a non secure layer.
  if (!input_buffer->flags.secure && (src.left - roundf(src.left) || src.top - roundf(src.top) ||
      src.right - roundf(src.right) || src.bottom - roundf(src.bottom))) {
    DLOGV_IF(kTagResources, "Input ROI is not integral");
    return kErrorNotSupported;
  }

  return kErrorNone;
}

DisplayError ResourceDefault::ValidateDimensions(const LayerRect &crop, const LayerRect &dst) {
  if (!IsValid(crop)) {
    Log(kTagResources, "Invalid crop rect", crop);
    return kErrorNotSupported;
  }

  if (!IsValid(dst)) {
    Log(kTagResources, "Invalid dst rect", dst);
    return kErrorNotSupported;
  }

  float crop_width = crop.right - crop.left;
  float crop_height = crop.bottom - crop.top;
  float dst_width = dst.right - dst.left;
  float dst_height = dst.bottom - dst.top;

  if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
    DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
             "crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
    return kErrorNotSupported;
  }

  return kErrorNone;
}

DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info) {
  DisplayError error = kErrorNone;

  const LayerRect &src_rect = pipe_info->src_roi;
  const LayerRect &dst_rect = pipe_info->dst_roi;

  error = ValidateDimensions(src_rect, dst_rect);
  if (error != kErrorNone) {
    return error;
  }

  error = ValidateScaling(src_rect, dst_rect, false);
  if (error != kErrorNone) {
    return error;
  }

  return kErrorNone;
}

DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
                                         bool rotate90) {
  DisplayError error = kErrorNone;

  float scale_x = 1.0f;
  float scale_y = 1.0f;

  error = GetScaleFactor(crop, dst, &scale_x, &scale_y);
  if (error != kErrorNone) {
    return error;
  }

  error = ValidateDownScaling(scale_x, scale_y);
  if (error != kErrorNone) {
    return error;
  }

  error = ValidateUpScaling(scale_x, scale_y);
  if (error != kErrorNone) {
    return error;
  }

  return kErrorNone;
}

DisplayError ResourceDefault::ValidateDownScaling(float scale_x, float scale_y) {
  if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
    float max_scale_down = FLOAT(hw_res_info_.max_scale_down);

    if (hw_res_info_.has_decimation) {
      max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
    }

    if (scale_x > max_scale_down || scale_y > max_scale_down) {
      DLOGV_IF(kTagResources,
               "Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
               "has_deci = %d", scale_x, scale_y, hw_res_info_.has_decimation);
      return kErrorNotSupported;
    }
  }

  DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);

  return kErrorNone;
}

DisplayError ResourceDefault::ValidateUpScaling(float scale_x, float scale_y) {
  float max_scale_up = FLOAT(hw_res_info_.max_scale_up);

  if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
    if ((1.0f / scale_x) > max_scale_up) {
      DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
      return kErrorNotSupported;
    }
  }

  if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
    if ((1.0f / scale_y) > max_scale_up) {
      DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
      return kErrorNotSupported;
    }
  }

  DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);

  return kErrorNone;
}

DisplayError ResourceDefault::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
                                        float *scale_x, float *scale_y) {
  float crop_width = crop.right - crop.left;
  float crop_height = crop.bottom - crop.top;
  float dst_width = dst.right - dst.left;
  float dst_height = dst.bottom - dst.top;

  *scale_x = crop_width / dst_width;
  *scale_y = crop_height / dst_height;

  return kErrorNone;
}

DisplayError ResourceDefault::SetDecimationFactor(HWPipeInfo *pipe) {
  float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
  float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
  float down_scale_h = src_h / dst_h;

  float src_w = pipe->src_roi.right - pipe->src_roi.left;
  float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
  float down_scale_w = src_w / dst_w;

  pipe->horizontal_decimation = 0;
  pipe->vertical_decimation = 0;

  if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
    return kErrorNotSupported;
  }

  if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
    return kErrorNotSupported;
  }

  DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
           pipe->horizontal_decimation, pipe->vertical_decimation);

  return kErrorNone;
}

void ResourceDefault::SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect,
                           LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
                           LayerRect *dst_right) {
  // Split rectangle horizontally and evenly into two.
  float src_width = src_rect.right - src_rect.left;
  float dst_width = dst_rect.right - dst_rect.left;
  float src_width_ori = src_width;
  src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, 1);
  dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);

  src_left->left = src_rect.left;
  src_left->right = src_rect.left + src_width;
  src_right->left = src_left->right;
  src_right->right = src_rect.right;

  src_left->top = src_rect.top;
  src_left->bottom = src_rect.bottom;
  src_right->top = src_rect.top;
  src_right->bottom = src_rect.bottom;

  dst_left->top = dst_rect.top;
  dst_left->bottom = dst_rect.bottom;
  dst_right->top = dst_rect.top;
  dst_right->bottom = dst_rect.bottom;

  dst_left->left = dst_rect.left;
  dst_left->right = dst_rect.left + dst_width;
  dst_right->left = dst_left->right;
  dst_right->right = dst_rect.right;
}

DisplayError ResourceDefault::AlignPipeConfig(const Layer &layer, HWPipeInfo *left_pipe,
                                         HWPipeInfo *right_pipe) {
  DisplayError error = kErrorNone;
  if (!left_pipe->valid) {
    DLOGE_IF(kTagResources, "left_pipe should not be invalid");
    return kErrorNotSupported;
  }

  error = ValidatePipeParams(left_pipe);
  if (error != kErrorNone) {
    goto PipeConfigExit;
  }

  if (right_pipe->valid) {
    // Make sure the  left and right ROI are conjunct
    right_pipe->src_roi.left = left_pipe->src_roi.right;
    right_pipe->dst_roi.left = left_pipe->dst_roi.right;
    error = ValidatePipeParams(right_pipe);
  }

PipeConfigExit:
  if (error != kErrorNone) {
    DLOGV_IF(kTagResources, "AlignPipeConfig failed");
  }
  return error;
}

DisplayError ResourceDefault::CalculateDecimation(float downscale, uint8_t *decimation) {
  float max_down_scale = FLOAT(hw_res_info_.max_scale_down);

  if (downscale <= max_down_scale) {
    *decimation = 0;
    return kErrorNone;
  } else if (!hw_res_info_.has_decimation) {
    DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
    return kErrorNotSupported;
  }

  // Decimation is the remaining downscale factor after doing max SDE downscale.
  // In SDE, decimation is supported in powers of 2.
  // For ex: If a pipe needs downscale of 8 but max_down_scale is 4
  // So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
  *decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
  return kErrorNone;
}

}  // namespace sdm

