1 /*
2 * Copyright (c) 2017 - 2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     vphal_render_vebox_iecp.cpp
24 //! \brief    VPHAL VEBOX Image Enhancement and Color Processing (IECP) interfaces
25 //! \details  VPHAL VEBOX Image Enhancement and Color Processing (IECP) interfaces
26 //!
27 
28 #include "vphal_render_vebox_procamp.h"
29 #include "vphal_render_vebox_ste.h"
30 #include "vphal_render_vebox_tcc.h"
31 #include "vphal_render_vebox_util_base.h"
32 
33 //!
34 //! \brief    Initial IECP filters
35 //! \details  Initial IECP filters.
36 //!           All avaliable opened IECP filters should add to m_filters array here.
37 //!
VPHAL_VEBOX_IECP_RENDERER()38 VPHAL_VEBOX_IECP_RENDERER::VPHAL_VEBOX_IECP_RENDERER()
39 {
40     int32_t i = 0;
41 
42     // add all avaliable opened IECP filters, max size is 15.
43 #if VPHAL_RENDER_VEBOX_TCC_ENABLE
44     m_filters[i++] = MOS_New(VPHAL_VEBOX_IECP_TCC);
45 #endif  // VPHAL_RENDER_VEBOX_TCC_ENABLE
46 #if VPHAL_RENDER_VEBOX_STE_ENABLE
47     m_filters[i++] = MOS_New(VPHAL_VEBOX_IECP_STE);
48 #endif // VPHAL_RENDER_VEBOX_STE_ENABLE
49 #if VPHAL_RENDER_VEBOX_PROCAMP_ENABLE
50     m_filters[i++] = MOS_New(VPHAL_VEBOX_IECP_ProcAmp);
51 #endif // VPHAL_RENDER_VEBOX_PROCAMP_ENABLE
52 
53     m_filters[i]  = nullptr;
54     m_filterCount = i;
55 
56     // Initial pointers as nullptr
57     m_veboxState = nullptr;
58     m_renderData = nullptr;
59 }
60 
61 //!
62 //! \brief    Destroy IECP filters
63 //! \details  Destroy IECP filters.
64 //!           Delete allocated IECP filters.
65 //!
~VPHAL_VEBOX_IECP_RENDERER()66 VPHAL_VEBOX_IECP_RENDERER::~VPHAL_VEBOX_IECP_RENDERER()
67 {
68     int32_t i = 0;
69 
70     for (i = 0; i < m_filterCount; i++)
71     {
72         if (m_filters[i])
73         {
74             MOS_Delete(m_filters[i]);
75             m_filters[i] = nullptr;
76         }
77     }
78 }
79 
80 //!
81 //! \brief    Vebox set alpha parameter
82 //! \details  Setup Alpha Params
83 //! \param    [in] pOutSurface
84 //!           Pointer to output surface of Vebox
85 //! \param    [in,out] pVphalVeboxIecpParams
86 //!           Pointer to IECP parameter
87 //! \return   void
88 //!
VeboxSetAlphaParams(PVPHAL_SURFACE pOutSurface,PVPHAL_VEBOX_IECP_PARAMS pVphalVeboxIecpParams)89 void VPHAL_VEBOX_IECP_RENDERER::VeboxSetAlphaParams(
90     PVPHAL_SURFACE                  pOutSurface,
91     PVPHAL_VEBOX_IECP_PARAMS        pVphalVeboxIecpParams)
92 {
93     PVPHAL_VEBOX_RENDER_DATA        pRenderData = m_renderData;
94 
95     if (pRenderData->pAlphaParams != nullptr)
96     {
97         switch (pRenderData->pAlphaParams->AlphaMode)
98         {
99         case VPHAL_ALPHA_FILL_MODE_NONE:
100             if (pOutSurface->Format == Format_A8R8G8B8    ||
101                 pOutSurface->Format == Format_A8B8G8R8    ||
102                 pOutSurface->Format == Format_R10G10B10A2 ||
103                 pOutSurface->Format == Format_B10G10R10A2 ||
104                 pOutSurface->Format == Format_AYUV)
105             {
106                 pVphalVeboxIecpParams->wAlphaValue =
107                     (uint8_t)(0xff * pRenderData->pAlphaParams->fAlpha);
108             }
109             else if (pOutSurface->Format == Format_Y416)
110             {
111                 pVphalVeboxIecpParams->wAlphaValue =
112                     (uint16_t)(0xffff * pRenderData->pAlphaParams->fAlpha);
113             }
114             else
115             {
116                 pVphalVeboxIecpParams->wAlphaValue = 0xff;
117             }
118             break;
119 
120             // VEBOX does not support Background Color
121         case VPHAL_ALPHA_FILL_MODE_BACKGROUND:
122             // VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM case is hit when the
123             // input does not have alpha
124             // So we set Opaque alpha channel.
125         case VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM:
126         case VPHAL_ALPHA_FILL_MODE_OPAQUE:
127         default:
128             if (pOutSurface->Format == Format_Y416)
129             {
130                 pVphalVeboxIecpParams->wAlphaValue = 0xffff;
131             }
132             else
133             {
134                 pVphalVeboxIecpParams->wAlphaValue = 0xff;
135             }
136 
137             break;
138         }
139     }
140     else
141     {
142         pVphalVeboxIecpParams->wAlphaValue = 0xff;
143     }
144 }
145 
146 //!
147 //! \brief    Initial Vebox IECP state parameter
148 //! \param    [in] VphalColorSpace
149 //!           Vphal color space
150 //! \param    [in] pMhwVeboxIecpParams
151 //!           Pointer to Mhw Vebox IECP parameters
152 //! \return   MOS_STATUS
153 //!
InitParams(VPHAL_CSPACE VphalColorSpace,PMHW_VEBOX_IECP_PARAMS pMhwVeboxIecpParams)154 MOS_STATUS VPHAL_VEBOX_IECP_RENDERER::InitParams(
155     VPHAL_CSPACE                    VphalColorSpace,
156     PMHW_VEBOX_IECP_PARAMS          pMhwVeboxIecpParams)
157 {
158     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
159     PVPHAL_VEBOX_IECP_PARAMS        pVphalVeboxIecpParams = m_renderData->GetVeboxIECPParams();
160     int32_t i = 0;
161 
162     VPHAL_RENDER_CHK_NULL(pMhwVeboxIecpParams);
163 
164     MOS_ZeroMemory(pMhwVeboxIecpParams, sizeof(*pMhwVeboxIecpParams));
165 
166     for (i = 0; i < m_filterCount; i++)
167     {
168         VPHAL_RENDER_CHK_NULL(m_filters[i]);
169         m_filters[i]->InitParams(pVphalVeboxIecpParams, pMhwVeboxIecpParams);
170     }
171 
172     pMhwVeboxIecpParams->ColorSpace     = VPHal_VpHalCspace2MhwCspace(VphalColorSpace);
173     pMhwVeboxIecpParams->dstFormat      = pVphalVeboxIecpParams->dstFormat;
174     pMhwVeboxIecpParams->srcFormat      = pVphalVeboxIecpParams->srcFormat;
175     pMhwVeboxIecpParams->bCSCEnable     = pVphalVeboxIecpParams->bCSCEnable;
176     pMhwVeboxIecpParams->pfCscCoeff     = pVphalVeboxIecpParams->pfCscCoeff;
177     pMhwVeboxIecpParams->pfCscInOffset  = pVphalVeboxIecpParams->pfCscInOffset;
178     pMhwVeboxIecpParams->pfCscOutOffset = pVphalVeboxIecpParams->pfCscOutOffset;
179     pMhwVeboxIecpParams->bAlphaEnable   = pVphalVeboxIecpParams->bAlphaEnable;
180     pMhwVeboxIecpParams->wAlphaValue    = pVphalVeboxIecpParams->wAlphaValue;
181 
182     // Front End CSC
183     pMhwVeboxIecpParams->bFeCSCEnable          = pVphalVeboxIecpParams->bFeCSCEnable;
184     pMhwVeboxIecpParams->pfFeCscCoeff          = pVphalVeboxIecpParams->pfFeCscCoeff;
185     pMhwVeboxIecpParams->pfFeCscInOffset       = pVphalVeboxIecpParams->pfFeCscInOffset;
186     pMhwVeboxIecpParams->pfFeCscOutOffset      = pVphalVeboxIecpParams->pfFeCscOutOffset;
187 
188 finish:
189     return eStatus;
190 }
191 
192 //!
193 //! \brief    Vebox set IECP parameter
194 //! \details  Set Vebox IECP state parameter
195 //! \param    [in] pSrcSurface
196 //!           Pointer to input surface of Vebox
197 //! \param    [in] pOutSurface
198 //!           Pointer to output surface of Vebox
199 //! \return   void
200 //!
SetParams(PVPHAL_SURFACE pSrcSurface,PVPHAL_SURFACE pOutSurface)201 void VPHAL_VEBOX_IECP_RENDERER::SetParams(
202     PVPHAL_SURFACE              pSrcSurface,
203     PVPHAL_SURFACE              pOutSurface)
204 {
205     PVPHAL_VEBOX_STATE              pVeboxState           = m_veboxState;
206     PVPHAL_VEBOX_RENDER_DATA        pRenderData           = m_renderData;
207     PVPHAL_VEBOX_IECP_PARAMS        pVphalVeboxIecpParams = m_renderData->GetVeboxIECPParams();
208     int32_t i = 0;
209 
210     for (i = 0; i < m_filterCount; i++)
211     {
212         if (m_filters[i])
213         {
214             m_filters[i]->SetParams(pSrcSurface, m_renderData);
215         }
216     }
217 
218     pRenderData->GetVeboxStateParams()->pVphalVeboxIecpParams = pVphalVeboxIecpParams;
219 
220     // Check if Back End CSC is enabled in VEBOX
221     if (pRenderData->bBeCsc)
222     {
223         // Calculate matrix if not done so before. CSC is expensive!
224         if ((pVeboxState->CscInputCspace  != pSrcSurface->ColorSpace) ||
225             (pVeboxState->CscOutputCspace != pOutSurface->ColorSpace))
226         {
227             // Get the matrix to use for conversion
228             pVeboxState->VeboxGetBeCSCMatrix(
229                 pSrcSurface,
230                 pOutSurface);
231 
232             // Store it for next BLT
233             pVeboxState->CscInputCspace  = pSrcSurface->ColorSpace;
234             pVeboxState->CscOutputCspace = pOutSurface->ColorSpace;
235         }
236 
237         // Copy the values into IECP Params
238         pVphalVeboxIecpParams->bCSCEnable       = true;
239         pVphalVeboxIecpParams->pfCscCoeff       = pVeboxState->fCscCoeff;
240         pVphalVeboxIecpParams->pfCscInOffset    = pVeboxState->fCscInOffset;
241         pVphalVeboxIecpParams->pfCscOutOffset   = pVeboxState->fCscOutOffset;
242 
243         // Set Alpha State
244         if ((pOutSurface->Format == Format_A8R8G8B8) ||
245             (pOutSurface->Format == Format_A8B8G8R8) ||
246             (pOutSurface->Format == Format_X8R8G8B8))
247         {
248             pVphalVeboxIecpParams->bAlphaEnable = true;
249             VeboxSetAlphaParams(pOutSurface, pVphalVeboxIecpParams);
250         }
251         else
252         {
253             pVphalVeboxIecpParams->bAlphaEnable = false;
254         }
255 
256         // Set the output format which can be referred by YUV_Channel_Swap bit
257         pVphalVeboxIecpParams->dstFormat = pOutSurface->Format;
258 
259         // Set input foramt
260         pVphalVeboxIecpParams->srcFormat = pSrcSurface->Format;
261     }
262 
263     // If 3DLUT is enabled, Front End CSC needs to be enabled explicitly for YUV output
264     if (pRenderData->bHdr3DLut)
265     {
266         if (IS_YUV_FORMAT(pOutSurface->Format) &&
267            (pVeboxState->CscOutputCspace != pOutSurface->ColorSpace))
268         {
269             VPHAL_CSPACE outColorSpace         = pOutSurface->ColorSpace;
270             VPHAL_CSPACE inColorSpace          = (IS_COLOR_SPACE_BT2020_YUV(pOutSurface->ColorSpace)) ? CSpace_BT2020_RGB : CSpace_sRGB;
271             // Get the matrix to use for conversion
272             VpHal_GetCscMatrix(
273                 inColorSpace,
274                 outColorSpace,
275                 pVeboxState->fFeCscCoeff,
276                 pVeboxState->fFeCscInOffset,
277                 pVeboxState->fFeCscOutOffset);
278 
279             // Copy the values into IECP Params
280             pVphalVeboxIecpParams->bFeCSCEnable          = true;
281             pVphalVeboxIecpParams->pfFeCscCoeff          = pVeboxState->fFeCscCoeff;
282             pVphalVeboxIecpParams->pfFeCscInOffset       = pVeboxState->fFeCscInOffset;
283             pVphalVeboxIecpParams->pfFeCscOutOffset      = pVeboxState->fFeCscOutOffset;
284         }
285     }
286     else
287     {
288         pVphalVeboxIecpParams->bFeCSCEnable              = false;
289     }
290 }
291