/*
 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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.
 */

/* Changes from Qualcomm Innovation Center are provided under the following license:
 *
 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 */

#include <dlfcn.h>
#include <log/log.h>
#include <mutex>

#include "gr_camera_info.h"
#include <QtiGrallocPriv.h>
#include <QtiGrallocDefs.h>

using std::lock_guard;
using std::mutex;

namespace gralloc {

CameraInfo *CameraInfo::s_instance = nullptr;

CameraInfo *CameraInfo::GetInstance() {
  static mutex s_lock;
  lock_guard<mutex> obj(s_lock);
  if (!s_instance) {
    s_instance = new CameraInfo();
  }

  return s_instance;
}

CameraInfo::CameraInfo() {
  libcamera_utils_ = ::dlopen("libcamxexternalformatutils.so", RTLD_NOW);
  if (libcamera_utils_) {
    *reinterpret_cast<void **>(&LINK_camera_get_stride_in_bytes) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetStrideInBytes");
    *reinterpret_cast<void **>(&LINK_camera_get_stride_in_pixels) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetStrideInPixels");
    *reinterpret_cast<void **>(&LINK_camera_get_scanline) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetScanline");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_size) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneSize");
    *reinterpret_cast<void **>(&LINK_camera_get_buffer_size) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetBufferSize");
    *reinterpret_cast<void **>(&LINK_camera_get_ubwc_info) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetUBWCInfo");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_alignment) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneAlignment");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_offset) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneOffset");
    *reinterpret_cast<void **>(&LINK_camera_is_per_plane_fd_needed) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_IsPerPlaneFdNeeded");
    *reinterpret_cast<void **>(&LINK_camera_get_bpp) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetBpp");
    *reinterpret_cast<void **>(&LINK_camera_get_per_plane_bpp) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPerPlaneBpp");
    *reinterpret_cast<void **>(&LINK_camera_get_subsampling_factor) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetSubsamplingFactor");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_count) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneCount");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_types) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneTypes");
    *reinterpret_cast<void **>(&LINK_camera_get_pixel_increment) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPixelIncrement");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_start_address_alignment) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneStartAddressAlignment");
  } else {
    ALOGE("%s: Failed to load libcamxexternalformatutils.so - %s", __FUNCTION__, strerror(errno));
  }
}

CameraInfo::~CameraInfo() {
  if (libcamera_utils_) {
    ::dlclose(libcamera_utils_);
  }
}

CamxPixelFormat CameraInfo::GetCameraPixelFormat(int hal_format) {
  CamxPixelFormat format = (CamxPixelFormat)0;
  switch (hal_format) {
    case HAL_PIXEL_FORMAT_NV21_ZSL:
      format = CAMERA_PIXEL_FORMAT_NV21_ZSL;
      break;
    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
      format = CAMERA_PIXEL_FORMAT_YUV_FLEX;
      break;
    case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX:
      format = CAMERA_PIXEL_FORMAT_UBWC_FLEX;
      break;
    case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX_2_BATCH:
      format = CAMERA_PIXEL_FORMAT_UBWC_FLEX_2_BATCH;
      break;
    case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX_4_BATCH:
      format = CAMERA_PIXEL_FORMAT_UBWC_FLEX_4_BATCH;
      break;
    case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX_8_BATCH:
      format = CAMERA_PIXEL_FORMAT_UBWC_FLEX_8_BATCH;
      break;
    case HAL_PIXEL_FORMAT_NV12_FLEX_2_BATCH:
      format = CAMERA_PIXEL_FORMAT_YUV_FLEX_2_BATCH;
      break;
    case HAL_PIXEL_FORMAT_NV12_FLEX_4_BATCH:
      format = CAMERA_PIXEL_FORMAT_YUV_FLEX_4_BATCH;
      break;
    case HAL_PIXEL_FORMAT_NV12_FLEX_8_BATCH:
      format = CAMERA_PIXEL_FORMAT_YUV_FLEX_8_BATCH;
      break;
    case HAL_PIXEL_FORMAT_MULTIPLANAR_FLEX:
      format = CAMERA_PIXEL_FORMAT_MULTIPLANAR_FLEX;
      break;
    case static_cast<int>(PixelFormat::RAW_OPAQUE):
      format = CAMERA_PIXEL_FORMAT_RAW_OPAQUE;
      break;
    case static_cast<int>(PixelFormat::RAW10):
      format = CAMERA_PIXEL_FORMAT_RAW10;
      break;
    case static_cast<int>(PixelFormat::RAW12):
      format = CAMERA_PIXEL_FORMAT_RAW12;
      break;
    default:
      ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
      break;
  }

  return format;
}

int CameraInfo::GetBufferSize(int format, int width, int height, unsigned int *size) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_buffer_size) {
    result = LINK_camera_get_buffer_size(GetCameraPixelFormat(format), width, height, size);
    if (result != 0) {
      ALOGE("%s: Failed to get the buffer size. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetBufferSize. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetStrideInBytes(int format, int plane_type, int width, int *stride_bytes) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_stride_in_bytes) {
    result = LINK_camera_get_stride_in_bytes(GetCameraPixelFormat(format),
                                             GetCamxPlaneType(plane_type), width, stride_bytes);
    if (result != 0) {
      ALOGE("%s: Failed to get the stride in bytes. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetStrideInBytes. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetStrideInPixels(int format, int plane_type, int width, float *stride_pixel) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_stride_in_pixels) {
    result = LINK_camera_get_stride_in_pixels(GetCameraPixelFormat(format),
                                              GetCamxPlaneType(plane_type), width, stride_pixel);
    if (result != 0) {
      ALOGE("%s: Failed to get the stride in pixels. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetStrideInPixels. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPixelIncrement(int format, int plane_type, int *pixel_increment) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_pixel_increment) {
    result = LINK_camera_get_pixel_increment(GetCameraPixelFormat(format),
                                             GetCamxPlaneType(plane_type), pixel_increment);
    if (result != 0) {
      ALOGE("%s: Failed to get pixel increment. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPixelIncrement. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPlaneOffset(int format, int plane_type, int width, int height, int *offset) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_offset) {
    result = LINK_camera_get_plane_offset(GetCameraPixelFormat(format),
                                          GetCamxPlaneType(plane_type), offset, width, height);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane offset. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneOffset. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetSubsamplingFactor(int format, int plane_type, bool isHorizontal,
                                     int *subsampling_factor) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_subsampling_factor) {
    result = LINK_camera_get_subsampling_factor(GetCameraPixelFormat(format),
                                                GetCamxPlaneType(plane_type), isHorizontal,
                                                subsampling_factor);
    if (result != 0) {
      ALOGE("%s: Failed to get the sub-sampling factor. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetSubsamplingFactor. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPlaneTypes(int format, PlaneComponent *plane_component_array, int *plane_count) {
  CamxPlaneType plane_types_array[8] = {};
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_types) {
    result =
        LINK_camera_get_plane_types(GetCameraPixelFormat(format), plane_types_array, plane_count);
    if (result == 0) {
      for (int plane = 0; plane < *plane_count; plane++) {
        plane_component_array[plane] = GetPlaneComponent(plane_types_array[plane]);
      }
    } else {
      ALOGE("%s: Failed to get the plane types. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneTypes. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetScanline(int format, int plane_type, int height, int *scanlines) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_scanline) {
    result = LINK_camera_get_scanline(GetCameraPixelFormat(format), GetCamxPlaneType(plane_type),
                                      height, scanlines);
    if (result != 0) {
      ALOGE("%s: Failed to get the scanlines. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetScanline. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetPlaneSize(int format, int plane_type, int width, int height,
                             unsigned int *size) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_size) {
    result = LINK_camera_get_plane_size(GetCameraPixelFormat(format), GetCamxPlaneType(plane_type),
                                        width, height, size);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane size. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneSize. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetCameraFormatPlaneInfo(int format, int width, int height, int *plane_count,
                                         PlaneLayoutInfo *plane_info) {
  int h_subsampling = 0;
  int v_subsampling = 0;
  int offset = 0;
  int pixel_increment = 0;
  float stride_pixel = 0;
  int stride_bytes = 0;
  int scanlines = 0;
  unsigned int plane_size = 0;
  PlaneComponent plane_type[8] = {};
  int result;
  result = GetPlaneTypes(format, plane_type, plane_count);
  if (result != 0) {
    ALOGE("%s: Failed to get the plane types. Error code : %d", __FUNCTION__, result);
    return result;
  }

  for (int i = 0; i < *plane_count; i++) {
    plane_info[i].component = plane_type[i];
    result = GetSubsamplingFactor(format, plane_type[i], true, &h_subsampling);
    if (result != 0) {
      ALOGE("%s: Failed to get horizontal subsampling factor. plane_type = %d, Error code : %d",
            __FUNCTION__, plane_type[i], result);
      break;
    }
    plane_info[i].h_subsampling = (uint32_t)h_subsampling;

    result = GetSubsamplingFactor(format, plane_type[i], false, &v_subsampling);
    if (result != 0) {
      ALOGE("%s: Failed to get vertical subsampling factor. plane_type = %d, Error code : %d",
            __FUNCTION__, plane_type[i], result);
      break;
    }
    plane_info[i].v_subsampling = (uint32_t)v_subsampling;

    result = GetPlaneOffset(format, plane_type[i], width, height, &offset);
    if (result != 0) {
      ALOGE("%s: Failed to get plane offset. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].offset = (uint32_t)offset;

    result = GetPixelIncrement(format, plane_type[i], &pixel_increment);
    if (result != 0) {
      ALOGE("%s: Failed to get pixel increment. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].step = (int32_t)pixel_increment;

    result = GetStrideInPixels(format, plane_type[i], width, &stride_pixel);
    if (result != 0) {
      ALOGE("%s: Failed to get stride in pixel. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].stride = (int32_t)stride_pixel;

    result = GetStrideInBytes(format, plane_type[i], width, &stride_bytes);
    if (result != 0) {
      ALOGE("%s: Failed to get stride in bytes. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].stride_bytes = (int32_t)stride_bytes;

    result = GetScanline(format, plane_type[i], height, &scanlines);
    if (result != 0) {
      ALOGE("%s: Failed to get scanlines. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].scanlines = (int32_t)scanlines;

    result = GetPlaneSize(format, plane_type[i], width, height, &plane_size);
    if (result != 0) {
      ALOGE("%s: Failed to get plane size. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].size = (uint32_t)plane_size;
  }

  return result;
}

int CameraInfo::GetUBWCInfo(int format, bool *is_supported, bool *is_pi, int *version) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_ubwc_info) {
    result = LINK_camera_get_ubwc_info(GetCameraPixelFormat(format), is_supported, is_pi, version);
    if (result != 0) {
      ALOGE("%s: Failed to get the UBWC info. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetUBWCInfo. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetPlaneAlignment(int format, int plane_type, unsigned int *alignment) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_alignment) {
    result = LINK_camera_get_plane_alignment(GetCameraPixelFormat(format),
                                             GetCamxPlaneType(plane_type), alignment);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane alignment. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneAlignment. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::IsPerPlaneFdNeeded(int format, bool *is_per_plane_fd_needed) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_is_per_plane_fd_needed) {
    result =
        LINK_camera_is_per_plane_fd_needed(GetCameraPixelFormat(format), is_per_plane_fd_needed);
    if (result != 0) {
      ALOGE("%s: Failed to get per_plane_fd flag. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_IsPerPlaneFdNeeded. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetBpp(int format, int *bpp) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_bpp) {
    result = LINK_camera_get_bpp(GetCameraPixelFormat(format), bpp);
    if (result != 0) {
      ALOGE("%s: Failed to get the bpp. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetBpp. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetPerPlaneBpp(int format, int plane_type, int *bpp) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_per_plane_bpp) {
    result = LINK_camera_get_per_plane_bpp(GetCameraPixelFormat(format),
                                           GetCamxPlaneType(plane_type), bpp);
    if (result != 0) {
      ALOGE("%s: Failed to get the per plane bpp. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPerPlaneBpp. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPlaneStartAddressAlignment(int format, int plane_type, int *alignment) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_start_address_alignment) {
    result = LINK_camera_get_plane_start_address_alignment(GetCameraPixelFormat(format),
                                                           GetCamxPlaneType(plane_type), alignment);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane star address alignment. Error code: %d", __FUNCTION__,
            result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneStartAddressAlignment. Error code : %d",
          __FUNCTION__, result);
  }

  return result;
}

PlaneComponent CameraInfo::GetPlaneComponent(CamxPlaneType plane_type) {
  PlaneComponent plane_component = (PlaneComponent)0;
  switch (plane_type) {
    case CAMERA_PLANE_TYPE_RAW:
      plane_component = (PlaneComponent)PLANE_COMPONENT_RAW;
      break;
    case CAMERA_PLANE_TYPE_Y:
      plane_component = (PlaneComponent)PLANE_COMPONENT_Y;
      break;
    case CAMERA_PLANE_TYPE_UV:
      plane_component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
      break;
    case CAMERA_PLANE_TYPE_U:
      plane_component = (PlaneComponent)PLANE_COMPONENT_Cb;
      break;
    case CAMERA_PLANE_TYPE_V:
      plane_component = (PlaneComponent)PLANE_COMPONENT_Cr;
      break;
    case CAMERA_PLANE_TYPE_META_Y:
      plane_component = (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Y);
      break;
    case CAMERA_PLANE_TYPE_META_VU:
      plane_component =
          (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
      break;
    default:
      ALOGE("%s: No PlaneComponent mapping for plane_type: %d", __FUNCTION__, plane_type);
      break;
  }

  return plane_component;
}

CamxPlaneType CameraInfo::GetCamxPlaneType(int plane_type) {
  CamxPlaneType camx_plane_type = (CamxPlaneType)0;
  switch (plane_type) {
    case PLANE_COMPONENT_RAW:
      camx_plane_type = CAMERA_PLANE_TYPE_RAW;
      break;
    case PLANE_COMPONENT_Y:
      camx_plane_type = CAMERA_PLANE_TYPE_Y;
      break;
    case (PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr):
      camx_plane_type = CAMERA_PLANE_TYPE_UV;
      break;
    case PLANE_COMPONENT_Cb:
      camx_plane_type = CAMERA_PLANE_TYPE_U;
      break;
    case PLANE_COMPONENT_Cr:
      camx_plane_type = CAMERA_PLANE_TYPE_V;
      break;
    case (PLANE_COMPONENT_META | PLANE_COMPONENT_Y):
      camx_plane_type = CAMERA_PLANE_TYPE_META_Y;
      break;
    case (PLANE_COMPONENT_META | PLANE_COMPONENT_Cr | PLANE_COMPONENT_Cb):
      camx_plane_type = CAMERA_PLANE_TYPE_META_VU;
      break;
    default:
      ALOGE("%s: No CamxPlane for plane_type: %d", __FUNCTION__, plane_type);
      break;
  }

  return camx_plane_type;
}

}  // namespace gralloc
