/*
 * Copyright (C) 2012 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 <aidl/android/hardware/graphics/common/BufferUsage.h>
#include <utils/Errors.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <hardware/hwcomposer_defs.h>
#include <hardware/exynos/ion.h>

#include "BrightnessController.h"
#include "ExynosLayer.h"
#include "ExynosResourceManager.h"
#include "ExynosHWCDebug.h"
#include "ExynosExternalDisplay.h"

#include "VendorVideoAPI.h"

/**
 * ExynosLayer implementation
 */

using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage;

ExynosLayer::ExynosLayer(ExynosDisplay* display)
      : ExynosMPPSource(MPP_SOURCE_LAYER, this),
        mDisplay(display),
        mCompositionType(HWC2_COMPOSITION_INVALID),
        mRequestedCompositionType(HWC2_COMPOSITION_INVALID),
        mExynosCompositionType(HWC2_COMPOSITION_INVALID),
        mValidateCompositionType(HWC2_COMPOSITION_INVALID),
        mPrevValidateCompositionType(HWC2_COMPOSITION_INVALID),
        mValidateExynosCompositionType(HWC2_COMPOSITION_INVALID),
        mOverlayInfo(0x0),
        mSupportedMPPFlag(0x0),
        mFps(0),
        mOverlayPriority(ePriorityLow),
        mGeometryChanged(0x0),
        mWindowIndex(0),
        mCompressionInfo({COMP_TYPE_NONE, 0}),
        mAcquireFence(-1),
        mPrevAcquireFence(-1),
        mReleaseFence(-1),
        mFrameCount(0),
        mLastFrameCount(0),
        mLastFpsTime(0),
        mNextLastFrameCount(0),
        mNextLastFpsTime(0),
        mLastLayerBuffer(NULL),
        mLayerBuffer(NULL),
        mLastUpdateTime(0),
        mDamageNum(0),
        mBlending(HWC2_BLEND_MODE_NONE),
        mPlaneAlpha(1.0),
        mTransform(0),
        mZOrder(0),
        mDataSpace(HAL_DATASPACE_UNKNOWN),
        mLayerFlag(0x0),
        mIsHdrLayer(false),
        mBufferHasMetaParcel(false),
        mMetaParcelFd(-1) {
    memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
    memset(&mSourceCrop, 0, sizeof(mSourceCrop));
    mVisibleRegionScreen.numRects = 0;
    mVisibleRegionScreen.rects = NULL;
    memset(&mColor, 0, sizeof(mColor));
    memset(&mPreprocessedInfo, 0, sizeof(mPreprocessedInfo));
    mCheckMPPFlag.clear();
    mCheckMPPFlag.reserve(MPP_LOGICAL_TYPE_NUM);
    mMetaParcel = NULL;
    mDamageRects.clear();
}

ExynosLayer::~ExynosLayer() {
    if (mMetaParcel != NULL) {
        munmap(mMetaParcel, sizeof(ExynosVideoMeta));
        mMetaParcel = NULL;
    }

    if (mMetaParcelFd >= 0) {
        close(mMetaParcelFd);
        mMetaParcelFd = -1;
    }

    if (mAcquireFence >= 0) {
        mAcquireFence =
                fence_close(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
    }

    if (mPrevAcquireFence != -1)
        mPrevAcquireFence = fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE,
                                        FENCE_IP_UNDEFINED);
}

/**
 * @return float
 */
float ExynosLayer::checkFps(bool increaseCount) {
    uint32_t frameDiff;
    mFrameCount += increaseCount ? 1 : 0;

    nsecs_t now = systemTime();
    if (mLastFpsTime == 0) { // Initialize values
        mLastFpsTime = now;
        mNextLastFpsTime = now;
        // TODO(b/268474771): set the initial FPS to the correct peak refresh rate
        mFps = 120;
        return mFps;
    }

    nsecs_t diff = now - mNextLastFpsTime;
    // Update mLastFrameCount for every 5s, to ensure that FPS calculation is only based on
    // frames in the past at most 10s.
    if (diff >= kLayerFpsStableTimeNs) {
        mLastFrameCount = mNextLastFrameCount;
        mNextLastFrameCount = mFrameCount;

        mLastFpsTime = mNextLastFpsTime;
        mNextLastFpsTime = now;
    }

    bool wasLowFps = (mFps < LOW_FPS_THRESHOLD) ? true : false;

    if (mFrameCount >= mLastFrameCount)
        frameDiff = (mFrameCount - mLastFrameCount);
    else
        frameDiff = (mFrameCount + (UINT_MAX - mLastFrameCount));

    diff = now - mLastFpsTime;
    mFps = (frameDiff * float(s2ns(1))) / diff;

    bool nowLowFps = (mFps < LOW_FPS_THRESHOLD) ? true : false;

    if ((mDisplay->mDisplayControl.handleLowFpsLayers) &&
        (wasLowFps != nowLowFps))
        setGeometryChanged(GEOMETRY_LAYER_FPS_CHANGED);

    return mFps;
}

/**
 * @return float
 */
float ExynosLayer::getFps() {
    return mFps;
}

int32_t ExynosLayer::doPreProcess()
{
    overlay_priority priority = ePriorityLow;
    mIsHdrLayer = false;
    mBufferHasMetaParcel = false;
    mLayerFlag = 0x0;

    mPreprocessedInfo.preProcessed = false;
    mPreprocessedInfo.sourceCrop = mSourceCrop;
    mPreprocessedInfo.displayFrame = mDisplayFrame;
    mPreprocessedInfo.interlacedType = V4L2_FIELD_NONE;
    mPreprocessedInfo.sdrDimRatio = mBrightness;

    if (mCompositionType == HWC2_COMPOSITION_SOLID_COLOR) {
        mLayerFlag |= EXYNOS_HWC_DIM_LAYER;
    } else {
        mLayerFlag &= ~(EXYNOS_HWC_DIM_LAYER);
    }

    if (mLayerBuffer == NULL) {
        if (mOverlayPriority != priority)
            setGeometryChanged(GEOMETRY_LAYER_PRIORITY_CHANGED);

        mOverlayPriority = priority;
        return NO_ERROR;
    }

    VendorGraphicBufferMeta gmeta(mLayerBuffer);

    mPreprocessedInfo.mUsePrivateFormat = false;
    mPreprocessedInfo.mPrivateFormat = gmeta.format;

    if (isFormatYUV(gmeta.format)) {
        mPreprocessedInfo.sourceCrop.top = (int)mSourceCrop.top;
        mPreprocessedInfo.sourceCrop.left = (int)mSourceCrop.left;
        mPreprocessedInfo.sourceCrop.bottom = (int)(mSourceCrop.bottom + 0.9);
        mPreprocessedInfo.sourceCrop.right = (int)(mSourceCrop.right + 0.9);
        mPreprocessedInfo.preProcessed = true;
    }

    if (isFormatYUV(gmeta.format)) {

        ExynosVideoMeta *metaData = NULL;
        int priv_fd = -1;

        if (gmeta.flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_2PRIVATE_DATA)
            priv_fd = gmeta.fd1;
        else if (gmeta.flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_3PRIVATE_DATA)
            priv_fd = gmeta.fd2;

        if (priv_fd >= 0) {

            metaData = (ExynosVideoMeta*)mmap(0, sizeof(ExynosVideoMeta), PROT_READ|PROT_WRITE, MAP_SHARED, priv_fd, 0);

            if (metaData == NULL) {
                HWC_LOGE(mDisplay, "Layer's metadata is NULL!!");
            } else if (metaData == MAP_FAILED) {
                HWC_LOGE(mDisplay, "Layer's metadata map failed!!");
            } else {
                mBufferHasMetaParcel = true;
                if ((metaData->eType & VIDEO_INFO_TYPE_HDR_STATIC) ||
                        (metaData->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC)) {
                    if (allocMetaParcel() == NO_ERROR) {
                        mMetaParcel->eType = metaData->eType;
                        if (metaData->eType & VIDEO_INFO_TYPE_HDR_STATIC) {
                            mMetaParcel->sHdrStaticInfo = metaData->sHdrStaticInfo;
                            HDEBUGLOGD(eDebugLayer, "HWC2: Static metadata min(%d), max(%d)",
                                    mMetaParcel->sHdrStaticInfo.sType1.mMinDisplayLuminance,
                                    mMetaParcel->sHdrStaticInfo.sType1.mMaxDisplayLuminance);
                        }
                        if (metaData->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC) {
                            /* Reserved field for dynamic meta data */
                            /* Currently It's not be used not only HWC but also OMX */
                            mMetaParcel->sHdrDynamicInfo = metaData->sHdrDynamicInfo;
                            HDEBUGLOGD(eDebugLayer, "HWC2: Layer has dynamic metadata");
                        }
                    }
                }
                if (metaData->eType & VIDEO_INFO_TYPE_INTERLACED) {
                    mPreprocessedInfo.interlacedType = metaData->data.dec.nInterlacedType;
                    if (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT) {
                        if ((int)mSourceCrop.left < (int)(gmeta.stride)) {
                            mPreprocessedInfo.sourceCrop.left = (int)mSourceCrop.left + gmeta.stride;
                            mPreprocessedInfo.sourceCrop.right = (int)mSourceCrop.right + gmeta.stride;
                        }
                    }
                    if (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB ||
                            mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT) {
                        mPreprocessedInfo.sourceCrop.top = (int)(mSourceCrop.top)/2;
                        mPreprocessedInfo.sourceCrop.bottom = (int)(mSourceCrop.bottom)/2;
                    }
                }
                if (metaData->eType & VIDEO_INFO_TYPE_CHECK_PIXEL_FORMAT) {
                    mPreprocessedInfo.mUsePrivateFormat = true;
                    mPreprocessedInfo.mPrivateFormat = metaData->nPixelFormat;
                }
                munmap(metaData, sizeof(ExynosVideoMeta));
            }
        }
        mPreprocessedInfo.preProcessed = true;
    }

    exynos_image src_img;
    exynos_image dst_img;
    setSrcExynosImage(&src_img);
    setDstExynosImage(&dst_img);
    ExynosMPP *exynosMPPVG = nullptr;
    if (isFormatYUV(gmeta.format)) {
        auto otfMPPs = ExynosResourceManager::getOtfMPPs();
        auto mpp_it = std::find_if(otfMPPs.begin(), otfMPPs.end(),
                [&src_img](auto m) { return m->isSrcFormatSupported(src_img); });
        exynosMPPVG = mpp_it == otfMPPs.end() ? nullptr : *mpp_it;
    }

    /* Set HDR Flag */
    if(hasHdrInfo(src_img)) mIsHdrLayer = true;

    if (isFormatYUV(gmeta.format) && exynosMPPVG) {
        /*
         * layer's sourceCrop should be aligned
         */
        uint32_t srcCropXAlign = exynosMPPVG->getSrcXOffsetAlign(src_img);
        uint32_t srcCropYAlign = exynosMPPVG->getSrcYOffsetAlign(src_img);
        uint32_t srcCropWidthAlign = exynosMPPVG->getSrcWidthAlign(src_img);
        uint32_t srcCropHeightAlign = exynosMPPVG->getSrcHeightAlign(src_img);
        mPreprocessedInfo.sourceCrop.left = pixel_align((int)mPreprocessedInfo.sourceCrop.left, srcCropXAlign);
        mPreprocessedInfo.sourceCrop.top = pixel_align((int)mPreprocessedInfo.sourceCrop.top, srcCropYAlign);
        mPreprocessedInfo.sourceCrop.right = mPreprocessedInfo.sourceCrop.left +
            pixel_align_down(WIDTH(mPreprocessedInfo.sourceCrop), srcCropWidthAlign);
        mPreprocessedInfo.sourceCrop.bottom = mPreprocessedInfo.sourceCrop.top +
            pixel_align_down(HEIGHT(mPreprocessedInfo.sourceCrop), srcCropHeightAlign);
        mPreprocessedInfo.preProcessed = true;
    }

    if (exynosMPPVG && ((getDrmMode(mLayerBuffer) != NO_DRM) ||
        (mIsHdrLayer == true)))
    {
        if ((mDisplay->mDisplayControl.adjustDisplayFrame == true) &&
            ((mSupportedMPPFlag & (MPP_LOGICAL_DPP_G | MPP_LOGICAL_DPP_VG | MPP_LOGICAL_DPP_VGFS | MPP_LOGICAL_DPP_VGRFS)) == 0))
        {
            /*
             * M2mMPP should be used for DRM, HDR video
             * layer's displayFrame is the source of DPP
             */
            uint32_t cropWidthAlign = exynosMPPVG->getSrcCropWidthAlign(src_img);
            uint32_t cropHeightAlign = exynosMPPVG->getSrcCropHeightAlign(src_img);

            mPreprocessedInfo.displayFrame.right = mDisplayFrame.left +
                pixel_align(WIDTH(mDisplayFrame), cropWidthAlign);
            mPreprocessedInfo.displayFrame.bottom = mDisplayFrame.top +
                pixel_align(HEIGHT(mDisplayFrame), cropHeightAlign);

            if (mPreprocessedInfo.displayFrame.right > (int)(mDisplay->mXres)) {
                mPreprocessedInfo.displayFrame.left = mDisplay->mXres -
                    pixel_align(WIDTH(mPreprocessedInfo.displayFrame), cropWidthAlign);
                mPreprocessedInfo.displayFrame.right = mDisplay->mXres;
            }

            if (mPreprocessedInfo.displayFrame.bottom > (int)(mDisplay->mYres)) {
                mPreprocessedInfo.displayFrame.top = mDisplay->mYres -
                    pixel_align_down(HEIGHT(mPreprocessedInfo.displayFrame), cropHeightAlign);
                mPreprocessedInfo.displayFrame.bottom = mDisplay->mYres;
            }
        }

        uint32_t minDstWidth = exynosMPPVG->getDstMinWidth(dst_img);
        uint32_t minDstHeight = exynosMPPVG->getDstMinHeight(dst_img);
        if ((uint32_t)WIDTH(mDisplayFrame) < minDstWidth) {
            ALOGI("%s DRM layer displayFrame width %d is smaller than otf minWidth %d",
                    mDisplay->mDisplayName.c_str(),
                    WIDTH(mDisplayFrame), minDstWidth);
            mPreprocessedInfo.displayFrame.right = mDisplayFrame.left +
                pixel_align(WIDTH(mDisplayFrame), minDstWidth);

            if (mPreprocessedInfo.displayFrame.right > (int)(mDisplay->mXres)) {
                mPreprocessedInfo.displayFrame.left = mDisplay->mXres -
                    pixel_align(WIDTH(mPreprocessedInfo.displayFrame), minDstWidth);
                mPreprocessedInfo.displayFrame.right = mDisplay->mXres;
            }
        }
        if ((uint32_t)HEIGHT(mDisplayFrame) < minDstHeight) {
            ALOGI("%s DRM layer displayFrame height %d is smaller than vpp minHeight %d",
                    mDisplay->mDisplayName.c_str(),
                    HEIGHT(mDisplayFrame), minDstHeight);
            mPreprocessedInfo.displayFrame.bottom = mDisplayFrame.top +
                pixel_align(HEIGHT(mDisplayFrame), minDstHeight);

            if (mPreprocessedInfo.displayFrame.bottom > (int)(mDisplay->mYres)) {
                mPreprocessedInfo.displayFrame.top = mDisplay->mYres -
                    pixel_align(HEIGHT(mPreprocessedInfo.displayFrame), minDstHeight);
                mPreprocessedInfo.displayFrame.bottom = mDisplay->mYres;
            }
        }
        mPreprocessedInfo.preProcessed = true;
    }

    if (VendorGraphicBufferMeta::get_usage(mLayerBuffer) &
               toUnderlying(AidlBufferUsage::FRONT_BUFFER)) {
        priority = ePriorityMax;
    } else if (getDrmMode(mLayerBuffer) != NO_DRM) {
        priority = ePriorityMax;
    } else if (mIsHdrLayer) {
        if (isFormatRgb(gmeta.format))
            priority = ePriorityMax;
        else
            priority = ePriorityHigh;
    } else if (isFormatYUV(gmeta.format)) {
        priority = ePriorityHigh;
    } else if ((mDisplay->mDisplayControl.cursorSupport == true) &&
               (mCompositionType == HWC2_COMPOSITION_CURSOR)) {
        priority = ePriorityMid;
    } else {
        priority = ePriorityLow;
    }

    if (mOverlayPriority != priority)
        setGeometryChanged(GEOMETRY_LAYER_PRIORITY_CHANGED);

    mOverlayPriority = priority;

    return NO_ERROR;
}

int32_t ExynosLayer::setCursorPosition(int32_t x, int32_t y) {
    return mDisplay->setCursorPositionAsync(x, y);
}


int32_t ExynosLayer::setLayerBuffer(buffer_handle_t buffer, int32_t acquireFence) {

    /* TODO : Exception here ? */
    //TODO mGeometryChanged  here

    uint64_t internal_format = 0;

    if (mDisplay->mPlugState == false)
        buffer = NULL;

    if (buffer != NULL) {
        if (VendorGraphicBufferMeta::get_fd(buffer,0) < 0)
            return HWC2_ERROR_BAD_LAYER;
    }

    VendorGraphicBufferMeta gmeta(mLayerBuffer);
    internal_format = gmeta.format;

    if ((mLayerBuffer == NULL) || (buffer == NULL))
        setGeometryChanged(GEOMETRY_LAYER_UNKNOWN_CHANGED);
    else {
        if (getDrmMode(VendorGraphicBufferMeta::get_producer_usage(mLayerBuffer)) != getDrmMode(gmeta.producer_usage))
            setGeometryChanged(GEOMETRY_LAYER_DRM_CHANGED);
        if (VendorGraphicBufferMeta::get_format(mLayerBuffer) != gmeta.format)
            setGeometryChanged(GEOMETRY_LAYER_FORMAT_CHANGED);
        if ((VendorGraphicBufferMeta::get_usage(buffer) &
                    toUnderlying(AidlBufferUsage::FRONT_BUFFER)) !=
                (VendorGraphicBufferMeta::get_usage(mLayerBuffer) &
                    toUnderlying(AidlBufferUsage::FRONT_BUFFER)))
            setGeometryChanged(GEOMETRY_LAYER_FRONT_BUFFER_USAGE_CHANGED);
    }

    {
        Mutex::Autolock lock(mDisplay->mDRMutex);
        mLayerBuffer = buffer;
        checkFps(mLastLayerBuffer != mLayerBuffer);
        if (mLayerBuffer != mLastLayerBuffer) {
            mLastUpdateTime = systemTime(CLOCK_MONOTONIC);
            if (mRequestedCompositionType != HWC2_COMPOSITION_REFRESH_RATE_INDICATOR)
                mDisplay->mBufferUpdates++;
        }
    }
    mPrevAcquireFence =
            fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
    mAcquireFence = fence_close(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);

    mAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, acquireFence);
    mPrevAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
                                           hwc_dup(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE,
                                                   FENCE_IP_LAYER, true));
    if (mReleaseFence >= 0)
        HWC_LOGE(NULL, "Layer's release fence is not initialized");
    mReleaseFence = -1;
#ifdef DISABLE_FENCE
    if (mAcquireFence >= 0)
        fence_close(mAcquireFence);
    mAcquireFence = -1;
#endif

    /* Set Compression Information from GraphicBuffer */
    uint32_t prevCompressionType = mCompressionInfo.type;
    mCompressionInfo = getCompressionInfo(mLayerBuffer);
    if (mCompressionInfo.type != prevCompressionType)
        setGeometryChanged(GEOMETRY_LAYER_COMPRESSED_CHANGED);

    if (buffer != NULL) {
        /*
         * HAL_DATASPACE_V0_JFIF = HAL_DATASPACE_STANDARD_BT601_625 |
         * HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_FULL,
         */
        if (gmeta.format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
            setLayerDataspace(HAL_DATASPACE_V0_JFIF);
    } else {
        setLayerDataspace(HAL_DATASPACE_UNKNOWN);
    }

    HDEBUGLOGD(eDebugFence,
               "layers bufferHandle: %p, mDataSpace: 0x%8x, acquireFence: %d, compressionType: "
               "0x%x, internal_format: 0x%" PRIx64 "",
               mLayerBuffer, mDataSpace, mAcquireFence, mCompressionInfo.type, internal_format);

    return 0;
}


int32_t ExynosLayer::setLayerSurfaceDamage(hwc_region_t damage) {

    mDamageNum = damage.numRects;
    mDamageRects.clear();

    if (mDamageNum == 0) return 0;

    for (size_t i = 0; i<mDamageNum; i++){
        mDamageRects.push_back(damage.rects[i]);
    }

    return 0;
}

int32_t ExynosLayer::setLayerBlendMode(int32_t /*hwc2_blend_mode_t*/ mode) {

    //TODO mGeometryChanged  here
    if (mode < 0)
        return HWC2_ERROR_BAD_PARAMETER;
    if (mBlending != mode)
        setGeometryChanged(GEOMETRY_LAYER_BLEND_CHANGED);
    mBlending = mode;
    return HWC2_ERROR_NONE;
}


int32_t ExynosLayer::setLayerColor(hwc_color_t color) {
    /* TODO : Implementation here */
    mColor = color;
    return 0;
}

int32_t ExynosLayer::setLayerCompositionType(int32_t /*hwc2_composition_t*/ type) {

    if (type < 0)
        return HWC2_ERROR_BAD_PARAMETER;

    // FIXME: HWC2_COMPOSITION_SCREENSHOT is not defined in AOSP
    //        HWC guys should fix this.
#if 0
    if (mDisplay->mType == HWC_DISPLAY_PRIMARY)
        if (type == HWC2_COMPOSITION_SCREENSHOT)
            type = HWC2_COMPOSITION_DEVICE;
#endif

    if (type != mCompositionType) {
        setGeometryChanged(GEOMETRY_LAYER_TYPE_CHANGED);
    }

    mCompositionType = type;
    mRequestedCompositionType = type;

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerDataspace(int32_t /*android_dataspace_t*/ dataspace) {
    android_dataspace currentDataSpace = (android_dataspace_t)dataspace;
    if ((mLayerBuffer != NULL) && (VendorGraphicBufferMeta::get_format(mLayerBuffer) == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL))
        currentDataSpace = HAL_DATASPACE_V0_JFIF;
    else {
        /* Change legacy dataspace */
        switch (dataspace) {
        case HAL_DATASPACE_SRGB_LINEAR:
            currentDataSpace = HAL_DATASPACE_V0_SRGB_LINEAR;
            break;
        case HAL_DATASPACE_SRGB:
            currentDataSpace = HAL_DATASPACE_V0_SRGB;
            break;
        case HAL_DATASPACE_JFIF:
            currentDataSpace = HAL_DATASPACE_V0_JFIF;
            break;
        case HAL_DATASPACE_BT601_625:
            currentDataSpace = HAL_DATASPACE_V0_BT601_625;
            break;
        case HAL_DATASPACE_BT601_525:
            currentDataSpace = HAL_DATASPACE_V0_BT601_525;
            break;
        case HAL_DATASPACE_BT709:
            currentDataSpace = HAL_DATASPACE_V0_BT709;
            break;
        default:
            currentDataSpace = (android_dataspace)dataspace;
            break;
        }
    }

    if (currentDataSpace != mDataSpace) {
        setGeometryChanged(GEOMETRY_LAYER_DATASPACE_CHANGED);
        // invalidate metadata if dataspace is changed. need metadata update
        // to be after dataspace update.
        if (mMetaParcel != nullptr) {
            mMetaParcel->eType = VIDEO_INFO_TYPE_INVALID;
        }
    }
    mDataSpace = currentDataSpace;

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerDisplayFrame(hwc_rect_t frame) {

    if ((frame.left != mDisplayFrame.left) ||
        (frame.top != mDisplayFrame.top) ||
        (frame.right != mDisplayFrame.right) ||
        (frame.bottom != mDisplayFrame.bottom))
        setGeometryChanged(GEOMETRY_LAYER_DISPLAYFRAME_CHANGED);
    mDisplayFrame = frame;

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerPlaneAlpha(float alpha) {
    if (alpha < 0.0f || alpha > 1.0f) {
        ALOGE("%s: invalid alpha %f", __func__, alpha);
        return HWC2_ERROR_BAD_PARAMETER;
    }

    if ((mPlaneAlpha != alpha) && ((mPlaneAlpha == 0.0) || (alpha == 0.0)))
        setGeometryChanged(GEOMETRY_LAYER_IGNORE_CHANGED);

    mPlaneAlpha = alpha;

    if (mPlaneAlpha > 0.0)
        mLayerFlag &= ~(EXYNOS_HWC_IGNORE_LAYER);
    else
        mLayerFlag |= EXYNOS_HWC_IGNORE_LAYER;

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerSidebandStream(const native_handle_t* __unused stream) {
    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerSourceCrop(hwc_frect_t crop) {
    if ((crop.left != mSourceCrop.left) ||
        (crop.top != mSourceCrop.top) ||
        (crop.right != mSourceCrop.right) ||
        (crop.bottom != mSourceCrop.bottom)) {
        setGeometryChanged(GEOMETRY_LAYER_SOURCECROP_CHANGED);
        mSourceCrop = crop;
    }

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerTransform(int32_t /*hwc_transform_t*/ transform) {

    if (mTransform != transform) {
        setGeometryChanged(GEOMETRY_LAYER_TRANSFORM_CHANGED);
        mTransform = transform;
    }

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerVisibleRegion(hwc_region_t visible) {

    mVisibleRegionScreen = visible;

    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerZOrder(uint32_t z) {
    if (mZOrder != z) {
        setGeometryChanged(GEOMETRY_LAYER_ZORDER_CHANGED);
        mZOrder = z;
    }
    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerPerFrameMetadata(uint32_t numElements,
        const int32_t* /*hw2_per_frame_metadata_key_t*/ keys, const float* metadata)
{
    if (allocMetaParcel() != NO_ERROR)
        return -1;
    unsigned int multipliedVal = 50000;
    mMetaParcel->eType =
        static_cast<ExynosVideoInfoType>(mMetaParcel->eType | VIDEO_INFO_TYPE_HDR_STATIC);
    for (uint32_t i = 0; i < numElements; i++) {
        HDEBUGLOGD(eDebugLayer, "HWC2: setLayerPerFrameMetadata key(%d), value(%7.5f)",
                keys[i], metadata[i]);
        switch (keys[i]) {
            case HWC2_DISPLAY_RED_PRIMARY_X:
                mMetaParcel->sHdrStaticInfo.sType1.mR.x =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_DISPLAY_RED_PRIMARY_Y:
                mMetaParcel->sHdrStaticInfo.sType1.mR.y =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_DISPLAY_GREEN_PRIMARY_X:
                mMetaParcel->sHdrStaticInfo.sType1.mG.x =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_DISPLAY_GREEN_PRIMARY_Y:
                mMetaParcel->sHdrStaticInfo.sType1.mG.y =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_DISPLAY_BLUE_PRIMARY_X:
                mMetaParcel->sHdrStaticInfo.sType1.mB.x =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_DISPLAY_BLUE_PRIMARY_Y:
                mMetaParcel->sHdrStaticInfo.sType1.mB.y =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_WHITE_POINT_X:
                mMetaParcel->sHdrStaticInfo.sType1.mW.x =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_WHITE_POINT_Y:
                mMetaParcel->sHdrStaticInfo.sType1.mW.y =
                    (unsigned int)(metadata[i] * multipliedVal);
                break;
            case HWC2_MAX_LUMINANCE:
                mMetaParcel->sHdrStaticInfo.sType1.mMaxDisplayLuminance =
                    (unsigned int)(metadata[i] * 10000);
                break;
            case HWC2_MIN_LUMINANCE:
                mMetaParcel->sHdrStaticInfo.sType1.mMinDisplayLuminance =
                    (unsigned int)(metadata[i] * 10000);
                break;
            case HWC2_MAX_CONTENT_LIGHT_LEVEL:
                /* Should be checked */
                mMetaParcel->sHdrStaticInfo.sType1.mMaxContentLightLevel =
                    (unsigned int)(metadata[i]);
                break;
            case HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL:
                /* Should be checked */
                mMetaParcel->sHdrStaticInfo.sType1.mMaxFrameAverageLightLevel =
                    (unsigned int)(metadata[i]);
                break;
            default:
                return HWC2_ERROR_UNSUPPORTED;
        }
    }
    return NO_ERROR;
}

int32_t ExynosLayer::setLayerPerFrameMetadataBlobs(uint32_t numElements, const int32_t* keys, const uint32_t* sizes,
        const uint8_t* metadata)
{
    const uint8_t *metadata_start = metadata;
    for (uint32_t i = 0; i < numElements; i++) {
        HDEBUGLOGD(eDebugLayer, "HWC2: setLayerPerFrameMetadataBlobs key(%d)", keys[i]);
        switch (keys[i]) {
        case HWC2_HDR10_PLUS_SEI:
            if (allocMetaParcel() == NO_ERROR) {
                mMetaParcel->eType =
                    static_cast<ExynosVideoInfoType>(mMetaParcel->eType | VIDEO_INFO_TYPE_HDR_DYNAMIC);
                ExynosHdrDynamicInfo *info = &(mMetaParcel->sHdrDynamicInfo);
                Exynos_parsing_user_data_registered_itu_t_t35(info, (void*)metadata_start,
                                                              sizes[i]);
            } else {
                ALOGE("Layer has no metaParcel!");
                return HWC2_ERROR_UNSUPPORTED;
            }
            break;
        default:
            return HWC2_ERROR_BAD_PARAMETER;
        }
        metadata_start += sizes[i];
    }
    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerColorTransform(const float* matrix)
{
    mLayerColorTransform.enable = true;
    for (uint32_t i = 0; i < TRANSFORM_MAT_SIZE; i++)
    {
        mLayerColorTransform.mat[i] = matrix[i];
    }

    return 0;
}

int32_t ExynosLayer::setLayerGenericMetadata(hwc2_layer_t __unused layer,
        uint32_t __unused keyLength, const char* __unused key,
        bool __unused mandatory, uint32_t __unused valueLength, const uint8_t* __unused value)
{
    return HWC2_ERROR_UNSUPPORTED;
}

int32_t ExynosLayer::setLayerBrightness(float brightness) {
    if (mDisplay->mType == HWC_DISPLAY_EXTERNAL && mDisplay->mBrightnessController == nullptr) {
        if (brightness == 1.0f) {
            return HWC2_ERROR_NONE;
        } else {
            HWC_LOGE(mDisplay, "[ExternalDisplay layer] setLayerBrightness != 1.0");
            return HWC2_ERROR_BAD_PARAMETER;
        }
    }

    if (mDisplay->mBrightnessController == nullptr ||
        !mDisplay->mBrightnessController->validateLayerBrightness(brightness)) {
        return HWC2_ERROR_BAD_PARAMETER;
    }

    if (mBrightness != brightness) {
        // Trigger display validation in case client composition is needed.
        setGeometryChanged(GEOMETRY_LAYER_WHITEPOINT_CHANGED);
        mBrightness = brightness;
    }
    return HWC2_ERROR_NONE;
}

int32_t ExynosLayer::setLayerBlockingRegion(const std::vector<hwc_rect_t>& blockingRegion) {
    hwc_rect_t maxRect;

    for (auto rect : blockingRegion) {
        maxRect = std::max(maxRect, rect, [](const hwc_rect_t& lhs, const hwc_rect_t& rhs) {
            return rectSize(lhs) < rectSize(rhs);
        });
    }

    mBlockingRect = maxRect;

    return HWC2_ERROR_NONE;
}

void ExynosLayer::resetValidateData()
{
    mValidateCompositionType = HWC2_COMPOSITION_INVALID;
    mOtfMPP = NULL;
    mM2mMPP = NULL;
    mOverlayInfo = 0x0;
    mWindowIndex = 0;
}

int32_t ExynosLayer::setSrcExynosImage(exynos_image *src_img)
{
    buffer_handle_t handle = mLayerBuffer;
    if (isDimLayer()) {
        src_img->format = HAL_PIXEL_FORMAT_RGBA_8888;
        src_img->usageFlags = 0xb00;
        src_img->bufferHandle = 0;

        src_img->x = 0;
        src_img->y = 0;

        if (mDisplay != NULL) {
            src_img->fullWidth = src_img->w = mDisplay->mXres;
            src_img->fullHeight = src_img->h = mDisplay->mYres;
        } else {
            src_img->fullWidth = src_img->w = 1440;
            src_img->fullHeight = src_img->h = 2560;
        }

        src_img->layerFlags = mLayerFlag;
        src_img->acquireFenceFd = mAcquireFence;
        src_img->releaseFenceFd = -1;
        src_img->dataSpace = HAL_DATASPACE_V0_SRGB;
        src_img->blending = mBlending;
        src_img->transform = mTransform;
        src_img->compressionInfo = mCompressionInfo;
        src_img->planeAlpha = mPlaneAlpha;
        src_img->zOrder = mZOrder;


        return NO_ERROR;
    }

    if (handle == NULL) {
        src_img->fullWidth = 0;
        src_img->fullHeight = 0;
        src_img->format = 0;
        src_img->usageFlags = 0x0;
        src_img->bufferHandle = handle;
    } else {
        VendorGraphicBufferMeta gmeta(handle);

        if ((mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB) ||
            (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT))
        {
            src_img->fullWidth = (gmeta.stride * 2);
            src_img->fullHeight = pixel_align_down((gmeta.vstride / 2), 2);
        } else {
            src_img->fullWidth = gmeta.stride;
            // The BW VDEC will generate AFBC streams based on the initial requested height
            // instead of the adjusted vstride from gralloc.
            src_img->fullHeight = (isAFBC32x8(mCompressionInfo) &&
                                   (gmeta.producer_usage & VendorGraphicBufferUsage::BW))
                    ? gmeta.height
                    : gmeta.vstride;
        }
        if (!mPreprocessedInfo.mUsePrivateFormat)
            src_img->format = gmeta.format;
        else
            src_img->format = mPreprocessedInfo.mPrivateFormat;
        src_img->usageFlags = gmeta.producer_usage;
        src_img->bufferHandle = handle;
    }
    src_img->x = (int)mPreprocessedInfo.sourceCrop.left;
    src_img->y = (int)mPreprocessedInfo.sourceCrop.top;
    src_img->w = (int)mPreprocessedInfo.sourceCrop.right - (int)mPreprocessedInfo.sourceCrop.left;
    src_img->h = (int)mPreprocessedInfo.sourceCrop.bottom - (int)mPreprocessedInfo.sourceCrop.top;
    if ((mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB) ||
        (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT))
    {
        while ((src_img->h % 2 != 0) ||
               (src_img->h > src_img->fullHeight)) {
            src_img->h -= 1;
        }
    }
    src_img->layerFlags = mLayerFlag;
    src_img->acquireFenceFd = mAcquireFence;
    src_img->releaseFenceFd = -1;

    src_img->dataSpace = mDataSpace;
    if(src_img->dataSpace == HAL_DATASPACE_UNKNOWN)
        src_img->dataSpace = HAL_DATASPACE_V0_SRGB;

    src_img->blending = mBlending;
    src_img->transform = mTransform;
    src_img->compressionInfo = mCompressionInfo;
    src_img->planeAlpha = mPlaneAlpha;
    src_img->zOrder = mZOrder;
    /* Copy HDR metadata */
    memset(&(src_img->metaParcel), 0, sizeof(src_img->metaParcel));
    src_img->metaType = VIDEO_INFO_TYPE_INVALID;
    if (mMetaParcel != NULL) {
        memcpy(&(src_img->metaParcel), mMetaParcel, sizeof(src_img->metaParcel));
        src_img->metaType = mMetaParcel->eType;
        src_img->hasMetaParcel = true;
    } else {
        src_img->hasMetaParcel = false;
    }

    src_img->needColorTransform = mLayerColorTransform.enable;
    src_img->needPreblending = mNeedPreblending;

    return NO_ERROR;
}

int32_t ExynosLayer::setDstExynosImage(exynos_image *dst_img)
{
    buffer_handle_t handle = mLayerBuffer;

    if (handle == NULL) {
        dst_img->usageFlags = 0x0;
    } else {
        dst_img->usageFlags = VendorGraphicBufferMeta::get_producer_usage(handle);
    }

    if (isDimLayer()) {
        dst_img->usageFlags = 0xb00;
    }

    dst_img->format = DEFAULT_MPP_DST_FORMAT;
    dst_img->x = mPreprocessedInfo.displayFrame.left;
    dst_img->y = mPreprocessedInfo.displayFrame.top;
    dst_img->w = (mPreprocessedInfo.displayFrame.right - mPreprocessedInfo.displayFrame.left);
    dst_img->h = (mPreprocessedInfo.displayFrame.bottom - mPreprocessedInfo.displayFrame.top);
    dst_img->layerFlags = mLayerFlag;
    dst_img->acquireFenceFd = -1;
    dst_img->releaseFenceFd = -1;
    dst_img->bufferHandle = NULL;
    dst_img->dataSpace = HAL_DATASPACE_UNKNOWN;
    if (mDisplay != NULL) {
        dst_img->fullWidth = mDisplay->mXres;
        dst_img->fullHeight = mDisplay->mYres;
        if (mDisplay->mColorMode != HAL_COLOR_MODE_NATIVE) {
            dst_img->dataSpace = colorModeToDataspace(mDisplay->mColorMode);
        } else {
            if (hasHdrInfo(mDataSpace)) {
                android_dataspace hdrDataSpace =
                    (android_dataspace)(HAL_DATASPACE_STANDARD_DCI_P3 | HAL_DATASPACE_TRANSFER_GAMMA2_2 | HAL_DATASPACE_RANGE_LIMITED);
                if (mDisplay->mType == HWC_DISPLAY_EXTERNAL) {
                    ExynosExternalDisplay *externalDisplay = (ExynosExternalDisplay*)mDisplay;
                    if (externalDisplay->mExternalHdrSupported == true)
                        dst_img->dataSpace = HAL_DATASPACE_UNKNOWN;
                    else
                        dst_img->dataSpace = hdrDataSpace;
                } else {
                    dst_img->dataSpace = hdrDataSpace;
                }
            }
        }
    } else {
        HWC_LOGE(NULL, "mDisplay is NULL");
    }
    dst_img->blending = mBlending;
    dst_img->transform = 0;
    dst_img->compressionInfo.type = COMP_TYPE_NONE;
    dst_img->planeAlpha = mPlaneAlpha;
    dst_img->zOrder = mZOrder;

    /* Copy HDR metadata */
    memset(&(dst_img->metaParcel), 0, sizeof(dst_img->metaParcel));
    dst_img->metaType = VIDEO_INFO_TYPE_INVALID;
    if (mMetaParcel != NULL) {
        memcpy(&(dst_img->metaParcel), mMetaParcel, sizeof(dst_img->metaParcel));
        dst_img->metaType = mMetaParcel->eType;
        dst_img->hasMetaParcel = true;
    } else {
        dst_img->hasMetaParcel = false;
    }

    return NO_ERROR;
}

int32_t ExynosLayer::resetAssignedResource()
{
    int32_t ret = NO_ERROR;
    if (mM2mMPP != NULL) {
        HDEBUGLOGD(eDebugResourceManager, "\t\t %s mpp is reset", mM2mMPP->mName.c_str());
        mM2mMPP->resetAssignedState(this);
        mM2mMPP = NULL;
    }
    if (mOtfMPP != NULL) {
        HDEBUGLOGD(eDebugResourceManager, "\t\t %s mpp is reset", mOtfMPP->mName.c_str());
        mOtfMPP->resetAssignedState();
        mOtfMPP = NULL;
    }
    return ret;
}

bool ExynosLayer::checkBtsCap(const uint32_t bts_refresh_rate) {
    if (mOtfMPP == nullptr) return true;

    exynos_image src_img;
    exynos_image dst_img;
    setSrcExynosImage(&src_img);
    setDstExynosImage(&dst_img);
    if (mOtfMPP->checkSpecificRestriction(bts_refresh_rate, src_img, dst_img)) {
        return false;
    }

    const bool isPerpendicular = !!(src_img.transform & HAL_TRANSFORM_ROT_90);
    const uint32_t srcWidth = isPerpendicular ? src_img.h : src_img.w;
    const uint32_t srcHeight = isPerpendicular ? src_img.w : src_img.h;
    const bool scaleDown = (srcWidth > dst_img.w || srcHeight > dst_img.h);

    if (!scaleDown) return true;

    const float resolution = float(src_img.w) * float(src_img.h) * bts_refresh_rate / 1000;

    return mOtfMPP->checkDownscaleCap(resolution, float(dst_img.h) / float(mDisplay->mYres));
}

void ExynosLayer::setSrcAcquireFence() {
    if (mAcquireFence == -1 && mPrevAcquireFence != -1) {
        mAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
                                           hwc_dup(mPrevAcquireFence, mDisplay,
                                                   FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER));
    } else if (mAcquireFence != -1) {
        setFenceInfo(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
                     HwcFenceDirection::FROM);
    }
}

void ExynosLayer::dump(String8& result)
{
    int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    int32_t fd, fd1, fd2;
    uint64_t unique_id;
    if (mLayerBuffer != NULL)
    {
        VendorGraphicBufferMeta gmeta(mLayerBuffer);
        format = gmeta.format;
        fd = gmeta.fd;
        fd1 = gmeta.fd1;
        fd2 = gmeta.fd2;
        unique_id = gmeta.unique_id;
    } else {
        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
        fd = -1;
        fd1 = -1;
        fd2 = -1;
        unique_id = 0;
    }

    {
        TableBuilder tb;
        tb.add("zOrder", mZOrder)
          .add("priority", mOverlayPriority);
        if (mCompositionType == HWC2_COMPOSITION_SOLID_COLOR) {
            tb.add("color", std::vector<uint64_t>({mColor.r, mColor.g, mColor.b, mColor.a}), true);
        } else {
            tb.add("handle", mLayerBuffer)
                    .add("fd", std::vector<int>({fd, fd1, fd2}))
                    .add("compression", getCompressionStr(mCompressionInfo).c_str());
        }
        tb.add("format", getFormatStr(format, mCompressionInfo.type).c_str())
                .add("dataSpace", mDataSpace, true)
                .add("colorTr", mLayerColorTransform.enable)
                .add("blend", mBlending, true)
                .add("planeAlpha", mPlaneAlpha)
                .add("fps", mFps);
        result.append(tb.build().c_str());
    }

    result.append(TableBuilder()
                          .add("sourceCrop",
                               std::vector<double>({mPreprocessedInfo.sourceCrop.left,
                                                    mPreprocessedInfo.sourceCrop.top,
                                                    mPreprocessedInfo.sourceCrop.right,
                                                    mPreprocessedInfo.sourceCrop.bottom}))
                          .add("dispFrame",
                               std::vector<int>({mPreprocessedInfo.displayFrame.left,
                                                 mPreprocessedInfo.displayFrame.top,
                                                 mPreprocessedInfo.displayFrame.right,
                                                 mPreprocessedInfo.displayFrame.bottom}))
                          .add("blockRect",
                               std::vector<int>({mBlockingRect.left, mBlockingRect.top,
                                                 mBlockingRect.right, mBlockingRect.bottom}))
                          .add("tr", mTransform, true)
                          .add("windowIndex", mWindowIndex)
                          .add("type", mCompositionType)
                          .add("exynosType", mExynosCompositionType)
                          .add("validateType", mValidateCompositionType)
                          .add("overlayInfo", mOverlayInfo, true)
                          .add("GrallocBufferId", unique_id)
                          .build()
                          .c_str());

    result.append(TableBuilder()
                          .add("MPPFlag", mSupportedMPPFlag, true)
                          .add("dim ratio", mPreprocessedInfo.sdrDimRatio)
                          .build()
                          .c_str());

    if ((mDisplay != NULL) && (mDisplay->mResourceManager != NULL)) {
        result.appendFormat("MPPFlags for otfMPP\n");
        for (uint32_t i = 0; i < mDisplay->mResourceManager->getOtfMPPSize(); i++) {
            result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getOtfMPP(i)->mName.c_str(),
                    mCheckMPPFlag[mDisplay->mResourceManager->getOtfMPP(i)->mLogicalType]);
        }
        result.appendFormat("\n");
        result.appendFormat("MPPFlags for m2mMPP\n");
        for (uint32_t i = 0; i < mDisplay->mResourceManager->getM2mMPPSize(); i++) {
            result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getM2mMPP(i)->mName.c_str(),
                    mCheckMPPFlag[mDisplay->mResourceManager->getM2mMPP(i)->mLogicalType]);
            if ((i!=0) && (i%4==0)) result.appendFormat("\n");
        }
        result.appendFormat("\n");
    }
    result.appendFormat("acquireFence: %d\n", mAcquireFence);
    if ((mOtfMPP == NULL) && (mM2mMPP == NULL))
        result.appendFormat("\tresource is not assigned.\n");
    if (mOtfMPP != NULL)
        result.appendFormat("\tassignedMPP: %s\n", mOtfMPP->mName.c_str());
    if (mM2mMPP != NULL)
        result.appendFormat("\tassignedM2mMPP: %s\n", mM2mMPP->mName.c_str());
    result.appendFormat("\tdump midImg\n");
    dumpExynosImage(result, mMidImg);

}

void ExynosLayer::printLayer()
{
    int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    int32_t fd, fd1, fd2;
    String8 result;
    if (mLayerBuffer != NULL)
    {
        VendorGraphicBufferMeta gmeta(mLayerBuffer);
        format = gmeta.format;
        fd = gmeta.fd;
        fd1 = gmeta.fd1;
        fd2 = gmeta.fd2;
    } else {
        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
        fd = -1;
        fd1 = -1;
        fd2 = -1;
    }
    result.appendFormat("handle: %p [fd: %d, %d, %d], acquireFence: %d, tr: 0x%2x, compression: "
                        "%s, dataSpace: 0x%8x, format: %s\n",
                        mLayerBuffer, fd, fd1, fd2, mAcquireFence, mTransform,
                        getCompressionStr(mCompressionInfo).c_str(), mDataSpace,
                        getFormatStr(format, mCompressionInfo.type).c_str());
    result.appendFormat("\tblend: 0x%4x, planeAlpha: %3.1f, zOrder: %d, color[0x%2x, 0x%2x, 0x%2x, 0x%2x]\n",
            mBlending, mPlaneAlpha, mZOrder, mColor.r, mColor.g, mColor.b, mColor.a);
    result.appendFormat("\tfps: %.2f, priority: %d, windowIndex: %d\n", mFps, mOverlayPriority,
                        mWindowIndex);
    result.appendFormat("\tsourceCrop[%7.1f,%7.1f,%7.1f,%7.1f], dispFrame[%5d,%5d,%5d,%5d]\n",
            mSourceCrop.left, mSourceCrop.top, mSourceCrop.right, mSourceCrop.bottom,
            mDisplayFrame.left, mDisplayFrame.top, mDisplayFrame.right, mDisplayFrame.bottom);
    result.appendFormat("\ttype: %2d, exynosType: %2d, validateType: %2d\n",
            mCompositionType, mExynosCompositionType, mValidateCompositionType);
    result.appendFormat("\toverlayInfo: 0x%8x, supportedMPPFlag: 0x%8x, geometryChanged: 0x%" PRIx64 "\n",
            mOverlayInfo, mSupportedMPPFlag, mGeometryChanged);

    if ((mDisplay != NULL) && (mDisplay->mResourceManager != NULL)) {
        result.appendFormat("MPPFlags for otfMPP\n");
        for (uint32_t i = 0; i < mDisplay->mResourceManager->getOtfMPPSize(); i++) {
            result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getOtfMPP(i)->mName.c_str(),
                    mCheckMPPFlag[mDisplay->mResourceManager->getOtfMPP(i)->mLogicalType]);
        }
        result.appendFormat("\n");
        result.appendFormat("MPPFlags for m2mMPP\n");
        for (uint32_t i = 0; i < mDisplay->mResourceManager->getM2mMPPSize(); i++) {
            result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getM2mMPP(i)->mName.c_str(),
                    mCheckMPPFlag[mDisplay->mResourceManager->getM2mMPP(i)->mLogicalType]);
            if ((i!=0) && (i%4==0)) result.appendFormat("\n");
        }
        result.appendFormat("\n");
    }

    ALOGD("%s", result.c_str());
    result.clear();

    if ((mOtfMPP == NULL) && (mM2mMPP == NULL))
        ALOGD("\tresource is not assigned.");
    if (mOtfMPP != NULL)
        ALOGD("\tassignedMPP: %s", mOtfMPP->mName.c_str());
    if (mM2mMPP != NULL)
        ALOGD("\tassignedM2mMPP: %s", mM2mMPP->mName.c_str());
    ALOGD("\t++ dump midImg ++");
    dumpExynosImage(result, mMidImg);
    ALOGD("%s", result.c_str());

}

void ExynosLayer::setGeometryChanged(uint64_t changedBit)
{
    mLastUpdateTime = systemTime(CLOCK_MONOTONIC);
    mGeometryChanged |= changedBit;
    if (mRequestedCompositionType != HWC2_COMPOSITION_REFRESH_RATE_INDICATOR)
        mDisplay->setGeometryChanged(changedBit);
}

int ExynosLayer::allocMetaParcel()
{
    /* Already allocated */
    if ((mMetaParcelFd >= 0) &&
        (mMetaParcel != NULL))
        return NO_ERROR;

    if (mMetaParcelFd < 0) {
         int ionFd = exynos_ion_open();
         if (ionFd >= 0) {
             mMetaParcelFd = exynos_ion_alloc(ionFd, sizeof(ExynosVideoMeta), EXYNOS_ION_HEAP_SYSTEM_MASK, 0);
             if (mMetaParcelFd < 0) {
                 ALOGE("Failed to ion alloc for metadata parcel");
                 return -1;
             }
             exynos_ion_close(ionFd);
         } else {
             ALOGE("Failed to open ion fd");
             return -1;
         }
    }

    mMetaParcel =
        (ExynosVideoMeta*)mmap(0, sizeof(ExynosVideoMeta), PROT_READ|PROT_WRITE, MAP_SHARED, mMetaParcelFd, 0);
    if (mMetaParcel == NULL) {
        ALOGE("Failed to map metadata parcel");
        return -1;
    }

    return NO_ERROR;
}

bool ExynosLayer::isDimLayer()
{
    if (mLayerFlag & EXYNOS_HWC_DIM_LAYER)
        return true;
    return false;
}
