/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cutils/log.h>
#include <dlfcn.h>
#include <tegra_adf.h>

#include "hwc2.h"

#define NVGR_PIXEL_FORMAT_YUV420  0x100
#define NVGR_PIXEL_FORMAT_YUV422  0x101
#define NVGR_PIXEL_FORMAT_YUV422R 0x102
#define NVGR_PIXEL_FORMAT_UYVY    0x104
#define NVGR_PIXEL_FORMAT_NV12    0x106

#define NVGR_SURFACE_LAYOUT_PITCH        1
#define NVGR_SURFACE_LAYOUT_TILED        2
#define NVGR_SURFACE_LAYOUT_BLOCK_LINEAR 3

#define NVGR_SURFACE_SIZE 56

#define NVGR_GET_SURFACE(surfaces, idx) \
        ((void*)((char *) surfaces + (idx * NVGR_SURFACE_SIZE)))

/* The surface struct is defined in an NVIDIA binary. Accesses to the struct
 * will be done using member offsets */
#define NVGR_GET_STRUCT_MEMBER(ptr, member_type, member_offset) \
        (*((member_type *)((char *) ptr + member_offset)))

#define NVGR_SURFACE_OFFSET_LAYOUT            12
#define NVGR_SURFACE_OFFSET_PITCH             16
#define NVGR_SURFACE_OFFSET_HMEM              20
#define NVGR_SURFACE_OFFSET_OFFSET            24
#define NVGR_SURFACE_OFFSET_BLOCK_HEIGHT_LOG2 32

hwc2_gralloc::hwc2_gralloc()
{
    nvgr = dlopen("gralloc.tegra132.so", RTLD_LOCAL | RTLD_LAZY);
    LOG_ALWAYS_FATAL_IF(!nvgr, "failed to find module");

    *(void **)(&nvgr_is_valid) = dlsym(nvgr, "nvgr_is_valid");
    LOG_ALWAYS_FATAL_IF(!nvgr_is_valid, "failed to find nvgr_is_valid symbol");

    *(void **)(&nvgr_is_stereo) = dlsym(nvgr, "nvgr_is_stereo");
    LOG_ALWAYS_FATAL_IF(!nvgr_is_stereo, "failed to find nvgr_is_stereo"
            " symbol");

    *(void **)(&nvgr_is_yuv) = dlsym(nvgr, "nvgr_is_yuv");
    LOG_ALWAYS_FATAL_IF(!nvgr_is_stereo, "failed to find nvgr_is_yuv symbol");

    *(void **)(&nvgr_get_format) = dlsym(nvgr, "nvgr_get_format");
    LOG_ALWAYS_FATAL_IF(!nvgr_get_format, "failed to find nvgr_get_format"
            " symbol");

    *(void **)(&nvgr_get_surfaces) = dlsym(nvgr, "nvgr_get_surfaces");
    LOG_ALWAYS_FATAL_IF(!nvgr_get_surfaces, "failed to find nvgr_get_surfaces"
            " symbol");

    *(void **)(&NvRmMemDmaBufFdFromHandle) = dlsym(nvgr,
            "NvRmMemDmaBufFdFromHandle");
    LOG_ALWAYS_FATAL_IF(!NvRmMemDmaBufFdFromHandle, "failed to find"
            " NvRmMemDmaBufFdFromHandle symbol");

    *(void **)(&nvgr_decompress) = dlsym(nvgr, "nvgr_decompress");
    LOG_ALWAYS_FATAL_IF(!nvgr_decompress, "failed to find nvgr_decompress"
            " symbol");
}

hwc2_gralloc::~hwc2_gralloc()
{
    dlclose(nvgr);
}

const hwc2_gralloc &hwc2_gralloc::get_instance()
{
    static hwc2_gralloc instance;
    return instance;
}

bool hwc2_gralloc::is_valid(buffer_handle_t handle) const
{
    return nvgr_is_valid(handle);
}

bool hwc2_gralloc::is_stereo(buffer_handle_t handle) const
{
    return nvgr_is_stereo(handle);
}

bool hwc2_gralloc::is_yuv(buffer_handle_t handle) const
{
    return nvgr_is_yuv(handle);
}

int hwc2_gralloc::get_format(buffer_handle_t handle) const
{
    int format = nvgr_get_format(handle);

    switch (format) {
    case HAL_PIXEL_FORMAT_RGB_565:
        return DRM_FORMAT_BGR565;
    case NVGR_PIXEL_FORMAT_YUV420:
        return DRM_FORMAT_YUV420;
    case NVGR_PIXEL_FORMAT_YUV422:
        return DRM_FORMAT_YUV422;
    case NVGR_PIXEL_FORMAT_YUV422R:
        return TEGRA_ADF_FORMAT_YCbCr422R;
    case NVGR_PIXEL_FORMAT_UYVY:
        return DRM_FORMAT_UYVY;
    case NVGR_PIXEL_FORMAT_NV12:
        return DRM_FORMAT_NV12;
    default:
        return adf_fourcc_for_hal_pixel_format(format);
    }
}

void hwc2_gralloc::get_surfaces(buffer_handle_t handle,
        const void **surf, size_t *surf_cnt) const
{
    nvgr_get_surfaces(handle, surf, surf_cnt);
}

void hwc2_gralloc::get_dma_buf(const void *surf, uint32_t surf_idx,
        int *out_fd) const
{
    NvRmMemDmaBufFdFromHandle(get_hmem(surf, surf_idx), out_fd);
}

int32_t hwc2_gralloc::get_layout(const void *surf, uint32_t surf_idx) const
{
    uint32_t layout = NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_LAYOUT);

    switch (layout) {
    case NVGR_SURFACE_LAYOUT_PITCH:
        return HWC2_WINDOW_CAP_PITCH;
    case NVGR_SURFACE_LAYOUT_TILED:
        return HWC2_WINDOW_CAP_TILED;
    case NVGR_SURFACE_LAYOUT_BLOCK_LINEAR:
        return HWC2_WINDOW_CAP_BLOCK_LINEAR;
    default:
        ALOGE("Unrecognized layout");
        return -1;
    }
}

uint32_t hwc2_gralloc::get_pitch(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_PITCH);
}

uint32_t hwc2_gralloc::get_hmem(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_HMEM);
}

uint32_t hwc2_gralloc::get_offset(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_OFFSET);
}

uint32_t hwc2_gralloc::get_block_height_log2(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_BLOCK_HEIGHT_LOG2);
}

uint32_t hwc2_gralloc::decompress(buffer_handle_t handle, int in_fence,
        int *out_fence) const
{
    return nvgr_decompress(handle, in_fence, out_fence);
}
