1 /*
2 * Copyright (c) 2018-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 vp_scaling_fliter.cpp
24 //! \brief Defines the common interface for scaling filters
25 //! this file is for the base interface which is shared by scaling in driver.
26 //!
27
28 #include "vp_scaling_filter.h"
29 #include "vp_vebox_cmd_packet.h"
30 #include "vp_utils.h"
31 #include "hw_filter.h"
32 #include "sw_filter_pipe.h"
33
34 using namespace vp;
35
36 namespace vp
37 {
38 MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput);
39 };
40
VpScalingFilter(PVP_MHWINTERFACE vpMhwInterface)41 VpScalingFilter::VpScalingFilter(
42 PVP_MHWINTERFACE vpMhwInterface) :
43 VpFilter(vpMhwInterface)
44 {
45
46 }
47
Init()48 MOS_STATUS VpScalingFilter::Init()
49 {
50 VP_FUNC_CALL();
51 m_bVdbox = false;
52 return MOS_STATUS_SUCCESS;
53 }
54
Init(CODECHAL_STANDARD codecStandard,CodecDecodeJpegChromaType jpegChromaType)55 MOS_STATUS VpScalingFilter::Init(
56 CODECHAL_STANDARD codecStandard,
57 CodecDecodeJpegChromaType jpegChromaType)
58 {
59 VP_FUNC_CALL();
60
61 m_bVdbox = true;
62 m_codecStandard = codecStandard;
63 m_jpegChromaType = jpegChromaType;
64 return MOS_STATUS_SUCCESS;
65 }
66
SfcAdjustBoundary(uint32_t * pdwSurfaceWidth,uint32_t * pdwSurfaceHeight)67 MOS_STATUS VpScalingFilter::SfcAdjustBoundary(
68 uint32_t *pdwSurfaceWidth,
69 uint32_t *pdwSurfaceHeight)
70 {
71 VP_FUNC_CALL();
72
73 VP_PUBLIC_CHK_NULL_RETURN(m_pvpMhwInterface);
74 VP_PUBLIC_CHK_NULL_RETURN(m_pvpMhwInterface->m_sfcInterface);
75 VP_PUBLIC_CHK_NULL_RETURN(pdwSurfaceWidth);
76 VP_PUBLIC_CHK_NULL_RETURN(pdwSurfaceHeight);
77
78 uint32_t widthAlignUnit = m_pvpMhwInterface->m_sfcInterface->m_veWidthAlignment;
79 uint32_t heightAlignUnit = m_pvpMhwInterface->m_sfcInterface->m_veHeightAlignment;
80 VP_PUBLIC_CHK_STATUS_RETURN(m_pvpMhwInterface->m_sfcInterface->GetInputFrameWidthHeightAlignUnit(widthAlignUnit, heightAlignUnit,
81 m_bVdbox, m_codecStandard, m_jpegChromaType));
82
83 uint32_t dwVeboxHeight = m_scalingParams.input.dwHeight;
84 uint32_t dwVeboxWidth = m_scalingParams.input.dwWidth;
85 uint32_t dwVeboxBottom = (uint32_t)m_scalingParams.input.rcMaxSrc.bottom;
86 uint32_t dwVeboxRight = (uint32_t)m_scalingParams.input.rcMaxSrc.right;
87
88 if (m_scalingParams.bDirectionalScalar)
89 {
90 dwVeboxHeight *= 2;
91 dwVeboxWidth *= 2;
92 dwVeboxBottom *= 2;
93 dwVeboxRight *= 2;
94 }
95 if (MEDIA_IS_SKU(m_pvpMhwInterface->m_skuTable, FtrHeight8AlignVE3DLUTDualPipe) && (m_executeCaps.bHDR3DLUT || m_executeCaps.bDV))
96 {
97 VP_PUBLIC_NORMALMESSAGE("SFC Align Frame Height as 8x due to 3Dlut Dual mode Enable");
98 heightAlignUnit = MOS_ALIGN_CEIL(heightAlignUnit, 8);
99 }
100
101 *pdwSurfaceHeight = MOS_ALIGN_CEIL(
102 MOS_MIN(dwVeboxHeight, MOS_MAX(dwVeboxBottom, MHW_VEBOX_MIN_HEIGHT)),
103 heightAlignUnit);
104 *pdwSurfaceWidth = MOS_ALIGN_CEIL(
105 MOS_MIN(dwVeboxWidth, MOS_MAX(dwVeboxRight, MHW_VEBOX_MIN_WIDTH)),
106 widthAlignUnit);
107
108 return MOS_STATUS_SUCCESS;
109 }
110
111 template <typename T>
swap(T & a,T & b)112 inline void swap(T &a, T &b)
113 {
114 T tmp = b;
115 b = a;
116 a = tmp;
117 }
118
GetFormatWidthHeightAlignUnit(MOS_FORMAT format,bool bOutput,bool bRotateNeeded,uint16_t & widthAlignUnit,uint16_t & heightAlignUnit)119 void VpScalingFilter::GetFormatWidthHeightAlignUnit(
120 MOS_FORMAT format,
121 bool bOutput,
122 bool bRotateNeeded,
123 uint16_t & widthAlignUnit,
124 uint16_t & heightAlignUnit)
125 {
126 VP_FUNC_CALL();
127
128 widthAlignUnit = 1;
129 heightAlignUnit = 1;
130
131 switch (VpHal_GetSurfaceColorPack(format))
132 {
133 case VPHAL_COLORPACK_420:
134 widthAlignUnit = 2;
135 heightAlignUnit = 2;
136 break;
137 case VPHAL_COLORPACK_422:
138 widthAlignUnit = 2;
139 break;
140 default:
141 break;
142 }
143 if (bRotateNeeded && bOutput)
144 {
145 // Output rect has been rotated in SwFilterScaling::Configure. Need to swap the alignUnit accordingly.
146 swap(widthAlignUnit, heightAlignUnit);
147 }
148 }
149
IsColorfillEnable()150 MOS_STATUS VpScalingFilter::IsColorfillEnable()
151 {
152 VP_FUNC_CALL();
153
154 m_bColorfillEnable = (m_scalingParams.pColorFillParams &&
155 (!m_scalingParams.pColorFillParams->bDisableColorfillinSFC) &&
156 (m_scalingParams.pColorFillParams->bOnePixelBiasinSFC ?
157 (!RECT1_CONTAINS_RECT2_ONEPIXELBIAS(m_scalingParams.input.rcDst, m_scalingParams.output.rcDst)) :
158 (!RECT1_CONTAINS_RECT2(m_scalingParams.input.rcDst, m_scalingParams.output.rcDst)))) ?
159 true : false;
160
161 return MOS_STATUS_SUCCESS;
162 }
163
SetColorFillParams()164 MOS_STATUS VpScalingFilter::SetColorFillParams()
165 {
166 VP_FUNC_CALL();
167
168 VPHAL_COLOR_SAMPLE_8 Src = {};
169 VPHAL_CSPACE src_cspace, dst_cspace;
170
171 VP_PUBLIC_CHK_NULL_RETURN(m_sfcScalingParams);
172
173 m_sfcScalingParams->sfcColorfillParams.bColorfillEnable = m_bColorfillEnable;
174
175 if (m_bColorfillEnable)
176 {
177 VP_PUBLIC_CHK_NULL_RETURN(m_scalingParams.pColorFillParams);
178 Src.dwValue = m_scalingParams.pColorFillParams->Color;
179 src_cspace = m_scalingParams.pColorFillParams->CSpace;
180 dst_cspace = m_scalingParams.csc.colorSpaceOutput;
181
182 // Convert BG color only if not done so before. CSC is expensive!
183 if ((m_colorFillColorSrc.dwValue != Src.dwValue) ||
184 (m_colorFillSrcCspace != src_cspace) ||
185 (m_colorFillRTCspace != dst_cspace))
186 {
187 // Clean history Dst BG Color if hit unsupported format
188 if (!VpHal_CSC_8(&m_colorFillColorDst, &Src, src_cspace, dst_cspace))
189 {
190 MOS_ZeroMemory(&m_colorFillColorDst, sizeof(m_colorFillColorDst));
191 }
192 // store the values for next iteration
193 m_colorFillColorSrc = Src;
194 m_colorFillSrcCspace = src_cspace;
195 m_colorFillRTCspace = dst_cspace;
196 }
197
198 VP_RENDER_CHK_STATUS_RETURN(SetYUVRGBPixel());
199 m_sfcScalingParams->sfcColorfillParams.fColorFillAPixel = (float)Src.A / 255.0F;
200 }
201
202 if (m_scalingParams.pCompAlpha)
203 {
204 VP_RENDER_CHK_STATUS_RETURN(SetAlphaPixelParams());
205 }
206 else
207 {
208 m_sfcScalingParams->sfcColorfillParams.fAlphaPixel = 1.0F;
209 }
210
211 return MOS_STATUS_SUCCESS;
212 }
213
SetYUVRGBPixel()214 MOS_STATUS VpScalingFilter::SetYUVRGBPixel()
215 {
216 VP_FUNC_CALL();
217
218 VP_PUBLIC_CHK_NULL_RETURN(m_sfcScalingParams);
219
220 if (IS_YUV_FORMAT(m_scalingParams.formatOutput) || IS_ALPHA_YUV_FORMAT(m_scalingParams.formatOutput))
221 {
222 m_sfcScalingParams->sfcColorfillParams.fColorFillYRPixel = (float)m_colorFillColorDst.Y / 255.0F;
223 m_sfcScalingParams->sfcColorfillParams.fColorFillUGPixel = (float)m_colorFillColorDst.U / 255.0F;
224 m_sfcScalingParams->sfcColorfillParams.fColorFillVBPixel = (float)m_colorFillColorDst.V / 255.0F;
225 }
226 else
227 {
228 // Swap the channel here because HW only natively supports XBGR output
229 if ((m_scalingParams.formatOutput == Format_A8R8G8B8) ||
230 (m_scalingParams.formatOutput == Format_X8R8G8B8) ||
231 (m_scalingParams.formatOutput == Format_R10G10B10A2) ||
232 (m_scalingParams.formatOutput == Format_A16R16G16B16))
233 {
234 m_sfcScalingParams->sfcColorfillParams.fColorFillYRPixel = (float)m_colorFillColorDst.B / 255.0F;
235 m_sfcScalingParams->sfcColorfillParams.fColorFillUGPixel = (float)m_colorFillColorDst.G / 255.0F;
236 m_sfcScalingParams->sfcColorfillParams.fColorFillVBPixel = (float)m_colorFillColorDst.R / 255.0F;
237 }
238 else
239 {
240 m_sfcScalingParams->sfcColorfillParams.fColorFillYRPixel = (float)m_colorFillColorDst.R / 255.0F;
241 m_sfcScalingParams->sfcColorfillParams.fColorFillUGPixel = (float)m_colorFillColorDst.G / 255.0F;
242 m_sfcScalingParams->sfcColorfillParams.fColorFillVBPixel = (float)m_colorFillColorDst.B / 255.0F;
243 }
244 }
245
246 return MOS_STATUS_SUCCESS;
247 }
248
SetAlphaPixelParams()249 MOS_STATUS VpScalingFilter::SetAlphaPixelParams()
250 {
251 VP_FUNC_CALL();
252
253 VP_PUBLIC_CHK_NULL_RETURN(m_sfcScalingParams);
254 VP_PUBLIC_CHK_NULL_RETURN(m_scalingParams.pCompAlpha);
255
256 switch (m_scalingParams.pCompAlpha->AlphaMode)
257 {
258 case VPHAL_ALPHA_FILL_MODE_NONE:
259 if (m_scalingParams.formatOutput == Format_A8R8G8B8 ||
260 m_scalingParams.formatOutput == Format_A8B8G8R8 ||
261 m_scalingParams.formatOutput == Format_R10G10B10A2 ||
262 m_scalingParams.formatOutput == Format_B10G10R10A2 ||
263 m_scalingParams.formatOutput == Format_AYUV ||
264 m_scalingParams.formatOutput == Format_Y410 ||
265 m_scalingParams.formatOutput == Format_Y416)
266 {
267 m_sfcScalingParams->sfcColorfillParams.fAlphaPixel = m_scalingParams.pCompAlpha->fAlpha;
268 m_sfcScalingParams->sfcColorfillParams.fColorFillAPixel = m_scalingParams.pCompAlpha->fAlpha;
269 }
270 else
271 {
272 m_sfcScalingParams->sfcColorfillParams.fAlphaPixel = 1.0F;
273 }
274 break;
275
276 case VPHAL_ALPHA_FILL_MODE_BACKGROUND:
277 m_sfcScalingParams->sfcColorfillParams.fAlphaPixel = m_bColorfillEnable ?
278 m_sfcScalingParams->sfcColorfillParams.fColorFillAPixel : 1.0F;
279 break;
280
281 case VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM:
282 case VPHAL_ALPHA_FILL_MODE_OPAQUE:
283 default:
284 m_sfcScalingParams->sfcColorfillParams.fAlphaPixel = 1.0F;
285 m_sfcScalingParams->sfcColorfillParams.fColorFillAPixel = 1.0F;
286 }
287 return MOS_STATUS_SUCCESS;
288 }
289
290
SetRectSurfaceAlignment(bool isOutputSurf,uint32_t & width,uint32_t & height,RECT & rcSrc,RECT & rcDst)291 MOS_STATUS VpScalingFilter::SetRectSurfaceAlignment(bool isOutputSurf, uint32_t &width, uint32_t &height, RECT &rcSrc, RECT &rcDst)
292 {
293 VP_FUNC_CALL();
294
295 uint16_t wWidthAlignUnit = 0;
296 uint16_t wHeightAlignUnit = 0;
297 uint16_t wWidthAlignUnitForDstRect = 0;
298 uint16_t wHeightAlignUnitForDstRect = 0;
299 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
300
301 GetFormatWidthHeightAlignUnit(isOutputSurf ? m_scalingParams.formatOutput : m_scalingParams.formatInput,
302 isOutputSurf, m_scalingParams.rotation.rotationNeeded, wWidthAlignUnit, wHeightAlignUnit);
303 GetFormatWidthHeightAlignUnit(m_scalingParams.formatOutput, true, m_scalingParams.rotation.rotationNeeded, wWidthAlignUnitForDstRect, wHeightAlignUnitForDstRect);
304
305 // The source rectangle is floored to the aligned unit to
306 // get rid of invalid data(ex: an odd numbered src rectangle with NV12 format
307 // will have invalid UV data for the last line of Y data).
308 rcSrc.bottom = MOS_ALIGN_FLOOR((uint32_t)rcSrc.bottom, wHeightAlignUnit);
309 rcSrc.right = MOS_ALIGN_FLOOR((uint32_t)rcSrc.right, wWidthAlignUnit);
310
311 rcSrc.top = MOS_ALIGN_CEIL((uint32_t)rcSrc.top, wHeightAlignUnit);
312 rcSrc.left = MOS_ALIGN_CEIL((uint32_t)rcSrc.left, wWidthAlignUnit);
313
314 // The Destination rectangle is rounded to the upper alignment unit to prevent the loss of
315 // data which was present in the source rectangle
316 // Current output alignment is based on input format.
317 // Better output alignmentg solution should be based on output format.
318 rcDst.bottom = MOS_ALIGN_CEIL((uint32_t)rcDst.bottom, wHeightAlignUnitForDstRect);
319 rcDst.right = MOS_ALIGN_CEIL((uint32_t)rcDst.right, wWidthAlignUnitForDstRect);
320
321 rcDst.top = MOS_ALIGN_FLOOR((uint32_t)rcDst.top, wHeightAlignUnitForDstRect);
322 rcDst.left = MOS_ALIGN_FLOOR((uint32_t)rcDst.left, wWidthAlignUnitForDstRect);
323
324 if (isOutputSurf)
325 {
326 height = MOS_ALIGN_CEIL(height, wHeightAlignUnit);
327 width = MOS_ALIGN_CEIL(width, wWidthAlignUnit);
328 }
329 else
330 {
331 height = MOS_ALIGN_FLOOR(height, wHeightAlignUnit);
332 width = MOS_ALIGN_FLOOR(width, wWidthAlignUnit);
333 }
334
335 if ((rcSrc.top == rcSrc.bottom) ||
336 (rcSrc.left == rcSrc.right) ||
337 (rcDst.top == rcDst.bottom) ||
338 (rcDst.left == rcDst.right) ||
339 (width == 0) ||
340 (height == 0))
341 {
342 VP_PUBLIC_NORMALMESSAGE("Surface Parameter is invalid.");
343 eStatus = MOS_STATUS_INVALID_PARAMETER;
344 }
345
346 return eStatus;
347 }
348
349 // Prepare
SetExecuteEngineCaps(FeatureParamScaling & scalingParams,VP_EXECUTE_CAPS vpExecuteCaps)350 MOS_STATUS VpScalingFilter::SetExecuteEngineCaps(
351 FeatureParamScaling &scalingParams,
352 VP_EXECUTE_CAPS vpExecuteCaps)
353 {
354 VP_FUNC_CALL();
355
356 m_executeCaps = vpExecuteCaps;
357
358 m_scalingParams = scalingParams;
359 if (!m_bVdbox)
360 {
361 m_scalingParams.input.rcMaxSrc = m_scalingParams.input.rcSrc;
362 }
363
364 // Set Src/Dst Surface Rect
365 VP_PUBLIC_CHK_STATUS_RETURN(SetRectSurfaceAlignment(false, m_scalingParams.input.dwWidth,
366 m_scalingParams.input.dwHeight, m_scalingParams.input.rcSrc, m_scalingParams.input.rcDst));
367 VP_PUBLIC_CHK_STATUS_RETURN(SetRectSurfaceAlignment(true, m_scalingParams.output.dwWidth,
368 m_scalingParams.output.dwHeight, m_scalingParams.output.rcSrc, m_scalingParams.output.rcDst));
369
370 return MOS_STATUS_SUCCESS;
371 }
372
CalculateEngineParams()373 MOS_STATUS VpScalingFilter::CalculateEngineParams()
374 {
375 VP_FUNC_CALL();
376
377 VP_RENDER_CHK_STATUS_RETURN(IsColorfillEnable());
378
379 if (m_executeCaps.bSFC)
380 {
381 uint32_t dwSurfaceWidth = 0;
382 uint32_t dwSurfaceHeight = 0;
383 uint16_t wOutputWidthAlignUnit = 1;
384 uint16_t wOutputHeightAlignUnit = 1;
385 uint16_t wInputWidthAlignUnit = 1;
386 uint16_t wInputHeightAlignUnit = 1;
387 uint32_t wOutputRegionWidth = 0;
388 uint32_t wOutputRegionHeight = 0;
389 float fScaleX = 0.0f;
390 float fScaleY = 0.0f;
391
392 if (!m_sfcScalingParams)
393 {
394 m_sfcScalingParams = (SFC_SCALING_PARAMS*)MOS_AllocAndZeroMemory(sizeof(SFC_SCALING_PARAMS));
395
396 if (m_sfcScalingParams == nullptr)
397 {
398 VP_PUBLIC_ASSERTMESSAGE("sfc Scaling Pamas buffer allocate failed, return nullpointer");
399 return MOS_STATUS_NO_SPACE;
400 }
401 }
402 else
403 {
404 MOS_ZeroMemory(m_sfcScalingParams, sizeof(SFC_SCALING_PARAMS));
405 }
406
407 // Set Scaling Mode
408 m_sfcScalingParams->bBilinearScaling = (VPHAL_SCALING_BILINEAR == m_scalingParams.scalingMode);
409
410 //Set input/Output boundary
411 VP_RENDER_CHK_STATUS_RETURN(SfcAdjustBoundary(
412 &dwSurfaceWidth,
413 &dwSurfaceHeight));
414
415 m_scalingParams.formatInput = GetSfcInputFormat(m_executeCaps,
416 m_scalingParams.formatInput,
417 m_scalingParams.csc.colorSpaceOutput);
418 m_sfcScalingParams->inputFrameFormat = m_scalingParams.formatInput;
419 m_sfcScalingParams->dwInputFrameHeight = dwSurfaceHeight;
420 m_sfcScalingParams->dwInputFrameWidth = dwSurfaceWidth;
421
422 // Apply alignment restriction to the Region of the output frame.
423 GetFormatWidthHeightAlignUnit(
424 m_scalingParams.formatOutput,
425 true,
426 m_scalingParams.rotation.rotationNeeded,
427 wOutputWidthAlignUnit,
428 wOutputHeightAlignUnit);
429
430 // Apply alignment restriction to Region of the input frame.
431 GetFormatWidthHeightAlignUnit(
432 m_sfcScalingParams->inputFrameFormat,
433 false,
434 m_scalingParams.rotation.rotationNeeded,
435 wInputWidthAlignUnit,
436 wInputHeightAlignUnit);
437
438 m_sfcScalingParams->dwOutputFrameHeight = MOS_ALIGN_CEIL(m_scalingParams.output.dwHeight, wOutputHeightAlignUnit);
439 m_sfcScalingParams->dwOutputFrameWidth = MOS_ALIGN_CEIL(m_scalingParams.output.dwWidth, wOutputWidthAlignUnit);
440
441 //Set source input offset in Horizontal/vertical
442 m_sfcScalingParams->dwSourceRegionHorizontalOffset = MOS_ALIGN_CEIL((uint32_t)m_scalingParams.input.rcSrc.left, wInputWidthAlignUnit);
443 m_sfcScalingParams->dwSourceRegionVerticalOffset = MOS_ALIGN_CEIL((uint32_t)m_scalingParams.input.rcSrc.top, wInputHeightAlignUnit);
444
445 // Exclude padding area of the SFC input
446 m_sfcScalingParams->dwSourceRegionHeight = MOS_ALIGN_FLOOR(
447 MOS_MIN((uint32_t)(m_scalingParams.input.rcSrc.bottom - m_scalingParams.input.rcSrc.top), m_sfcScalingParams->dwInputFrameHeight),
448 wInputHeightAlignUnit);
449 m_sfcScalingParams->dwSourceRegionWidth = MOS_ALIGN_FLOOR(
450 MOS_MIN((uint32_t)(m_scalingParams.input.rcSrc.right - m_scalingParams.input.rcSrc.left), m_sfcScalingParams->dwInputFrameWidth),
451 wInputWidthAlignUnit);
452
453 // Size of the Output Region over the Render Target
454 wOutputRegionHeight = MOS_ALIGN_CEIL(
455 MOS_MIN((uint32_t)(m_scalingParams.input.rcDst.bottom - m_scalingParams.input.rcDst.top), m_scalingParams.output.dwHeight),
456 wOutputHeightAlignUnit);
457 wOutputRegionWidth = MOS_ALIGN_CEIL(
458 MOS_MIN((uint32_t)(m_scalingParams.input.rcDst.right - m_scalingParams.input.rcDst.left), m_scalingParams.output.dwWidth),
459 wOutputWidthAlignUnit);
460
461 fScaleX = (float)wOutputRegionWidth / (float)m_sfcScalingParams->dwSourceRegionWidth;
462 fScaleY = (float)wOutputRegionHeight / (float)m_sfcScalingParams->dwSourceRegionHeight;
463
464 if (m_bVdbox)
465 {
466 // In VD-to-SFC modes, source region must be programmed to same value as Input Frame Resolution.
467 // SourceRegion should be updated after fScale being calculated, or scaling ratio may be incorrect.
468 m_sfcScalingParams->dwSourceRegionHeight = m_sfcScalingParams->dwInputFrameHeight;
469 m_sfcScalingParams->dwSourceRegionWidth = m_sfcScalingParams->dwInputFrameWidth;
470 }
471
472 // Size of the Scaled Region over the Render Target
473 m_sfcScalingParams->dwScaledRegionHeight = MOS_ALIGN_CEIL(MOS_UF_ROUND(fScaleY * m_sfcScalingParams->dwSourceRegionHeight), wOutputHeightAlignUnit);
474 m_sfcScalingParams->dwScaledRegionWidth = MOS_ALIGN_CEIL(MOS_UF_ROUND(fScaleX * m_sfcScalingParams->dwSourceRegionWidth), wOutputWidthAlignUnit);
475
476 m_sfcScalingParams->dwScaledRegionHeight = MOS_MIN(m_sfcScalingParams->dwScaledRegionHeight, m_sfcScalingParams->dwOutputFrameHeight);
477 m_sfcScalingParams->dwScaledRegionWidth = MOS_MIN(m_sfcScalingParams->dwScaledRegionWidth, m_sfcScalingParams->dwOutputFrameWidth);
478
479 if (m_bVdbox)
480 {
481 // In VD-to-SFC modes, scaled region should be programmed to same value as Output Frame Resolution.
482 // Output Frame Resolution should be updated after scaled region being calculated, or scaling ratio may be incorrect.
483 m_sfcScalingParams->dwOutputFrameHeight = m_sfcScalingParams->dwScaledRegionHeight;
484 m_sfcScalingParams->dwOutputFrameWidth = m_sfcScalingParams->dwScaledRegionWidth;
485 }
486
487 uint32_t dstInputLeftAligned = MOS_ALIGN_FLOOR((uint32_t)m_scalingParams.input.rcDst.left, wOutputWidthAlignUnit);
488 uint32_t dstInputTopAligned = MOS_ALIGN_FLOOR((uint32_t)m_scalingParams.input.rcDst.top, wOutputHeightAlignUnit);
489
490 if (m_scalingParams.rotation.rotationNeeded)
491 {
492 m_sfcScalingParams->dwScaledRegionHorizontalOffset = dstInputTopAligned;
493 m_sfcScalingParams->dwScaledRegionVerticalOffset = dstInputLeftAligned;
494 }
495 else
496 {
497 m_sfcScalingParams->dwScaledRegionHorizontalOffset = dstInputLeftAligned;
498 m_sfcScalingParams->dwScaledRegionVerticalOffset = dstInputTopAligned;
499 }
500
501 // Refine the Scaling ratios in the X and Y direction. SFC output Scaled size may be changed based on the restriction of SFC alignment.
502 // The scaling ratio could be changed and not equal to the fScaleX/Y.
503 // Driver must make sure that the scaling ratio should be matched with the output/input size before send to HW
504 m_sfcScalingParams->fAVSXScalingRatio = (float)m_sfcScalingParams->dwScaledRegionWidth / (float)m_sfcScalingParams->dwSourceRegionWidth;
505 m_sfcScalingParams->fAVSYScalingRatio = (float)m_sfcScalingParams->dwScaledRegionHeight / (float)m_sfcScalingParams->dwSourceRegionHeight;
506
507 m_sfcScalingParams->sfcScalingMode = m_scalingParams.scalingMode;
508
509 m_sfcScalingParams->interlacedScalingType = m_scalingParams.interlacedScalingType;
510 m_sfcScalingParams->srcSampleType = m_scalingParams.input.sampleType;
511 m_sfcScalingParams->dstSampleType = m_scalingParams.output.sampleType;
512
513 VP_RENDER_CHK_STATUS_RETURN(SetColorFillParams());
514 }
515 // Need add support for Render engine
516 else
517 {
518
519 }
520
521 return MOS_STATUS_SUCCESS;
522 }
523
Prepare()524 MOS_STATUS VpScalingFilter::Prepare()
525 {
526 VP_FUNC_CALL();
527
528 return MOS_STATUS_SUCCESS;
529 }
530
Destroy()531 MOS_STATUS VpScalingFilter::Destroy()
532 {
533 VP_FUNC_CALL();
534
535 if (m_sfcScalingParams)
536 {
537 MOS_FreeMemory(m_sfcScalingParams);
538 m_sfcScalingParams = nullptr;
539 }
540
541 return MOS_STATUS_SUCCESS;
542 }
543
544 /****************************************************************************************************/
545 /* HwFilter Scaling Parameter */
546 /****************************************************************************************************/
Create(HW_FILTER_SCALING_PARAM & param,FeatureType featureType)547 HwFilterParameter *HwFilterScalingParameter::Create(HW_FILTER_SCALING_PARAM ¶m, FeatureType featureType)
548 {
549 VP_FUNC_CALL();
550
551 HwFilterScalingParameter *p = MOS_New(HwFilterScalingParameter, featureType);
552 if (p)
553 {
554 if (MOS_FAILED(p->Initialize(param)))
555 {
556 MOS_Delete(p);
557 return nullptr;
558 }
559 }
560 return p;
561 }
562
HwFilterScalingParameter(FeatureType featureType)563 HwFilterScalingParameter::HwFilterScalingParameter(FeatureType featureType) : HwFilterParameter(featureType)
564 {
565 }
566
~HwFilterScalingParameter()567 HwFilterScalingParameter::~HwFilterScalingParameter()
568 {
569 }
570
ConfigParams(HwFilter & hwFilter)571 MOS_STATUS HwFilterScalingParameter::ConfigParams(HwFilter &hwFilter)
572 {
573 VP_FUNC_CALL();
574
575 return hwFilter.ConfigParam(m_Params);
576 }
577
Initialize(HW_FILTER_SCALING_PARAM & param)578 MOS_STATUS HwFilterScalingParameter::Initialize(HW_FILTER_SCALING_PARAM ¶m)
579 {
580 VP_FUNC_CALL();
581
582 m_Params = param;
583 return MOS_STATUS_SUCCESS;
584 }
585
586 /****************************************************************************************************/
587 /* Packet Sfc Scaling Parameter */
588 /****************************************************************************************************/
Create(HW_FILTER_SCALING_PARAM & param)589 VpPacketParameter *VpSfcScalingParameter::Create(HW_FILTER_SCALING_PARAM ¶m)
590 {
591 VP_FUNC_CALL();
592
593 if (nullptr == param.pPacketParamFactory)
594 {
595 return nullptr;
596 }
597 VpSfcScalingParameter *p = dynamic_cast<VpSfcScalingParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
598 if (p)
599 {
600 if (MOS_FAILED(p->Initialize(param)))
601 {
602 VpPacketParameter *pParam = p;
603 param.pPacketParamFactory->ReturnPacketParameter(pParam);
604 return nullptr;
605 }
606 }
607 return p;
608 }
609
VpSfcScalingParameter(PVP_MHWINTERFACE pHwInterface,PacketParamFactoryBase * packetParamFactory)610 VpSfcScalingParameter::VpSfcScalingParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) :
611 VpPacketParameter(packetParamFactory), m_ScalingFilter(pHwInterface)
612 {
613 }
614
~VpSfcScalingParameter()615 VpSfcScalingParameter::~VpSfcScalingParameter()
616 {
617 }
618
SetPacketParam(VpCmdPacket * pPacket)619 bool VpSfcScalingParameter::SetPacketParam(VpCmdPacket *pPacket)
620 {
621 VP_FUNC_CALL();
622
623 VpVeboxCmdPacket *pVeboxPacket = dynamic_cast<VpVeboxCmdPacket *>(pPacket);
624 if (nullptr == pVeboxPacket)
625 {
626 return false;
627 }
628
629 SFC_SCALING_PARAMS *pParams = m_ScalingFilter.GetSfcParams();
630 if (nullptr == pParams)
631 {
632 return false;
633 }
634 return MOS_SUCCEEDED(pVeboxPacket->SetScalingParams(pParams));
635 }
636
Initialize(HW_FILTER_SCALING_PARAM & params)637 MOS_STATUS VpSfcScalingParameter::Initialize(HW_FILTER_SCALING_PARAM ¶ms)
638 {
639 VP_FUNC_CALL();
640
641 VP_PUBLIC_CHK_STATUS_RETURN(m_ScalingFilter.Init());
642 VP_PUBLIC_CHK_STATUS_RETURN(m_ScalingFilter.SetExecuteEngineCaps(params.scalingParams, params.vpExecuteCaps));
643 VP_PUBLIC_CHK_STATUS_RETURN(m_ScalingFilter.CalculateEngineParams());
644 return MOS_STATUS_SUCCESS;
645 }
646
647 /****************************************************************************************************/
648 /* Policy Sfc Scaling Handler */
649 /****************************************************************************************************/
PolicySfcScalingHandler(VP_HW_CAPS & hwCaps)650 PolicySfcScalingHandler::PolicySfcScalingHandler(VP_HW_CAPS &hwCaps) : PolicyFeatureHandler(hwCaps)
651 {
652 m_Type = FeatureTypeScalingOnSfc;
653 }
~PolicySfcScalingHandler()654 PolicySfcScalingHandler::~PolicySfcScalingHandler()
655 {}
656
IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)657 bool PolicySfcScalingHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
658 {
659 VP_FUNC_CALL();
660
661 return vpExecuteCaps.bSfcScaling;
662 }
663
CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps,SwFilterPipe & swFilterPipe,PVP_MHWINTERFACE pHwInterface)664 HwFilterParameter *PolicySfcScalingHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface)
665 {
666 VP_FUNC_CALL();
667
668 if (IsFeatureEnabled(vpExecuteCaps))
669 {
670 if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
671 {
672 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
673 return nullptr;
674 }
675
676 SwFilterScaling *swFilter = dynamic_cast<SwFilterScaling *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeScalingOnSfc));
677
678 if (nullptr == swFilter)
679 {
680 VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
681 return nullptr;
682 }
683
684 FeatureParamScaling ¶m = swFilter->GetSwFilterParams();
685
686 HW_FILTER_SCALING_PARAM paramScaling = {};
687 paramScaling.type = m_Type;
688 paramScaling.pHwInterface = pHwInterface;
689 paramScaling.vpExecuteCaps = vpExecuteCaps;
690 paramScaling.pPacketParamFactory = &m_PacketParamFactory;
691 paramScaling.scalingParams = param;
692 paramScaling.pfnCreatePacketParam = PolicySfcScalingHandler::CreatePacketParam;
693
694 HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
695
696 if (pHwFilterParam)
697 {
698 if (MOS_FAILED(((HwFilterScalingParameter*)pHwFilterParam)->Initialize(paramScaling)))
699 {
700 ReleaseHwFeatureParameter(pHwFilterParam);
701 }
702 }
703 else
704 {
705 pHwFilterParam = HwFilterScalingParameter::Create(paramScaling, m_Type);
706 }
707
708 return pHwFilterParam;
709 }
710 else
711 {
712 return nullptr;
713 }
714 }
715
Get1stPassScaledSize(uint32_t input,uint32_t output,bool is2PassNeeded)716 uint32_t PolicySfcScalingHandler::Get1stPassScaledSize(uint32_t input, uint32_t output, bool is2PassNeeded)
717 {
718 VP_FUNC_CALL();
719
720 if (!is2PassNeeded)
721 {
722 bool scalingIn1stPass = input >= output ?
723 m_hwCaps.m_rules.sfcMultiPassSupport.scaling.downScaling.scalingIn1stPassIf1PassEnough :
724 m_hwCaps.m_rules.sfcMultiPassSupport.scaling.upScaling.scalingIn1stPassIf1PassEnough;
725 return scalingIn1stPass ? output : input;
726 }
727
728 float ratioFor1stPass = 0;
729 uint32_t scaledSize = 0;
730
731 if (input >= output)
732 {
733 ratioFor1stPass = m_hwCaps.m_rules.sfcMultiPassSupport.scaling.downScaling.ratioFor1stPass;
734 scaledSize = MOS_MAX(output, (uint32_t)(input * ratioFor1stPass));
735 }
736 else
737 {
738 ratioFor1stPass = m_hwCaps.m_rules.sfcMultiPassSupport.scaling.upScaling.ratioFor1stPass;
739 scaledSize = MOS_MIN(output, (uint32_t)(input * ratioFor1stPass));
740 }
741 return scaledSize;
742 }
743
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)744 MOS_STATUS PolicySfcScalingHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
745 {
746 VP_FUNC_CALL();
747
748 SwFilterScaling *featureScaling = dynamic_cast<SwFilterScaling *>(&feature);
749 VP_PUBLIC_CHK_NULL_RETURN(featureScaling);
750
751 if (caps.b1stPassOfSfc2PassScaling)
752 {
753 SwFilterScaling *filter2ndPass = featureScaling;
754 SwFilterScaling *filter1ndPass = (SwFilterScaling *)feature.Clone();
755
756 VP_PUBLIC_CHK_NULL_RETURN(filter1ndPass);
757 VP_PUBLIC_CHK_NULL_RETURN(filter2ndPass);
758
759 filter1ndPass->GetFilterEngineCaps() = filter2ndPass->GetFilterEngineCaps();
760 filter1ndPass->SetFeatureType(filter2ndPass->GetFeatureType());
761
762 FeatureParamScaling ¶ms2ndPass = filter2ndPass->GetSwFilterParams();
763 FeatureParamScaling ¶ms1stPass = filter1ndPass->GetSwFilterParams();
764
765 uint32_t inputWidth = params1stPass.input.rcSrc.right - params1stPass.input.rcSrc.left;
766 uint32_t inputHeight = params1stPass.input.rcSrc.bottom - params1stPass.input.rcSrc.top;
767 uint32_t outputWidth = params1stPass.input.rcDst.right - params1stPass.input.rcDst.left;
768 uint32_t outputHeight = params1stPass.input.rcDst.bottom - params1stPass.input.rcDst.top;
769
770 uint32_t scaledWidth = Get1stPassScaledSize(inputWidth, outputWidth, filter1ndPass->GetFilterEngineCaps().sfc2PassScalingNeededX);
771 uint32_t scaledHeight = Get1stPassScaledSize(inputHeight, outputHeight, filter1ndPass->GetFilterEngineCaps().sfc2PassScalingNeededY);
772
773 VP_PUBLIC_NORMALMESSAGE("2 pass sfc scaling setting: (%dx%d)->(%dx%d)->(%dx%d)",
774 inputWidth, inputHeight, scaledWidth, scaledHeight, outputWidth, outputHeight);
775
776 params1stPass.input.rcDst.left = 0;
777 params1stPass.input.rcDst.right = scaledWidth;
778 params1stPass.input.rcDst.top = 0;
779 params1stPass.input.rcDst.bottom = scaledHeight;
780
781 params1stPass.output.dwWidth = scaledWidth;
782 params1stPass.output.dwHeight = scaledHeight;
783 params1stPass.output.rcSrc = params1stPass.input.rcDst;
784 params1stPass.output.rcDst = params1stPass.input.rcDst;
785 params1stPass.output.rcMaxSrc = params1stPass.output.rcSrc;
786
787 params2ndPass.input.dwWidth = params1stPass.output.dwWidth;
788 params2ndPass.input.dwHeight = params1stPass.output.dwHeight;
789 params2ndPass.input.rcSrc = params1stPass.input.rcDst;
790 params2ndPass.input.rcMaxSrc = params2ndPass.input.rcSrc;
791
792 // Set engine caps for filter in 2nd pass.
793 filter2ndPass->SetFeatureType(FeatureTypeScaling);
794 filter2ndPass->GetFilterEngineCaps().value = 0;
795 filter2ndPass->GetFilterEngineCaps().bEnabled = 1;
796 filter2ndPass->GetFilterEngineCaps().SfcNeeded = 1;
797 filter2ndPass->GetFilterEngineCaps().usedForNextPass = 1;
798
799 executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
800 }
801 else
802 {
803 if (caps.bOutputPipeFeatureInuse)
804 {
805 return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
806 }
807 else
808 {
809 SwFilterScaling *filter2ndPass = featureScaling;
810 SwFilterScaling *filter1ndPass = (SwFilterScaling *)feature.Clone();
811
812 filter1ndPass->GetFilterEngineCaps().value = 0;
813 filter1ndPass->SetFeatureType(FeatureType::FeatureTypeScaling);
814
815 FeatureParamScaling ¶ms2ndPass = filter2ndPass->GetSwFilterParams();
816 FeatureParamScaling ¶ms1stPass = filter1ndPass->GetSwFilterParams();
817
818 uint32_t inputWidth = params1stPass.input.rcSrc.right - params1stPass.input.rcSrc.left;
819 uint32_t inputHeight = params1stPass.input.rcSrc.bottom - params1stPass.input.rcSrc.top;
820 uint32_t outputWidth = params1stPass.input.rcDst.right - params1stPass.input.rcDst.left;
821 uint32_t outputHeight = params1stPass.input.rcDst.bottom - params1stPass.input.rcDst.top;
822
823 VP_PUBLIC_NORMALMESSAGE("sfc scaling w/o rectangle info on target surface: (%dx%d)->(%dx%d)",
824 inputWidth, inputHeight, outputWidth, outputHeight);
825
826 params1stPass.input.rcDst.left = 0;
827 params1stPass.input.rcDst.right = outputWidth;
828 params1stPass.input.rcDst.top = 0;
829 params1stPass.input.rcDst.bottom = outputHeight;
830
831 params1stPass.output.dwWidth = outputWidth;
832 params1stPass.output.dwHeight = outputHeight;
833 params1stPass.output.rcSrc = params1stPass.input.rcDst;
834 params1stPass.output.rcDst = params1stPass.input.rcDst;
835 params1stPass.output.rcMaxSrc = params1stPass.output.rcSrc;
836
837 params2ndPass.input.dwWidth = params1stPass.output.dwWidth;
838 params2ndPass.input.dwHeight = params1stPass.output.dwHeight;
839 params2ndPass.input.rcSrc = params1stPass.input.rcDst;
840 params2ndPass.input.rcMaxSrc = params2ndPass.input.rcSrc;
841
842 // Set engine caps for filter in 2nd pass.
843 filter2ndPass->SetFeatureType(FeatureTypeScaling);
844 filter2ndPass->GetFilterEngineCaps().value = 0;
845 filter2ndPass->GetFilterEngineCaps().bEnabled = 1;
846 filter2ndPass->GetFilterEngineCaps().SfcNeeded = 1;
847 filter2ndPass->GetFilterEngineCaps().RenderNeeded = 1;
848 filter2ndPass->GetFilterEngineCaps().fcSupported = 1;
849 filter2ndPass->GetFilterEngineCaps().usedForNextPass = 1;
850
851 executePipe.AddSwFilterUnordered(filter1ndPass, isInputPipe, index);
852
853 }
854 }
855
856 return MOS_STATUS_SUCCESS;
857 }
858
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)859 MOS_STATUS PolicySfcColorFillHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
860 {
861 VP_FUNC_CALL();
862
863 if (caps.bSFC && caps.bSfcScaling)
864 {
865 if (true == isInputPipe)
866 {
867 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
868 }
869
870 SwFilterScaling *scaling = dynamic_cast<SwFilterScaling *>(executePipe.GetSwFilter(true, 0, FeatureTypeScaling));
871 SwFilterColorFill *colorfill = dynamic_cast<SwFilterColorFill *>(&feature);
872
873 if (colorfill)
874 {
875 if (scaling)
876 {
877 scaling->GetSwFilterParams().pColorFillParams = colorfill->GetSwFilterParams().colorFillParams;
878 }
879 bool removeFeatureFromFeaturePipe = featurePipe.IsAllInputPipeSurfaceFeatureEmpty();
880 if (removeFeatureFromFeaturePipe)
881 {
882 // Will be removed and destroyed in Policy::UpdateFeaturePipe.
883 colorfill->GetFilterEngineCaps().bEnabled = false;
884 }
885 else
886 {
887 colorfill->ResetFeatureType();
888 }
889 return MOS_STATUS_SUCCESS;
890 }
891 }
892
893 return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
894 }
895
UpdateUnusedFeature(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)896 MOS_STATUS PolicySfcColorFillHandler::UpdateUnusedFeature(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
897 {
898 VP_FUNC_CALL();
899
900 if (true == isInputPipe)
901 {
902 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
903 }
904
905 SwFilterColorFill *colorfill = dynamic_cast<SwFilterColorFill *>(&feature);
906 if (colorfill)
907 {
908 bool removeFeatureFromFeaturePipe = featurePipe.IsAllInputPipeSurfaceFeatureEmpty();
909 if (removeFeatureFromFeaturePipe)
910 {
911 // Will be removed and destroyed in Policy::UpdateFeaturePipe.
912 colorfill->GetFilterEngineCaps().bEnabled = false;
913 }
914 else
915 {
916 colorfill->ResetFeatureType();
917 }
918 }
919
920 return MOS_STATUS_SUCCESS;
921 }
922
UpdateFeaturePipe(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)923 MOS_STATUS PolicySfcAlphaHandler::UpdateFeaturePipe(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
924 {
925 VP_FUNC_CALL();
926
927 if (caps.bSFC && caps.bSfcScaling)
928 {
929 if (true == isInputPipe)
930 {
931 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
932 }
933
934 SwFilterScaling *scaling = dynamic_cast<SwFilterScaling *>(executePipe.GetSwFilter(true, 0, FeatureTypeScaling));
935 SwFilterCsc *csc = dynamic_cast<SwFilterCsc *>(executePipe.GetSwFilter(true, 0, FeatureTypeCsc));
936 SwFilterAlpha *alpha = dynamic_cast<SwFilterAlpha *>(&feature);
937
938 if (alpha)
939 {
940 if (scaling)
941 {
942 scaling->GetSwFilterParams().pCompAlpha = alpha->GetSwFilterParams().compAlpha;
943 }
944 if (csc)
945 {
946 csc->GetSwFilterParams().pAlphaParams = alpha->GetSwFilterParams().compAlpha;
947 }
948 bool removeFeatureFromFeaturePipe = featurePipe.IsAllInputPipeSurfaceFeatureEmpty();
949 if (removeFeatureFromFeaturePipe)
950 {
951 // Will be removed and destroyed in Policy::UpdateFeaturePipe.
952 alpha->GetFilterEngineCaps().bEnabled = false;
953 }
954 else
955 {
956 alpha->ResetFeatureType();
957 }
958 return MOS_STATUS_SUCCESS;
959 }
960 }
961
962 return PolicyFeatureHandler::UpdateFeaturePipe(caps, feature, featurePipe, executePipe, isInputPipe, index);
963 }
964
UpdateUnusedFeature(VP_EXECUTE_CAPS caps,SwFilter & feature,SwFilterPipe & featurePipe,SwFilterPipe & executePipe,bool isInputPipe,int index)965 MOS_STATUS PolicySfcAlphaHandler::UpdateUnusedFeature(VP_EXECUTE_CAPS caps, SwFilter &feature, SwFilterPipe &featurePipe, SwFilterPipe &executePipe, bool isInputPipe, int index)
966 {
967 VP_FUNC_CALL();
968
969 if (true == isInputPipe)
970 {
971 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
972 }
973
974 SwFilterAlpha *alpha = dynamic_cast<SwFilterAlpha *>(&feature);
975 if (alpha)
976 {
977 bool removeFeatureFromFeaturePipe = featurePipe.IsAllInputPipeSurfaceFeatureEmpty();
978 if (removeFeatureFromFeaturePipe)
979 {
980 // Will be removed and destroyed in Policy::UpdateFeaturePipe.
981 alpha->GetFilterEngineCaps().bEnabled = false;
982 }
983 else
984 {
985 alpha->ResetFeatureType();
986 }
987 }
988
989 return MOS_STATUS_SUCCESS;
990 }
991