1 /*
2 * Copyright (c) 2020-2022 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 #include "surface_impl.h"
16 #include <unistd.h>
17 #include "buffer_client_producer.h"
18 #include "buffer_common.h"
19 #include "buffer_manager.h"
20 #include "buffer_queue_consumer.h"
21 #include "buffer_queue_producer.h"
22 #include "surface_buffer_impl.h"
23
24 namespace OHOS {
SurfaceImpl()25 SurfaceImpl::SurfaceImpl()
26 : consumer_(nullptr), producer_(nullptr), IsConsumer_(true)
27 {
28 sid_ = {
29 .handle = 0,
30 .token = 0
31 };
32 }
33
SurfaceImpl(const SvcIdentity & sid)34 SurfaceImpl::SurfaceImpl(const SvcIdentity& sid)
35 : sid_(sid), consumer_(nullptr), producer_(nullptr), IsConsumer_(false)
36 {
37 }
38
~SurfaceImpl()39 SurfaceImpl::~SurfaceImpl()
40 {
41 if (consumer_ != nullptr) {
42 delete consumer_;
43 consumer_ = nullptr;
44 }
45 if (producer_ != nullptr) {
46 delete producer_;
47 producer_ = nullptr;
48 }
49 if (sid_.handle != 0) {
50 ReleaseSvc(sid_);
51 }
52 }
53
Init()54 bool SurfaceImpl::Init()
55 {
56 if (!BufferManager::GetInstance()->Init()) {
57 GRAPHIC_LOGE("Failed init buffer manager");
58 return false;
59 }
60 if (IsConsumer_) {
61 BufferQueue* bufferQueue = new BufferQueue();
62 if (bufferQueue == nullptr) {
63 GRAPHIC_LOGE("Surface consumer(buffer queue) init failed.");
64 return false;
65 }
66
67 if (!bufferQueue->Init()) {
68 GRAPHIC_LOGE("Buffer queue init failed.");
69 delete bufferQueue;
70 return false;
71 }
72
73 producer_ = new BufferQueueProducer(bufferQueue);
74 if (producer_ == nullptr) {
75 GRAPHIC_LOGE("Surface consumer(producer) init failed.");
76 delete bufferQueue;
77 return false;
78 }
79 consumer_ = new BufferQueueConsumer(*bufferQueue);
80 if (consumer_ == nullptr) {
81 GRAPHIC_LOGE("Surface consumer(consumer) init failed.");
82 delete producer_;
83 producer_ = nullptr;
84 return false;
85 }
86 objectStub_.func = IpcRequestHandler;
87 objectStub_.args = reinterpret_cast<void*>(producer_);
88 objectStub_.isRemote = false;
89 sid_.handle = IPC_INVALID_HANDLE;
90 sid_.token = SERVICE_TYPE_ANONYMOUS;
91 sid_.cookie = reinterpret_cast<uintptr_t>(&objectStub_);
92 } else {
93 producer_ = new BufferClientProducer(sid_);
94 if (producer_ == nullptr) {
95 GRAPHIC_LOGE("Surface producer init failed.");
96 return false;
97 }
98 }
99 return true;
100 }
101
SetWidthAndHeight(uint32_t width,uint32_t height)102 void SurfaceImpl::SetWidthAndHeight(uint32_t width, uint32_t height)
103 {
104 RETURN_IF_FAIL(producer_ != nullptr);
105 RETURN_IF_FAIL(width > 0 && width <= SURFACE_MAX_WIDTH);
106 RETURN_IF_FAIL(height > 0 && height <= SURFACE_MAX_HEIGHT);
107 producer_->SetWidthAndHeight(width, height);
108 }
109
GetWidth()110 uint32_t SurfaceImpl::GetWidth()
111 {
112 RETURN_VAL_IF_FAIL(producer_, 0);
113 return producer_->GetWidth();
114 }
115
GetHeight()116 uint32_t SurfaceImpl::GetHeight()
117 {
118 RETURN_VAL_IF_FAIL(producer_, 0);
119 return producer_->GetHeight();
120 }
121
SetFormat(uint32_t format)122 void SurfaceImpl::SetFormat(uint32_t format)
123 {
124 RETURN_IF_FAIL(producer_);
125 producer_->SetFormat(format);
126 }
127
GetFormat()128 uint32_t SurfaceImpl::GetFormat()
129 {
130 RETURN_VAL_IF_FAIL(producer_, 0);
131 return producer_->GetFormat();
132 }
133
SetStrideAlignment(uint32_t strideAlignment)134 void SurfaceImpl::SetStrideAlignment(uint32_t strideAlignment)
135 {
136 RETURN_IF_FAIL(producer_);
137 RETURN_IF_FAIL(strideAlignment >= SURFACE_MIN_STRIDE_ALIGNMENT && strideAlignment <= SURFACE_MAX_STRIDE_ALIGNMENT);
138 producer_->SetStrideAlignment(strideAlignment);
139 }
140
GetStrideAlignment()141 uint32_t SurfaceImpl::GetStrideAlignment()
142 {
143 RETURN_VAL_IF_FAIL(producer_, 0);
144 return producer_->GetStrideAlignment();
145 }
146
GetStride()147 uint32_t SurfaceImpl::GetStride()
148 {
149 RETURN_VAL_IF_FAIL(producer_, 0);
150 return producer_->GetStride();
151 }
152
SetSize(uint32_t size)153 void SurfaceImpl::SetSize(uint32_t size)
154 {
155 RETURN_IF_FAIL(producer_);
156 RETURN_IF_FAIL(size > 0 && size < SURFACE_MAX_SIZE);
157 producer_->SetSize(size);
158 }
159
GetSize()160 uint32_t SurfaceImpl::GetSize()
161 {
162 RETURN_VAL_IF_FAIL(producer_, 0);
163 return producer_->GetSize();
164 }
165
SetUsage(uint32_t usage)166 void SurfaceImpl::SetUsage(uint32_t usage)
167 {
168 RETURN_IF_FAIL(producer_);
169 RETURN_IF_FAIL(usage < BUFFER_CONSUMER_USAGE_MAX);
170 producer_->SetUsage(usage);
171 }
172
GetUsage()173 uint32_t SurfaceImpl::GetUsage()
174 {
175 uint32_t usage = producer_->GetUsage();
176 return usage;
177 }
178
SetQueueSize(uint8_t queueSize)179 void SurfaceImpl::SetQueueSize(uint8_t queueSize)
180 {
181 RETURN_IF_FAIL(producer_);
182 RETURN_IF_FAIL(queueSize >= SURFACE_MIN_QUEUE_SIZE && queueSize <= SURFACE_MAX_QUEUE_SIZE);
183 producer_->SetQueueSize(queueSize);
184 }
185
GetQueueSize()186 uint8_t SurfaceImpl::GetQueueSize()
187 {
188 RETURN_VAL_IF_FAIL(producer_, SURFACE_ERROR_INVALID_PARAM);
189 uint8_t queueSize = producer_->GetQueueSize();
190 return queueSize;
191 }
192
SetUserData(const std::string & key,const std::string & value)193 void SurfaceImpl::SetUserData(const std::string& key, const std::string& value)
194 {
195 RETURN_IF_FAIL(producer_ != nullptr);
196 producer_->SetUserData(key, value);
197 }
198
GetUserData(const std::string & key)199 std::string SurfaceImpl::GetUserData(const std::string& key)
200 {
201 RETURN_VAL_IF_FAIL(producer_ != nullptr, std::string());
202 return producer_->GetUserData(key);
203 }
204
RequestBuffer(uint8_t wait)205 SurfaceBuffer* SurfaceImpl::RequestBuffer(uint8_t wait)
206 {
207 RETURN_VAL_IF_FAIL(producer_, nullptr);
208 return producer_->RequestBuffer(wait);
209 }
210
FlushBuffer(SurfaceBuffer * buffer)211 int32_t SurfaceImpl::FlushBuffer(SurfaceBuffer* buffer)
212 {
213 RETURN_VAL_IF_FAIL(producer_, SURFACE_ERROR_INVALID_PARAM);
214 RETURN_VAL_IF_FAIL(buffer != nullptr, SURFACE_ERROR_INVALID_PARAM);
215 SurfaceBufferImpl* liteBuffer = reinterpret_cast<SurfaceBufferImpl*>(buffer);
216 return producer_->FlushBuffer(liteBuffer);
217 }
218
AcquireBuffer()219 SurfaceBuffer* SurfaceImpl::AcquireBuffer()
220 {
221 RETURN_VAL_IF_FAIL(consumer_, nullptr);
222 return consumer_->AcquireBuffer();
223 }
224
ReleaseBuffer(SurfaceBuffer * buffer)225 bool SurfaceImpl::ReleaseBuffer(SurfaceBuffer* buffer)
226 {
227 RETURN_VAL_IF_FAIL(consumer_, false);
228 SurfaceBufferImpl* liteBuffer = reinterpret_cast<SurfaceBufferImpl*>(buffer);
229 return consumer_->ReleaseBuffer(*liteBuffer);
230 }
231
CancelBuffer(SurfaceBuffer * buffer)232 void SurfaceImpl::CancelBuffer(SurfaceBuffer* buffer)
233 {
234 RETURN_IF_FAIL(producer_);
235 RETURN_IF_FAIL(buffer != nullptr);
236 SurfaceBufferImpl* liteBuffer = reinterpret_cast<SurfaceBufferImpl*>(buffer);
237 producer_->Cancel(liteBuffer);
238 }
239
RegisterConsumerListener(IBufferConsumerListener & listener)240 void SurfaceImpl::RegisterConsumerListener(IBufferConsumerListener& listener)
241 {
242 RETURN_IF_FAIL(producer_);
243 BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer *>(producer_);
244 bufferQueueProducer->RegisterConsumerListener(listener);
245 }
246
UnregisterConsumerListener()247 void SurfaceImpl::UnregisterConsumerListener()
248 {
249 RETURN_IF_FAIL(producer_);
250 BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer *>(producer_);
251 bufferQueueProducer->UnregisterConsumerListener();
252 }
253
WriteIoIpcIo(IpcIo & io)254 void SurfaceImpl::WriteIoIpcIo(IpcIo& io)
255 {
256 WriteRemoteObject(&io, &sid_);
257 }
258
IpcRequestHandler(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)259 int32_t SurfaceImpl::IpcRequestHandler(uint32_t code, IpcIo* data, IpcIo* reply, MessageOption option)
260 {
261 BufferQueueProducer* product = reinterpret_cast<BufferQueueProducer*>(option.args);
262 return product->OnIpcMsg(code, data, reply, option);
263 }
264
DoIpcMsg(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)265 int32_t SurfaceImpl::DoIpcMsg(uint32_t code, IpcIo* data, IpcIo* reply, MessageOption option)
266 {
267 RETURN_VAL_IF_FAIL(producer_, SURFACE_ERROR_INVALID_PARAM);
268 RETURN_VAL_IF_FAIL(data != nullptr, SURFACE_ERROR_INVALID_PARAM);
269 BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer*>(producer_);
270 return bufferQueueProducer->OnIpcMsg(code, data, reply, option);
271 }
272
GenericSurfaceByIpcIo(IpcIo & io)273 Surface* SurfaceImpl::GenericSurfaceByIpcIo(IpcIo& io)
274 {
275 SvcIdentity sid;
276 bool ret = ReadRemoteObject(&io, &sid);
277 if (ret) {
278 SurfaceImpl* surface = new SurfaceImpl(sid);
279 if (surface != nullptr) {
280 if (surface->Init()) {
281 return reinterpret_cast<Surface *>(surface);
282 } else {
283 GRAPHIC_LOGE("surface init failed");
284 delete surface;
285 }
286 }
287 }
288 return nullptr;
289 }
290 } // namespace OHOS
291