/*
 * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright 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.
 *
 * Changes from Qualcomm Innovation Center are provided under the following license:
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 */

/*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
*      contributors may be used to endorse or promote products derived
*      from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "hwc_layers.h"
#include <utils/debug.h>
#include <stdint.h>
#include <utility>
#include <cmath>
#include <gr_utils.h>

#define __CLASS__ "HWCLayer"
using aidl::android::hardware::graphics::common::StandardMetadataType;

namespace sdm {

std::atomic<hwc2_layer_t> HWCLayer::next_id_(1);

DisplayError SetCSC(const native_handle_t *handle, ColorMetaData *color_metadata) {
  void *hnd = const_cast<native_handle_t *>(handle);

  auto error =
      gralloc::GetMetaDataValue(hnd, qtigralloc::MetadataType_ColorMetadata.value, color_metadata);

  if (error != gralloc::Error::NONE) {
    int csc = HAL_CSC_ITU_R_601;
    error = gralloc::GetMetaDataValue(hnd, qtigralloc::MetadataType_ColorSpace.value, &csc);

    if (error == gralloc::Error::NONE) {
      if (csc == HAL_CSC_ITU_R_601_FR || csc == HAL_CSC_ITU_R_709_FR ||
          csc == HAL_CSC_ITU_R_2020_FR) {
        color_metadata->range = Range_Full;
      }
      color_metadata->transfer = Transfer_sRGB;

      switch (csc) {
        case HAL_CSC_ITU_R_601:
        case HAL_CSC_ITU_R_601_FR:
          // video and display driver uses 601_525
          color_metadata->colorPrimaries = ColorPrimaries_BT601_6_525;
          break;
        case HAL_CSC_ITU_R_709:
        case HAL_CSC_ITU_R_709_FR:
          color_metadata->colorPrimaries = ColorPrimaries_BT709_5;
          break;
        case HAL_CSC_ITU_R_2020:
        case HAL_CSC_ITU_R_2020_FR:
          color_metadata->colorPrimaries = ColorPrimaries_BT2020;
          break;
        default:
          DLOGE("Unsupported CSC: %d", csc);
          return kErrorNotSupported;
      }
    }
  }

  return kErrorNone;
}

// Returns true when color primary is supported
bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary) {
  auto standard = dataspace & HAL_DATASPACE_STANDARD_MASK;
  bool supported_csc = true;
  switch (standard) {
    case HAL_DATASPACE_STANDARD_BT709:
      *color_primary = ColorPrimaries_BT709_5;
      break;
    case HAL_DATASPACE_STANDARD_BT601_525:
    case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
      *color_primary = ColorPrimaries_BT601_6_525;
      break;
    case HAL_DATASPACE_STANDARD_BT601_625:
    case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
      *color_primary = ColorPrimaries_BT601_6_625;
      break;
    case HAL_DATASPACE_STANDARD_DCI_P3:
      *color_primary = ColorPrimaries_DCIP3;
      break;
    case HAL_DATASPACE_STANDARD_BT2020:
      *color_primary = ColorPrimaries_BT2020;
      break;
    default:
      DLOGW_IF(kTagClient, "Unsupported Standard Request = %d", standard);
      supported_csc = false;
  }
  return supported_csc;
}

bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer) {
  auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK;
  bool supported_transfer = true;
  switch (transfer) {
    case HAL_DATASPACE_TRANSFER_SRGB:
      *gamma_transfer = Transfer_sRGB;
      break;
    case HAL_DATASPACE_TRANSFER_SMPTE_170M:
      *gamma_transfer = Transfer_SMPTE_170M;
      break;
    case HAL_DATASPACE_TRANSFER_ST2084:
      *gamma_transfer = Transfer_SMPTE_ST2084;
      break;
    case HAL_DATASPACE_TRANSFER_HLG:
      *gamma_transfer = Transfer_HLG;
      break;
    case HAL_DATASPACE_TRANSFER_LINEAR:
      *gamma_transfer = Transfer_Linear;
      break;
    case HAL_DATASPACE_TRANSFER_GAMMA2_2:
      *gamma_transfer = Transfer_Gamma2_2;
      break;
    case HAL_DATASPACE_TRANSFER_GAMMA2_8:
      *gamma_transfer = Transfer_Gamma2_8;
      break;
    default:
      DLOGW_IF(kTagClient, "Unsupported Transfer Request = %d", transfer);
      supported_transfer = false;
  }
  return supported_transfer;
}

bool GetRange(const int32_t &dataspace, ColorRange *color_range) {
  auto range = dataspace & HAL_DATASPACE_RANGE_MASK;
  switch (range) {
    case HAL_DATASPACE_RANGE_FULL:
      *color_range = Range_Full;
      break;
    case HAL_DATASPACE_RANGE_LIMITED:
      *color_range = Range_Limited;
      break;
    case HAL_DATASPACE_RANGE_EXTENDED:
      *color_range = Range_Extended;
      break;
    default:
      DLOGW_IF(kTagClient, "Unsupported Range Request = %d", range);
      return false;
  }
  return true;
}

bool IsHdr(const ColorPrimaries &color_primary, const GammaTransfer &gamma_transfer) {
  return (color_primary == ColorPrimaries_BT2020) &&
         ((gamma_transfer == Transfer_SMPTE_ST2084) || (gamma_transfer == Transfer_HLG));
}

bool IsBT2020(const ColorPrimaries &color_primary) {
  switch (color_primary) {
    case ColorPrimaries_BT2020:
      return true;
      break;
    default:
      return false;
  }
}

int32_t TranslateFromLegacyDataspace(const int32_t &legacy_ds) {
  int32_t dataspace = legacy_ds;

  if (dataspace & 0xffff) {
    switch (dataspace & 0xffff) {
      case HAL_DATASPACE_SRGB:
        dataspace = HAL_DATASPACE_V0_SRGB;
        break;
      case HAL_DATASPACE_JFIF:
        dataspace = HAL_DATASPACE_V0_JFIF;
        break;
      case HAL_DATASPACE_SRGB_LINEAR:
        dataspace = HAL_DATASPACE_V0_SRGB_LINEAR;
        break;
      case HAL_DATASPACE_BT601_625:
        dataspace = HAL_DATASPACE_V0_BT601_625;
        break;
      case HAL_DATASPACE_BT601_525:
        dataspace = HAL_DATASPACE_V0_BT601_525;
        break;
      case HAL_DATASPACE_BT709:
        dataspace = HAL_DATASPACE_V0_BT709;
        break;
      default:
        // unknown legacy dataspace
        DLOGW_IF(kTagClient, "Unsupported dataspace type %d", dataspace);
    }
  }

  if (dataspace == HAL_DATASPACE_UNKNOWN) {
    dataspace = HAL_DATASPACE_V0_SRGB;
  }

  return dataspace;
}

// Retrieve ColorMetaData from android_data_space_t (STANDARD|TRANSFER|RANGE)
bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata) {
  bool valid = false;
  valid = GetColorPrimary(dataspace, &(color_metadata->colorPrimaries));
  if (valid) {
    valid = GetTransfer(dataspace, &(color_metadata->transfer));
  }
  if (valid) {
    valid = GetRange(dataspace, &(color_metadata->range));
  }

  return valid;
}

DisplayError ColorMetadataToDataspace(ColorMetaData color_metadata, Dataspace *dataspace) {
  Dataspace primaries, transfer, range = Dataspace::UNKNOWN;

  switch (color_metadata.colorPrimaries) {
    case ColorPrimaries_BT709_5:
      primaries = Dataspace::STANDARD_BT709;
      break;
    // TODO(user): verify this is equivalent
    case ColorPrimaries_BT470_6M:
      primaries = Dataspace::STANDARD_BT470M;
      break;
    case ColorPrimaries_BT601_6_625:
      primaries = Dataspace::STANDARD_BT601_625;
      break;
    case ColorPrimaries_BT601_6_525:
      primaries = Dataspace::STANDARD_BT601_525;
      break;
    case ColorPrimaries_GenericFilm:
      primaries = Dataspace::STANDARD_FILM;
      break;
    case ColorPrimaries_BT2020:
      primaries = Dataspace::STANDARD_BT2020;
      break;
    case ColorPrimaries_AdobeRGB:
      primaries = Dataspace::STANDARD_ADOBE_RGB;
      break;
    case ColorPrimaries_DCIP3:
      primaries = Dataspace::STANDARD_DCI_P3;
      break;
    default:
      return kErrorNotSupported;
      /*
       ColorPrimaries_SMPTE_240M;
       ColorPrimaries_SMPTE_ST428;
       ColorPrimaries_EBU3213;
      */
  }

  switch (color_metadata.transfer) {
    case Transfer_sRGB:
      transfer = Dataspace::TRANSFER_SRGB;
      break;
    case Transfer_Gamma2_2:
      transfer = Dataspace::TRANSFER_GAMMA2_2;
      break;
    case Transfer_Gamma2_8:
      transfer = Dataspace::TRANSFER_GAMMA2_8;
      break;
    case Transfer_SMPTE_170M:
      transfer = Dataspace::TRANSFER_SMPTE_170M;
      break;
    case Transfer_Linear:
      transfer = Dataspace::TRANSFER_LINEAR;
      break;
    case Transfer_SMPTE_ST2084:
      transfer = Dataspace::TRANSFER_ST2084;
      break;
    case Transfer_HLG:
      transfer = Dataspace::TRANSFER_HLG;
      break;
    default:
      return kErrorNotSupported;
      /*
      Transfer_SMPTE_240M
      Transfer_Log
      Transfer_Log_Sqrt
      Transfer_XvYCC
      Transfer_BT1361
      Transfer_sYCC
      Transfer_BT2020_2_1
      Transfer_BT2020_2_2
      Transfer_ST_428
      */
  }

  switch (color_metadata.range) {
    case Range_Full:
      range = Dataspace::RANGE_FULL;
      break;
    case Range_Limited:
      range = Dataspace::RANGE_LIMITED;
      break;
    case Range_Extended:
      range = Dataspace::RANGE_EXTENDED;
      break;
    default:
      return kErrorNotSupported;
  }

  *dataspace = (Dataspace)((uint32_t)primaries | (uint32_t)transfer | (uint32_t)range);
  return kErrorNone;
}

// Layer operations
HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator)
    : id_(next_id_++), display_id_(display_id), buffer_allocator_(buf_allocator) {
  layer_ = new Layer();
  geometry_changes_ |= kAdded;
}

HWCLayer::~HWCLayer() {
  // Close any fences left for this layer
  release_fence_ = nullptr;
  if (layer_) {
    if (buffer_fd_ >= 0) {
      ::close(buffer_fd_);
    }
    delete layer_;
  }
}

HWC2::Error HWCLayer::SetLayerBuffer(buffer_handle_t buffer, shared_ptr<Fence> acquire_fence) {
  if (!buffer) {
    if (client_requested_ == HWC2::Composition::Device ||
        client_requested_ == HWC2::Composition::Cursor) {
      DLOGW("Invalid buffer handle: %p on layer: %d client requested comp type %d", buffer,
            UINT32(id_), client_requested_);
      return HWC2::Error::BadParameter;
    } else {
      return HWC2::Error::None;
    }
  }

  const native_handle_t *handle = reinterpret_cast<const native_handle_t *>(buffer);
  void *hnd = const_cast<native_handle_t *>(handle);
  int fd;
  gralloc::GetMetaDataValue(hnd, qtigralloc::MetadataType_FD.value, &fd);

  if (fd < 0) {
    return HWC2::Error::BadParameter;
  }

  LayerBuffer *layer_buffer = &layer_->input_buffer;
  int aligned_width, aligned_height;
  buffer_allocator_->GetCustomWidthAndHeight(reinterpret_cast<const native_handle_t *>(buffer),
                                             &aligned_width, &aligned_height);
  int fmt, flag;
  gralloc::GetMetaDataValue(hnd, (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED, &fmt);
  gralloc::GetMetaDataValue(hnd, (int64_t)qtigralloc::MetadataType_PrivateFlags.value, &flag);
  LayerBufferFormat format = GetSDMFormat(fmt, flag);
  if ((format != layer_buffer->format) || (UINT32(aligned_width) != layer_buffer->width) ||
      (UINT32(aligned_height) != layer_buffer->height)) {
    // Layer buffer geometry has changed.
    geometry_changes_ |= kBufferGeometry;
  }

  layer_buffer->format = format;
  layer_buffer->width = UINT32(aligned_width);
  layer_buffer->height = UINT32(aligned_height);

  auto err_w = gralloc::GetMetaDataValue(hnd, (int64_t)StandardMetadataType::WIDTH,
                                         &layer_buffer->unaligned_width);
  if (err_w != gralloc::Error::NONE) {
    DLOGE("Failed to retrieve unaligned width");
  }
  auto err_h = gralloc::GetMetaDataValue(hnd, (int64_t)StandardMetadataType::HEIGHT,
                                         &layer_buffer->unaligned_height);
  if (err_h != gralloc::Error::NONE) {
    DLOGE("Failed to retrieve unaligned height");
  }
  int32_t buffer_type;
  gralloc::GetMetaDataValue(hnd, (int64_t)qtigralloc::MetadataType_BufferType.value, &buffer_type);

  layer_buffer->flags.video = (buffer_type == BUFFER_TYPE_VIDEO) ? true : false;
  if (SetMetaData(handle, layer_) != kErrorNone) {
    return HWC2::Error::BadLayer;
  }

  // TZ Protected Buffer - L1
  secure_ = (flag & qtigralloc::PRIV_FLAGS_SECURE_BUFFER);
  bool secure_camera = secure_ && (flag & qtigralloc::PRIV_FLAGS_CAMERA_WRITE);
  bool secure_display = (flag & qtigralloc::PRIV_FLAGS_SECURE_DISPLAY);
  if (secure_ != layer_buffer->flags.secure || secure_camera != layer_buffer->flags.secure_camera ||
      secure_display != layer_buffer->flags.secure_display) {
    // Secure attribute of layer buffer has changed.
    layer_->update_mask.set(kSecurity);
  }

  layer_buffer->flags.secure = secure_;
  layer_buffer->flags.secure_camera = secure_camera;
  layer_buffer->flags.secure_display = secure_display;

  layer_buffer->acquire_fence = acquire_fence;

  int buffer_fd = buffer_fd_;
  buffer_fd_ = ::dup(fd);
  if (buffer_fd >= 0) {
    ::close(buffer_fd);
  }

  layer_buffer->planes[0].fd = buffer_fd_;
  layer_buffer->planes[0].offset = 0;
  auto err =
      gralloc::GetMetaDataValue(hnd, QTI_ALIGNED_WIDTH_IN_PIXELS, &layer_buffer->planes[0].stride);
  if (err != gralloc::Error::NONE) {
    DLOGW("Failed to retrieve aligned width");
  }

  err = gralloc::GetMetaDataValue(hnd, (int64_t)StandardMetadataType::ALLOCATION_SIZE,
                                  &layer_buffer->size);

  if (err != gralloc::Error::NONE) {
    DLOGW("Failed to retrieve allocation size");
  }
  buffer_flipped_ = reinterpret_cast<uint64_t>(handle) != layer_buffer->buffer_id;
  layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
  int64_t hd_id, hd_usage;
  err = gralloc::GetMetaDataValue(hnd, (int64_t)StandardMetadataType::BUFFER_ID,
                                  &layer_buffer->handle_id);
  if (err != gralloc::Error::NONE) {
    DLOGW("Failed to retrieve buffer id");
  }
  err = gralloc::GetMetaDataValue(hnd, (int64_t)StandardMetadataType::USAGE, &layer_buffer->usage);
  if (err != gralloc::Error::NONE) {
    DLOGW("Failed to retrieve handle usage");
  }
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
  surface_updated_ = true;
  if ((damage.numRects == 1) && (damage.rects[0].bottom == 0) && (damage.rects[0].right == 0)) {
    surface_updated_ = false;
  }

  if (!layer_->flags.updating && surface_updated_) {
    layer_->update_mask.set(kSurfaceInvalidate);
  }

  // Check if there is an update in SurfaceDamage rects.
  if (layer_->dirty_regions.size() != damage.numRects) {
    layer_->update_mask.set(kSurfaceInvalidate);
  } else {
    for (uint32_t j = 0; j < damage.numRects; j++) {
      LayerRect damage_rect;
      SetRect(damage.rects[j], &damage_rect);
      if (damage_rect != layer_->dirty_regions.at(j)) {
        layer_->update_mask.set(kSurfaceDamage);
        break;
      }
    }
  }

  SetDirtyRegions(damage);
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerBlendMode(HWC2::BlendMode mode) {
  LayerBlending blending = kBlendingPremultiplied;
  switch (mode) {
    case HWC2::BlendMode::Coverage:
      blending = kBlendingCoverage;
      break;
    case HWC2::BlendMode::Premultiplied:
      blending = kBlendingPremultiplied;
      break;
    case HWC2::BlendMode::None:
      blending = kBlendingOpaque;
      break;
    default:
      return HWC2::Error::BadParameter;
  }

  if (layer_->blending != blending) {
    geometry_changes_ |= kBlendMode;
    layer_->blending = blending;
  }
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
  if (client_requested_ != HWC2::Composition::SolidColor) {
    return HWC2::Error::None;
  }
  if (layer_->solid_fill_color != GetUint32Color(color)) {
    layer_->solid_fill_color = GetUint32Color(color);
    layer_->update_mask.set(kSurfaceInvalidate);
    surface_updated_ = true;
  } else {
    surface_updated_ = false;
  }

  layer_->input_buffer.format = kFormatARGB8888;
  DLOGV_IF(kTagClient, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
           layer_->solid_fill_color);
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
  // Validation is required when the client changes the composition type
  if ((type != client_requested_) || (type != device_selected_) ||
      (type == HWC2::Composition::Client)) {
    layer_->update_mask.set(kClientCompRequest);
  }
  client_requested_ = type;
  client_requested_orig_ = type;
  switch (type) {
    case HWC2::Composition::Client:
      break;
    case HWC2::Composition::Device:
      // We try and default to this in SDM
      break;
    case HWC2::Composition::SolidColor:
      break;
    case HWC2::Composition::Cursor:
      break;
    case HWC2::Composition::Invalid:
      return HWC2::Error::BadParameter;
    default:
      return HWC2::Error::Unsupported;
  }

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerDataspace(int32_t dataspace) {
  // Map deprecated dataspace values to appropriate new enums
  dataspace = TranslateFromLegacyDataspace(dataspace);

  // cache the dataspace, to be used later to update SDM ColorMetaData
  if (dataspace_ != dataspace) {
    geometry_changes_ |= kDataspace;
    dataspace_ = dataspace;
    if (layer_->input_buffer.buffer_id) {
      ValidateAndSetCSC(reinterpret_cast<native_handle_t *>(layer_->input_buffer.buffer_id));
    }
  }
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
  LayerRect dst_rect = {};

  SetRect(frame, &dst_rect);
  if (dst_rect_ != dst_rect) {
    geometry_changes_ |= kDisplayFrame;
    dst_rect_ = dst_rect;
  }

  return HWC2::Error::None;
}

void HWCLayer::ResetPerFrameData() {
  layer_->dst_rect = dst_rect_;
  layer_->transform = layer_transform_;
}

HWC2::Error HWCLayer::SetCursorPosition(int32_t x, int32_t y) {
  hwc_rect_t frame = {};
  frame.left = x;
  frame.top = y;
  frame.right = x + INT(layer_->dst_rect.right - layer_->dst_rect.left);
  frame.bottom = y + INT(layer_->dst_rect.bottom - layer_->dst_rect.top);
  SetLayerDisplayFrame(frame);

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
  if (alpha < 0.0f || alpha > 1.0f) {
    return HWC2::Error::BadParameter;
  }

  uint8_t kMaxPlaneAlpha = 255;
  //  Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
  uint8_t plane_alpha = static_cast<uint8_t>(std::round(float(kMaxPlaneAlpha) * alpha));

  //  if alpha lies in the range (0.998, 1), plane_alpha becomes 255 when rounded off,
  //  while alpha < 1. HWC knows layer as opaque and marks punch hole for that layer in fbt,
  //  while SF knows it as non-opaque and doesn't create punch hole.
  if ((plane_alpha == kMaxPlaneAlpha) && (alpha < 1.0f)) {
    plane_alpha = (kMaxPlaneAlpha - 1);
  }

  if (layer_->plane_alpha != plane_alpha) {
    geometry_changes_ |= kPlaneAlpha;
    layer_->plane_alpha = plane_alpha;
  }

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) {
  LayerRect src_rect = {};
  SetRect(crop, &src_rect);
  non_integral_source_crop_ =
      ((crop.left != roundf(crop.left)) || (crop.top != roundf(crop.top)) ||
       (crop.right != roundf(crop.right)) || (crop.bottom != roundf(crop.bottom)));
  if (non_integral_source_crop_) {
    DLOGV_IF(kTagClient, "Crop: LTRB %f %f %f %f", crop.left, crop.top, crop.right, crop.bottom);
  }
  if (layer_->src_rect != src_rect) {
    geometry_changes_ |= kSourceCrop;
    layer_->src_rect = src_rect;
  }

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerTransform(HWC2::Transform transform) {
  LayerTransform layer_transform = {};
  switch (transform) {
    case HWC2::Transform::FlipH:
      layer_transform.flip_horizontal = true;
      break;
    case HWC2::Transform::FlipV:
      layer_transform.flip_vertical = true;
      break;
    case HWC2::Transform::Rotate90:
      layer_transform.rotation = 90.0f;
      break;
    case HWC2::Transform::Rotate180:
      layer_transform.flip_horizontal = true;
      layer_transform.flip_vertical = true;
      break;
    case HWC2::Transform::Rotate270:
      layer_transform.rotation = 90.0f;
      layer_transform.flip_horizontal = true;
      layer_transform.flip_vertical = true;
      break;
    case HWC2::Transform::FlipHRotate90:
      layer_transform.rotation = 90.0f;
      layer_transform.flip_horizontal = true;
      break;
    case HWC2::Transform::FlipVRotate90:
      layer_transform.rotation = 90.0f;
      layer_transform.flip_vertical = true;
      break;
    case HWC2::Transform::None:
      break;
    default:
      //  bad transform
      return HWC2::Error::BadParameter;
  }

  if (layer_transform_ != layer_transform) {
    geometry_changes_ |= kTransform;
    layer_transform_ = layer_transform;
  }

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerVisibleRegion(hwc_region_t visible) {
  layer_->visible_regions.clear();
  for (uint32_t i = 0; i < visible.numRects; i++) {
    LayerRect rect;
    SetRect(visible.rects[i], &rect);
    layer_->visible_regions.push_back(rect);
  }

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerZOrder(uint32_t z) {
  if (z_ != z) {
    geometry_changes_ |= kZOrder;
    z_ = z;
  }

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerType(IQtiComposerClient::LayerType type) {
  LayerTypes layer_type = kLayerUnknown;
  switch (type) {
    case IQtiComposerClient::LayerType::UNKNOWN:
      layer_type = kLayerUnknown;
      break;
    case IQtiComposerClient::LayerType::APP:
      layer_type = kLayerApp;
      break;
    case IQtiComposerClient::LayerType::GAME:
      layer_type = kLayerGame;
      break;
    case IQtiComposerClient::LayerType::BROWSER:
      layer_type = kLayerBrowser;
      break;
    default:
      DLOGW("Unsupported layer type %d", layer_type);
      break;
  }

  type_ = layer_type;
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerFlag(IQtiComposerClient::LayerFlag flag) {
  compatible_ = (flag == IQtiComposerClient::LayerFlag::COMPATIBLE);

  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerColorTransform(const float *matrix) {
  if (std::memcmp(matrix, layer_->color_transform_matrix, sizeof(layer_->color_transform_matrix))) {
    std::memcpy(layer_->color_transform_matrix, matrix, sizeof(layer_->color_transform_matrix));
    layer_->update_mask.set(kColorTransformUpdate);
    color_transform_matrix_set_ = true;
    if (!std::memcmp(matrix, kIdentityMatrix, sizeof(kIdentityMatrix))) {
      color_transform_matrix_set_ = false;
    }
  }
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerPerFrameMetadata(uint32_t num_elements,
                                               const PerFrameMetadataKey *keys,
                                               const float *metadata) {
  auto old_mastering_display = layer_->input_buffer.color_metadata.masteringDisplayInfo;
  auto old_content_light = layer_->input_buffer.color_metadata.contentLightLevel;
  auto &mastering_display = layer_->input_buffer.color_metadata.masteringDisplayInfo;
  auto &content_light = layer_->input_buffer.color_metadata.contentLightLevel;
  for (uint32_t i = 0; i < num_elements; i++) {
    switch (keys[i]) {
      case PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X:
        mastering_display.colorVolumeSEIEnabled = true;
        mastering_display.primaries.rgbPrimaries[0][0] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y:
        mastering_display.primaries.rgbPrimaries[0][1] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X:
        mastering_display.primaries.rgbPrimaries[1][0] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y:
        mastering_display.primaries.rgbPrimaries[1][1] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X:
        mastering_display.primaries.rgbPrimaries[2][0] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y:
        mastering_display.primaries.rgbPrimaries[2][1] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::WHITE_POINT_X:
        mastering_display.primaries.whitePoint[0] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::WHITE_POINT_Y:
        mastering_display.primaries.whitePoint[1] = UINT32(metadata[i] * 50000);
        break;
      case PerFrameMetadataKey::MAX_LUMINANCE:
        mastering_display.maxDisplayLuminance = UINT32(metadata[i]);
        break;
      case PerFrameMetadataKey::MIN_LUMINANCE:
        mastering_display.minDisplayLuminance = UINT32(metadata[i] * 10000);
        break;
      case PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL:
        content_light.lightLevelSEIEnabled = true;
        content_light.maxContentLightLevel = UINT32(metadata[i]);
        break;
      case PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL:
        content_light.minPicAverageLightLevel = UINT32(metadata[i]);
        break;
      default:
        break;
    }
  }
  if ((!SameConfig(&old_mastering_display, &mastering_display, UINT32(sizeof(MasteringDisplay)))) ||
      (!SameConfig(&old_content_light, &content_light, UINT32(sizeof(ContentLightLevel))))) {
    layer_->update_mask.set(kContentMetadata);
    geometry_changes_ |= kDataspace;
  }
  return HWC2::Error::None;
}

HWC2::Error HWCLayer::SetLayerPerFrameMetadataBlobs(uint32_t num_elements,
                                                    const PerFrameMetadataKey *keys,
                                                    const uint32_t *sizes,
                                                    const uint8_t *metadata) {
  if (!keys || !sizes || !metadata) {
    DLOGE("metadata or sizes or keys is null");
    return HWC2::Error::BadParameter;
  }

  ColorMetaData &color_metadata = layer_->input_buffer.color_metadata;
  for (uint32_t i = 0; i < num_elements; i++) {
    switch (keys[i]) {
      case PerFrameMetadataKey::HDR10_PLUS_SEI:
        if (sizes[i] > HDR_DYNAMIC_META_DATA_SZ) {
          DLOGE("Size of HDR10_PLUS_SEI = %d", sizes[i]);
          return HWC2::Error::BadParameter;
        }
        // if dynamic metadata changes, store and set needs validate
        if (!SameConfig(static_cast<const uint8_t *>(color_metadata.dynamicMetaDataPayload),
                        metadata, sizes[i])) {
          geometry_changes_ |= kDataspace;
          color_metadata.dynamicMetaDataValid = true;
          color_metadata.dynamicMetaDataLen = sizes[i];
          std::memcpy(color_metadata.dynamicMetaDataPayload, metadata, sizes[i]);
          layer_->update_mask.set(kContentMetadata);
        }
        break;
      default:
        DLOGW("Invalid key = %d", keys[i]);
        return HWC2::Error::BadParameter;
    }
  }
  return HWC2::Error::None;
}

void HWCLayer::SetRect(const hwc_rect_t &source, LayerRect *target) {
  target->left = FLOAT(source.left);
  target->top = FLOAT(source.top);
  target->right = FLOAT(source.right);
  target->bottom = FLOAT(source.bottom);
}

void HWCLayer::SetRect(const hwc_frect_t &source, LayerRect *target) {
  // Recommended way of rounding as in hwcomposer2.h - SetLayerSourceCrop
  target->left = std::ceil(source.left);
  target->top = std::ceil(source.top);
  target->right = std::floor(source.right);
  target->bottom = std::floor(source.bottom);
}

uint32_t HWCLayer::GetUint32Color(const hwc_color_t &source) {
  // Returns 32 bit ARGB
  uint32_t a = UINT32(source.a) << 24;
  uint32_t r = UINT32(source.r) << 16;
  uint32_t g = UINT32(source.g) << 8;
  uint32_t b = UINT32(source.b);
  uint32_t color = a | r | g | b;
  return color;
}

LayerBufferFormat HWCLayer::GetSDMFormat(const int32_t &source, const int flags) {
  LayerBufferFormat format = kFormatInvalid;
  if (flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED) {
    switch (source) {
      case static_cast<int>(PixelFormat::RGBA_8888):
        format = kFormatRGBA8888Ubwc;
        break;
      case static_cast<int>(PixelFormat::RGBX_8888):
        format = kFormatRGBX8888Ubwc;
        break;
      case HAL_PIXEL_FORMAT_BGR_565:
        format = kFormatBGR565Ubwc;
        break;
      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        format = kFormatYCbCr420SPVenusUbwc;
        break;
      case static_cast<int>(PixelFormat::RGBA_1010102):
        format = kFormatRGBA1010102Ubwc;
        break;
      case HAL_PIXEL_FORMAT_RGBX_1010102:
        format = kFormatRGBX1010102Ubwc;
        break;
      case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
        format = kFormatYCbCr420TP10Ubwc;
        break;
      case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
        format = kFormatYCbCr420P010Ubwc;
        break;
      case HAL_PIXEL_FORMAT_RGBA_FP16:
        format = kFormatRGBA16161616FUbwc;
        break;
      default:
        DLOGW("Unsupported format type for UBWC: %d", source);
        return kFormatInvalid;
    }
    return format;
  }

  switch (source) {
    case static_cast<int>(PixelFormat::RGBA_8888):
      format = kFormatRGBA8888;
      break;
    case HAL_PIXEL_FORMAT_RGBA_5551:
      format = kFormatRGBA5551;
      break;
    case HAL_PIXEL_FORMAT_RGBA_4444:
      format = kFormatRGBA4444;
      break;
    case static_cast<int>(PixelFormat::BGRA_8888):
      format = kFormatBGRA8888;
      break;
    case static_cast<int>(PixelFormat::RGBX_8888):
      format = kFormatRGBX8888;
      break;
    case HAL_PIXEL_FORMAT_BGRX_8888:
      format = kFormatBGRX8888;
      break;
    case static_cast<int>(PixelFormat::RGB_888):
      format = kFormatRGB888;
      break;
    case HAL_PIXEL_FORMAT_BGR_888:
      format = kFormatBGR888;
      break;
    case static_cast<int>(PixelFormat::RGB_565):
      format = kFormatRGB565;
      break;
    case HAL_PIXEL_FORMAT_BGR_565:
      format = kFormatBGR565;
      break;
    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
      format = kFormatYCbCr420SemiPlanarVenus;
      break;
    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
      format = kFormatYCrCb420SemiPlanarVenus;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
      format = kFormatYCbCr420SPVenusUbwc;
      break;
    case static_cast<int>(PixelFormat::YV12):
      format = kFormatYCrCb420PlanarStride16;
      break;
    case static_cast<int>(PixelFormat::YCRCB_420_SP):
      format = kFormatYCrCb420SemiPlanar;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
      format = kFormatYCbCr420SemiPlanar;
      break;
    case static_cast<int>(PixelFormat::YCBCR_422_SP):
      format = kFormatYCbCr422H2V1SemiPlanar;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_422_I:
      format = kFormatYCbCr422H2V1Packed;
      break;
    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
      format = kFormatCbYCrY422H2V1Packed;
      break;
    case static_cast<int>(PixelFormat::RGBA_1010102):
      format = kFormatRGBA1010102;
      break;
    case HAL_PIXEL_FORMAT_ARGB_2101010:
      format = kFormatARGB2101010;
      break;
    case HAL_PIXEL_FORMAT_RGBX_1010102:
      format = kFormatRGBX1010102;
      break;
    case HAL_PIXEL_FORMAT_XRGB_2101010:
      format = kFormatXRGB2101010;
      break;
    case HAL_PIXEL_FORMAT_BGRA_1010102:
      format = kFormatBGRA1010102;
      break;
    case HAL_PIXEL_FORMAT_ABGR_2101010:
      format = kFormatABGR2101010;
      break;
    case HAL_PIXEL_FORMAT_BGRX_1010102:
      format = kFormatBGRX1010102;
      break;
    case HAL_PIXEL_FORMAT_XBGR_2101010:
      format = kFormatXBGR2101010;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
      format = kFormatYCbCr420P010;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
      format = kFormatYCbCr420TP10Ubwc;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
      format = kFormatYCbCr420P010Ubwc;
      break;
    case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
      format = kFormatYCbCr420P010Venus;
      break;
    case static_cast<int>(PixelFormat::RGBA_FP16):
      format = kFormatRGBA16161616F;
      break;
    default:
      DLOGW("Unsupported format type = %d", source);
      return kFormatInvalid;
  }

  return format;
}

void HWCLayer::GetUBWCStatsFromMetaData(UBWCStats *cr_stats, UbwcCrStatsVector *cr_vec) {
  // TODO(user): Check if we can use UBWCStats directly
  // in layer_buffer or copy directly to Vector
  if (cr_stats->bDataValid) {
    switch (cr_stats->version) {
      case UBWC_4_0:
      case UBWC_3_0:
      case UBWC_2_0:
        cr_vec->push_back(std::make_pair(32, cr_stats->ubwc_stats.nCRStatsTile32));
        cr_vec->push_back(std::make_pair(64, cr_stats->ubwc_stats.nCRStatsTile64));
        cr_vec->push_back(std::make_pair(96, cr_stats->ubwc_stats.nCRStatsTile96));
        cr_vec->push_back(std::make_pair(128, cr_stats->ubwc_stats.nCRStatsTile128));
        cr_vec->push_back(std::make_pair(160, cr_stats->ubwc_stats.nCRStatsTile160));
        cr_vec->push_back(std::make_pair(192, cr_stats->ubwc_stats.nCRStatsTile192));
        cr_vec->push_back(std::make_pair(256, cr_stats->ubwc_stats.nCRStatsTile256));
        break;
      default:
        DLOGW("Invalid UBWC Version %d", cr_stats->version);
        break;
    }  // switch(cr_stats->version)
  }    // if (cr_stats->bDatvalid)
}

DisplayError HWCLayer::SetMetaData(const native_handle_t *pvt_handle, Layer *layer) {
  LayerBuffer *layer_buffer = &layer->input_buffer;
  void *handle = const_cast<native_handle_t *>(pvt_handle);

  std::string name = "";
  gralloc::GetMetaDataValue(handle, android::gralloc4::MetadataType_Name.value, &name);
  name_ = name;

  float fps = 0;
  uint32_t frame_rate = layer->frame_rate;
  if (gralloc::GetMetaDataValue(handle, qtigralloc::MetadataType_RefreshRate.value, &fps) ==
      gralloc::Error::NONE) {
    frame_rate = (fps != 0) ? RoundToStandardFPS(fps) : layer->frame_rate;
    has_metadata_refresh_rate_ = true;
  }

  int32_t interlaced = 0;
  gralloc::GetMetaDataValue(handle, qtigralloc::MetadataType_PPParamInterlaced.value, &interlaced);
  bool interlace = interlaced ? true : false;

  if (interlace != layer_buffer->flags.interlace) {
    DLOGI("Layer buffer interlaced metadata has changed. old=%d, new=%d",
          layer_buffer->flags.interlace, interlace);
  }

  uint32_t linear_format = 0;
  if (gralloc::GetMetaDataValue(handle, qtigralloc::MetadataType_LinearFormat.value,
                                &linear_format) == gralloc::Error::NONE) {
    layer_buffer->format = GetSDMFormat(INT32(linear_format), 0);
  }

  if ((interlace != layer_buffer->flags.interlace) || (frame_rate != layer->frame_rate)) {
    // Layer buffer metadata has changed.
    layer->frame_rate = frame_rate;
    layer_buffer->flags.interlace = interlace;
    layer_->update_mask.set(kMetadataUpdate);
  }

  // Check if metadata is set
  struct UBWCStats cr_stats[NUM_UBWC_CR_STATS_LAYERS] = {};

  for (int i = 0; i < NUM_UBWC_CR_STATS_LAYERS; i++) {
    layer_buffer->ubwc_crstats[i].clear();
  }

  if (gralloc::GetMetaDataValue(handle, qtigralloc::MetadataType_UBWCCRStatsInfo.value, cr_stats) ==
      gralloc::Error::NONE) {
    // Only copy top layer for now as only top field for interlaced is used
    GetUBWCStatsFromMetaData(&cr_stats[0], &(layer_buffer->ubwc_crstats[0]));
  }

  uint32_t single_buffer = 0;
  gralloc::GetMetaDataValue(handle, qtigralloc::MetadataType_SingleBufferMode.value,
                            &single_buffer);
  single_buffer_ = (single_buffer == 1);

  // Handle colorMetaData / Dataspace handling now
  ValidateAndSetCSC(static_cast<native_handle_t *>(handle));

  int extended_md_set = qtigralloc::getMetadataState(handle, QTI_CUSTOM_CONTENT_METADATA);
  if (extended_md_set > 0) {
    std::shared_ptr<CustomContentMetadata> dv_md = std::make_shared<CustomContentMetadata>();
    int err = buffer_allocator_->GetCustomContentMetadata(handle, dv_md.get());

    if (!err) {
      if (!layer_buffer->extended_content_metadata ||
          dv_md->size != layer_buffer->extended_content_metadata->size ||
          !SameConfig(layer_buffer->extended_content_metadata->metadataPayload,
                      dv_md->metadataPayload, dv_md->size)) {
        layer_buffer->extended_content_metadata = dv_md;
        layer_->update_mask.set(kContentMetadata);
      }
    }
  } else if (layer_buffer->extended_content_metadata) {
    // Buffer switch scenario - cleanup old metadata
    layer_buffer->extended_content_metadata = nullptr;
    layer_->update_mask.set(kContentMetadata);
  }

  if (!ignore_sdr_histogram_md_ ||
      IsHdr(layer_buffer->color_metadata.colorPrimaries, layer_buffer->color_metadata.transfer)) {

    VideoHistogramMetadata histogram = {};
    if (layer_->update_mask.test(kContentMetadata) == false &&
        gralloc::GetMetaDataValue(static_cast<native_handle_t *>(handle),
                                  qtigralloc::MetadataType_VideoHistogramStats.value,
                                  &histogram) == gralloc::Error::NONE) {
      uint32_t bins = histogram.stat_len / sizeof(histogram.stats_info[0]);
      layer_buffer->hist_data.display_width = layer_buffer->unaligned_width;
      layer_buffer->hist_data.display_height = layer_buffer->unaligned_height;
      if (histogram.stat_len <= sizeof(histogram.stats_info) && bins > 0) {
        layer_buffer->hist_data.stats_info.clear();
        layer_buffer->hist_data.stats_info.reserve(bins);
        for (uint32_t i = 0; i < bins; i++) {
          layer_buffer->hist_data.stats_info.push_back(histogram.stats_info[i]);
        }

        layer_buffer->hist_data.stats_valid = true;
        layer_->update_mask.set(kContentMetadata);
      }
    }
  }

  layer_buffer->timestamp_data.valid = false;

  int timestamp_set = qtigralloc::getMetadataState(handle, QTI_VIDEO_TS_INFO);
  if (timestamp_set > 0) {
    VideoTimestampInfo timestamp_info = {};
    int err = static_cast<int>(qtigralloc::get(handle, QTI_VIDEO_TS_INFO, &timestamp_info));

    if (!err && timestamp_info.enable) {
      layer_buffer->timestamp_data.valid = true;
      layer_buffer->timestamp_data.frame_number = timestamp_info.frame_number;
      layer_buffer->timestamp_data.frame_timestamp_us = timestamp_info.frame_timestamp_us;
    }
  }

  return kErrorNone;
}

bool HWCLayer::IsDataSpaceSupported() {
  if (client_requested_ != HWC2::Composition::Device &&
      client_requested_ != HWC2::Composition::Cursor) {
    // Layers marked for GPU can have any dataspace
    return true;
  }

  return dataspace_supported_;
}

void HWCLayer::ValidateAndSetCSC(const native_handle_t *handle) {
  LayerBuffer *layer_buffer = &layer_->input_buffer;
  bool use_color_metadata = true;
  ColorMetaData csc = {};
  if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
    use_color_metadata = false;
    bool valid_csc = GetSDMColorSpace(dataspace_, &csc);
    if (!valid_csc) {
      dataspace_supported_ = false;
      return;
    }

    if (layer_buffer->color_metadata.transfer != csc.transfer ||
        layer_buffer->color_metadata.colorPrimaries != csc.colorPrimaries ||
        layer_buffer->color_metadata.range != csc.range) {
      // ColorMetadata updated. Needs validate.
      layer_->update_mask.set(kMetadataUpdate);
      // if we are here here, update the sdm layer csc.
      layer_buffer->color_metadata.transfer = csc.transfer;
      layer_buffer->color_metadata.colorPrimaries = csc.colorPrimaries;
      layer_buffer->color_metadata.range = csc.range;
    }
  }

  if (IsBT2020(layer_buffer->color_metadata.colorPrimaries)) {
    // android_dataspace_t doesnt support mastering display and light levels
    // so retrieve it from metadata for BT2020(HDR)
    use_color_metadata = true;
  }

  if (use_color_metadata) {
    ColorMetaData new_metadata = layer_buffer->color_metadata;
    if (sdm::SetCSC(handle, &new_metadata) == kErrorNone) {
      // If dataspace is KNOWN, overwrite the gralloc metadata CSC using the previously derived CSC
      // from dataspace.
      if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
        new_metadata.colorPrimaries = layer_buffer->color_metadata.colorPrimaries;
        new_metadata.transfer = layer_buffer->color_metadata.transfer;
        new_metadata.range = layer_buffer->color_metadata.range;
      }
      if ((layer_buffer->color_metadata.colorPrimaries != new_metadata.colorPrimaries) ||
          (layer_buffer->color_metadata.transfer != new_metadata.transfer) ||
          (layer_buffer->color_metadata.range != new_metadata.range)) {
        layer_buffer->color_metadata.colorPrimaries = new_metadata.colorPrimaries;
        layer_buffer->color_metadata.transfer = new_metadata.transfer;
        layer_buffer->color_metadata.range = new_metadata.range;
        layer_->update_mask.set(kMetadataUpdate);
      }
      if (layer_buffer->color_metadata.matrixCoefficients != new_metadata.matrixCoefficients) {
        layer_buffer->color_metadata.matrixCoefficients = new_metadata.matrixCoefficients;
        layer_->update_mask.set(kMetadataUpdate);
      }
      DLOGV_IF(kTagClient,
               "Layer id = %d ColorVolEnabled = %d ContentLightLevelEnabled = %d "
               "cRIEnabled = %d Dynamic Metadata valid = %d size = %d",
               UINT32(id_), new_metadata.masteringDisplayInfo.colorVolumeSEIEnabled,
               new_metadata.contentLightLevel.lightLevelSEIEnabled, new_metadata.cRI.criEnabled,
               new_metadata.dynamicMetaDataValid, new_metadata.dynamicMetaDataLen);
      // Read color metadata from gralloc handle if it's enabled by clients, this will override the
      // values set using the Composer API's(SetLayerPerFrameMetaData)
      if (new_metadata.masteringDisplayInfo.colorVolumeSEIEnabled &&
          !SameConfig(&new_metadata.masteringDisplayInfo,
                      &layer_buffer->color_metadata.masteringDisplayInfo,
                      UINT32(sizeof(MasteringDisplay)))) {
        layer_buffer->color_metadata.masteringDisplayInfo = new_metadata.masteringDisplayInfo;
        layer_->update_mask.set(kContentMetadata);
      }
      if (new_metadata.contentLightLevel.lightLevelSEIEnabled &&
          !SameConfig(&new_metadata.contentLightLevel,
                      &layer_buffer->color_metadata.contentLightLevel,
                      UINT32(sizeof(ContentLightLevel)))) {
        layer_buffer->color_metadata.contentLightLevel = new_metadata.contentLightLevel;
        layer_->update_mask.set(kContentMetadata);
      }
      if (new_metadata.cRI.criEnabled &&
          !SameConfig(&new_metadata.cRI, &layer_buffer->color_metadata.cRI,
                      UINT32(sizeof(ColorRemappingInfo)))) {
        layer_buffer->color_metadata.cRI = new_metadata.cRI;
        layer_->update_mask.set(kMetadataUpdate);
      }
      if (new_metadata.dynamicMetaDataValid &&
          new_metadata.dynamicMetaDataLen < HDR_DYNAMIC_META_DATA_SZ &&
          ((new_metadata.dynamicMetaDataLen != layer_buffer->color_metadata.dynamicMetaDataLen) ||
            !SameConfig(layer_buffer->color_metadata.dynamicMetaDataPayload,
                        new_metadata.dynamicMetaDataPayload, new_metadata.dynamicMetaDataLen))) {
        layer_buffer->color_metadata.dynamicMetaDataValid = true;
        layer_buffer->color_metadata.dynamicMetaDataLen = new_metadata.dynamicMetaDataLen;
        std::memcpy(layer_buffer->color_metadata.dynamicMetaDataPayload,
                    new_metadata.dynamicMetaDataPayload, new_metadata.dynamicMetaDataLen);
        layer_->update_mask.set(kContentMetadata);
      }
    } else {
      dataspace_supported_ = false;
      return;
    }
  }

  dataspace_supported_ = true;
}

uint32_t HWCLayer::RoundToStandardFPS(float fps) {
  static const int32_t standard_fps[4] = {24, 30, 48, 60};
  int32_t frame_rate = (uint32_t)(fps);

  int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
  for (int i = 0; i < count; i++) {
    if ((standard_fps[i] - frame_rate) < 2) {
      // Most likely used for video, the fps can fluctuate
      // Ex: b/w 29 and 30 for 30 fps clip
      return standard_fps[i];
    }
  }

  return frame_rate;
}

void HWCLayer::SetComposition(const LayerComposition &sdm_composition) {
  auto hwc_composition = HWC2::Composition::Invalid;
  switch (sdm_composition) {
    case kCompositionGPU:
      hwc_composition = HWC2::Composition::Client;
      break;
    case kCompositionCursor:
      hwc_composition = HWC2::Composition::Cursor;
      break;
    default:
      hwc_composition = HWC2::Composition::Device;
      break;
  }
  // Update solid fill composition
  if (sdm_composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
    hwc_composition = HWC2::Composition::SolidColor;
  }
  device_selected_ = hwc_composition;

  return;
}

shared_ptr<Fence> HWCLayer::GetReleaseFence() {
  return release_fence_;
}

void HWCLayer::SetReleaseFence(const shared_ptr<Fence> &release_fence) {
  release_fence_ = release_fence;
}

bool HWCLayer::IsRotationPresent() {
  return ((layer_->transform.rotation != 0.0f) || layer_->transform.flip_horizontal ||
          layer_->transform.flip_vertical);
}

bool HWCLayer::IsScalingPresent() {
  uint32_t src_width = static_cast<uint32_t>(layer_->src_rect.right - layer_->src_rect.left);
  uint32_t src_height = static_cast<uint32_t>(layer_->src_rect.bottom - layer_->src_rect.top);
  uint32_t dst_width = static_cast<uint32_t>(layer_->dst_rect.right - layer_->dst_rect.left);
  uint32_t dst_height = static_cast<uint32_t>(layer_->dst_rect.bottom - layer_->dst_rect.top);

  if ((layer_->transform.rotation == 90.0) || (layer_->transform.rotation == 270.0)) {
    std::swap(src_width, src_height);
  }

  return ((src_width != dst_width) || (dst_height != src_height));
}

void HWCLayer::SetDirtyRegions(hwc_region_t surface_damage) {
  layer_->dirty_regions.clear();
  for (uint32_t i = 0; i < surface_damage.numRects; i++) {
    LayerRect rect;
    SetRect(surface_damage.rects[i], &rect);
    layer_->dirty_regions.push_back(rect);
  }
}

void HWCLayer::SetLayerAsMask() {
  layer_->input_buffer.flags.mask_layer = true;
  DLOGV_IF(kTagClient,
           " Layer Id: "
           "[%" PRIu64 "]",
           id_);
}

void HWCLayer::ResetGeometryChanges() {
  geometry_changes_ = GeometryChanges::kNone;
  layer_->geometry_changes = GeometryChanges::kNone;
}

}  // namespace sdm
