1 /*
2 * Copyright (c) 2022, 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_packet_reuse_manager.cpp
24 //! \brief    Defines the common classes for vp packet reuse
25 //!           this file is for the base interface which is shared by all features.
26 //!
27 
28 #include "vp_packet_reuse_manager.h"
29 #include "vp_vebox_cmd_packet_base.h"
30 #include "vp_user_feature_control.h"
31 #include "policy.h"
32 
33 using namespace vp;
34 
35 /*******************************************************************/
36 /***********************VpFeatureReuseBase**************************/
37 /*******************************************************************/
38 
~VpFeatureReuseBase()39 VpFeatureReuseBase::~VpFeatureReuseBase()
40 {
41 }
42 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)43 MOS_STATUS VpFeatureReuseBase::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
44 {
45     reused = false;
46     return MOS_STATUS_SUCCESS;
47 }
48 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)49 MOS_STATUS VpFeatureReuseBase::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
50 {
51     VP_PUBLIC_ASSERTMESSAGE("UpdatePacket must be overridden in subclass");
52     return MOS_STATUS_INVALID_PARAMETER;
53 }
54 
CheckTeamsParams(bool reusable,bool & reused,SwFilter * filter,uint32_t index)55 MOS_STATUS VpFeatureReuseBase::CheckTeamsParams(bool reusable, bool &reused, SwFilter *filter, uint32_t index)
56 {
57     reused = false;
58     return MOS_STATUS_SUCCESS;
59 }
60 
StoreTeamsParams(SwFilter * filter,uint32_t index)61 MOS_STATUS VpFeatureReuseBase::StoreTeamsParams(SwFilter *filter, uint32_t index)
62 {
63     return MOS_STATUS_SUCCESS;
64 }
65 
66 /*******************************************************************/
67 /***********************VpScalingReuse******************************/
68 /*******************************************************************/
69 
VpScalingReuse()70 VpScalingReuse::VpScalingReuse()
71 {
72     m_params_Teams.clear();
73 }
74 
~VpScalingReuse()75 VpScalingReuse::~VpScalingReuse()
76 {
77 }
78 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)79 MOS_STATUS VpScalingReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
80 {
81     VP_FUNC_CALL();
82     SwFilterScaling *scaling = dynamic_cast<SwFilterScaling *>(filter);
83     VP_PUBLIC_CHK_NULL_RETURN(scaling);
84     FeatureParamScaling &params = scaling->GetSwFilterParams();
85     if (reusable && params == m_params)
86     {
87         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
88         // is enough. UpdatePacket should use params in swfilter instead of m_params.
89         reused = true;
90     }
91     else
92     {
93         reused = false;
94         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
95     }
96     return MOS_STATUS_SUCCESS;
97 }
98 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)99 MOS_STATUS VpScalingReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
100 {
101     // Parameters should be no change in UpdateFeatureParams.
102     // No need update.
103     return MOS_STATUS_SUCCESS;
104 }
105 
UpdateFeatureParams(FeatureParamScaling & params)106 MOS_STATUS VpScalingReuse::UpdateFeatureParams(FeatureParamScaling &params)
107 {
108     m_params = params;
109     if (params.pColorFillParams)
110     {
111         m_colorFillParams = *params.pColorFillParams;
112         m_params.pColorFillParams = &m_colorFillParams;
113     }
114     if (params.pCompAlpha)
115     {
116         m_compAlpha = *params.pCompAlpha;
117         m_params.pCompAlpha = &m_compAlpha;
118     }
119     return MOS_STATUS_SUCCESS;
120 }
121 
CheckTeamsParams(bool reusable,bool & reused,SwFilter * filter,uint32_t index)122 MOS_STATUS VpScalingReuse::CheckTeamsParams(bool reusable, bool &reused, SwFilter *filter, uint32_t index)
123 {
124     VP_FUNC_CALL();
125     SwFilterScaling     *scaling = dynamic_cast<SwFilterScaling *>(filter);
126     VP_PUBLIC_CHK_NULL_RETURN(scaling);
127     FeatureParamScaling &params  = scaling->GetSwFilterParams();
128     auto                 it      = m_params_Teams.find(index);
129     VP_PUBLIC_CHK_NOT_FOUND_RETURN(it, &m_params_Teams);
130 
131     if (reusable && params == it->second)
132     {
133         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
134         // is enough. UpdatePacket should use params in swfilter instead of m_params.
135         reused = true;
136     }
137     else
138     {
139         reused = false;
140     }
141     return MOS_STATUS_SUCCESS;
142 }
143 
StoreTeamsParams(SwFilter * filter,uint32_t index)144 MOS_STATUS VpScalingReuse::StoreTeamsParams(SwFilter *filter, uint32_t index)
145 {
146     VP_FUNC_CALL();
147     SwFilterScaling     *scaling = dynamic_cast<SwFilterScaling *>(filter);
148     VP_PUBLIC_CHK_NULL_RETURN(scaling);
149     FeatureParamScaling &params  = scaling->GetSwFilterParams();
150     auto                 it      = m_params_Teams.find(index);
151     if (it != m_params_Teams.end())
152     {
153         m_params_Teams.erase(index);
154     }
155 
156     m_params_Teams.insert(std::make_pair(index, params));
157     return MOS_STATUS_SUCCESS;
158 }
159 
160 /*******************************************************************/
161 /***********************VpCscReuse**********************************/
162 /*******************************************************************/
VpCscReuse()163 VpCscReuse::VpCscReuse()
164 {
165     m_params_Teams.clear();
166 }
167 
~VpCscReuse()168 VpCscReuse::~VpCscReuse()
169 {
170 }
171 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)172 MOS_STATUS VpCscReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
173 {
174     VP_FUNC_CALL();
175     auto IsIefEnabled = [&](PVPHAL_IEF_PARAMS iefParams)
176     {
177         return (iefParams && iefParams->bEnabled && iefParams->fIEFFactor > 0.0F);
178     };
179 
180     SwFilterCsc *csc = dynamic_cast<SwFilterCsc *>(filter);
181     VP_PUBLIC_CHK_NULL_RETURN(csc);
182     FeatureParamCsc &params = csc->GetSwFilterParams();
183     // pIEFParams to be updated.
184     if (reusable &&
185         params.formatInput == m_params.formatInput &&
186         params.formatOutput == m_params.formatOutput &&
187         params.input == m_params.input &&
188         params.output == m_params.output &&
189         (nullptr == params.pAlphaParams && nullptr == m_params.pAlphaParams ||
190         nullptr != params.pAlphaParams && nullptr != m_params.pAlphaParams &&
191         0 == memcmp(params.pAlphaParams, m_params.pAlphaParams, sizeof(VPHAL_ALPHA_PARAMS))) &&
192         IsIefEnabled(params.pIEFParams) == IsIefEnabled(m_params.pIEFParams))
193     {
194         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
195         // is enough. UpdatePacket should use params in swfilter instead of m_params.
196         reused = true;
197     }
198     else
199     {
200         reused = false;
201         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
202     }
203     return MOS_STATUS_SUCCESS;
204 }
205 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)206 MOS_STATUS VpCscReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
207 {
208     VP_FUNC_CALL();
209     VpVeboxCmdPacketBase *veboxPacket = dynamic_cast<VpVeboxCmdPacketBase *>(packet);
210     VP_PUBLIC_CHK_NULL_RETURN(veboxPacket);
211 
212     SwFilterCsc *scaling = dynamic_cast<SwFilterCsc *>(filter);
213     VP_PUBLIC_CHK_NULL_RETURN(scaling);
214     FeatureParamCsc &params = scaling->GetSwFilterParams();
215 
216     VP_PUBLIC_CHK_STATUS_RETURN(veboxPacket->UpdateCscParams(params));
217     return MOS_STATUS_SUCCESS;
218 }
219 
UpdateFeatureParams(FeatureParamCsc & params)220 MOS_STATUS VpCscReuse::UpdateFeatureParams(FeatureParamCsc &params)
221 {
222     VP_FUNC_CALL();
223     m_params = params;
224 
225     if (params.pAlphaParams)
226     {
227         m_alphaParams = *params.pAlphaParams;
228         m_params.pAlphaParams = &m_alphaParams;
229     }
230     else
231     {
232         m_params.pAlphaParams = nullptr;
233     }
234 
235     if (params.pIEFParams)
236     {
237         m_iefParams = *params.pIEFParams;
238         m_params.pIEFParams = &m_iefParams;
239     }
240     else
241     {
242         m_params.pIEFParams = nullptr;
243     }
244 
245     return MOS_STATUS_SUCCESS;
246 }
247 
CheckTeamsParams(bool reusable,bool & reused,SwFilter * filter,uint32_t index)248 MOS_STATUS VpCscReuse::CheckTeamsParams(bool reusable, bool &reused, SwFilter *filter, uint32_t index)
249 {
250     VP_FUNC_CALL();
251     auto IsIefEnabled = [&](PVPHAL_IEF_PARAMS iefParams) {
252         return (iefParams && iefParams->bEnabled && iefParams->fIEFFactor > 0.0F);
253     };
254 
255     SwFilterCsc     *csc    = dynamic_cast<SwFilterCsc *>(filter);
256     VP_PUBLIC_CHK_NULL_RETURN(csc);
257     FeatureParamCsc &params = csc->GetSwFilterParams();
258     auto             it     = m_params_Teams.find(index);
259     VP_PUBLIC_CHK_NOT_FOUND_RETURN(it, &m_params_Teams);
260 
261     // pIEFParams to be updated.
262     if (reusable &&
263         params.formatInput == it->second.formatInput &&
264         params.formatOutput == it->second.formatOutput &&
265         params.input == it->second.input &&
266         params.output == it->second.output &&
267         (nullptr == params.pAlphaParams && nullptr == m_params.pAlphaParams ||
268         nullptr != params.pAlphaParams && nullptr != m_params.pAlphaParams &&
269         0 == memcmp(params.pAlphaParams, m_params.pAlphaParams, sizeof(VPHAL_ALPHA_PARAMS))) &&
270         IsIefEnabled(params.pIEFParams) == false)
271     {
272         reused = true;
273     }
274     else
275     {
276         reused = false;
277     }
278     return MOS_STATUS_SUCCESS;
279 }
280 
StoreTeamsParams(SwFilter * filter,uint32_t index)281 MOS_STATUS VpCscReuse::StoreTeamsParams(SwFilter *filter, uint32_t index)
282 {
283     VP_FUNC_CALL();
284     SwFilterCsc     *csc    = dynamic_cast<SwFilterCsc *>(filter);
285     VP_PUBLIC_CHK_NULL_RETURN(csc);
286     FeatureParamCsc &params = csc->GetSwFilterParams();
287     auto             it     = m_params_Teams.find(index);
288     if (it != m_params_Teams.end())
289     {
290         m_params_Teams.erase(index);
291     }
292 
293     m_params_Teams.insert(std::make_pair(index, params));
294     return MOS_STATUS_SUCCESS;
295 }
296 
297 /*******************************************************************/
298 /***********************VpRotMirReuse*******************************/
299 /*******************************************************************/
300 
VpRotMirReuse()301 VpRotMirReuse::VpRotMirReuse()
302 {
303     m_params_Teams.clear();
304 }
305 
~VpRotMirReuse()306 VpRotMirReuse::~VpRotMirReuse()
307 {
308 }
309 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)310 MOS_STATUS VpRotMirReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
311 {
312     VP_FUNC_CALL();
313     SwFilterRotMir *rot = dynamic_cast<SwFilterRotMir *>(filter);
314     VP_PUBLIC_CHK_NULL_RETURN(rot);
315     FeatureParamRotMir &params = rot->GetSwFilterParams();
316     if (reusable && params == m_params)
317     {
318         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
319         // is enough. UpdatePacket should use params in swfilter instead of m_params.
320         reused = true;
321     }
322     else
323     {
324         reused = false;
325         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
326     }
327     return MOS_STATUS_SUCCESS;
328 }
329 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)330 MOS_STATUS VpRotMirReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
331 {
332     // Parameters should be no change in UpdateFeatureParams.
333     // No need update.
334     return MOS_STATUS_SUCCESS;
335 }
336 
UpdateFeatureParams(FeatureParamRotMir & params)337 MOS_STATUS VpRotMirReuse::UpdateFeatureParams(FeatureParamRotMir &params)
338 {
339     m_params = params;
340 
341     return MOS_STATUS_SUCCESS;
342 }
343 
CheckTeamsParams(bool reusable,bool & reused,SwFilter * filter,uint32_t index)344 MOS_STATUS VpRotMirReuse::CheckTeamsParams(bool reusable, bool &reused, SwFilter *filter, uint32_t index)
345 {
346     VP_FUNC_CALL();
347 
348     SwFilterRotMir     *rot    = dynamic_cast<SwFilterRotMir *>(filter);
349     VP_PUBLIC_CHK_NULL_RETURN(rot);
350 
351     FeatureParamRotMir &params = rot->GetSwFilterParams();
352     auto               it      = m_params_Teams.find(index);
353     VP_PUBLIC_CHK_NOT_FOUND_RETURN(it, &m_params_Teams);
354 
355     // pIEFParams to be updated.
356     if (reusable &&
357         params == it->second)
358     {
359         reused = true;
360     }
361     else
362     {
363         reused = false;
364     }
365     return MOS_STATUS_SUCCESS;
366 }
367 
StoreTeamsParams(SwFilter * filter,uint32_t index)368 MOS_STATUS VpRotMirReuse::StoreTeamsParams(SwFilter *filter, uint32_t index)
369 {
370     VP_FUNC_CALL();
371     SwFilterRotMir     *rot    = dynamic_cast<SwFilterRotMir *>(filter);
372     VP_PUBLIC_CHK_NULL_RETURN(rot);
373 
374     FeatureParamRotMir &params = rot->GetSwFilterParams();
375     auto                it     = m_params_Teams.find(index);
376     if (it != m_params_Teams.end())
377     {
378         m_params_Teams.erase(index);
379     }
380 
381     m_params_Teams.insert(std::make_pair(index, params));
382     return MOS_STATUS_SUCCESS;
383 }
384 
385 /*******************************************************************/
386 /***********************VpColorFillReuse****************************/
387 /*******************************************************************/
388 
VpColorFillReuse()389 VpColorFillReuse::VpColorFillReuse()
390 {
391 }
392 
~VpColorFillReuse()393 VpColorFillReuse::~VpColorFillReuse()
394 {
395 }
396 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)397 MOS_STATUS VpColorFillReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
398 {
399     VP_FUNC_CALL();
400     SwFilterColorFill *colorfill = dynamic_cast<SwFilterColorFill *>(filter);
401     VP_PUBLIC_CHK_NULL_RETURN(colorfill);
402     FeatureParamColorFill &params = colorfill->GetSwFilterParams();
403     if (reusable && params == m_params)
404     {
405         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
406         // is enough. UpdatePacket should use params in swfilter instead of m_params.
407         reused = true;
408     }
409     else
410     {
411         reused = false;
412         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
413     }
414     return MOS_STATUS_SUCCESS;
415 }
416 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)417 MOS_STATUS VpColorFillReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
418 {
419     // Parameters should be no change in UpdateFeatureParams.
420     // No need update.
421     return MOS_STATUS_SUCCESS;
422 }
423 
UpdateFeatureParams(FeatureParamColorFill & params)424 MOS_STATUS VpColorFillReuse::UpdateFeatureParams(FeatureParamColorFill &params)
425 {
426     m_params = params;
427 
428     if (params.colorFillParams)
429     {
430         m_colorFillParams = *params.colorFillParams;
431         m_params.colorFillParams = &m_colorFillParams;
432     }
433 
434     return MOS_STATUS_SUCCESS;
435 }
436 
437 /*******************************************************************/
438 /***********************VpAlphaReuse********************************/
439 /*******************************************************************/
440 
VpAlphaReuse()441 VpAlphaReuse::VpAlphaReuse()
442 {
443 }
444 
~VpAlphaReuse()445 VpAlphaReuse::~VpAlphaReuse()
446 {
447 }
448 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)449 MOS_STATUS VpAlphaReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
450 {
451     VP_FUNC_CALL();
452     SwFilterAlpha *alpha = dynamic_cast<SwFilterAlpha *>(filter);
453     VP_PUBLIC_CHK_NULL_RETURN(alpha);
454     FeatureParamAlpha &params = alpha->GetSwFilterParams();
455     if (reusable && params == m_params)
456     {
457         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
458         // is enough. UpdatePacket should use params in swfilter instead of m_params.
459         reused = true;
460     }
461     else
462     {
463         reused = false;
464         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
465     }
466     return MOS_STATUS_SUCCESS;
467 }
468 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)469 MOS_STATUS VpAlphaReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
470 {
471     // Parameters should be no change in UpdateFeatureParams.
472     // No need update.
473     return MOS_STATUS_SUCCESS;
474 }
475 
UpdateFeatureParams(FeatureParamAlpha & params)476 MOS_STATUS VpAlphaReuse::UpdateFeatureParams(FeatureParamAlpha &params)
477 {
478     m_params = params;
479 
480     if (params.compAlpha)
481     {
482         m_compAlpha = *params.compAlpha;
483         m_params.compAlpha = &m_compAlpha;
484     }
485 
486     return MOS_STATUS_SUCCESS;
487 }
488 
489 /*******************************************************************/
490 /***********************VpDenoiseReuse********************************/
491 /*******************************************************************/
492 
VpDenoiseReuse()493 VpDenoiseReuse::VpDenoiseReuse()
494 {
495 }
496 
~VpDenoiseReuse()497 VpDenoiseReuse::~VpDenoiseReuse()
498 {
499 }
500 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)501 MOS_STATUS VpDenoiseReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
502 {
503     VP_FUNC_CALL();
504     SwFilterDenoise     *dn    = dynamic_cast<SwFilterDenoise *>(filter);
505     VP_PUBLIC_CHK_NULL_RETURN(dn);
506     FeatureParamDenoise &params = dn->GetSwFilterParams();
507     if (reusable && params == m_params)
508     {
509         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
510         // is enough. UpdatePacket should use params in swfilter instead of m_params.
511         reused = true;
512     }
513     else
514     {
515         reused = false;
516         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
517     }
518     return MOS_STATUS_SUCCESS;
519 }
520 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)521 MOS_STATUS VpDenoiseReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
522 {
523     VP_FUNC_CALL();
524     VpVeboxCmdPacketBase *veboxPacket = dynamic_cast<VpVeboxCmdPacketBase *>(packet);
525     VP_PUBLIC_CHK_NULL_RETURN(veboxPacket);
526 
527     SwFilterDenoise *denoise = dynamic_cast<SwFilterDenoise *>(filter);
528     VP_PUBLIC_CHK_NULL_RETURN(denoise);
529     FeatureParamDenoise &params = denoise->GetSwFilterParams();
530 
531     VP_PUBLIC_CHK_STATUS_RETURN(veboxPacket->UpdateDenoiseParams(params));
532     return MOS_STATUS_SUCCESS;
533 }
534 
UpdateFeatureParams(FeatureParamDenoise & params)535 MOS_STATUS VpDenoiseReuse::UpdateFeatureParams(FeatureParamDenoise &params)
536 {
537     m_params = params;
538     return MOS_STATUS_SUCCESS;
539 }
540 
541 /*******************************************************************/
542 /***********************VpTccReuse**********************************/
543 /*******************************************************************/
544 
VpTccReuse()545 VpTccReuse::VpTccReuse()
546 {
547 }
548 
~VpTccReuse()549 VpTccReuse::~VpTccReuse()
550 {
551 }
552 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)553 MOS_STATUS VpTccReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
554 {
555     VP_FUNC_CALL();
556     SwFilterTcc *tcc = dynamic_cast<SwFilterTcc *>(filter);
557     VP_PUBLIC_CHK_NULL_RETURN(tcc);
558     FeatureParamTcc &params = tcc->GetSwFilterParams();
559     if (reusable && params.bEnableTCC == m_params.bEnableTCC)
560     {
561         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
562         // is enough. UpdatePacket should use params in swfilter instead of m_params.
563         reused = true;
564     }
565     else
566     {
567         reused = false;
568         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
569     }
570     return MOS_STATUS_SUCCESS;
571 }
572 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)573 MOS_STATUS VpTccReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
574 {
575     VP_FUNC_CALL();
576     VpVeboxCmdPacketBase *veboxPacket = dynamic_cast<VpVeboxCmdPacketBase *>(packet);
577     VP_PUBLIC_CHK_NULL_RETURN(veboxPacket);
578 
579     SwFilterTcc *tcc = dynamic_cast<SwFilterTcc *>(filter);
580     VP_PUBLIC_CHK_NULL_RETURN(tcc);
581     FeatureParamTcc &params = tcc->GetSwFilterParams();
582 
583     VP_PUBLIC_CHK_STATUS_RETURN(veboxPacket->UpdateTccParams(params));
584     return MOS_STATUS_SUCCESS;
585 }
586 
UpdateFeatureParams(FeatureParamTcc & params)587 MOS_STATUS VpTccReuse::UpdateFeatureParams(FeatureParamTcc &params)
588 {
589     m_params = params;
590     return MOS_STATUS_SUCCESS;
591 }
592 
593 /*******************************************************************/
594 /***********************VpSteReuse**********************************/
595 /*******************************************************************/
596 
VpSteReuse()597 VpSteReuse::VpSteReuse()
598 {
599 }
600 
~VpSteReuse()601 VpSteReuse::~VpSteReuse()
602 {
603 }
604 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)605 MOS_STATUS VpSteReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
606 {
607     VP_FUNC_CALL();
608     SwFilterSte     *ste    = dynamic_cast<SwFilterSte *>(filter);
609     VP_PUBLIC_CHK_NULL_RETURN(ste);
610     FeatureParamSte &params = ste->GetSwFilterParams();
611     if (reusable && params.bEnableSTE == m_params.bEnableSTE)
612     {
613         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
614         // is enough. UpdatePacket should use params in swfilter instead of m_params.
615         reused = true;
616     }
617     else
618     {
619         reused = false;
620         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
621     }
622     return MOS_STATUS_SUCCESS;
623 }
624 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)625 MOS_STATUS VpSteReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
626 {
627     VP_FUNC_CALL();
628     VpVeboxCmdPacketBase *veboxPacket = dynamic_cast<VpVeboxCmdPacketBase *>(packet);
629     VP_PUBLIC_CHK_NULL_RETURN(veboxPacket);
630 
631     SwFilterSte *ste = dynamic_cast<SwFilterSte *>(filter);
632     VP_PUBLIC_CHK_NULL_RETURN(ste);
633     FeatureParamSte &params = ste->GetSwFilterParams();
634 
635     VP_PUBLIC_CHK_STATUS_RETURN(veboxPacket->UpdateSteParams(params));
636     return MOS_STATUS_SUCCESS;
637 }
638 
UpdateFeatureParams(FeatureParamSte & params)639 MOS_STATUS VpSteReuse::UpdateFeatureParams(FeatureParamSte &params)
640 {
641     m_params = params;
642     return MOS_STATUS_SUCCESS;
643 }
644 
645 /*******************************************************************/
646 /***********************VpProcampReuse**********************************/
647 /*******************************************************************/
648 
VpProcampReuse()649 VpProcampReuse::VpProcampReuse()
650 {
651 }
652 
~VpProcampReuse()653 VpProcampReuse::~VpProcampReuse()
654 {
655 }
656 
UpdateFeatureParams(bool reusable,bool & reused,SwFilter * filter)657 MOS_STATUS VpProcampReuse::UpdateFeatureParams(bool reusable, bool &reused, SwFilter *filter)
658 {
659     VP_FUNC_CALL();
660     SwFilterProcamp *procamp    = dynamic_cast<SwFilterProcamp *>(filter);
661     VP_PUBLIC_CHK_NULL_RETURN(procamp);
662     FeatureParamProcamp &params  = procamp->GetSwFilterParams();
663     if (reusable && ((params.procampParams && m_params.procampParams && params.procampParams->bEnabled == m_params.procampParams->bEnabled) ||
664         (!params.procampParams && !m_params.procampParams)))
665     {
666         // No need call UpdateFeatureParams. Just keep compared items updated in m_params
667         // is enough. UpdatePacket should use params in swfilter instead of m_params.
668         reused = true;
669     }
670     else
671     {
672         reused = false;
673         VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatureParams(params));
674     }
675     return MOS_STATUS_SUCCESS;
676 }
677 
UpdatePacket(SwFilter * filter,VpCmdPacket * packet)678 MOS_STATUS VpProcampReuse::UpdatePacket(SwFilter *filter, VpCmdPacket *packet)
679 {
680     VP_FUNC_CALL();
681     VpVeboxCmdPacketBase *veboxPacket = dynamic_cast<VpVeboxCmdPacketBase *>(packet);
682     VP_PUBLIC_CHK_NULL_RETURN(veboxPacket);
683 
684     SwFilterProcamp *procamp = dynamic_cast<SwFilterProcamp *>(filter);
685     VP_PUBLIC_CHK_NULL_RETURN(procamp);
686     FeatureParamProcamp &params = procamp->GetSwFilterParams();
687 
688     VP_PUBLIC_CHK_STATUS_RETURN(veboxPacket->UpdateProcampParams(params));
689     return MOS_STATUS_SUCCESS;
690 }
691 
UpdateFeatureParams(FeatureParamProcamp & params)692 MOS_STATUS VpProcampReuse::UpdateFeatureParams(FeatureParamProcamp &params)
693 {
694     m_params = params;
695     if (params.procampParams)
696     {
697         m_procampParams        = *params.procampParams;
698         m_params.procampParams = &m_procampParams;
699     }
700     return MOS_STATUS_SUCCESS;
701 }
702 
703 /*******************************************************************/
704 /***********************VpPacketReuseManager************************/
705 /*******************************************************************/
706 
VpPacketReuseManager(PacketPipeFactory & packetPipeFactory,VpUserFeatureControl & userFeatureControl)707 VpPacketReuseManager::VpPacketReuseManager(PacketPipeFactory &packetPipeFactory, VpUserFeatureControl &userFeatureControl) :
708     m_packetPipeFactory(packetPipeFactory), m_disablePacketReuse(userFeatureControl.IsPacketReuseDisabled())
709 {
710     m_pipeReused_TeamsPacket.clear();
711     m_enablePacketReuseTeamsAlways = userFeatureControl.IsPacketReuseEnabledTeamsAlways();
712 }
713 
~VpPacketReuseManager()714 VpPacketReuseManager::~VpPacketReuseManager()
715 {
716     for (uint32_t index = 0; index < m_pipeReused_TeamsPacket.size(); index++)
717     {
718         auto pipeReuseHandle = m_pipeReused_TeamsPacket.find(index);
719         if (pipeReuseHandle != m_pipeReused_TeamsPacket.end() &&
720             pipeReuseHandle->second != m_pipeReused)
721         {
722             m_packetPipeFactory.ReturnPacketPipe(pipeReuseHandle->second);
723         }
724     }
725     m_pipeReused_TeamsPacket.clear();
726 
727     if (m_pipeReused)
728     {
729         m_packetPipeFactory.ReturnPacketPipe(m_pipeReused);
730     }
731     for (auto &it : m_features)
732     {
733         if (it.second)
734         {
735             MOS_Delete(it.second);
736         }
737     }
738     m_features.clear();
739 }
740 
RegisterFeatures()741 MOS_STATUS VpPacketReuseManager::RegisterFeatures()
742 {
743     VP_FUNC_CALL()
744     if (m_disablePacketReuse)
745     {
746         return MOS_STATUS_SUCCESS;
747     }
748     VpFeatureReuseBase *p = MOS_New(VpScalingReuse);
749     VP_PUBLIC_CHK_NULL_RETURN(p);
750     m_features.insert(std::make_pair(FeatureTypeScaling, p));
751 
752     p = MOS_New(VpCscReuse);
753     VP_PUBLIC_CHK_NULL_RETURN(p);
754     m_features.insert(std::make_pair(FeatureTypeCsc, p));
755 
756     p = MOS_New(VpRotMirReuse);
757     VP_PUBLIC_CHK_NULL_RETURN(p);
758     m_features.insert(std::make_pair(FeatureTypeRotMir, p));
759 
760     p = MOS_New(VpColorFillReuse);
761     VP_PUBLIC_CHK_NULL_RETURN(p);
762     m_features.insert(std::make_pair(FeatureTypeColorFill, p));
763 
764     p = MOS_New(VpDenoiseReuse);
765     VP_PUBLIC_CHK_NULL_RETURN(p);
766     m_features.insert(std::make_pair(FeatureTypeDn, p));
767 
768     p = MOS_New(VpAlphaReuse);
769     VP_PUBLIC_CHK_NULL_RETURN(p);
770     m_features.insert(std::make_pair(FeatureTypeAlpha, p));
771 
772     p = MOS_New(VpTccReuse);
773     VP_PUBLIC_CHK_NULL_RETURN(p);
774     m_features.insert(std::make_pair(FeatureTypeTcc, p));
775 
776     p = MOS_New(VpSteReuse);
777     VP_PUBLIC_CHK_NULL_RETURN(p);
778     m_features.insert(std::make_pair(FeatureTypeSte, p));
779 
780     p = MOS_New(VpProcampReuse);
781     VP_PUBLIC_CHK_NULL_RETURN(p);
782     m_features.insert(std::make_pair(FeatureTypeProcamp, p));
783 
784 
785     return MOS_STATUS_SUCCESS;
786 }
787 
PreparePacketPipeReuse(SwFilterPipe * & swFilterPipe,Policy & policy,VpResourceManager & resMgr,bool & isPacketPipeReused,bool & isTeamsWL)788 MOS_STATUS VpPacketReuseManager::PreparePacketPipeReuse(SwFilterPipe *&swFilterPipe, Policy &policy, VpResourceManager &resMgr, bool &isPacketPipeReused, bool &isTeamsWL)
789 {
790     VP_FUNC_CALL();
791     bool reusableOfLastPipe = m_reusable;
792     bool foundPipe          = false;
793     uint32_t index          = 0;
794 
795     m_reusable = true;
796 
797     if (m_disablePacketReuse)
798     {
799         m_reusable = false;
800         VP_PUBLIC_NORMALMESSAGE("Not reusable since Packet reuse disabled.");
801         return MOS_STATUS_SUCCESS;
802     }
803 
804     if (nullptr == swFilterPipe || swFilterPipe->GetSurfaceCount(true) != 1)
805     {
806         m_reusable = false;
807         VP_PUBLIC_NORMALMESSAGE("Not reusable for multi-layer cases.");
808 
809         if (m_pipeReused)
810         {
811             m_packetPipeFactory.ReturnPacketPipe(m_pipeReused);
812         }
813 
814         return MOS_STATUS_SUCCESS;
815     }
816 
817     auto &pipe = *swFilterPipe;
818     auto featureRegistered = policy.GetFeatureRegistered();
819 
820     isPacketPipeReused = true;
821 
822     for (auto feature : featureRegistered)
823     {
824         SwFilter *swfilter = pipe.GetSwFilter(true, 0, feature);
825         auto it = m_features.find(feature);
826         bool ignoreUpdateFeatureParams = false;
827 
828         if (m_features.end() == it)
829         {
830             if (nullptr != swfilter)
831             {
832                 // unreused feature && nullptr != swfilter
833                 m_reusable         = false;
834                 isPacketPipeReused = false;
835                 if (m_pipeReused)
836                 {
837                     m_packetPipeFactory.ReturnPacketPipe(m_pipeReused);
838                 }
839                 return MOS_STATUS_SUCCESS;
840             }
841             else
842             {
843                 // unreused feature && nullptr == swfilter
844                 continue;
845             }
846         }
847         else
848         {
849             // handle reused feature
850             VP_PUBLIC_CHK_STATUS_RETURN(it->second->HandleNullSwFilter(reusableOfLastPipe, isPacketPipeReused, swfilter, ignoreUpdateFeatureParams));
851             if (ignoreUpdateFeatureParams)
852             {
853                 continue;
854             }
855         }
856 
857         bool reused = false;
858         VP_PUBLIC_CHK_STATUS_RETURN(it->second->UpdateFeatureParams(reusableOfLastPipe, reused, swfilter));
859         if (!reused)
860         {
861             VP_PUBLIC_NORMALMESSAGE("Packet not reused for feature %d", feature);
862         }
863         else
864         {
865             VP_PUBLIC_NORMALMESSAGE("Packet  reused for feature %d", feature);
866         }
867         isPacketPipeReused &= reused;
868     }
869 
870     m_TeamsPacket       = false;
871     m_TeamsPacket_reuse = false;
872 
873     if (isTeamsWL || m_enablePacketReuseTeamsAlways)
874     {
875         for (auto feature : featureRegistered)
876         {
877             SwFilter *swfilter = pipe.GetSwFilter(true, 0, feature);
878             if (nullptr == swfilter)
879             {
880                 continue;
881             }
882 
883             if (feature == FeatureTypeCsc ||
884                 feature == FeatureTypeScaling ||
885                 feature == FeatureTypeRotMir)
886             {
887                 // Teams feature
888             }
889             else
890             {
891                 m_TeamsPacket = false;
892                 break;
893             }
894 
895             m_TeamsPacket = true;
896         }
897 
898         if (nullptr == swFilterPipe || swFilterPipe->GetSurfaceCount(true) != 1 || swFilterPipe->GetSurfaceCount(false) != 1)
899         {
900             m_TeamsPacket = false;
901         }
902     }
903 
904     if (!isPacketPipeReused && m_TeamsPacket)
905     {
906         SwFilter *scaling = pipe.GetSwFilter(true, 0, FeatureTypeScaling);
907         SwFilter *csc     = pipe.GetSwFilter(true, 0, FeatureTypeCsc);
908         SwFilter *rot     = pipe.GetSwFilter(true, 0, FeatureTypeRotMir);
909 
910         bool reused = false;
911 
912         auto scalingreuse = m_features.find(FeatureTypeScaling);
913         auto cscreuse     = m_features.find(FeatureTypeCsc);
914         auto rotreuse     = m_features.find(FeatureTypeRotMir);
915         if (scalingreuse == m_features.end() ||
916             cscreuse == m_features.end()     ||
917             rotreuse == m_features.end())
918         {
919             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_HANDLE);
920         }
921 
922         for (index = 0; index < m_pipeReused_TeamsPacket.size(); index++)
923         {
924             scalingreuse->second->CheckTeamsParams(reusableOfLastPipe, reused, scaling, index);
925             if (!reused)
926             {
927                 continue;
928             }
929 
930             cscreuse->second->CheckTeamsParams(reusableOfLastPipe, reused, csc, index);
931             if (!reused)
932             {
933                 continue;
934             }
935 
936             rotreuse->second->CheckTeamsParams(reusableOfLastPipe, reused, rot, index);
937             if (reused)
938             {
939                 break;
940             }
941         }
942         // if not found, store the new params and packet
943         if (!reused)
944         {
945             scalingreuse->second->StoreTeamsParams(scaling, curIndex);
946             cscreuse->second->StoreTeamsParams(csc, curIndex);
947             rotreuse->second->StoreTeamsParams(rot, curIndex);
948 
949             m_TeamsPacket_reuse = false;
950 
951             foundPipe = false;
952             for (index = 0; index < m_pipeReused_TeamsPacket.size(); index++)
953             {
954                 auto pipeReuseHandle = m_pipeReused_TeamsPacket.find(index);
955                 if (pipeReuseHandle != m_pipeReused_TeamsPacket.end() &&
956                     m_pipeReused == pipeReuseHandle->second)
957                 {
958                     foundPipe = true;
959                     break;
960                 }
961             }
962 
963             if (foundPipe == false)
964             {
965                 if (m_pipeReused)
966                 {
967                     m_packetPipeFactory.ReturnPacketPipe(m_pipeReused);
968                 }
969             }
970             else
971             {
972                 m_pipeReused = nullptr;
973             }
974 
975             return MOS_STATUS_SUCCESS;
976         }
977         else
978         {
979             auto pipe_TeamsPacket = m_pipeReused_TeamsPacket.find(index);
980 
981             VpCmdPacket *packet = pipe_TeamsPacket->second->GetPacket(0);
982             VP_PUBLIC_CHK_NULL_RETURN(packet);
983 
984 
985             m_pipeReused = pipe_TeamsPacket->second;
986 
987             VP_SURFACE_SETTING surfSetting = {};
988             VP_EXECUTE_CAPS    caps        = packet->GetExecuteCaps();
989             resMgr.GetUpdatedExecuteResource(featureRegistered, caps, pipe, surfSetting);
990 
991             VP_PUBLIC_CHK_STATUS_RETURN(packet->PacketInitForReuse(pipe.GetSurface(true, 0), pipe.GetSurface(false, 0), pipe.GetPastSurface(0), surfSetting, caps));
992 
993             // Update Packet
994             for (auto it : m_features)
995             {
996                 SwFilter *swfilter = pipe.GetSwFilter(true, 0, it.first);
997                 if (nullptr == swfilter)
998                 {
999                     continue;
1000                 }
1001 
1002                 VP_PUBLIC_NORMALMESSAGE("Update Packet for feature %d", it.first);
1003                 VP_PUBLIC_CHK_STATUS_RETURN(it.second->UpdatePacket(swfilter, packet));
1004             }
1005 
1006             m_TeamsPacket_reuse = true;
1007             isPacketPipeReused  = true;
1008             return MOS_STATUS_SUCCESS;
1009         }
1010     }
1011 
1012     if (!isPacketPipeReused)
1013     {
1014         // m_pipeReused will be udpated in UpdatePacketPipeConfig.
1015         VP_PUBLIC_NORMALMESSAGE("Packet cannot be reused.");
1016 
1017         foundPipe = false;
1018         for (index = 0; index < m_pipeReused_TeamsPacket.size(); index++)
1019         {
1020             auto pipeReuseHandle = m_pipeReused_TeamsPacket.find(index);
1021             if (pipeReuseHandle != m_pipeReused_TeamsPacket.end() &&
1022                 m_pipeReused == pipeReuseHandle->second)
1023             {
1024                 foundPipe = true;
1025                 break;
1026             }
1027         }
1028 
1029         if (foundPipe == false)
1030         {
1031             if (m_pipeReused)
1032             {
1033                 m_packetPipeFactory.ReturnPacketPipe(m_pipeReused);
1034             }
1035         }
1036         else
1037         {
1038             m_pipeReused = nullptr;
1039         }
1040 
1041         return MOS_STATUS_SUCCESS;
1042     }
1043 
1044     VP_PUBLIC_CHK_NULL_RETURN(m_pipeReused);
1045 
1046     if (0 == m_pipeReused->PacketNum())
1047     {
1048         VP_PUBLIC_ASSERTMESSAGE("Invalid pipe for reuse!");
1049         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1050     }
1051 
1052     VpCmdPacket *packet = m_pipeReused->GetPacket(0);
1053     VP_PUBLIC_CHK_NULL_RETURN(packet);
1054 
1055     VP_SURFACE_SETTING surfSetting = {};
1056     VP_EXECUTE_CAPS caps = packet->GetExecuteCaps();
1057     resMgr.GetUpdatedExecuteResource(featureRegistered, caps, pipe, surfSetting);
1058 
1059     VP_PUBLIC_CHK_STATUS_RETURN(packet->PacketInitForReuse(pipe.GetSurface(true, 0), pipe.GetSurface(false, 0), pipe.GetPastSurface(0), surfSetting, caps));
1060 
1061     // Update Packet
1062     for (auto it : m_features)
1063     {
1064         SwFilter *swfilter = pipe.GetSwFilter(true, 0, it.first);
1065         if (nullptr == swfilter)
1066         {
1067             continue;
1068         }
1069 
1070         VP_PUBLIC_NORMALMESSAGE("Update Packet for feature %d", it.first);
1071         VP_PUBLIC_CHK_STATUS_RETURN(it.second->UpdatePacket(swfilter, packet));
1072     }
1073 
1074     return MOS_STATUS_SUCCESS;
1075 }
1076 
1077 // Be called for not reused case before packet pipe execution.
UpdatePacketPipeConfig(PacketPipe * & pipe)1078 MOS_STATUS VpPacketReuseManager::UpdatePacketPipeConfig(PacketPipe *&pipe)
1079 {
1080     VP_FUNC_CALL();
1081     if (!m_reusable)
1082     {
1083         VP_PUBLIC_NORMALMESSAGE("Bypass UpdatePacketPipeConfig since not reusable.");
1084         return MOS_STATUS_SUCCESS;
1085     }
1086     if (nullptr == pipe || pipe->PacketNum() > 1)
1087     {
1088         VP_PUBLIC_NORMALMESSAGE("Not reusable for multi-pass case.");
1089         m_reusable = false;
1090         return MOS_STATUS_SUCCESS;
1091     }
1092 
1093     auto *packet = pipe->GetPacket(0);
1094     if (nullptr == packet)
1095     {
1096         VP_PUBLIC_ASSERTMESSAGE("Invalid packet!");
1097         m_reusable = false;
1098         VP_PUBLIC_CHK_NULL_RETURN(packet);
1099     }
1100 
1101     VP_EXECUTE_CAPS caps = packet->GetExecuteCaps();
1102     if (caps.bRender)
1103     {
1104         VP_PUBLIC_NORMALMESSAGE("Not reusable for render case.");
1105         m_reusable = false;
1106         return MOS_STATUS_SUCCESS;
1107     }
1108 
1109     if (caps.enableSFCLinearOutputByTileConvert)
1110     {
1111         VP_PUBLIC_NORMALMESSAGE("Not reusable for enableSFCLinearOutputByTileConvert case.");
1112         m_reusable = false;
1113         return MOS_STATUS_SUCCESS;
1114     }
1115 
1116     if (m_TeamsPacket && !m_TeamsPacket_reuse)
1117     {
1118         auto it = m_pipeReused_TeamsPacket.find(curIndex);
1119         if (it != m_pipeReused_TeamsPacket.end())
1120         {
1121             m_packetPipeFactory.ReturnPacketPipe(it->second);
1122             m_pipeReused_TeamsPacket.erase(curIndex);
1123         }
1124 
1125         m_pipeReused_TeamsPacket.insert(std::make_pair(curIndex, pipe));
1126 
1127         curIndex++;
1128         if (curIndex >= MaxTeamsPacketSize)
1129         {
1130             curIndex = 0;
1131         }
1132     }
1133 
1134     if (!m_TeamsPacket)
1135     {
1136         if (m_pipeReused)
1137         {
1138             m_packetPipeFactory.ReturnPacketPipe(m_pipeReused);
1139         }
1140     }
1141 
1142     m_pipeReused = pipe;
1143 
1144     pipe = nullptr;
1145 
1146     return MOS_STATUS_SUCCESS;
1147 }
1148 
1149