• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "image_effect_inner.h"
17 
18 #include <cassert>
19 #include <securec.h>
20 #include <algorithm>
21 #include <sync_fence.h>
22 #include <thread>
23 
24 #include "qos.h"
25 #include "metadata_helper.h"
26 #include "common_utils.h"
27 #include "filter_factory.h"
28 #include "image_sink_filter.h"
29 #include "image_source_filter.h"
30 #include "effect_surface_adapter.h"
31 #include "pipeline_core.h"
32 #include "effect_json_helper.h"
33 #include "efilter_factory.h"
34 #include "external_loader.h"
35 #include "effect_context.h"
36 #include "colorspace_helper.h"
37 #include "memcpy_helper.h"
38 
39 #include "v1_1/buffer_handle_meta_key_type.h"
40 #include "effect_log.h"
41 #include "effect_trace.h"
42 #include "render_task.h"
43 #include "render_environment.h"
44 #include "native_window.h"
45 #include "image_source.h"
46 #include "capability_negotiate.h"
47 
48 #define RENDER_QUEUE_SIZE 8
49 #define COMMON_TASK_TAG 0
50 namespace OHOS {
51 namespace Media {
52 namespace Effect {
53 using namespace OHOS::HDI::Display::Graphic::Common;
54 
55 enum class EffectState {
56     IDLE,
57     RUNNING,
58 };
59 
60 const int STRUCT_IMAGE_EFFECT_CONSTANT = 1;
61 const int DESTRUCTOR_IMAGE_EFFECT_CONSTANT = 2;
62 const std::string FUNCTION_FLUSH_SURFACE_BUFFER = "flushSurfaceBuffer";
63 
64 class ImageEffect::Impl {
65 public:
Impl()66     Impl()
67     {
68         InitPipeline();
69         InitEffectContext();
70     }
71 
72     void CreatePipeline(std::vector<std::shared_ptr<EFilter>> &efilters);
73 
74     bool CheckEffectSurface() const;
75     sptr<IConsumerSurface> GetConsumerSurface() const;
76     GSError AcquireConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& syncFence,
77         int64_t& timestamp, OHOS::Rect& damages) const;
78     GSError ReleaseConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& syncFence) const;
79     GSError DetachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const;
80     GSError AttachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const;
81 private:
82     void InitPipeline();
83     void InitEffectContext();
84 
85 public:
86     std::unique_ptr<EffectSurfaceAdapter> surfaceAdapter_;
87     std::shared_ptr<PipelineCore> pipeline_;
88     std::shared_ptr<ImageSourceFilter> srcFilter_;
89     std::shared_ptr<ImageSinkFilter> sinkFilter_;
90     std::shared_ptr<EffectContext> effectContext_;
91     EffectState effectState_ = EffectState::IDLE;
92     bool isQosEnabled_ = false;
93 };
94 
InitPipeline()95 void ImageEffect::Impl::InitPipeline()
96 {
97     srcFilter_ = FilterFactory::Instance().CreateFilterWithType<ImageSourceFilter>(GET_FILTER_NAME(ImageSourceFilter));
98     sinkFilter_ = FilterFactory::Instance().CreateFilterWithType<ImageSinkFilter>(GET_FILTER_NAME(ImageSinkFilter));
99     CHECK_AND_RETURN(srcFilter_ != nullptr);
100     CHECK_AND_RETURN(sinkFilter_ != nullptr);
101 }
102 
InitEffectContext()103 void ImageEffect::Impl::InitEffectContext()
104 {
105     effectContext_ = std::make_shared<EffectContext>();
106     effectContext_->memoryManager_ = std::make_shared<EffectMemoryManager>();
107     effectContext_->renderStrategy_ = std::make_shared<RenderStrategy>();
108     effectContext_->capNegotiate_ = std::make_shared<CapabilityNegotiate>();
109     effectContext_->renderEnvironment_ = std::make_shared<RenderEnvironment>();
110     effectContext_->colorSpaceManager_ = std::make_shared<ColorSpaceManager>();
111     effectContext_->cacheNegotiate_ = std::make_shared<EFilterCacheNegotiate>();
112     effectContext_->metaInfoNegotiate_ = std::make_shared<EfilterMetaInfoNegotiate>();
113 }
114 
CreatePipeline(std::vector<std::shared_ptr<EFilter>> & efilters)115 void ImageEffect::Impl::CreatePipeline(std::vector<std::shared_ptr<EFilter>> &efilters)
116 {
117     pipeline_ = std::make_shared<PipelineCore>();
118     pipeline_->Init(nullptr);
119 
120     CHECK_AND_RETURN_LOG(srcFilter_ != nullptr, "srcFilter is null");
121     std::vector<Filter *> filtersToPipeline; // Note: Filters must be inserted in sequence.
122     filtersToPipeline.push_back(srcFilter_.get());
123     for (const auto &eFilter : efilters) {
124         filtersToPipeline.push_back(eFilter.get());
125     }
126     filtersToPipeline.push_back(sinkFilter_.get());
127 
128     ErrorCode res = pipeline_->AddFilters(filtersToPipeline);
129     CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "pipeline add filters fail! res=%{public}d", res);
130 
131     res = pipeline_->LinkFilters(filtersToPipeline);
132     CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "pipeline link filter fail! res=%{public}d", res);
133 }
134 
CheckEffectSurface() const135 bool ImageEffect::Impl::CheckEffectSurface() const
136 {
137     CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, false, "Impl::CheckEffectSurface: surfaceAdapter is nullptr");
138 
139     return surfaceAdapter_->CheckEffectSurface();
140 }
141 
GetConsumerSurface() const142 sptr<IConsumerSurface> ImageEffect::Impl::GetConsumerSurface() const
143 {
144     CHECK_AND_RETURN_RET_LOG(surfaceAdapter_, nullptr, "Impl::GetConsumerSurface: surfaceAdapter is nullptr");
145 
146     return surfaceAdapter_->GetConsumerSurface();
147 }
148 
AcquireConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & syncFence,int64_t & timestamp,OHOS::Rect & damages) const149 GSError ImageEffect::Impl::AcquireConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& syncFence,
150     int64_t& timestamp, OHOS::Rect& damages) const
151 {
152     CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
153         "Impl::AcquireConsumerSurfaceBuffer: surfaceAdapter is nullptr");
154 
155     return surfaceAdapter_->AcquireConsumerSurfaceBuffer(buffer, syncFence, timestamp, damages);
156 }
157 
ReleaseConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & syncFence) const158 GSError ImageEffect::Impl::ReleaseConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer,
159     const sptr<SyncFence>& syncFence) const
160 {
161     CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
162         "Impl::ReleaseConsumerSurfaceBuffer: surfaceAdapter is nullptr");
163 
164     return surfaceAdapter_->ReleaseConsumerSurfaceBuffer(buffer, syncFence);
165 }
166 
DetachConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer) const167 GSError ImageEffect::Impl::DetachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const
168 {
169     CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
170         "Impl::DetachConsumerSurfaceBuffer: surfaceAdapter is nullptr");
171 
172     return surfaceAdapter_->DetachConsumerSurfaceBuffer(buffer);
173 }
174 
AttachConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer) const175 GSError ImageEffect::Impl::AttachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const
176 {
177     CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
178         "Impl::AttachConsumerSurfaceBuffer: surfaceAdapter is nullptr");
179 
180     return surfaceAdapter_->AttachConsumerSurfaceBuffer(buffer);
181 }
182 
183 struct EffectParameters {
EffectParametersOHOS::Media::Effect::EffectParameters184     EffectParameters(std::shared_ptr<EffectBuffer> &srcEffectBuffer, std::shared_ptr<EffectBuffer> &dstEffectBuffer,
185         std::map<ConfigType, Any> &config, std::shared_ptr<EffectContext> &effectContext)
186         : srcEffectBuffer_(std::move(srcEffectBuffer)),
187           dstEffectBuffer_(std::move(dstEffectBuffer)),
188           config_(std::move(config)),
189           effectContext_(std::move(effectContext)) {};
190     std::shared_ptr<EffectBuffer> &&srcEffectBuffer_;
191     std::shared_ptr<EffectBuffer> &&dstEffectBuffer_;
192     std::map<ConfigType, Any> &&config_;
193     std::shared_ptr<EffectContext> &&effectContext_;
194 };
195 
196 enum class RunningType : int32_t {
197     DEFAULT = 0,
198     FOREGROUND = 1,
199     BACKGROUND = 2,
200 };
201 
202 const std::vector<std::string> priorityEFilter_ = {
203     "Crop"
204 };
205 const std::unordered_map<std::string, ConfigType> configTypeTab_ = {
206     { "runningType", ConfigType::IPTYPE },
207 };
208 const std::unordered_map<int32_t, std::vector<IPType>> runningTypeTab_{
209     { std::underlying_type<RunningType>::type(RunningType::FOREGROUND), { IPType::CPU, IPType::GPU } },
210     { std::underlying_type<RunningType>::type(RunningType::BACKGROUND), { IPType::CPU } },
211 };
212 
ImageEffect(const char * name)213 ImageEffect::ImageEffect(const char *name)
214 {
215     imageEffectFlag_ = STRUCT_IMAGE_EFFECT_CONSTANT;
216     impl_ = std::make_shared<Impl>();
217     if (name != nullptr) {
218         name_ = name;
219     }
220     ExternLoader::Instance()->InitExt();
221     ExtInitModule();
222 
223     if (m_renderThread == nullptr) {
224         auto func = [this]() {
225             EFFECT_LOGD("ImageEffect has no render work to do!");
226         };
227         m_renderThread = new RenderThread<>(RENDER_QUEUE_SIZE, func);
228         m_renderThread->Start();
229         if (name != nullptr && strcmp(name, "Photo") == 0) {
230             auto task = std::make_shared<RenderTask<>>([this]() { this->InitEGLEnv(); }, COMMON_TASK_TAG,
231                 RequestTaskId());
232             m_renderThread->AddTask(task);
233             task->Wait();
234         }
235     }
236 }
237 
~ImageEffect()238 ImageEffect::~ImageEffect()
239 {
240     EFFECT_LOGI("ImageEffect destruct enter!");
241     if (failureCount_ > 0) {
242         EFFECT_LOGE("ImageEffect::SwapBuffers attach fail %{public}d times", failureCount_);
243     }
244     imageEffectFlag_ = DESTRUCTOR_IMAGE_EFFECT_CONSTANT;
245     impl_->surfaceAdapter_ = nullptr;
246     m_renderThread->ClearTask();
247     auto task = std::make_shared<RenderTask<>>([this]() { this->DestroyEGLEnv(); }, COMMON_TASK_TAG,
248         RequestTaskId());
249     m_renderThread->AddTask(task);
250     task->Wait();
251     EFFECT_LOGI("ImageEffect destruct destroy egl env!");
252     ExtDeinitModule();
253     m_renderThread->Stop();
254     delete m_renderThread;
255 
256     impl_->effectContext_->renderEnvironment_ = nullptr;
257     if (toProducerSurface_) {
258         auto res = toProducerSurface_->Disconnect();
259         EFFECT_LOGI("ImageEffect::~ImageEffect disconnect res=%{public}d, id=%{public}" PRIu64,
260             res, toProducerSurface_->GetUniqueId());
261         toProducerSurface_ = nullptr;
262     }
263     fromProducerSurface_ = nullptr;
264     impl_ = nullptr;
265     EFFECT_LOGI("ImageEffect destruct end!");
266 }
267 
AddEFilter(const std::shared_ptr<EFilter> & efilter)268 void ImageEffect::AddEFilter(const std::shared_ptr<EFilter> &efilter)
269 {
270     std::unique_lock<std::mutex> lock(innerEffectMutex_);
271     auto priorityEFilter = std::find_if(priorityEFilter_.begin(), priorityEFilter_.end(),
272         [&efilter](const std::string &name) { return name.compare(efilter->GetName()) == 0; });
273     if (priorityEFilter == priorityEFilter_.end()) {
274         efilters_.emplace_back(efilter);
275     } else {
276         auto result =
277             std::find_if(efilters_.rbegin(), efilters_.rend(), [&priorityEFilter](std::shared_ptr<EFilter> &efilter) {
278                 return priorityEFilter->compare(efilter->GetName()) == 0;
279             });
280         if (result == efilters_.rend()) {
281             efilters_.insert(efilters_.begin(), efilter);
282         } else {
283             efilters_.insert(result.base(), efilter);
284         }
285     }
286 
287     impl_->CreatePipeline(efilters_);
288 }
289 
InsertEFilter(const std::shared_ptr<EFilter> & efilter,uint32_t index)290 ErrorCode ImageEffect::InsertEFilter(const std::shared_ptr<EFilter> &efilter, uint32_t index)
291 {
292     std::unique_lock<std::mutex> lock(innerEffectMutex_);
293     ErrorCode res = Effect::InsertEFilter(efilter, index);
294     if (res == ErrorCode::SUCCESS) {
295         impl_->CreatePipeline(efilters_);
296     }
297     return res;
298 }
299 
RemoveEFilter(const std::shared_ptr<EFilter> & efilter)300 void ImageEffect::RemoveEFilter(const std::shared_ptr<EFilter> &efilter)
301 {
302     Effect::RemoveEFilter(efilter);
303     impl_->CreatePipeline(efilters_);
304 }
305 
RemoveEFilter(uint32_t index)306 ErrorCode ImageEffect::RemoveEFilter(uint32_t index)
307 {
308     ErrorCode res = Effect::RemoveEFilter(index);
309     if (res == ErrorCode::SUCCESS) {
310         impl_->CreatePipeline(efilters_);
311     }
312     return res;
313 }
314 
ReplaceEFilter(const std::shared_ptr<EFilter> & efilter,uint32_t index)315 ErrorCode ImageEffect::ReplaceEFilter(const std::shared_ptr<EFilter> &efilter, uint32_t index)
316 {
317     std::unique_lock<std::mutex> lock(innerEffectMutex_);
318     ErrorCode res = Effect::ReplaceEFilter(efilter, index);
319     if (res == ErrorCode::SUCCESS) {
320         impl_->CreatePipeline(efilters_);
321     }
322     return res;
323 }
324 
RequestTaskId()325 unsigned long int ImageEffect::RequestTaskId()
326 {
327     return m_currentTaskId.fetch_add(1);
328 }
329 
SetInputPixelMap(PixelMap * pixelMap)330 ErrorCode ImageEffect::SetInputPixelMap(PixelMap* pixelMap)
331 {
332     std::unique_lock<std::mutex> lock(innerEffectMutex_);
333     EFFECT_LOGD("ImageEffect::SetInputPixelMap");
334     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INVALID_SRC_PIXELMAP, "invalid source pixelMap");
335     impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
336 
337     ClearDataInfo(inDateInfo_);
338     inDateInfo_.dataType_ = DataType::PIXEL_MAP;
339     inDateInfo_.pixelMap_ = pixelMap;
340     return ErrorCode::SUCCESS;
341 }
342 
ConfigSourceFilter(std::shared_ptr<ImageSourceFilter> & srcFilter,std::shared_ptr<EffectBuffer> & srcBuffer,std::shared_ptr<EffectContext> & context)343 ErrorCode ConfigSourceFilter(std::shared_ptr<ImageSourceFilter> &srcFilter, std::shared_ptr<EffectBuffer> &srcBuffer,
344     std::shared_ptr<EffectContext> &context)
345 {
346     CHECK_AND_RETURN_RET_LOG(srcFilter != nullptr, ErrorCode::ERR_INPUT_NULL, "srcFilter is null");
347 
348     ErrorCode res = srcFilter->SetSource(srcBuffer, context);
349     FALSE_RETURN_MSG_E(res == ErrorCode::SUCCESS, res, "set source fail! res=%{public}d", res);
350 
351     return ErrorCode::SUCCESS;
352 }
353 
ConfigSinkFilter(std::shared_ptr<ImageSinkFilter> & sinkFilter,std::shared_ptr<EffectBuffer> & sinkBuffer,sptr<Surface> & toXComponentSurface)354 ErrorCode ConfigSinkFilter(std::shared_ptr<ImageSinkFilter> &sinkFilter, std::shared_ptr<EffectBuffer> &sinkBuffer,
355     sptr<Surface> &toXComponentSurface)
356 {
357     CHECK_AND_RETURN_RET_LOG(sinkFilter != nullptr, ErrorCode::ERR_INPUT_NULL, "sinkFilter is null");
358 
359     ErrorCode res = sinkFilter->SetSink(sinkBuffer);
360     FALSE_RETURN_MSG_E(res == ErrorCode::SUCCESS, res, "set sink fail! res=%{public}d", res);
361     res = sinkFilter->SetXComponentSurface(toXComponentSurface);
362     FALSE_RETURN_MSG_E(res == ErrorCode::SUCCESS, res, "SetRenderSurface fail! res=%{public}d", res);
363 
364     return ErrorCode::SUCCESS;
365 }
366 
GetConfigIPTypes(const std::map<ConfigType,Any> & config,std::vector<IPType> & configIPTypes)367 void GetConfigIPTypes(const std::map<ConfigType, Any> &config, std::vector<IPType> &configIPTypes)
368 {
369     auto it = config.find(ConfigType::IPTYPE);
370     if (it == config.end()) {
371         EFFECT_LOGE("ipType config not set! use default config.");
372         configIPTypes = { IPType::CPU, IPType::GPU };
373         return;
374     }
375 
376     ErrorCode result = CommonUtils::ParseAny(it->second, configIPTypes);
377     if (result == ErrorCode::SUCCESS) {
378         return;
379     }
380     EFFECT_LOGE("parse ipType fail! use default config.");
381     configIPTypes = { IPType::CPU, IPType::GPU };
382 }
383 
AdjustEffectFormat(IEffectFormat & effectFormat)384 void AdjustEffectFormat(IEffectFormat& effectFormat) {
385     switch (effectFormat) {
386         case IEffectFormat::RGBA_1010102:
387         case IEffectFormat::YCBCR_P010:
388         case IEffectFormat::YCRCB_P010:
389             effectFormat = IEffectFormat::RGBA_1010102;
390             break;
391         default:
392             effectFormat = IEffectFormat::RGBA8888;
393             break;
394     }
395 }
396 
ChooseIPType(const std::shared_ptr<EffectBuffer> & srcEffectBuffer,const std::shared_ptr<EffectContext> & context,const std::map<ConfigType,Any> & config,IPType & runningIPType)397 ErrorCode ChooseIPType(const std::shared_ptr<EffectBuffer> &srcEffectBuffer,
398     const std::shared_ptr<EffectContext> &context, const std::map<ConfigType, Any> &config,
399     IPType &runningIPType)
400 {
401     std::vector<IPType> configIPTypes;
402     GetConfigIPTypes(config, configIPTypes);
403     bool isTextureInput = srcEffectBuffer->extraInfo_->dataType == DataType::TEX;
404 
405     runningIPType = isTextureInput ? IPType::GPU : IPType::DEFAULT;
406     IPType priorityIPType = IPType::GPU;
407     IEffectFormat effectFormat = srcEffectBuffer->bufferInfo_->formatType_;
408     const std::vector<std::shared_ptr<Capability>> &caps = context->capNegotiate_->GetCapabilityList();
409     for (const auto &capability : caps) {
410         if (capability == nullptr || capability->pixelFormatCap_ == nullptr) {
411             continue;
412         }
413         std::map<IEffectFormat, std::vector<IPType>> &formats = capability->pixelFormatCap_->formats;
414 
415         if (runningIPType == IPType::GPU && !isTextureInput) {
416             AdjustEffectFormat(effectFormat);
417         }
418 
419         auto it = formats.find(effectFormat);
420         if (it == formats.end()) {
421             EFFECT_LOGE("effectFormat not support! effectFormat=%{public}d, name=%{public}s",
422                 effectFormat, capability->name_.c_str());
423             return isTextureInput ? ErrorCode::ERR_UNSUPPORTED_FORMAT_TYPE : ErrorCode::SUCCESS;
424         }
425 
426         std::vector<IPType> &ipTypes = it->second;
427         if (std::find(configIPTypes.begin(), configIPTypes.end(), priorityIPType) != configIPTypes.end() &&
428             std::find(ipTypes.begin(), ipTypes.end(), priorityIPType) != ipTypes.end()) {
429             runningIPType = IPType::GPU;
430         } else {
431             if (runningIPType == IPType::DEFAULT) {
432                 runningIPType = IPType::CPU;
433             }
434             return isTextureInput ? ErrorCode::ERR_UNSUPPORTED_IPTYPE_FOR_EFFECT : ErrorCode::SUCCESS;
435         }
436     }
437 
438     return ErrorCode::SUCCESS;
439 }
440 
ProcessPipelineTask(std::shared_ptr<PipelineCore> pipeline,const EffectParameters & effectParameters)441 ErrorCode ProcessPipelineTask(std::shared_ptr<PipelineCore> pipeline, const EffectParameters &effectParameters)
442 {
443     EFFECT_TRACE_NAME("ProcessPipelineTask");
444     EFFECT_TRACE_BEGIN("ConvertColorSpace");
445     ErrorCode res = ColorSpaceHelper::ConvertColorSpace(effectParameters.srcEffectBuffer_,
446         effectParameters.effectContext_);
447     EFFECT_TRACE_END();
448     if (res != ErrorCode::SUCCESS) {
449         EFFECT_LOGE("ProcessPipelineTask:ConvertColorSpace fail! res=%{public}d", res);
450         return res;
451     }
452 
453     IPType runningIPType;
454     res = ChooseIPType(effectParameters.srcEffectBuffer_, effectParameters.effectContext_, effectParameters.config_,
455         runningIPType);
456     if (res != ErrorCode::SUCCESS) {
457         EFFECT_LOGE("choose running ip type fail! res=%{public}d", res);
458         return res;
459     }
460     if (effectParameters.effectContext_->renderEnvironment_->GetEGLStatus() != EGLStatus::READY
461         && runningIPType == IPType::GPU) {
462         bool isCustomEnv = effectParameters.srcEffectBuffer_->extraInfo_->dataType == DataType::TEX;
463         effectParameters.effectContext_->renderEnvironment_->Init(isCustomEnv);
464         effectParameters.effectContext_->renderEnvironment_->Prepare();
465     }
466     effectParameters.effectContext_->ipType_ = runningIPType;
467     effectParameters.effectContext_->memoryManager_->SetIPType(runningIPType);
468 
469     res = pipeline->Start();
470     if (res != ErrorCode::SUCCESS) {
471         EFFECT_LOGE("pipeline start fail! res=%{public}d", res);
472         return res;
473     }
474     return ErrorCode::SUCCESS;
475 }
476 
StartPipelineInner(std::shared_ptr<PipelineCore> & pipeline,const EffectParameters & effectParameters,unsigned long int taskId,RenderThread<> * thread,bool isNeedCreateThread=false)477 ErrorCode StartPipelineInner(std::shared_ptr<PipelineCore> &pipeline, const EffectParameters &effectParameters,
478     unsigned long int taskId, RenderThread<> *thread, bool isNeedCreateThread = false)
479 {
480     if (thread == nullptr) {
481         EFFECT_LOGE("pipeline Prepare fail! render thread is nullptr");
482         return ErrorCode::ERR_INVALID_OPERATION;
483     }
484 
485     if (!isNeedCreateThread) {
486         return ProcessPipelineTask(pipeline, effectParameters);
487     } else {
488         auto prom = std::make_shared<std::promise<ErrorCode>>();
489         std::future<ErrorCode> fut = prom->get_future();
490         auto task = std::make_shared<RenderTask<>>([pipeline, &effectParameters, &prom]() {
491             auto res = ProcessPipelineTask(pipeline, effectParameters);
492             prom->set_value(res);
493             return;
494         }, 0, taskId);
495         thread->AddTask(task);
496         task->Wait();
497         ErrorCode res = fut.get();
498         return res;
499     }
500     return ErrorCode::SUCCESS;
501 }
502 
StartPipeline(std::shared_ptr<PipelineCore> & pipeline,const EffectParameters & effectParameters,unsigned long int taskId,RenderThread<> * thread,bool isNeedCreateThread=false)503 ErrorCode StartPipeline(std::shared_ptr<PipelineCore> &pipeline, const EffectParameters &effectParameters,
504     unsigned long int taskId, RenderThread<> *thread, bool isNeedCreateThread = false)
505 {
506     effectParameters.effectContext_->renderStrategy_->Init(effectParameters.srcEffectBuffer_,
507         effectParameters.dstEffectBuffer_);
508     effectParameters.effectContext_->colorSpaceManager_->Init(effectParameters.srcEffectBuffer_,
509         effectParameters.dstEffectBuffer_);
510     effectParameters.effectContext_->memoryManager_->Init(effectParameters.srcEffectBuffer_,
511         effectParameters.dstEffectBuffer_);
512     ErrorCode res = StartPipelineInner(pipeline, effectParameters, taskId, thread, isNeedCreateThread);
513     effectParameters.effectContext_->memoryManager_->Deinit();
514     effectParameters.effectContext_->colorSpaceManager_->Deinit();
515     effectParameters.effectContext_->renderStrategy_->Deinit();
516     effectParameters.effectContext_->capNegotiate_->ClearNegotiateResult();
517     return res;
518 }
519 
Start()520 ErrorCode ImageEffect::Start()
521 {
522     switch (inDateInfo_.dataType_) {
523         case DataType::PIXEL_MAP:
524         case DataType::SURFACE_BUFFER:
525         case DataType::URI:
526         case DataType::PATH:
527         case DataType::PICTURE:
528         case DataType::TEX: {
529             impl_->effectState_ = EffectState::RUNNING;
530             ErrorCode res = this->Render();
531             Stop();
532             return res;
533         }
534         case DataType::SURFACE:
535             impl_->effectState_ = EffectState::RUNNING;
536             if (impl_->surfaceAdapter_) {
537                 impl_->surfaceAdapter_->ConsumerRequestCpuAccess(true);
538             }
539             break;
540         default:
541             EFFECT_LOGE("Not set input data!");
542             return ErrorCode::ERR_NOT_SET_INPUT_DATA;
543     }
544     return ErrorCode::SUCCESS;
545 }
546 
Stop()547 void ImageEffect::Stop()
548 {
549     std::unique_lock<std::mutex> lock(innerEffectMutex_);
550     impl_->effectState_ = EffectState::IDLE;
551     if (impl_->surfaceAdapter_) {
552         impl_->surfaceAdapter_->ConsumerRequestCpuAccess(false);
553     }
554     impl_->effectContext_->logStrategy_ = LOG_STRATEGY::NORMAL;
555     impl_->effectContext_->memoryManager_->ClearMemory();
556 }
557 
SetInputSurfaceBuffer(OHOS::SurfaceBuffer * surfaceBuffer)558 ErrorCode ImageEffect::SetInputSurfaceBuffer(OHOS::SurfaceBuffer *surfaceBuffer)
559 {
560     CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, ErrorCode::ERR_INVALID_SRC_SURFACEBUFFER,
561         "invalid source surface buffer");
562     if (needPreFlush_) {
563         surfaceBuffer->FlushCache();
564     }
565 
566     ClearDataInfo(inDateInfo_);
567     inDateInfo_.dataType_ = DataType::SURFACE_BUFFER;
568     inDateInfo_.surfaceBufferInfo_.surfaceBuffer_ = surfaceBuffer;
569 
570     return ErrorCode::SUCCESS;
571 }
572 
SetOutputSurfaceBuffer(OHOS::SurfaceBuffer * surfaceBuffer)573 ErrorCode ImageEffect::SetOutputSurfaceBuffer(OHOS::SurfaceBuffer *surfaceBuffer)
574 {
575     ClearDataInfo(outDateInfo_);
576     if (surfaceBuffer == nullptr) {
577         EFFECT_LOGI("SetOutputSurfaceBuffer: surfaceBuffer set to null!");
578         return ErrorCode::SUCCESS;
579     }
580 
581     outDateInfo_.dataType_ = DataType::SURFACE_BUFFER;
582     outDateInfo_.surfaceBufferInfo_.surfaceBuffer_ = surfaceBuffer;
583 
584     return ErrorCode::SUCCESS;
585 }
586 
SetInputUri(const std::string & uri)587 ErrorCode ImageEffect::SetInputUri(const std::string &uri)
588 {
589     EFFECT_LOGD("ImageEffect::SetInputUri");
590     if (!CommonUtils::EndsWithJPG(uri) && !CommonUtils::EndsWithHEIF(uri)) {
591         EFFECT_LOGE("SetInputUri: file type is not support! only support jpg/jpeg and heif.");
592         return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
593     }
594     ClearDataInfo(inDateInfo_);
595     inDateInfo_.dataType_ = DataType::URI;
596     inDateInfo_.uri_ = std::move(uri);
597 
598     return ErrorCode::SUCCESS;
599 }
600 
SetOutputUri(const std::string & uri)601 ErrorCode ImageEffect::SetOutputUri(const std::string &uri)
602 {
603     EFFECT_LOGD("ImageEffect::SetOutputUri");
604     if (uri.empty()) {
605         EFFECT_LOGI("SetOutputUri: uri set to null!");
606         ClearDataInfo(outDateInfo_);
607         return ErrorCode::SUCCESS;
608     }
609 
610     if (!CommonUtils::EndsWithJPG(uri) && !CommonUtils::EndsWithHEIF(uri)) {
611         EFFECT_LOGE("SetOutputUri: file type is not support! only support jpg/jpeg and heif.");
612         return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
613     }
614     ClearDataInfo(outDateInfo_);
615     outDateInfo_.dataType_ = DataType::URI;
616     outDateInfo_.uri_ = std::move(uri);
617 
618     return ErrorCode::SUCCESS;
619 }
620 
SetInputPath(const std::string & path)621 ErrorCode ImageEffect::SetInputPath(const std::string &path)
622 {
623     EFFECT_LOGD("ImageEffect::SetInputPath");
624     if (!CommonUtils::EndsWithJPG(path) && !CommonUtils::EndsWithHEIF(path)) {
625         EFFECT_LOGE("SetInputPath: file type is not support! only support jpg/jpeg and heif.");
626         return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
627     }
628     ClearDataInfo(inDateInfo_);
629     inDateInfo_.dataType_ = DataType::PATH;
630     inDateInfo_.path_ = std::move(path);
631 
632     return ErrorCode::SUCCESS;
633 }
634 
SetOutputPath(const std::string & path)635 ErrorCode ImageEffect::SetOutputPath(const std::string &path)
636 {
637     EFFECT_LOGD("ImageEffect::SetOutputPath");
638     if (path.empty()) {
639         EFFECT_LOGI("SetOutputPath: path set to null!");
640         ClearDataInfo(outDateInfo_);
641         return ErrorCode::SUCCESS;
642     }
643 
644     if (!CommonUtils::EndsWithJPG(path) && !CommonUtils::EndsWithHEIF(path)) {
645         EFFECT_LOGE("SetOutputPath: file type is not support! only support jpg/jpeg and heif.");
646         return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
647     }
648     ClearDataInfo(outDateInfo_);
649     outDateInfo_.dataType_ = DataType::PATH;
650     outDateInfo_.path_ = std::move(path);
651 
652     return ErrorCode::SUCCESS;
653 }
654 
CheckPixelmapColorSpace(std::shared_ptr<EffectBuffer> & srcEffectBuffer,std::shared_ptr<EffectBuffer> & dstEffectBuffer)655 ErrorCode CheckPixelmapColorSpace(std::shared_ptr<EffectBuffer> &srcEffectBuffer,
656     std::shared_ptr<EffectBuffer> &dstEffectBuffer)
657 {
658     // the format for pixel map is same or not.
659     CHECK_AND_RETURN_RET_LOG(srcEffectBuffer->bufferInfo_->formatType_ == dstEffectBuffer->bufferInfo_->formatType_,
660         ErrorCode::ERR_NOT_SUPPORT_DIFF_FORMAT,
661         "not support different format. srcFormat=%{public}d, dstFormat=%{public}d",
662         srcEffectBuffer->bufferInfo_->formatType_, dstEffectBuffer->bufferInfo_->formatType_);
663 
664     if (srcEffectBuffer->extraInfo_->dataType == DataType::TEX) {
665         return ErrorCode::SUCCESS;
666     }
667 
668     // color space is same or not.
669     EffectColorSpace srcColorSpace = srcEffectBuffer->bufferInfo_->colorSpace_;
670     EffectColorSpace dstColorSpace = dstEffectBuffer->bufferInfo_->colorSpace_;
671     bool isSrcHdr = ColorSpaceHelper::IsHdrColorSpace(srcColorSpace);
672     bool isDstHdr = ColorSpaceHelper::IsHdrColorSpace(dstColorSpace);
673     CHECK_AND_RETURN_RET_LOG(isSrcHdr == isDstHdr, ErrorCode::ERR_NOT_SUPPORT_INPUT_OUTPUT_COLORSPACE,
674         "not support different colorspace. src=%{public}d, dst=%{public}d", srcColorSpace, dstColorSpace);
675     return ErrorCode::SUCCESS;
676 }
677 
dataTypeCheckFunc(DataType srcDataType,DataType dstDataType)678 static bool dataTypeCheckFunc(DataType srcDataType, DataType dstDataType) {
679     if (srcDataType == dstDataType) {
680         return true;
681     }
682     std::vector<std::pair<DataType, DataType>> extraSupportTab = {
683         { DataType::PIXEL_MAP, DataType::NATIVE_WINDOW },
684         { DataType::PICTURE, DataType::NATIVE_WINDOW },
685     };
686     return extraSupportTab.end() != std::find_if(extraSupportTab.begin(), extraSupportTab.end(),
687         [&srcDataType, &dstDataType](const std::pair<DataType, DataType> &data) {
688         return data.first == srcDataType && data.second == dstDataType;
689     });
690 };
691 
CheckToRenderPara(std::shared_ptr<EffectBuffer> & srcEffectBuffer,std::shared_ptr<EffectBuffer> & dstEffectBuffer)692 ErrorCode CheckToRenderPara(std::shared_ptr<EffectBuffer> &srcEffectBuffer,
693     std::shared_ptr<EffectBuffer> &dstEffectBuffer)
694 {
695     CHECK_AND_RETURN_RET_LOG(srcEffectBuffer != nullptr, ErrorCode::ERR_PARSE_FOR_EFFECT_BUFFER_FAIL,
696         "invalid srcEffectBuffer");
697     CHECK_AND_RETURN_RET_LOG(srcEffectBuffer->bufferInfo_ != nullptr, ErrorCode::ERR_BUFFER_INFO_NULL,
698         "buffer info is null! srcBufferInfo=%{public}d", srcEffectBuffer->bufferInfo_ == nullptr);
699     CHECK_AND_RETURN_RET_LOG(srcEffectBuffer->extraInfo_ != nullptr, ErrorCode::ERR_EXTRA_INFO_NULL,
700         "extra info is null! srcExtraInfo=%{public}d", srcEffectBuffer->extraInfo_ == nullptr);
701 
702     // allow developers not to set the out parameter.
703     if (dstEffectBuffer == nullptr) {
704         if (srcEffectBuffer->extraInfo_->dataType == DataType::TEX) {
705             return ErrorCode::ERR_NO_DST_TEX;
706         }
707         return ErrorCode::SUCCESS;
708     }
709 
710     CHECK_AND_RETURN_RET_LOG(dstEffectBuffer->bufferInfo_ != nullptr, ErrorCode::ERR_BUFFER_INFO_NULL,
711         "buffer info is null! srcBufferInfo=%{public}d", dstEffectBuffer->bufferInfo_ == nullptr);
712     CHECK_AND_RETURN_RET_LOG(dstEffectBuffer->extraInfo_ != nullptr, ErrorCode::ERR_EXTRA_INFO_NULL,
713         "extra info is null! dstExtraInfo=%{public}d", dstEffectBuffer->extraInfo_ == nullptr);
714 
715     if (dstEffectBuffer->bufferInfo_->tex_ != nullptr && dstEffectBuffer->bufferInfo_->tex_->Width() == 0
716         && dstEffectBuffer->bufferInfo_->tex_->Height() == 0) {
717         return ErrorCode::SUCCESS;
718     }
719 
720     // input and output type is same or not.
721     DataType srcDataType = srcEffectBuffer->extraInfo_->dataType;
722     DataType dtsDataType = dstEffectBuffer->extraInfo_->dataType;
723     CHECK_AND_RETURN_RET_LOG(dataTypeCheckFunc(srcDataType, dtsDataType), ErrorCode::ERR_NOT_SUPPORT_DIFF_DATATYPE,
724         "not supported dataType. srcDataType=%{public}d, dstDataType=%{public}d", srcDataType, dtsDataType);
725 
726     if (srcEffectBuffer->bufferInfo_->tex_ != nullptr && dstEffectBuffer->bufferInfo_->tex_ != nullptr) {
727         unsigned int input = srcEffectBuffer->bufferInfo_->tex_->GetName();
728         unsigned int output = dstEffectBuffer->bufferInfo_->tex_->GetName();
729         if (input == output) {
730             return ErrorCode::ERR_INVALID_TEXTURE;
731         }
732     }
733 
734     // color space is same or not.
735     if (srcDataType == DataType::PIXEL_MAP && dtsDataType != DataType::NATIVE_WINDOW) {
736         return CheckPixelmapColorSpace(srcEffectBuffer, dstEffectBuffer);
737     }
738 
739     return ErrorCode::SUCCESS;
740 }
741 
GetImageInfoFromPixelMap(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata) const742 ErrorCode ImageEffect::GetImageInfoFromPixelMap(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
743     std::shared_ptr<ExifMetadata> &exifMetadata) const
744 {
745     width = static_cast<uint32_t>(inDateInfo_.pixelMap_->GetWidth());
746     height = static_cast<uint32_t>(inDateInfo_.pixelMap_->GetHeight());
747     pixelFormat = inDateInfo_.pixelMap_->GetPixelFormat();
748     exifMetadata = inDateInfo_.pixelMap_->GetExifMetadata();
749     return ErrorCode::SUCCESS;
750 }
751 
GetImageInfoFromSurface(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat) const752 ErrorCode ImageEffect::GetImageInfoFromSurface(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat) const
753 {
754     width = static_cast<uint32_t>(inDateInfo_.surfaceBufferInfo_.surfaceBuffer_->GetWidth());
755     height = static_cast<uint32_t>(inDateInfo_.surfaceBufferInfo_.surfaceBuffer_->GetHeight());
756     pixelFormat = static_cast<PixelFormat>(inDateInfo_.surfaceBufferInfo_.surfaceBuffer_->GetFormat());
757     return ErrorCode::SUCCESS;
758 }
759 
GetImageInfoFromPath(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata) const760 ErrorCode ImageEffect::GetImageInfoFromPath(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
761     std::shared_ptr<ExifMetadata> &exifMetadata) const
762 {
763     auto path = inDateInfo_.dataType_ == DataType::URI ? CommonUtils::UrlToPath(inDateInfo_.uri_) : inDateInfo_.path_;
764     std::shared_ptr<ImageSource> imageSource = CommonUtils::GetImageSourceFromPath(path);
765     CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, ErrorCode::ERR_CREATE_IMAGESOURCE_FAIL,
766         "CreateImageSource fail! path=%{public}s", path.c_str());
767     ImageInfo info;
768     imageSource->GetImageInfo(info);
769     width = static_cast<uint32_t>(info.size.width);
770     height = static_cast<uint32_t>(info.size.height);
771     pixelFormat = info.pixelFormat;
772     exifMetadata = imageSource->GetExifMetadata();
773     return ErrorCode::SUCCESS;
774 }
775 
GetImageInfoFromPicture(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata) const776 ErrorCode ImageEffect::GetImageInfoFromPicture(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
777     std::shared_ptr<ExifMetadata> &exifMetadata) const
778 {
779     std::shared_ptr<PixelMap> pixelMap = inDateInfo_.picture_->GetMainPixel();
780     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_GET_MAIN_PIXELMAP_FROM_PICTURE_FAIL,
781         "GetImageInfoFromPicture pixelMap is nullptr!");
782     width = static_cast<uint32_t>(pixelMap->GetWidth());
783     height = static_cast<uint32_t>(pixelMap->GetHeight());
784     pixelFormat = pixelMap->GetPixelFormat();
785     exifMetadata = inDateInfo_.picture_->GetExifMetadata();
786     return ErrorCode::SUCCESS;
787 }
788 
GetImageInfoFromTexInfo(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat) const789 ErrorCode ImageEffect::GetImageInfoFromTexInfo(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat) const
790 {
791     int32_t texId = inDateInfo_.textureInfo_.textureId_;
792     width = GLUtils::GetTexWidth(texId);
793     CHECK_AND_RETURN_RET_LOG(width > 0, ErrorCode::ERR_INVALID_TEXTURE, "input tex width is invalid");
794     height = GLUtils::GetTexHeight(texId);
795     CHECK_AND_RETURN_RET_LOG(height > 0, ErrorCode::ERR_INVALID_TEXTURE, "input tex height is invalid");
796     pixelFormat = CommonUtils::SwitchGLFormatToPixelFormat(GLUtils::GetTexFormat(texId));
797     CHECK_AND_RETURN_RET_LOG(pixelFormat != PixelFormat::UNKNOWN, ErrorCode::ERR_UNSUPPORTED_FORMAT_TYPE,
798         "input tex pixelFormat is invalid");
799     return ErrorCode::SUCCESS;
800 }
801 
GetImageInfo(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata)802 ErrorCode ImageEffect::GetImageInfo(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
803     std::shared_ptr<ExifMetadata> &exifMetadata)
804 {
805     ErrorCode errorCode = ErrorCode::SUCCESS;
806     switch (inDateInfo_.dataType_) {
807         case DataType::PIXEL_MAP: {
808             errorCode = GetImageInfoFromPixelMap(width, height, pixelFormat, exifMetadata);
809             CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromPixelMap fail!");
810             break;
811         }
812         case DataType::SURFACE:
813         case DataType::SURFACE_BUFFER: {
814             errorCode = GetImageInfoFromSurface(width, height, pixelFormat);
815             CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromSurface fail!");
816             break;
817         }
818         case DataType::URI:
819         case DataType::PATH: {
820             errorCode = GetImageInfoFromPath(width, height, pixelFormat, exifMetadata);
821             CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromPath fail!");
822             break;
823         }
824         case DataType::NATIVE_WINDOW:
825             width = 0;
826             height = 0;
827             break;
828         case DataType::PICTURE: {
829             errorCode = GetImageInfoFromPicture(width, height, pixelFormat, exifMetadata);
830             CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromPicture fail!");
831             break;
832         }
833         case DataType::TEX: {
834             errorCode = GetImageInfoFromTexInfo(width, height, pixelFormat);
835             CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromTexInfo fail!");
836             break;
837         }
838         case DataType::UNKNOWN:
839             EFFECT_LOGE("dataType is unknown! DataType is not set!");
840             return  ErrorCode::ERR_UNSUPPORTED_DATA_TYPE;
841         default:
842             EFFECT_LOGE("dataType is not support! dataType=%{public}d", static_cast<int>(inDateInfo_.dataType_));
843             return ErrorCode::ERR_UNSUPPORTED_DATA_TYPE;
844     }
845     return errorCode;
846 }
847 
InitEffectBuffer(std::shared_ptr<EffectBuffer> & srcEffectBuffer,std::shared_ptr<EffectBuffer> & dstEffectBuffer,IEffectFormat format)848 ErrorCode ImageEffect::InitEffectBuffer(std::shared_ptr<EffectBuffer> &srcEffectBuffer,
849     std::shared_ptr<EffectBuffer> &dstEffectBuffer, IEffectFormat format)
850 {
851     ErrorCode res = LockAll(srcEffectBuffer, dstEffectBuffer, format);
852     if (res != ErrorCode::SUCCESS) {
853         UnLockAll();
854         return res;
855     }
856 
857     res = CheckToRenderPara(srcEffectBuffer, dstEffectBuffer);
858     if (res != ErrorCode::SUCCESS) {
859         UnLockAll();
860         return res;
861     }
862     return ErrorCode::SUCCESS;
863 }
864 
ConfigureFilters(std::shared_ptr<EffectBuffer> srcEffectBuffer,std::shared_ptr<EffectBuffer> dstEffectBuffer)865 ErrorCode ImageEffect::ConfigureFilters(std::shared_ptr<EffectBuffer> srcEffectBuffer,
866     std::shared_ptr<EffectBuffer> dstEffectBuffer) {
867     std::shared_ptr<ImageSourceFilter> &sourceFilter = impl_->srcFilter_;
868     ErrorCode res = ConfigSourceFilter(sourceFilter, srcEffectBuffer, impl_->effectContext_);
869     if (res != ErrorCode::SUCCESS) {
870         UnLockAll();
871         return res;
872     }
873 
874     std::shared_ptr<ImageSinkFilter> &sinkFilter = impl_->sinkFilter_;
875     res = ConfigSinkFilter(sinkFilter, dstEffectBuffer, toProducerSurface_);
876     if (res != ErrorCode::SUCCESS) {
877         UnLockAll();
878         return res;
879     }
880 
881     return ErrorCode::SUCCESS;
882 }
883 
SetPathToSink()884 void ImageEffect::SetPathToSink()
885 {
886     if (inDateInfo_.dataType_ == DataType::URI) {
887         impl_->sinkFilter_->inPath_ = CommonUtils::UrlToPath(inDateInfo_.uri_);
888     } else if (inDateInfo_.dataType_ == DataType::PATH) {
889         impl_->sinkFilter_->inPath_ = inDateInfo_.path_;
890     }
891 }
892 
Render()893 ErrorCode ImageEffect::Render()
894 {
895     EFFECT_TRACE_NAME("ImageEffect::Render");
896     CHECK_AND_RETURN_RET_LOG(!efilters_.empty(), ErrorCode::ERR_NOT_FILTERS_WITH_RENDER, "efilters is empty");
897 
898     uint32_t width = 0;
899     uint32_t height = 0;
900     PixelFormat pixelFormat = PixelFormat::RGBA_8888;
901     std::shared_ptr<ExifMetadata> exifMetadata = nullptr;
902 
903     ErrorCode res = GetImageInfo(width, height, pixelFormat, exifMetadata);
904     CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "set image info fail! res = %{public}d", res);
905     IEffectFormat format = CommonUtils::SwitchToEffectFormat(pixelFormat);
906     impl_->effectContext_->exifMetadata_ = exifMetadata;
907 
908     std::shared_ptr<ImageSourceFilter> &sourceFilter = impl_->srcFilter_;
909     sourceFilter->SetNegotiateParameter(width, height, format, impl_->effectContext_);
910 
911     res = impl_->pipeline_->Prepare();
912     CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "pipeline prepare fail! res=%{public}d", res);
913 
914     RemoveGainMapIfNeed();
915     if (inDateInfo_.dataType_ == DataType::URI || inDateInfo_.dataType_ == DataType::PATH) {
916         const std::vector<std::shared_ptr<Capability>> &capabilities =
917             impl_->effectContext_->capNegotiate_->GetCapabilityList();
918         format = CapabilityNegotiate::NegotiateFormat(capabilities);
919     }
920     EFFECT_LOGD("image effect render, negotiate format=%{public}d", format);
921     SetPathToSink();
922 
923     std::shared_ptr<EffectBuffer> srcEffectBuffer = nullptr;
924     std::shared_ptr<EffectBuffer> dstEffectBuffer = nullptr;
925     res = InitEffectBuffer(srcEffectBuffer, dstEffectBuffer, format);
926     CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "init effectBuffer fail! res=%{puiblic}d", res);
927 
928     res = ConfigureFilters(srcEffectBuffer, dstEffectBuffer);
929     CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "configure filters fail! res=%{puiblic}d", res);
930 
931     std::shared_ptr<EffectBuffer> outBuffer = dstEffectBuffer != nullptr ? dstEffectBuffer : srcEffectBuffer;
932     impl_->effectContext_->renderEnvironment_->SetOutputType(outBuffer->extraInfo_->dataType);
933     EffectParameters effectParameters(srcEffectBuffer, dstEffectBuffer, config_, impl_->effectContext_);
934     bool isNeedCreateThread = !impl_->isQosEnabled_ && srcEffectBuffer->extraInfo_->dataType != DataType::TEX;
935     res = StartPipeline(impl_->pipeline_, effectParameters, RequestTaskId(), m_renderThread, isNeedCreateThread);
936     if (res != ErrorCode::SUCCESS) {
937         EFFECT_LOGE("StartPipeline fail! res=%{public}d", res);
938         UnLockAll();
939         return res;
940     }
941 
942     UnLockAll();
943     return res;
944 }
945 
Save(EffectJsonPtr & res)946 ErrorCode ImageEffect::Save(EffectJsonPtr &res)
947 {
948     EffectJsonPtr effect = EffectJsonHelper::CreateArray();
949     for (auto it = efilters_.begin(); it != efilters_.end(); it++) {
950         EffectJsonPtr data = EffectJsonHelper::CreateObject();
951         std::shared_ptr<EFilter> efilter = *it;
952         efilter->Save(data);
953         effect->Add(data);
954     }
955 
956     EffectJsonPtr info  = EffectJsonHelper::CreateObject();
957     info->Put("filters", effect);
958     info->Put("name", name_);
959     if (extraInfo_ != nullptr) {
960         extraInfo_->Replace("imageEffect", info);
961         res = extraInfo_;
962     } else {
963         res->Put("imageEffect", info);
964     }
965     return ErrorCode::SUCCESS;
966 }
967 
Restore(std::string & info)968 std::shared_ptr<ImageEffect> ImageEffect::Restore(std::string &info)
969 {
970     EFFECT_TRACE_NAME("ImageEffect::Restore");
971     const EffectJsonPtr root = EffectJsonHelper::ParseJsonData(info);
972     CHECK_AND_RETURN_RET_LOG(root->HasElement("imageEffect"), nullptr, "Restore: no imageEffect");
973     const EffectJsonPtr &imageInfo = root->GetElement("imageEffect");
974     CHECK_AND_RETURN_RET_LOG(imageInfo != nullptr, nullptr, "Restore: imageInfo is null!");
975     CHECK_AND_RETURN_RET_LOG(imageInfo->HasElement("name"), nullptr, "Restore: imageEffect no name");
976     std::string effectName = imageInfo->GetString("name");
977     CHECK_AND_RETURN_RET_LOG(!effectName.empty(), nullptr, "Restore: imageEffect get name failed");
978 
979     CHECK_AND_RETURN_RET_LOG(imageInfo->HasElement("filters"), nullptr, "Restore: imageEffect no filters");
980     std::vector<EffectJsonPtr> efiltersInfo = imageInfo->GetArray("filters");
981     CHECK_AND_RETURN_RET_LOG(!efiltersInfo.empty(), nullptr, "Restore: filters not array");
982 
983     std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(effectName.c_str());
984     for (auto &efilterInfo : efiltersInfo) {
985         std::string name = efilterInfo->GetString("name");
986         CHECK_AND_CONTINUE_LOG(!name.empty(), "Restore: [name] not exist");
987         std::shared_ptr<EFilter> efilter = EFilterFactory::Instance()->Restore(name, efilterInfo, nullptr);
988         CHECK_AND_RETURN_RET_LOG(efilter != nullptr, nullptr,
989             "Restore: efilter restore fail! name=%{public}s", name.c_str());
990         imageEffect->AddEFilter(efilter);
991     }
992     return imageEffect;
993 }
994 
SetOutputPixelMap(PixelMap * pixelMap)995 ErrorCode ImageEffect::SetOutputPixelMap(PixelMap* pixelMap)
996 {
997     std::unique_lock<std::mutex> lock(innerEffectMutex_);
998     EFFECT_LOGD("ImageEffect::SetOutputPixelMap");
999     ClearDataInfo(outDateInfo_);
1000     if (pixelMap == nullptr) {
1001         EFFECT_LOGI("SetOutputPixelMap: pixelMap set to null!");
1002         return ErrorCode::SUCCESS;
1003     }
1004 
1005     outDateInfo_.dataType_ = DataType::PIXEL_MAP;
1006     outDateInfo_.pixelMap_ = pixelMap;
1007 
1008     return ErrorCode::SUCCESS;
1009 }
1010 
SetOutputSurface(sptr<Surface> & surface)1011 ErrorCode ImageEffect::SetOutputSurface(sptr<Surface>& surface)
1012 {
1013     std::unique_lock<std::mutex> lock(innerEffectMutex_);
1014     if (surface == nullptr) {
1015         EFFECT_LOGE("surface is null.");
1016         return ErrorCode::ERR_INPUT_NULL;
1017     }
1018     outDateInfo_.dataType_ = DataType::SURFACE;
1019     toProducerSurface_ = surface;
1020 
1021     if (impl_->surfaceAdapter_ == nullptr) {
1022         impl_->surfaceAdapter_ = std::make_unique<EffectSurfaceAdapter>();
1023     }
1024     impl_->surfaceAdapter_->SetOutputSurfaceDefaultUsage(toProducerSurface_->GetDefaultUsage());
1025 
1026     toProducerSurface_->SetTransform(GRAPHIC_ROTATE_BUTT);
1027     return ErrorCode::SUCCESS;
1028 }
1029 
UpdateProducerSurfaceInfo()1030 void ImageEffect::UpdateProducerSurfaceInfo()
1031 {
1032     if (impl_->surfaceAdapter_ == nullptr) {
1033         EFFECT_LOGE("impl surfaceAdapter is nullptr!");
1034         return;
1035     }
1036     auto transform = impl_->surfaceAdapter_->GetTransform();
1037     if (transform == toProducerTransform_) {
1038         return;
1039     }
1040     toProducerTransform_ = transform;
1041     EFFECT_LOGI("Set toProducerSurface transform %{public}d, GRAPHIC_ROTATE_270: %{public}d",
1042         transform, GRAPHIC_ROTATE_270);
1043 
1044     if (toProducerSurface_ == nullptr) {
1045         EFFECT_LOGE("toProducerSurface_ is nullptr!");
1046         return;
1047     }
1048     toProducerSurface_->SetTransform(transform);
1049 }
1050 
MemoryCopyForSurfaceBuffer(sptr<SurfaceBuffer> & buffer,OHOS::sptr<SurfaceBuffer> & outBuffer)1051 void MemoryCopyForSurfaceBuffer(sptr<SurfaceBuffer> &buffer, OHOS::sptr<SurfaceBuffer> &outBuffer)
1052 {
1053     CopyInfo src = {
1054         .bufferInfo = {
1055             .width_ = static_cast<uint32_t>(buffer->GetWidth()),
1056             .height_ = static_cast<uint32_t>(buffer->GetHeight()),
1057             .len_ = buffer->GetSize(),
1058             .formatType_ = CommonUtils::SwitchToEffectFormat((GraphicPixelFormat)buffer->GetFormat()),
1059             .rowStride_ = static_cast<uint32_t>(buffer->GetStride()),
1060         },
1061         .data = static_cast<uint8_t *>(buffer->GetVirAddr()),
1062     };
1063     CopyInfo dst = {
1064         .bufferInfo = {
1065             .width_ = static_cast<uint32_t>(outBuffer->GetWidth()),
1066             .height_ = static_cast<uint32_t>(outBuffer->GetHeight()),
1067             .len_ = outBuffer->GetSize(),
1068             .formatType_ = CommonUtils::SwitchToEffectFormat((GraphicPixelFormat)outBuffer->GetFormat()),
1069             .rowStride_ = static_cast<uint32_t>(outBuffer->GetStride()),
1070         },
1071         .data = static_cast<uint8_t *>(outBuffer->GetVirAddr()),
1072     };
1073     MemcpyHelper::CopyData(src, dst);
1074 }
1075 
IsSurfaceBufferHebc(sptr<SurfaceBuffer> & buffer)1076 bool IsSurfaceBufferHebc(sptr<SurfaceBuffer> &buffer)
1077 {
1078     V1_1::BufferHandleAttrKey key = V1_1::BufferHandleAttrKey::ATTRKEY_ACCESS_TYPE;
1079     std::vector<uint8_t> values;
1080     auto res = buffer->GetMetadata(key, values);
1081     CHECK_AND_RETURN_RET(res == 0, false);
1082 
1083     V1_1::HebcAccessType hebcAccessType = V1_1::HebcAccessType::HEBC_ACCESS_UNINIT;
1084     res = MetadataHelper::ConvertVecToMetadata(values, hebcAccessType);
1085     CHECK_AND_RETURN_RET(res == 0, false);
1086 
1087     if (hebcAccessType == V1_1::HEBC_ACCESS_HW_ONLY) {
1088         EFFECT_LOGD("IsSurfaceBufferHebc: surface buffer is Hebc data!");
1089         return true;
1090     }
1091     return false;
1092 }
1093 
SetSurfaceBufferHebcAccessType(sptr<SurfaceBuffer> & buffer,V1_1::HebcAccessType hebcAccessType)1094 void SetSurfaceBufferHebcAccessType(sptr<SurfaceBuffer> &buffer, V1_1::HebcAccessType hebcAccessType)
1095 {
1096     std::vector<uint8_t> values;
1097     auto res = MetadataHelper::ConvertMetadataToVec(hebcAccessType, values);
1098     CHECK_AND_RETURN_LOG(res == 0, "SetSurfaceBufferHebcAccessType: ConvertVecToMetadata fail! res=%{public}d", res);
1099 
1100     V1_1::BufferHandleAttrKey key = V1_1::BufferHandleAttrKey::ATTRKEY_ACCESS_TYPE;
1101     res = buffer->SetMetadata(key, values, false);
1102     CHECK_AND_RETURN_LOG(res == 0, "SetSurfaceBufferHebcAccessType: SetMetadata fail! res=%{public}d", res);
1103 }
1104 
SetSurfaceBufferRequestHebcAccessType(sptr<SurfaceBuffer> & buffer,V1_1::HebcAccessType hebcAccessType)1105 void SetSurfaceBufferRequestHebcAccessType(sptr<SurfaceBuffer> &buffer, V1_1::HebcAccessType hebcAccessType)
1106 {
1107     std::vector<uint8_t> values;
1108     auto res = MetadataHelper::ConvertMetadataToVec(hebcAccessType, values);
1109     CHECK_AND_RETURN_LOG(res == 0,
1110         "SetSurfaceBufferRequestHebcAccessType: ConvertVecToMetadata fail! res=%{public}d", res);
1111 
1112     V1_1::BufferHandleAttrKey key = V1_1::BufferHandleAttrKey::ATTRKEY_REQUEST_ACCESS_TYPE;
1113     res = buffer->SetMetadata(key, values, false);
1114     CHECK_AND_RETURN_LOG(res == 0,
1115         "SetSurfaceBufferRequestHebcAccessType: SetMetadata fail! res=%{public}d", res);
1116 }
1117 
RenderBuffer()1118 void ImageEffect::RenderBuffer()
1119 {
1120     auto entry = bufferPool_->TryPop(false);
1121     CHECK_AND_RETURN_LOG(entry != std::nullopt, "ProcessRender: No available buffer in bufferPool!");
1122     std::unique_lock<std::mutex> lock(innerEffectMutex_);
1123     inDateInfo_.surfaceBufferInfo_ = {
1124         .surfaceBuffer_ = entry->buffer_,
1125         .timestamp_ = entry->timestamp_,
1126     };
1127     outDateInfo_.surfaceBufferInfo_ = {
1128         .surfaceBuffer_ = entry->buffer_,
1129         .timestamp_ = entry->timestamp_,
1130     };
1131     impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
1132     this->Render();
1133     if (impl_->effectContext_->logStrategy_ == LOG_STRATEGY::NORMAL) {
1134         impl_->effectContext_->logStrategy_ = LOG_STRATEGY::LIMITED;
1135     }
1136 
1137     EFFECT_LOGD("ProcessRender: FlushBuffer: %{public}d", entry->buffer_->GetSeqNum());
1138     auto ret = FlushBuffer(entry->buffer_, entry->syncFence_, true, true, entry->timestamp_);
1139     CHECK_AND_RETURN_LOG(ret == GSError::GSERROR_OK, "ProcessRender: FlushBuffer fail! ret=%{public}d", ret);
1140 }
1141 
GetBufferRequestConfig(const sptr<SurfaceBuffer> & buffer)1142 BufferRequestConfig ImageEffect::GetBufferRequestConfig(const sptr<SurfaceBuffer>& buffer)
1143 {
1144     return {
1145         .width = buffer->GetWidth(),
1146         .height = buffer->GetHeight(),
1147         .strideAlignment = 0x8,
1148         .format = buffer->GetFormat(),
1149         .usage = buffer->GetUsage(),
1150         .timeout = 0,
1151         .colorGamut = buffer->GetSurfaceBufferColorGamut(),
1152         .transform = buffer->GetSurfaceBufferTransform(),
1153     };
1154 }
1155 
FlushBuffer(sptr<SurfaceBuffer> & flushBuffer,sptr<SyncFence> & syncFence,bool isNeedAttach,bool isSendFence,int64_t & timestamp)1156 GSError ImageEffect::FlushBuffer(sptr<SurfaceBuffer>& flushBuffer, sptr<SyncFence>& syncFence, bool isNeedAttach,
1157     bool isSendFence, int64_t& timestamp)
1158 {
1159     BufferFlushConfig flushConfig = {
1160         .damage = {
1161             .w = flushBuffer->GetWidth(),
1162             .h = flushBuffer->GetHeight(),
1163         },
1164         .timestamp = timestamp,
1165     };
1166 
1167     CHECK_AND_RETURN_RET_LOG(imageEffectFlag_ == STRUCT_IMAGE_EFFECT_CONSTANT, GSERROR_NOT_INIT,
1168         "FlushBuffer: ImageEffect not exist.");
1169     CHECK_AND_RETURN_RET_LOG(toProducerSurface_ != nullptr, GSERROR_NOT_INIT,
1170         "FlushBuffer: toProducerSurface is nullptr.");
1171 
1172     auto ret = GSError::GSERROR_OK;
1173     const sptr<SyncFence> invalidFence = SyncFence::InvalidFence();
1174     if (isNeedAttach) {
1175         ret = toProducerSurface_->AttachAndFlushBuffer(flushBuffer, isSendFence ? syncFence : invalidFence,
1176             flushConfig, false);
1177         if (ret != GSError::GSERROR_OK) {
1178             EFFECT_LOGE("AttachAndFlushBuffer: attach and flush buffer failed. %{public}d", ret);
1179         }
1180     } else {
1181         ret = toProducerSurface_->FlushBuffer(flushBuffer, isSendFence ? syncFence : invalidFence, flushConfig);
1182         if (ret != GSError::GSERROR_OK) {
1183             EFFECT_LOGE("FlushBuffer: flush buffer failed. %{public}d", ret);
1184         }
1185     }
1186 
1187     return ret;
1188 }
1189 
ReleaseBuffer(sptr<OHOS::SurfaceBuffer> & buffer,sptr<OHOS::SyncFence> & fence)1190 GSError ImageEffect::ReleaseBuffer(sptr<OHOS::SurfaceBuffer> &buffer, sptr<OHOS::SyncFence> &fence)
1191 {
1192     auto ret = impl_->ReleaseConsumerSurfaceBuffer(buffer, fence);
1193     if (ret != GSError::GSERROR_OK) {
1194         EFFECT_LOGE("ReleaseBuffer: ReleaseConsumerSurfaceBuffer failed. %{public}d", ret);
1195     }
1196     return ret;
1197 }
1198 
SubmitRenderTask(BufferEntry && entry)1199 bool ImageEffect::SubmitRenderTask(BufferEntry &&entry)
1200 {
1201     bool success = bufferPool_->TryPush(std::move(entry));
1202     EFFECT_LOGD("SubmitRenderTask: bufferPool size: %{public}d", (int)bufferPool_->Size());
1203     CHECK_AND_RETURN_RET_LOG(m_renderThread, true, "SubmitRenderTask: m_renderThread is null!");
1204     CHECK_AND_RETURN_RET_LOG(success, true, "SubmitRenderTask: bufferPool push failed!");
1205 
1206     auto task = std::make_shared<RenderTask<>>([this]() {
1207         RenderBuffer();
1208     }, COMMON_TASK_TAG + 1, m_currentTaskId.fetch_add(1));
1209     m_renderThread->AddTask(task);
1210     return false;
1211 }
1212 
ProcessRender(BufferProcessInfo & bufferProcessInfo,bool & isNeedSwap,int64_t & timestamp)1213 void ImageEffect::ProcessRender(BufferProcessInfo& bufferProcessInfo, bool& isNeedSwap, int64_t& timestamp)
1214 {
1215     auto& [inBuffer, outBuffer, inBufferSyncFence, outBufferSyncFence, isSrcHebcData] = bufferProcessInfo;
1216 
1217     constexpr uint32_t waitForEver = -1;
1218     (void)inBufferSyncFence->Wait(waitForEver);
1219     CHECK_AND_RETURN_LOG(inBuffer, "ProcessRender: inBuffer is nullptr!");
1220 
1221     {
1222         EFFECT_TRACE_BEGIN("ProcessRender: InvalidateCache");
1223         (void)inBuffer->InvalidateCache();
1224         EFFECT_TRACE_END();
1225     }
1226 
1227     CHECK_AND_RETURN_LOG(toProducerSurface_ != nullptr, "ProcessRender: toProducerSurface is nullptr.");
1228     auto requestConfig = GetBufferRequestConfig(inBuffer);
1229     auto ret = toProducerSurface_->RequestAndDetachBuffer(outBuffer, outBufferSyncFence, requestConfig);
1230     if (ret != 0 || outBuffer == nullptr) {
1231         EFFECT_LOGE("ProcessRender::RequestAndDetachBuffer failed. %{public}d", ret);
1232         return;
1233     }
1234     EFFECT_LOGD("ProcessRender: inBuffer: %{public}d, outBuffer: %{public}d",
1235         inBuffer->GetSeqNum(), outBuffer->GetSeqNum());
1236 
1237     ret = impl_->DetachConsumerSurfaceBuffer(inBuffer);
1238     if (ret != GSError::GSERROR_OK) {
1239         EFFECT_LOGE("ProcessRender: DetachConsumerSurfaceBuffer failed. %{public}d", ret);
1240         ReleaseBuffer(inBuffer, inBufferSyncFence);
1241         FlushBuffer(outBuffer, outBufferSyncFence, true, true, timestamp);
1242         return;
1243     }
1244 
1245     SetSurfaceBufferRequestHebcAccessType(outBuffer, V1_1::HebcAccessType::HEBC_ACCESS_CPU_ACCESS);
1246     ret = impl_->AttachConsumerSurfaceBuffer(outBuffer);
1247     if (ret != GSError::GSERROR_OK) {
1248         EFFECT_LOGE("ProcessRender: AttachConsumerSurfaceBuffer failed. %{public}d", ret);
1249     }
1250 
1251     ret = ReleaseBuffer(outBuffer, outBufferSyncFence);
1252     if (ret != GSError::GSERROR_OK) {
1253         EFFECT_LOGE("ProcessRender: ReleaseConsumerSurfaceBuffer failed. %{public}d", ret);
1254         impl_->DetachConsumerSurfaceBuffer(outBuffer);
1255         return;
1256     }
1257 
1258     SetSurfaceBufferHebcAccessType(inBuffer, isSrcHebcData ?
1259         V1_1::HebcAccessType::HEBC_ACCESS_HW_ONLY : V1_1::HebcAccessType::HEBC_ACCESS_CPU_ACCESS);
1260     isNeedSwap = SubmitRenderTask({inBuffer->GetSeqNum(), inBuffer, inBufferSyncFence, timestamp});
1261 }
1262 
ProcessSwapBuffers(BufferProcessInfo & bufferProcessInfo,int64_t & timestamp)1263 void ImageEffect::ProcessSwapBuffers(BufferProcessInfo& bufferProcessInfo, int64_t& timestamp)
1264 {
1265     sptr<SurfaceBuffer> inBuffer = bufferProcessInfo.inBuffer_;
1266     sptr<SurfaceBuffer> outBuffer = bufferProcessInfo.outBuffer_;
1267     sptr<SyncFence> inBufferSyncFence = bufferProcessInfo.inBufferSyncFence_;
1268     sptr<SyncFence> outBufferSyncFence = bufferProcessInfo.outBufferSyncFence_;
1269     // inBuffer aquired from impl
1270     auto requestConfig = GetBufferRequestConfig(inBuffer);
1271     auto ret = toProducerSurface_->RequestAndDetachBuffer(outBuffer, outBufferSyncFence, requestConfig);
1272     if (ret != 0 || outBuffer == nullptr) {
1273         EFFECT_LOGE("ProcessSwapBuffers::RequestAndDetachBuffer failed. %{public}d", ret);
1274         ReleaseBuffer(inBuffer, inBufferSyncFence);
1275         return;
1276     }
1277     CHECK_AND_RETURN_LOG(inBuffer != nullptr && outBuffer != nullptr,
1278         "ProcessSwapBuffers: inBuffer or outBuffer is nullptr");
1279     // outBuffer requestAndDetached from XC
1280     EFFECT_LOGD("ProcessSwapBuffers: inBuffer: %{public}d, outBuffer: %{public}d",
1281         inBuffer->GetSeqNum(), outBuffer->GetSeqNum());
1282 
1283     ret = impl_->DetachConsumerSurfaceBuffer(inBuffer);
1284     if (ret != GSError::GSERROR_OK) {
1285         EFFECT_LOGE("ProcessSwapBuffers: DetachConsumerSurfaceBuffer failed. %{public}d", ret);
1286         ReleaseBuffer(inBuffer, inBufferSyncFence);
1287         FlushBuffer(outBuffer, outBufferSyncFence, true, true, timestamp);
1288         return;
1289     }
1290     // inBuffer detached from impl
1291     ret = impl_->AttachConsumerSurfaceBuffer(outBuffer);
1292     if (ret != GSError::GSERROR_OK) {
1293         EFFECT_LOGE("ProcessSwapBuffers: AttachConsumerSurfaceBuffer failed. %{public}d", ret);
1294         failureCount_++;
1295         impl_->AttachConsumerSurfaceBuffer(inBuffer);
1296         ReleaseBuffer(inBuffer, inBufferSyncFence);
1297         FlushBuffer(outBuffer, inBufferSyncFence, true, false, timestamp);
1298         return;
1299     }
1300     // outBuffer attached in Impl
1301     ret = FlushBuffer(inBuffer, inBufferSyncFence, true, true, timestamp);
1302     if (ret != GSError::GSERROR_OK) {
1303         EFFECT_LOGE("ProcessSwapBuffers: FlushBuffer failed. %{public}d", ret);
1304         ReleaseBuffer(outBuffer, outBufferSyncFence);
1305         return;
1306     }
1307     // inBuffer attachAndFlushed in XC
1308     ret = ReleaseBuffer(outBuffer, outBufferSyncFence);
1309     // outBuffer release in impl
1310     CHECK_AND_RETURN_LOG(ret == GSError::GSERROR_OK,
1311         "ProcessSwapBuffers: ReleaseConsumerSurfaceBuffer failed. %{public}d", ret);
1312 }
1313 
OnBufferAvailableWithCPU()1314 void ImageEffect::OnBufferAvailableWithCPU()
1315 {
1316     sptr<SurfaceBuffer> inBuffer = nullptr;
1317     sptr<SurfaceBuffer> outBuffer = nullptr;
1318     int64_t timestamp = 0;
1319     OHOS::Rect damages = {};
1320     sptr<SyncFence> inBufferSyncFence = SyncFence::INVALID_FENCE;
1321 
1322     CHECK_AND_RETURN_LOG(impl_->CheckEffectSurface(),
1323         "OnBufferAvailableToProcess: onBufferAvailableToProcess consumerSurface_ not exist");
1324 
1325     auto ret = impl_->AcquireConsumerSurfaceBuffer(inBuffer, inBufferSyncFence, timestamp, damages);
1326     CHECK_AND_RETURN_LOG(ret == 0 && inBuffer != nullptr, "AcquireBuffer failed. %{public}d", ret);
1327 
1328     outDateInfo_.dataType_ = DataType::SURFACE;
1329     UpdateProducerSurfaceInfo();
1330 
1331     bool isSrcHebcData = false;
1332     CHECK_AND_RETURN_LOG(impl_ != nullptr, "OnBufferAvailableWithCPU: impl is nullptr.");
1333     UpdateConsumerBuffersNumber();
1334     UpdateCycleBuffersNumber();
1335     bool isNeedSwap = true;
1336     bool isNeedRender = impl_->effectState_ == EffectState::RUNNING;
1337     if (isNeedRender) {
1338         isSrcHebcData = IsSurfaceBufferHebc(inBuffer);
1339         isNeedRender = !isSrcHebcData;
1340     }
1341 
1342     BufferProcessInfo bufferProcessInfo = {
1343         .inBuffer_ = inBuffer,
1344         .outBuffer_ = outBuffer,
1345         .inBufferSyncFence_ = inBufferSyncFence,
1346         .outBufferSyncFence_ = SyncFence::INVALID_FENCE,
1347         .isSrcHebcData_ = isSrcHebcData,
1348     };
1349 
1350     if (isNeedRender) {
1351         EFFECT_TRACE_BEGIN("ProcessRender");
1352         ProcessRender(bufferProcessInfo, isNeedSwap, timestamp);
1353         EFFECT_TRACE_END();
1354     }
1355     if (isNeedSwap) {
1356         EFFECT_TRACE_BEGIN("ProcessSwapBuffers");
1357         ProcessSwapBuffers(bufferProcessInfo, timestamp);
1358         EFFECT_TRACE_END();
1359     }
1360 }
1361 
ConsumerBufferAvailable()1362 void ImageEffect::ConsumerBufferAvailable()
1363 {
1364     CHECK_AND_RETURN_LOG(imageEffectFlag_ == STRUCT_IMAGE_EFFECT_CONSTANT,
1365         "ImageEffect::ConsumerBufferAvailable ImageEffect not exist.");
1366     if (!impl_->isQosEnabled_) {
1367         OHOS::QOS::SetThreadQos(OHOS::QOS::QosLevel::QOS_USER_INTERACTIVE);
1368         impl_->isQosEnabled_ = true;
1369     }
1370     std::unique_lock<std::mutex> lock(consumerListenerMutex_);
1371     CHECK_AND_RETURN_LOG(imageEffectFlag_ == STRUCT_IMAGE_EFFECT_CONSTANT,
1372         "ImageEffect::ConsumerBufferAvailable ImageEffect not exist.");
1373     OnBufferAvailableWithCPU();
1374 }
1375 
GetInputSurface()1376 sptr<Surface> ImageEffect::GetInputSurface()
1377 {
1378     inDateInfo_.dataType_ = DataType::SURFACE;
1379     if (fromProducerSurface_ != nullptr) {
1380         return fromProducerSurface_;
1381     }
1382 
1383     if (impl_->surfaceAdapter_ == nullptr) {
1384         impl_->surfaceAdapter_ = std::make_unique<EffectSurfaceAdapter>();
1385     }
1386 
1387     if (impl_->surfaceAdapter_) {
1388         fromProducerSurface_ = impl_->surfaceAdapter_->GetProducerSurface();
1389     }
1390 
1391     auto consumerListener = [this]() {
1392         return ConsumerBufferAvailable();
1393     };
1394 
1395     if (impl_->surfaceAdapter_) {
1396         impl_->surfaceAdapter_->SetConsumerListener(std::move(consumerListener));
1397     }
1398 
1399     auto consumerSurface = impl_->GetConsumerSurface();
1400     if (fromProducerSurface_ && consumerSurface) {
1401         int maxBufferPoolSize = std::max((int)fromProducerSurface_->GetQueueSize(),
1402             (int)consumerSurface->GetQueueSize());
1403         maxBufferPoolSize = std::min(maxBufferPoolSize, RENDER_QUEUE_SIZE);
1404         EFFECT_LOGD("GetInputSurface: maxBufferPoolSize=%{public}d", maxBufferPoolSize);
1405         bufferPool_ = std::make_shared<ThreadSafeBufferQueue<BufferEntry>>(maxBufferPoolSize);
1406     }
1407 
1408     return fromProducerSurface_;
1409 }
1410 
SetOutNativeWindow(OHNativeWindow * nativeWindow)1411 ErrorCode ImageEffect::SetOutNativeWindow(OHNativeWindow *nativeWindow)
1412 {
1413     std::unique_lock<std::mutex> lock(innerEffectMutex_);
1414     CHECK_AND_RETURN_RET_LOG(nativeWindow != nullptr, ErrorCode::ERR_INPUT_NULL, "nativeWindow is nullptr");
1415     OHOS::sptr<OHOS::Surface> surface = nativeWindow->surface;
1416     CHECK_AND_RETURN_RET_LOG(surface != nullptr, ErrorCode::ERR_INPUT_NULL, "surface is nullptr");
1417     toProducerSurface_ = surface;
1418     outDateInfo_.dataType_ = DataType::NATIVE_WINDOW;
1419     impl_->effectContext_->renderEnvironment_->InitEngine(nativeWindow);
1420     if (impl_->surfaceAdapter_ == nullptr) {
1421         impl_->surfaceAdapter_ = std::make_unique<EffectSurfaceAdapter>();
1422     }
1423     impl_->surfaceAdapter_->SetOutputSurfaceDefaultUsage(toProducerSurface_->GetDefaultUsage());
1424 
1425     toProducerSurface_->SetTransform(GRAPHIC_ROTATE_BUTT);
1426     return ErrorCode::SUCCESS;
1427 }
1428 
Configure(const std::string & key,const Any & value)1429 ErrorCode ImageEffect::Configure(const std::string &key, const Any &value)
1430 {
1431     if (FUNCTION_FLUSH_SURFACE_BUFFER.compare(key) == 0) {
1432         EFFECT_LOGI("ImageEffect Configure FlushCache");
1433         needPreFlush_ = true;
1434         return ErrorCode::SUCCESS;
1435     }
1436     auto configTypeIt = std::find_if(configTypeTab_.begin(), configTypeTab_.end(),
1437         [&key](const std::pair<std::string, ConfigType> &item) { return item.first.compare(key) == 0; });
1438 
1439     CHECK_AND_RETURN_RET_LOG(configTypeIt != configTypeTab_.end(), ErrorCode::ERR_UNSUPPORTED_CONFIG_TYPE,
1440         "config key is not support! key=%{public}s", key.c_str());
1441 
1442     ConfigType configType = configTypeIt->second;
1443     switch (configType) {
1444         case ConfigType::IPTYPE: {
1445             int32_t runningType;
1446             ErrorCode result = CommonUtils::ParseAny(value, runningType);
1447             CHECK_AND_RETURN_RET_LOG(result == ErrorCode::SUCCESS, result,
1448                 "parse any fail! expect type is uint32_t! key=%{public}s", key.c_str());
1449             auto it = std::find_if(runningTypeTab_.begin(), runningTypeTab_.end(),
1450                 [&runningType](const std::pair<int32_t, std::vector<IPType>> &item) {
1451                     return item.first == runningType;
1452                 });
1453             CHECK_AND_RETURN_RET_LOG(it != runningTypeTab_.end(), ErrorCode::ERR_UNSUPPORTED_RUNNINGTYPE,
1454                 "not support runningType! key=%{public}s, runningType=%{public}d", key.c_str(), runningType);
1455             config_[configType] = it->second;
1456             break;
1457         }
1458         default:
1459             EFFECT_LOGE("config type is not support! configType=%{public}d", configType);
1460             return ErrorCode::ERR_UNSUPPORTED_CONFIG_TYPE;
1461     }
1462     return ErrorCode::SUCCESS;
1463 }
1464 
ClearDataInfo(DataInfo & dataInfo)1465 void ImageEffect::ClearDataInfo(DataInfo &dataInfo)
1466 {
1467     dataInfo.dataType_ = DataType::UNKNOWN;
1468     dataInfo.pixelMap_ = nullptr;
1469     dataInfo.surfaceBufferInfo_.surfaceBuffer_ = nullptr;
1470     dataInfo.surfaceBufferInfo_.timestamp_ = 0;
1471     dataInfo.uri_ = "";
1472     dataInfo.path_ = "";
1473 }
1474 
IsSameInOutputData(const DataInfo & inDataInfo,const DataInfo & outDataInfo)1475 bool IsSameInOutputData(const DataInfo &inDataInfo, const DataInfo &outDataInfo)
1476 {
1477     if (inDataInfo.dataType_ != outDataInfo.dataType_) {
1478         return false;
1479     }
1480 
1481     switch (inDataInfo.dataType_) {
1482         case DataType::PIXEL_MAP:
1483             return inDataInfo.pixelMap_ == outDataInfo.pixelMap_;
1484         case DataType::SURFACE_BUFFER:
1485             return inDataInfo.surfaceBufferInfo_.surfaceBuffer_ == outDataInfo.surfaceBufferInfo_.surfaceBuffer_;
1486         case DataType::PATH:
1487             return inDataInfo.path_ == outDataInfo.path_;
1488         case DataType::URI:
1489             return inDataInfo.uri_ == outDataInfo.uri_;
1490         case DataType::PICTURE:
1491             return inDataInfo.picture_ == outDataInfo.picture_;
1492         default:
1493             return false;
1494     }
1495 }
1496 
RemoveGainMapIfNeed() const1497 void ImageEffect::RemoveGainMapIfNeed() const
1498 {
1499     auto context = impl_->effectContext_;
1500     const auto& supportedHdrFormats = context->filtersSupportedHdrFormat_;
1501     const bool needRemove = supportedHdrFormats.find(HdrFormat::HDR8_GAINMAP) == supportedHdrFormats.end();
1502     if (!needRemove) {
1503         return;
1504     }
1505 
1506     EFFECT_LOGI("RemoveGainMapIfNeed: gainMap is not supported, remove it!");
1507     if (outDateInfo_.dataType_ == DataType::PICTURE && outDateInfo_.picture_ &&
1508         outDateInfo_.picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP)) {
1509         outDateInfo_.picture_->DropAuxiliaryPicture(AuxiliaryPictureType::GAINMAP);
1510     } else if (inDateInfo_.dataType_ == DataType::PICTURE && inDateInfo_.picture_ &&
1511         inDateInfo_.picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP)) {
1512         inDateInfo_.picture_->DropAuxiliaryPicture(AuxiliaryPictureType::GAINMAP);
1513     }
1514 }
1515 
LockAll(std::shared_ptr<EffectBuffer> & srcEffectBuffer,std::shared_ptr<EffectBuffer> & dstEffectBuffer,IEffectFormat format)1516 ErrorCode ImageEffect::LockAll(std::shared_ptr<EffectBuffer> &srcEffectBuffer,
1517     std::shared_ptr<EffectBuffer> &dstEffectBuffer, IEffectFormat format)
1518 {
1519     ErrorCode res = ParseDataInfo(inDateInfo_, srcEffectBuffer, false, format, impl_->effectContext_->logStrategy_);
1520     if (res != ErrorCode::SUCCESS) {
1521         EFFECT_LOGE("ParseDataInfo inData fail! res=%{public}d", res);
1522         return res;
1523     }
1524     EFFECT_LOGD("input data set, parse data info success! dataType=%{public}d", inDateInfo_.dataType_);
1525 
1526     if (outDateInfo_.dataType_ != DataType::UNKNOWN && !IsSameInOutputData(inDateInfo_, outDateInfo_)) {
1527         EFFECT_LOGD("output data set, start parse data info. dataType=%{public}d", outDateInfo_.dataType_);
1528         res = ParseDataInfo(outDateInfo_, dstEffectBuffer, true, format, impl_->effectContext_->logStrategy_);
1529         if (res != ErrorCode::SUCCESS) {
1530             EFFECT_LOGE("ParseDataInfo outData fail! res=%{public}d", res);
1531             return res;
1532         }
1533         EFFECT_LOGD("output data set, parse data info success! dataType=%{public}d", outDateInfo_.dataType_);
1534     }
1535 
1536     return ErrorCode::SUCCESS;
1537 }
1538 
ParseDataInfo(DataInfo & dataInfo,std::shared_ptr<EffectBuffer> & effectBuffer,bool isOutputData,IEffectFormat format,LOG_STRATEGY strategy)1539 ErrorCode ImageEffect::ParseDataInfo(DataInfo &dataInfo, std::shared_ptr<EffectBuffer> &effectBuffer,
1540     bool isOutputData, IEffectFormat format, LOG_STRATEGY strategy)
1541 {
1542     switch (dataInfo.dataType_) {
1543         case DataType::PIXEL_MAP:
1544             return CommonUtils::LockPixelMap(dataInfo.pixelMap_, effectBuffer);
1545         case DataType::SURFACE:
1546         case DataType::SURFACE_BUFFER:
1547             return CommonUtils::ParseSurfaceData(dataInfo.surfaceBufferInfo_.surfaceBuffer_, effectBuffer,
1548                 dataInfo.dataType_, strategy, dataInfo.surfaceBufferInfo_.timestamp_);
1549         case DataType::URI:
1550             return CommonUtils::ParseUri(dataInfo.uri_, effectBuffer, isOutputData, format);
1551         case DataType::PATH:
1552             return CommonUtils::ParsePath(dataInfo.path_, effectBuffer, isOutputData, format);
1553         case DataType::NATIVE_WINDOW:
1554             return CommonUtils::ParseNativeWindowData(effectBuffer, dataInfo.dataType_);
1555         case DataType::PICTURE:
1556             return CommonUtils::ParsePicture(dataInfo.picture_, effectBuffer);
1557         case DataType::TEX:
1558             return CommonUtils::ParseTex(dataInfo.textureInfo_.textureId_, dataInfo.textureInfo_.colorSpace_,
1559                 effectBuffer);
1560         case DataType::UNKNOWN:
1561             EFFECT_LOGW("dataType is unknown! Data is not set!");
1562             return ErrorCode::ERR_NO_DATA;
1563         default:
1564             EFFECT_LOGW("dataType is not support! dataType=%{public}d", dataInfo.dataType_);
1565             return ErrorCode::ERR_UNSUPPORTED_DATA_TYPE;
1566     }
1567 }
1568 
UnLockAll()1569 void ImageEffect::UnLockAll()
1570 {
1571     UnLockData(inDateInfo_);
1572     UnLockData(outDateInfo_);
1573 }
1574 
UnLockData(DataInfo & dataInfo)1575 void ImageEffect::UnLockData(DataInfo &dataInfo)
1576 {
1577     switch (dataInfo.dataType_) {
1578         case DataType::PIXEL_MAP: {
1579             CommonUtils::UnlockPixelMap(dataInfo.pixelMap_);
1580             return;
1581         }
1582         default:
1583             return;
1584     }
1585 }
1586 
InitEGLEnv()1587 void ImageEffect::InitEGLEnv()
1588 {
1589     EFFECT_TRACE_NAME("ImageEffect::InitEGLEnv");
1590     impl_->effectContext_->renderEnvironment_->Init();
1591     impl_->effectContext_->renderEnvironment_->Prepare();
1592 }
1593 
DestroyEGLEnv()1594 void ImageEffect::DestroyEGLEnv()
1595 {
1596     EFFECT_LOGI("ImageEffect DestroyEGLEnv enter!");
1597     if (impl_->effectContext_->renderEnvironment_ == nullptr) {
1598         return;
1599     }
1600     impl_->effectContext_->renderEnvironment_->ReleaseParam();
1601     impl_->effectContext_->renderEnvironment_->Release();
1602     EFFECT_LOGI("ImageEffect DestroyEGLEnv end!");
1603 }
1604 
SetExtraInfo(EffectJsonPtr res)1605 ErrorCode ImageEffect::SetExtraInfo(EffectJsonPtr res)
1606 {
1607     extraInfo_ = res;
1608     return ErrorCode::SUCCESS;
1609 }
1610 
ExtInitModule()1611 void ImageEffect::ExtInitModule()
1612 {
1613 }
1614 
ExtDeinitModule()1615 void ImageEffect::ExtDeinitModule()
1616 {
1617 }
1618 
SetInputPicture(Picture * picture)1619 ErrorCode ImageEffect::SetInputPicture(Picture *picture)
1620 {
1621     EFFECT_LOGD("ImageEffect::SetInputPicture");
1622     CHECK_AND_RETURN_RET_LOG(picture != nullptr, ErrorCode::ERR_INPUT_NULL,
1623         "ImageEffect::SetInputPicture: picture is null!");
1624 
1625     impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
1626     ClearDataInfo(inDateInfo_);
1627     inDateInfo_.dataType_ = DataType::PICTURE;
1628     inDateInfo_.picture_ = picture;
1629 
1630     return ErrorCode::SUCCESS;
1631 }
1632 
SetOutputPicture(Picture * picture)1633 ErrorCode ImageEffect::SetOutputPicture(Picture *picture)
1634 {
1635     EFFECT_LOGD("ImageEffect::SetOutputPicture");
1636     ClearDataInfo(outDateInfo_);
1637 
1638     if (picture == nullptr) {
1639         EFFECT_LOGI("SetOutputPicture:picture set to null!");
1640         return ErrorCode::SUCCESS;
1641     }
1642 
1643     outDateInfo_.dataType_ = DataType::PICTURE;
1644     outDateInfo_.picture_ = picture;
1645 
1646     return ErrorCode::SUCCESS;
1647 }
1648 
SetInputTexture(int32_t textureId,int32_t colorSpace)1649 ErrorCode ImageEffect::SetInputTexture(int32_t textureId, int32_t colorSpace)
1650 {
1651     ClearDataInfo(inDateInfo_);
1652     inDateInfo_.dataType_ = DataType::TEX;
1653     CHECK_AND_RETURN_RET_LOG(textureId > 0, ErrorCode::ERR_INPUT_NULL,
1654         "ImageEffect::SetInputTexture: tex is invalid!");
1655     inDateInfo_.textureInfo_.textureId_ = textureId;
1656     inDateInfo_.textureInfo_.colorSpace_ = colorSpace;
1657     return ErrorCode::SUCCESS;
1658 }
1659 
SetOutputTexture(int32_t textureId)1660 ErrorCode ImageEffect::SetOutputTexture(int32_t textureId)
1661 {
1662     ClearDataInfo(outDateInfo_);
1663     outDateInfo_.dataType_ = DataType::TEX;
1664     CHECK_AND_RETURN_RET_LOG(textureId > 0, ErrorCode::ERR_INPUT_NULL,
1665         "ImageEffect::SetInputTexture: tex is invalid!");
1666     outDateInfo_.textureInfo_.textureId_ = textureId;
1667     return ErrorCode::SUCCESS;
1668 }
1669 
UpdateConsumerBuffersNumber()1670 void ImageEffect::UpdateConsumerBuffersNumber()
1671 {
1672     if (setConsumerBufferSize_) {
1673         return;
1674     }
1675 
1676     if (!toProducerSurface_ || !fromProducerSurface_) {
1677         EFFECT_LOGE("UpdateConsumerBuffersNumber: toProducerSurface_ or fromProducerSurface_ is null!");
1678         return;
1679     }
1680 
1681     auto errorCode = toProducerSurface_->SetQueueSize(fromProducerSurface_->GetQueueSize());
1682     if (errorCode != 0) {
1683         EFFECT_LOGE("UpdateConsumerBuffersNumber: SetQueueSize failed! code: %{public}d", errorCode);
1684         return;
1685     }
1686 
1687     EFFECT_LOGI("UpdateConsumerBuffersNumber: SetQueueSize success! ConsumedrBuffersNumber: %{public}d",
1688         fromProducerSurface_->GetQueueSize());
1689     setConsumerBufferSize_ = true;
1690     return;
1691 }
1692 
UpdateCycleBuffersNumber()1693 void ImageEffect::UpdateCycleBuffersNumber()
1694 {
1695     if (setCycleBuffersNumber_) {
1696         return;
1697     }
1698 
1699     if (!toProducerSurface_ || !fromProducerSurface_) {
1700         EFFECT_LOGE("UpdateCycleBuffersNumber: toProducerSurface_ or fromProducerSurface_ is null!");
1701         return;
1702     }
1703 
1704     uint32_t cycleBuffersNumber = toProducerSurface_->GetQueueSize() + fromProducerSurface_->GetQueueSize();
1705     auto errorCode = toProducerSurface_->SetCycleBuffersNumber(cycleBuffersNumber);
1706     if (errorCode != 0) {
1707         EFFECT_LOGE("UpdateCycleBuffersNumber: SetCycleBuffersNumber failed! code: %{public}d", errorCode);
1708         return;
1709     }
1710 
1711     EFFECT_LOGI("UpdateCycleBuffersNumber: SetCycleBuffersNumber success! cycleBuffersNumber: %{public}d",
1712         cycleBuffersNumber);
1713     setCycleBuffersNumber_ = true;
1714     return;
1715 }
1716 } // namespace Effect
1717 } // namespace Media
1718 } // namespace OHOS
1719