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