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 24namespace OHOS { 25SurfaceImpl::SurfaceImpl() 26 : consumer_(nullptr), producer_(nullptr), IsConsumer_(true) 27{ 28 sid_ = { 29 .handle = 0, 30 .token = 0 31 }; 32} 33 34SurfaceImpl::SurfaceImpl(const SvcIdentity& sid) 35 : sid_(sid), consumer_(nullptr), producer_(nullptr), IsConsumer_(false) 36{ 37} 38 39SurfaceImpl::~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 54bool 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 102void 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 110uint32_t SurfaceImpl::GetWidth() 111{ 112 RETURN_VAL_IF_FAIL(producer_, 0); 113 return producer_->GetWidth(); 114} 115 116uint32_t SurfaceImpl::GetHeight() 117{ 118 RETURN_VAL_IF_FAIL(producer_, 0); 119 return producer_->GetHeight(); 120} 121 122void SurfaceImpl::SetFormat(uint32_t format) 123{ 124 RETURN_IF_FAIL(producer_); 125 producer_->SetFormat(format); 126} 127 128uint32_t SurfaceImpl::GetFormat() 129{ 130 RETURN_VAL_IF_FAIL(producer_, 0); 131 return producer_->GetFormat(); 132} 133 134void 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 141uint32_t SurfaceImpl::GetStrideAlignment() 142{ 143 RETURN_VAL_IF_FAIL(producer_, 0); 144 return producer_->GetStrideAlignment(); 145} 146 147uint32_t SurfaceImpl::GetStride() 148{ 149 RETURN_VAL_IF_FAIL(producer_, 0); 150 return producer_->GetStride(); 151} 152 153void 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 160uint32_t SurfaceImpl::GetSize() 161{ 162 RETURN_VAL_IF_FAIL(producer_, 0); 163 return producer_->GetSize(); 164} 165 166void 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 173uint32_t SurfaceImpl::GetUsage() 174{ 175 uint32_t usage = producer_->GetUsage(); 176 return usage; 177} 178 179void 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 186uint8_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 193void SurfaceImpl::SetUserData(const std::string& key, const std::string& value) 194{ 195 RETURN_IF_FAIL(producer_ != nullptr); 196 producer_->SetUserData(key, value); 197} 198 199std::string SurfaceImpl::GetUserData(const std::string& key) 200{ 201 RETURN_VAL_IF_FAIL(producer_ != nullptr, std::string()); 202 return producer_->GetUserData(key); 203} 204 205SurfaceBuffer* SurfaceImpl::RequestBuffer(uint8_t wait) 206{ 207 RETURN_VAL_IF_FAIL(producer_, nullptr); 208 return producer_->RequestBuffer(wait); 209} 210 211int32_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 219SurfaceBuffer* SurfaceImpl::AcquireBuffer() 220{ 221 RETURN_VAL_IF_FAIL(consumer_, nullptr); 222 return consumer_->AcquireBuffer(); 223} 224 225bool 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 232void 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 240void SurfaceImpl::RegisterConsumerListener(IBufferConsumerListener& listener) 241{ 242 RETURN_IF_FAIL(producer_); 243 BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer *>(producer_); 244 bufferQueueProducer->RegisterConsumerListener(listener); 245} 246 247void SurfaceImpl::UnregisterConsumerListener() 248{ 249 RETURN_IF_FAIL(producer_); 250 BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer *>(producer_); 251 bufferQueueProducer->UnregisterConsumerListener(); 252} 253 254void SurfaceImpl::WriteIoIpcIo(IpcIo& io) 255{ 256 WriteRemoteObject(&io, &sid_); 257} 258 259int32_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 265int32_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 273Surface* 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