/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

//!
//! \file     media_scalability.cpp
//! \brief    Defines the common interface for media scalability
//! \details  The media scalability interface is further sub-divided by component,
//!           this file is for the base interface which is shared by all components.
//!

#include "media_scalability.h"
#include "mos_os_virtualengine.h"

MediaScalability::MediaScalability(MediaContext *mediaContext) :
    m_mediaContext(mediaContext) 
{
    if (m_mediaContext == nullptr)
    {
        SCALABILITY_ASSERTMESSAGE("mediaContext is null ptr! Construct MediaScalability failed!");
    }
}

bool MediaScalability::IsScalabilityModeMatched(ScalabilityPars *params)
{
    bool isMatched = false;


#if (_DEBUG || _RELEASE_INTERNAL)

    if (m_osInterface == nullptr)
    {
        return false;
    }
    if (m_osInterface->bEnableDbgOvrdInVE)
    {
        isMatched = true;
    }
    else
#endif
    {
        isMatched = m_scalabilityOption->IsScalabilityOptionMatched(params);
    }

    return isMatched;
}

bool MediaScalability::IsScalabilityModeMatched(MediaScalabilityOption &scalabOption)
{
#if (_DEBUG || _RELEASE_INTERNAL)
    if (m_osInterface == nullptr)
    {
        return false;
    }
    if (m_osInterface->bEnableDbgOvrdInVE)
    {
        return true;
    }
    else
#endif
    {
        return m_scalabilityOption->IsScalabilityOptionMatched(scalabOption);
    }
}

bool MediaScalability::IsGpuCtxCreateOptionMatched(PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption1, PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption2)
{
    bool isMatched = false;
    //Current only need new GpuCtxCreateOption when LRCACount changed.
    //It can be improved if needed.
    if (gpuCtxCreateOption1->LRCACount == gpuCtxCreateOption2->LRCACount)
    {
        isMatched = true;
    }
    return isMatched;
}

MOS_STATUS MediaScalability::VerifySpaceAvailable(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
{
    SCALABILITY_FUNCTION_ENTER;
    SCALABILITY_CHK_NULL_RETURN(m_osInterface);

    MOS_STATUS eStatus         = MOS_STATUS_SUCCESS;
    MOS_STATUS statusPatchList = MOS_STATUS_SUCCESS;
    MOS_STATUS statusCmdBuf    = MOS_STATUS_SUCCESS;
    // Try a maximum of 3 attempts to request the required sizes from OS
    // OS could reset the sizes if necessary, therefore, requires to re-verify
    for (auto i = 0; i < 3; i++)
    {
        //Experiment shows resizing CmdBuf size and PatchList size in two calls one after the other would cause previously
        //successfully requested size to fallback to wrong value, hence never satisfying the requirement. So we call pfnResize()
        //only once depending on whether CmdBuf size not enough, or PatchList size not enough, or both.
        if (requestedPatchListSize)
        {
            statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
                m_osInterface,
                requestedPatchListSize);
        }
        statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
            m_osInterface,
            requestedSize,
            0);

        if (statusPatchList != MOS_STATUS_SUCCESS && statusCmdBuf != MOS_STATUS_SUCCESS)
        {
            SCALABILITY_CHK_STATUS_RETURN(ResizeCommandBufferAndPatchList(requestedSize + COMMAND_BUFFER_RESERVED_SPACE, requestedPatchListSize));
        }
        else if (statusPatchList != MOS_STATUS_SUCCESS)
        {
            SCALABILITY_CHK_STATUS_RETURN(ResizeCommandBufferAndPatchList(0, requestedPatchListSize));
        }
        else if (statusCmdBuf != MOS_STATUS_SUCCESS)
        {
            SCALABILITY_CHK_STATUS_RETURN(ResizeCommandBufferAndPatchList(requestedSize + COMMAND_BUFFER_RESERVED_SPACE, 0));
        }
        else
        {
            // This flag is just a hint for encode, decode/vpp don't use this flag.
            singleTaskPhaseSupportedInPak = true;
            return eStatus;
        }

    }

    if (requestedPatchListSize)
    {
        statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
            m_osInterface,
            requestedPatchListSize);
    }
    statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
        m_osInterface,
        requestedSize,
        0);

    if(statusPatchList != MOS_STATUS_SUCCESS || statusCmdBuf != MOS_STATUS_SUCCESS)
    {
        eStatus = MOS_STATUS_NO_SPACE;
    }

    return eStatus;
}

MOS_STATUS MediaScalability::Destroy()
{
    if (m_osInterface->apoMosEnabled)
    {
        if (m_veState)
        {
            SCALABILITY_CHK_STATUS_RETURN(MosInterface::SetVirtualEngineState(m_osInterface->osStreamState, m_veState));
            return MosInterface::DestroyVirtualEngineState(m_osInterface->osStreamState);
        }

        // No VE state to destroy in some scalability instances
        return MOS_STATUS_SUCCESS;
    }

    if (m_veInterface)
    {
        if(m_veInterface->pfnVEDestroy)
        {
            m_veInterface->pfnVEDestroy(m_veInterface);
        }
        MOS_FreeMemAndSetNull(m_veInterface);
    }
    else
    {
        // For VE not enabled/supported case, such as vp vebox on some platform, m_veInterface is nullptr.
        // MOS_STATUS_SUCCESS should be returned for such case.
        if (MOS_VE_SUPPORTED(m_osInterface))
        {
            SCALABILITY_CHK_NULL_RETURN(m_veInterface);
        }
    }

    return MOS_STATUS_SUCCESS;
}
