Files
graphic_surface_lite/frameworks/surface_impl.cpp
T
2021-03-11 18:45:14 +08:00

303 lines
8.3 KiB
C++
Executable File

/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "surface_impl.h"
#include <unistd.h>
#include "buffer_client_producer.h"
#include "buffer_common.h"
#include "buffer_manager.h"
#include "buffer_queue_consumer.h"
#include "buffer_queue_producer.h"
#include "surface_buffer_impl.h"
namespace OHOS {
SurfaceImpl::SurfaceImpl()
: consumer_(nullptr), producer_(nullptr), IsConsumer_(true)
{
sid_ = {
.handle = 0,
.token = 0
};
}
SurfaceImpl::SurfaceImpl(const SvcIdentity& sid)
: sid_(sid), consumer_(nullptr), producer_(nullptr), IsConsumer_(false)
{
}
SurfaceImpl::~SurfaceImpl()
{
if (consumer_ != nullptr) {
delete consumer_;
consumer_ = nullptr;
}
if (producer_ != nullptr) {
delete producer_;
producer_ = nullptr;
}
#ifdef __LINUX__
if (sid_.handle != 0) {
BinderRelease(sid_.ipcContext, sid_.handle);
}
#endif
}
bool SurfaceImpl::Init()
{
if (!BufferManager::GetInstance()->Init()) {
GRAPHIC_LOGE("Failed init buffer manager");
return false;
}
if (IsConsumer_) {
BufferQueue* bufferQueue = new BufferQueue();
if (bufferQueue == nullptr) {
GRAPHIC_LOGE("Surface consumer(buffer queue) init failed.");
return false;
}
if (!bufferQueue->Init()) {
GRAPHIC_LOGE("Buffer queue init failed.");
delete bufferQueue;
return false;
}
producer_ = new BufferQueueProducer(bufferQueue);
if (producer_ == nullptr) {
GRAPHIC_LOGE("Surface consumer(producer) init failed.");
delete bufferQueue;
return false;
}
consumer_ = new BufferQueueConsumer(*bufferQueue);
if (consumer_ == nullptr) {
GRAPHIC_LOGE("Surface consumer(consumer) init failed.");
delete producer_;
producer_ = nullptr;
return false;
}
SvcIdentity svc;
int32_t ret = RegisterIpcCallback(IpcRequestHandler, 0, IPC_WAIT_FOREVER, &svc, producer_);
if (ret != LITEIPC_OK) {
GRAPHIC_LOGE("Surface RegisterIpcCallback failed.");
delete consumer_;
consumer_ = nullptr;
delete producer_;
producer_ = nullptr;
return false;
}
sid_ = svc;
} else {
producer_ = new BufferClientProducer(sid_);
if (producer_ == nullptr) {
GRAPHIC_LOGE("Surface producer init failed.");
return false;
}
}
return true;
}
void SurfaceImpl::SetWidthAndHeight(uint32_t width, uint32_t height)
{
RETURN_IF_FAIL(producer_ != nullptr);
RETURN_IF_FAIL(width > 0 && width <= SURFACE_MAX_WIDTH);
RETURN_IF_FAIL(height > 0 && height <= SURFACE_MAX_HEIGHT);
producer_->SetWidthAndHeight(width, height);
}
uint32_t SurfaceImpl::GetWidth()
{
RETURN_VAL_IF_FAIL(producer_, 0);
return producer_->GetWidth();
}
uint32_t SurfaceImpl::GetHeight()
{
RETURN_VAL_IF_FAIL(producer_, 0);
return producer_->GetHeight();
}
void SurfaceImpl::SetFormat(uint32_t format)
{
RETURN_IF_FAIL(producer_);
producer_->SetFormat(format);
}
uint32_t SurfaceImpl::GetFormat()
{
RETURN_VAL_IF_FAIL(producer_, 0);
return producer_->GetFormat();
}
void SurfaceImpl::SetStrideAlignment(uint32_t strideAlignment)
{
RETURN_IF_FAIL(producer_);
RETURN_IF_FAIL(strideAlignment >= SURFACE_MIN_STRIDE_ALIGNMENT && strideAlignment <= SURFACE_MAX_STRIDE_ALIGNMENT);
producer_->SetStrideAlignment(strideAlignment);
}
uint32_t SurfaceImpl::GetStrideAlignment()
{
RETURN_VAL_IF_FAIL(producer_, 0);
return producer_->GetStrideAlignment();
}
uint32_t SurfaceImpl::GetStride()
{
RETURN_VAL_IF_FAIL(producer_, 0);
return producer_->GetStride();
}
void SurfaceImpl::SetSize(uint32_t size)
{
RETURN_IF_FAIL(producer_);
RETURN_IF_FAIL(size > 0 && size < SURFACE_MAX_SIZE);
producer_->SetSize(size);
}
uint32_t SurfaceImpl::GetSize()
{
RETURN_VAL_IF_FAIL(producer_, 0);
return producer_->GetSize();
}
void SurfaceImpl::SetUsage(uint32_t usage)
{
RETURN_IF_FAIL(producer_);
RETURN_IF_FAIL(usage < BUFFER_CONSUMER_USAGE_MAX);
producer_->SetUsage(usage);
}
uint32_t SurfaceImpl::GetUsage()
{
uint32_t usage = producer_->GetUsage();
return usage;
}
void SurfaceImpl::SetQueueSize(uint8_t queueSize)
{
RETURN_IF_FAIL(producer_);
RETURN_IF_FAIL(queueSize >= SURFACE_MIN_QUEUE_SIZE && queueSize <= SURFACE_MAX_QUEUE_SIZE);
producer_->SetQueueSize(queueSize);
}
uint8_t SurfaceImpl::GetQueueSize()
{
RETURN_VAL_IF_FAIL(producer_, SURFACE_ERROR_INVAILD_PARAM);
uint8_t queueSize = producer_->GetQueueSize();
return queueSize;
}
void SurfaceImpl::SetUserData(const std::string& key, const std::string& value)
{
RETURN_IF_FAIL(producer_ != nullptr);
producer_->SetUserData(key, value);
}
std::string SurfaceImpl::GetUserData(const std::string& key)
{
RETURN_VAL_IF_FAIL(producer_ != nullptr, std::string());
return producer_->GetUserData(key);
}
SurfaceBuffer* SurfaceImpl::RequestBuffer(uint8_t wait)
{
RETURN_VAL_IF_FAIL(producer_, nullptr);
return producer_->RequestBuffer(wait);
}
int32_t SurfaceImpl::FlushBuffer(SurfaceBuffer* buffer)
{
RETURN_VAL_IF_FAIL(producer_, SURFACE_ERROR_INVAILD_PARAM);
RETURN_VAL_IF_FAIL(buffer != nullptr, SURFACE_ERROR_INVAILD_PARAM);
SurfaceBufferImpl* liteBuffer = reinterpret_cast<SurfaceBufferImpl*>(buffer);
return producer_->FlushBuffer(liteBuffer);
}
SurfaceBuffer* SurfaceImpl::AcquireBuffer()
{
RETURN_VAL_IF_FAIL(consumer_, nullptr);
return consumer_->AcquireBuffer();
}
bool SurfaceImpl::ReleaseBuffer(SurfaceBuffer* buffer)
{
RETURN_VAL_IF_FAIL(consumer_, false);
SurfaceBufferImpl* liteBuffer = reinterpret_cast<SurfaceBufferImpl*>(buffer);
return consumer_->ReleaseBuffer(*liteBuffer);
}
void SurfaceImpl::CancelBuffer(SurfaceBuffer* buffer)
{
RETURN_IF_FAIL(producer_);
RETURN_IF_FAIL(buffer != nullptr);
SurfaceBufferImpl* liteBuffer = reinterpret_cast<SurfaceBufferImpl*>(buffer);
producer_->Cancel(liteBuffer);
}
void SurfaceImpl::RegisterConsumerListener(IBufferConsumerListener& listener)
{
RETURN_IF_FAIL(producer_);
BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer *>(producer_);
bufferQueueProducer->RegisterConsumerListener(listener);
}
void SurfaceImpl::UnregisterConsumerListener()
{
RETURN_IF_FAIL(producer_);
BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer *>(producer_);
bufferQueueProducer->UnregisterConsumerListener();
}
void SurfaceImpl::WriteIoIpcIo(IpcIo& io)
{
IpcIoPushSvc(&io, &sid_);
}
int32_t SurfaceImpl::IpcRequestHandler(const IpcContext* context, void* ipcMsg, IpcIo* io, void* arg)
{
BufferQueueProducer* product = (BufferQueueProducer*) arg;
return product->OnIpcMsg(ipcMsg, io);
}
int32_t SurfaceImpl::DoIpcMsg(void* ipcMsg, IpcIo* io)
{
RETURN_VAL_IF_FAIL(producer_, SURFACE_ERROR_INVAILD_PARAM);
RETURN_VAL_IF_FAIL(ipcMsg != nullptr, SURFACE_ERROR_INVAILD_PARAM);
RETURN_VAL_IF_FAIL(io != nullptr, SURFACE_ERROR_INVAILD_PARAM);
BufferQueueProducer* bufferQueueProducer = reinterpret_cast<BufferQueueProducer*>(producer_);
return bufferQueueProducer->OnIpcMsg(ipcMsg, io);
}
Surface* SurfaceImpl::GenericSurfaceByIpcIo(IpcIo& io)
{
SvcIdentity* sid = IpcIoPopSvc(&io);
if (sid != NULL) {
SurfaceImpl* surface = new SurfaceImpl(*sid);
#ifdef __LINUX__
BinderAcquire(sid->ipcContext, sid->handle);
free(sid);
sid = nullptr;
#endif
if (surface != nullptr) {
if (surface->Init()) {
return surface;
} else {
GRAPHIC_LOGE("surface init failed");
delete surface;
}
}
}
return nullptr;
}
} // namespace OHOS