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