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 "effect_surface_adapter.h"
17
18 #include <surface_utils.h>
19 #include <sync_fence.h>
20
21 #include "effect_log.h"
22
23 namespace OHOS {
24 namespace Media {
25 namespace Effect {
26 constexpr int32_t IE_INVALID_FENCE = -1;
27 const int32_t STRUCT_EFFECT_SURFACE_CONSTANT = 1;
28 const int32_t DESTRUCTOR_EFFECT_SURFACE_CONSTANT = 2;
29
EffectSurfaceAdapter()30 EffectSurfaceAdapter::EffectSurfaceAdapter()
31 {
32 effectSurfaceFlag_ = STRUCT_EFFECT_SURFACE_CONSTANT;
33 }
34
~EffectSurfaceAdapter()35 EffectSurfaceAdapter::~EffectSurfaceAdapter()
36 {
37 if (receiverConsumerSurface_) {
38 GSError result = receiverConsumerSurface_->UnregisterConsumerListener();
39 EFFECT_LOGE("EffectSurfaceAdapter::~EffectSurfaceAdapter UnregisterConsumerListener. result=%{public}d",
40 result);
41 effectSurfaceFlag_ = DESTRUCTOR_EFFECT_SURFACE_CONSTANT;
42 receiverConsumerSurface_ = nullptr;
43 }
44 }
45
Initialize()46 ErrorCode EffectSurfaceAdapter::Initialize()
47 {
48 receiverConsumerSurface_ = IConsumerSurface::Create("EffectSurfaceAdapter");
49 if (receiverConsumerSurface_ == nullptr) {
50 EFFECT_LOGE("Surface::CreateSurfaceAsConsumer::Create failed.");
51 return ErrorCode::ERR_IMAGE_EFFECT_RECEIVER_INIT_FAILED;
52 }
53
54 uint64_t usage = BUFFER_USAGE_CPU_HW_BOTH | BUFFER_USAGE_MEM_MMZ_CACHE;
55 if (outputSurfaceDefaultUsage_ & BUFFER_USAGE_HW_COMPOSER) {
56 usage |= BUFFER_USAGE_HW_COMPOSER;
57 }
58 (void)receiverConsumerSurface_->SetDefaultUsage(usage);
59
60 auto producer = receiverConsumerSurface_->GetProducer();
61 fromProducerSurface_ = Surface::CreateSurfaceAsProducer(producer);
62 if (fromProducerSurface_ == nullptr) {
63 EFFECT_LOGE("Surface::CreateSurfaceAsProducer failed");
64 return ErrorCode::ERR_IMAGE_EFFECT_RECEIVER_INIT_FAILED;
65 }
66
67 // register consumer listener
68 receiverConsumerSurface_->RegisterConsumerListener(this);
69
70 auto surfaceUtils = SurfaceUtils::GetInstance();
71 auto ret = surfaceUtils->Add(fromProducerSurface_->GetUniqueId(), fromProducerSurface_);
72 if (ret != SurfaceError::SURFACE_ERROR_OK) {
73 EFFECT_LOGE("add surface error: %{public}d", ret);
74 return ErrorCode::ERR_IMAGE_EFFECT_RECEIVER_INIT_FAILED;
75 }
76 EFFECT_LOGI("producer create success, unique id:%{private}llu",
77 static_cast<unsigned long long>(fromProducerSurface_->GetUniqueId()));
78
79 return ErrorCode::SUCCESS;
80 }
81
GetProducerSurface()82 sptr<Surface> EffectSurfaceAdapter::GetProducerSurface()
83 {
84 if (fromProducerSurface_) {
85 return fromProducerSurface_;
86 }
87
88 if (Initialize() != ErrorCode::SUCCESS) {
89 return nullptr;
90 }
91
92 return fromProducerSurface_;
93 }
94
SetConsumerListener(ConsumerBufferAvailable && consumerBufferAvailable)95 ErrorCode EffectSurfaceAdapter::SetConsumerListener(ConsumerBufferAvailable &&consumerBufferAvailable)
96 {
97 if (!consumerBufferAvailable) {
98 return ErrorCode::ERR_INPUT_NULL;
99 }
100
101 consumerBufferAvailable_ = std::move(consumerBufferAvailable);
102 return ErrorCode::SUCCESS;
103 }
104
GetTransform() const105 GraphicTransformType EffectSurfaceAdapter::GetTransform() const
106 {
107 if (receiverConsumerSurface_) {
108 return receiverConsumerSurface_->GetTransform();
109 }
110
111 return GRAPHIC_ROTATE_BUTT;
112 }
113
SetOutputSurfaceDefaultUsage(uint64_t usage)114 void EffectSurfaceAdapter::SetOutputSurfaceDefaultUsage(uint64_t usage)
115 {
116 EFFECT_LOGD("SetOutputSurfaceDefaultUsage: usage=%{public}llu", static_cast<unsigned long long>(usage));
117 outputSurfaceDefaultUsage_ = usage;
118 }
119
ConsumerRequestCpuAccess(bool isCpuAccess)120 void EffectSurfaceAdapter::ConsumerRequestCpuAccess(bool isCpuAccess)
121 {
122 EFFECT_LOGD("ConsumerRequestCpuAccess: isCpuAccess=%{public}d", isCpuAccess);
123 if (receiverConsumerSurface_) {
124 receiverConsumerSurface_->ConsumerRequestCpuAccess(isCpuAccess);
125 }
126 }
127
OnBufferAvailable()128 void EffectSurfaceAdapter::OnBufferAvailable()
129 {
130 OHOS::sptr<SurfaceBuffer> inBuffer;
131 OHOS::sptr<SurfaceBuffer> outBuffer;
132 int64_t timestamp = 0;
133 Rect damages{};
134 sptr<SyncFence> syncFence = SyncFence::INVALID_FENCE;
135 CHECK_AND_RETURN_LOG(effectSurfaceFlag_ == STRUCT_EFFECT_SURFACE_CONSTANT,
136 "EffectSurfaceAdapter::OnBufferAvailable AcquireBuffer surface not exist.");
137 CHECK_AND_RETURN_LOG(receiverConsumerSurface_,
138 "EffectSurfaceAdapter::OnBufferAvailable receiverConsumerSurface_ is nullptr.");
139 auto ret = receiverConsumerSurface_->AcquireBuffer(inBuffer, syncFence, timestamp, damages);
140 CHECK_AND_RETURN_LOG(ret == 0, "AcquireBuffer failed. %{public}d", ret);
141
142 constexpr uint32_t waitForEver = -1;
143 (void)syncFence->Wait(waitForEver);
144
145 bool isNeedSwap = true;
146 if (consumerBufferAvailable_) {
147 isNeedSwap = consumerBufferAvailable_(inBuffer, outBuffer, damages, timestamp);
148 } else {
149 EFFECT_LOGE("not register handle buffer.");
150 }
151 CHECK_AND_RETURN_LOG(effectSurfaceFlag_ == STRUCT_EFFECT_SURFACE_CONSTANT,
152 "EffectSurfaceAdapter::OnBufferAvailable ReleaseBuffer surface not exist.");
153 CHECK_AND_RETURN_LOG(receiverConsumerSurface_,
154 "EffectSurfaceAdapter::OnBufferAvailable receiverConsumerSurface_ is nullptr.");
155 auto releaseBuffer = (isNeedSwap) ? outBuffer : inBuffer;
156 if (isNeedSwap) {
157 auto detRet = receiverConsumerSurface_->DetachBufferFromQueue(inBuffer);
158 CHECK_AND_RETURN_LOG(detRet == GSError::GSERROR_OK,
159 "EffectSurfaceAdapter::OnBufferAvailable: detach buffer from consumerSurface_ failed");
160 detRet = receiverConsumerSurface_->AttachBufferToQueue(outBuffer);
161 CHECK_AND_RETURN_LOG(detRet == GSError::GSERROR_OK,
162 "EffectSurfaceAdapter::OnBufferAvailable: attach buffer from consumerSurface_ failed");
163 }
164 (void)receiverConsumerSurface_->ReleaseBuffer(releaseBuffer, IE_INVALID_FENCE);
165 }
166
OnTunnelHandleChange()167 void EffectSurfaceAdapter::OnTunnelHandleChange() {}
OnGoBackground()168 void EffectSurfaceAdapter::OnGoBackground() {}
OnCleanCache()169 void EffectSurfaceAdapter::OnCleanCache() {}
170 }
171 }
172 }