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 }