/* * Copyright (c) 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 "buffer_queue_producer.h" #include #include #include #include "buffer_extra_data_impl.h" #include "buffer_log.h" #include "buffer_producer_listener.h" #include "buffer_utils.h" #include "frame_report.h" #include "sync_fence.h" #define BUFFER_PRODUCER_API_FUNC_PAIR(apiSequenceNum, func) \ {apiSequenceNum, [](BufferQueueProducer *that, MessageParcel &arguments, MessageParcel &reply, \ MessageOption &option){return that->func(arguments, reply, option);}} \ namespace OHOS { namespace { constexpr int32_t BUFFER_MATRIX_SIZE = 16; } // namespace BufferQueueProducer::BufferQueueProducer(sptr bufferQueue) : producerSurfaceDeathRecipient_(new ProducerSurfaceDeathRecipient(this)) { bufferQueue_ = std::move(bufferQueue); if (bufferQueue_ != nullptr) { bufferQueue_->GetName(name_); uniqueId_ = bufferQueue_->GetUniqueId(); } memberFuncMap_ = { BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_INIT_INFO, GetProducerInitInfoRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_REQUEST_BUFFER, RequestBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_REQUEST_BUFFERS, RequestBuffersRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_CANCEL_BUFFER, CancelBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_FLUSH_BUFFER, FlushBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_FLUSH_BUFFERS, FlushBuffersRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_ATTACH_BUFFER, AttachBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_DETACH_BUFFER, DetachBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_QUEUE_SIZE, GetQueueSizeRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_QUEUE_SIZE, SetQueueSizeRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_NAME, GetNameRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_DEFAULT_WIDTH, GetDefaultWidthRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_DEFAULT_HEIGHT, GetDefaultHeightRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_DEFAULT_USAGE, GetDefaultUsageRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_UNIQUE_ID, GetUniqueIdRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_CLEAN_CACHE, CleanCacheRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_REGISTER_RELEASE_LISTENER, RegisterReleaseListenerRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_TRANSFORM, SetTransformRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_IS_SUPPORTED_ALLOC, IsSupportedAllocRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_NAMEANDUNIQUEDID, GetNameAndUniqueIdRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_DISCONNECT, DisconnectRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_CONNECT, ConnectRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_SCALING_MODE, SetScalingModeRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_METADATA, SetMetaDataRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_METADATASET, SetMetaDataSetRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_TUNNEL_HANDLE, SetTunnelHandleRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GO_BACKGROUND, GoBackgroundRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_PRESENT_TIMESTAMP, GetPresentTimestampRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_UNREGISTER_RELEASE_LISTENER, UnRegisterReleaseListenerRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_LAST_FLUSHED_BUFFER, GetLastFlushedBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_TRANSFORM, GetTransformRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_ATTACH_BUFFER_TO_QUEUE, AttachBufferToQueueRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_DETACH_BUFFER_FROM_QUEUE, DetachBufferFromQueueRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_DEFAULT_USAGE, SetDefaultUsageRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_TRANSFORMHINT, GetTransformHintRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_TRANSFORMHINT, SetTransformHintRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_BUFFER_HOLD, SetBufferHoldRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_SCALING_MODEV2, SetScalingModeV2Remote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_SOURCE_TYPE, SetSurfaceSourceTypeRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_SOURCE_TYPE, GetSurfaceSourceTypeRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_SET_APP_FRAMEWORK_TYPE, SetSurfaceAppFrameworkTypeRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_GET_APP_FRAMEWORK_TYPE, GetSurfaceAppFrameworkTypeRemote), BUFFER_PRODUCER_API_FUNC_PAIR( BUFFER_PRODUCER_SET_HDRWHITEPOINTBRIGHTNESS, SetHdrWhitePointBrightnessRemote), BUFFER_PRODUCER_API_FUNC_PAIR( BUFFER_PRODUCER_SET_SDRWHITEPOINTBRIGHTNESS, SetSdrWhitePointBrightnessRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_ACQUIRE_LAST_FLUSHED_BUFFER, AcquireLastFlushedBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_RELEASE_LAST_FLUSHED_BUFFER, ReleaseLastFlushedBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_REQUEST_AND_DETACH_BUFFER, RequestAndDetachBufferRemote), BUFFER_PRODUCER_API_FUNC_PAIR(BUFFER_PRODUCER_ATTACH_AND_FLUSH_BUFFER, AttachAndFlushBufferRemote), }; } BufferQueueProducer::~BufferQueueProducer() { if (token_ && producerSurfaceDeathRecipient_) { token_->RemoveDeathRecipient(producerSurfaceDeathRecipient_); token_ = nullptr; } } GSError BufferQueueProducer::CheckConnectLocked() { if (connectedPid_ == 0) { BLOGW("no connections, uniqueId: %{public}" PRIu64 ".", uniqueId_); return SURFACE_ERROR_CONSUMER_DISCONNECTED; } if (connectedPid_ != GetCallingPid()) { BLOGW("connected by: %{public}d, uniqueId: %{public}" PRIu64 ".", connectedPid_, uniqueId_); return SURFACE_ERROR_CONSUMER_IS_CONNECTED; } return GSERROR_OK; } int32_t BufferQueueProducer::OnRemoteRequest(uint32_t code, MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { auto it = memberFuncMap_.find(code); if (it == memberFuncMap_.end()) { BLOGE("cannot process %{public}u", code); return 0; } if (it->second == nullptr) { BLOGE("memberFuncMap_[%{public}u] is nullptr", code); return 0; } auto remoteDescriptor = arguments.ReadInterfaceToken(); if (GetDescriptor() != remoteDescriptor) { return ERR_INVALID_STATE; } auto ret = it->second(this, arguments, reply, option); return ret; } int32_t BufferQueueProducer::RequestBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { RequestBufferReturnValue retval; sptr bedataimpl = new BufferExtraDataImpl; BufferRequestConfig config = {}; int64_t startTimeNs = 0; int64_t endTimeNs = 0; bool isActiveGame = Rosen::FrameReport::GetInstance().IsActiveGameWithPid(connectedPid_); if (isActiveGame) { startTimeNs = std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()).count(); } ReadRequestConfig(arguments, config); GSError sret = RequestBuffer(config, bedataimpl, retval); reply.WriteInt32(sret); if (sret == GSERROR_OK) { WriteSurfaceBufferImpl(reply, retval.sequence, retval.buffer); bedataimpl->WriteToParcel(reply); retval.fence->WriteToMessageParcel(reply); reply.WriteUInt32Vector(retval.deletingBuffers); } else { reply.WriteBool(retval.isConnected); } if (isActiveGame) { endTimeNs = std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()).count(); Rosen::FrameReport::GetInstance().SetDequeueBufferTime(name_, (endTimeNs - startTimeNs)); } return 0; } int32_t BufferQueueProducer::RequestBuffersRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::vector retvalues; std::vector> bedataimpls; BufferRequestConfig config = {}; uint32_t num = 0; arguments.ReadUint32(num); ReadRequestConfig(arguments, config); if (num == 0 || num > SURFACE_MAX_QUEUE_SIZE) { return 0; } retvalues.resize(num); bedataimpls.reserve(num); for (uint32_t i = 0; i < num; ++i) { sptr data = new BufferExtraDataImpl; bedataimpls.emplace_back(data); } GSError sret = RequestBuffers(config, bedataimpls, retvalues); reply.WriteInt32(sret); if (sret == GSERROR_OK || sret == GSERROR_NO_BUFFER) { num = static_cast(retvalues.size()); reply.WriteUint32(num); for (uint32_t i = 0; i < num; ++i) { WriteSurfaceBufferImpl(reply, retvalues[i].sequence, retvalues[i].buffer); bedataimpls[i]->WriteToParcel(reply); retvalues[i].fence->WriteToMessageParcel(reply); reply.WriteUInt32Vector(retvalues[i].deletingBuffers); } } else if (sret != GSERROR_OK) { reply.WriteBool(retvalues[0].isConnected); } return 0; } int32_t BufferQueueProducer::GetProducerInitInfoRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { ProducerInitInfo info; (void)GetProducerInitInfo(info); reply.WriteInt32(info.width); reply.WriteInt32(info.height); reply.WriteUint64(info.uniqueId); reply.WriteString(info.name); sptr token = arguments.ReadRemoteObject(); if (token == nullptr) { reply.WriteInt32(GSERROR_INVALID_ARGUMENTS); return GSERROR_INVALID_ARGUMENTS; } bool result = HandleDeathRecipient(token); reply.WriteInt32(result ? GSERROR_OK : SURFACE_ERROR_UNKOWN); return 0; } int32_t BufferQueueProducer::CancelBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence; sptr bedataimpl = new BufferExtraDataImpl; sequence = arguments.ReadUint32(); bedataimpl->ReadFromParcel(arguments); GSError sret = CancelBuffer(sequence, bedataimpl); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::FlushBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence; BufferFlushConfigWithDamages config; sptr bedataimpl = new BufferExtraDataImpl; int64_t startTimeNs = 0; int64_t endTimeNs = 0; bool isActiveGame = Rosen::FrameReport::GetInstance().IsActiveGameWithPid(connectedPid_); if (isActiveGame) { startTimeNs = std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()).count(); } sequence = arguments.ReadUint32(); bedataimpl->ReadFromParcel(arguments); sptr fence = SyncFence::ReadFromMessageParcel(arguments); ReadFlushConfig(arguments, config); GSError sret = FlushBuffer(sequence, bedataimpl, fence, config); reply.WriteInt32(sret); if (isActiveGame) { uint64_t uniqueId = GetUniqueId(); endTimeNs = std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()).count(); Rosen::FrameReport::GetInstance().SetQueueBufferTime(uniqueId, name_, (endTimeNs - startTimeNs)); Rosen::FrameReport::GetInstance().Report(name_); } return 0; } int32_t BufferQueueProducer::FlushBuffersRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::vector sequences; std::vector configs; std::vector> bedataimpls; std::vector> fences; arguments.ReadUInt32Vector(&sequences); if (sequences.size() == 0 || sequences.size() > SURFACE_MAX_QUEUE_SIZE) { return 0; } for (size_t i = 0; i < sequences.size(); ++i) { sptr bedataimpl = new BufferExtraDataImpl; bedataimpl->ReadFromParcel(arguments); bedataimpls.emplace_back(bedataimpl); sptr fence = SyncFence::ReadFromMessageParcel(arguments); fences.emplace_back(fence); BufferFlushConfigWithDamages config; ReadFlushConfig(arguments, config); configs.emplace_back(config); } GSError sret = FlushBuffers(sequences, bedataimpls, fences, configs); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetLastFlushedBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr buffer; sptr fence; float matrix[BUFFER_MATRIX_SIZE]; bool isUseNewMatrix = arguments.ReadBool(); GSError sret = GetLastFlushedBuffer(buffer, fence, matrix, isUseNewMatrix); reply.WriteInt32(sret); if (sret == GSERROR_OK) { uint32_t sequence = buffer->GetSeqNum(); WriteSurfaceBufferImpl(reply, sequence, buffer); buffer->WriteBufferRequestConfig(reply); fence->WriteToMessageParcel(reply); std::vector writeMatrixVector(matrix, matrix + sizeof(matrix) / sizeof(float)); reply.WriteFloatVector(writeMatrixVector); } return 0; } int32_t BufferQueueProducer::AttachBufferToQueueReadBuffer(MessageParcel &arguments, MessageParcel &reply, MessageOption &option, sptr &buffer) { uint32_t sequence; GSError sRet = ReadSurfaceBufferImpl(arguments, sequence, buffer); if (sRet != GSERROR_OK || buffer == nullptr) { reply.WriteInt32(SURFACE_ERROR_UNKOWN); return ERR_INVALID_DATA; } sRet = buffer->ReadBufferRequestConfig(arguments); if (sRet != GSERROR_OK) { reply.WriteInt32(SURFACE_ERROR_UNKOWN); return ERR_INVALID_DATA; } return ERR_NONE; } int32_t BufferQueueProducer::AttachBufferToQueueRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr buffer = nullptr; auto ret = AttachBufferToQueueReadBuffer(arguments, reply, option, buffer); if (ret != ERR_NONE) { return ret; } GSError sRet = AttachBufferToQueue(buffer); reply.WriteInt32(sRet); return ERR_NONE; } int32_t BufferQueueProducer::DetachBufferFromQueueRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr buffer = nullptr; uint32_t sequence; GSError ret = ReadSurfaceBufferImpl(arguments, sequence, buffer); if (ret != GSERROR_OK || buffer == nullptr) { reply.WriteInt32(SURFACE_ERROR_UNKOWN); return 0; } ret = DetachBufferFromQueue(buffer); reply.WriteInt32(ret); return 0; } int32_t BufferQueueProducer::AttachBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr buffer; uint32_t sequence; int32_t timeOut; GSError ret = ReadSurfaceBufferImpl(arguments, sequence, buffer); if (ret != GSERROR_OK || buffer == nullptr) { reply.WriteInt32(ret); return 0; } timeOut = arguments.ReadInt32(); ret = AttachBuffer(buffer, timeOut); reply.WriteInt32(ret); return 0; } int32_t BufferQueueProducer::DetachBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { return 0; } int32_t BufferQueueProducer::GetQueueSizeRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { reply.WriteInt32(GetQueueSize()); return 0; } int32_t BufferQueueProducer::SetQueueSizeRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t queueSize = arguments.ReadUint32(); GSError sret = SetQueueSize(queueSize); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetNameRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::string name; auto sret = bufferQueue_->GetName(name); reply.WriteInt32(sret); if (sret == GSERROR_OK) { reply.WriteString(name); } return 0; } int32_t BufferQueueProducer::GetNameAndUniqueIdRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::string name = "not init"; uint64_t uniqueId = 0; auto ret = GetNameAndUniqueId(name, uniqueId); reply.WriteInt32(ret); if (ret == GSERROR_OK) { reply.WriteString(name); reply.WriteUint64(uniqueId); } return 0; } int32_t BufferQueueProducer::GetDefaultWidthRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { reply.WriteInt32(GetDefaultWidth()); return 0; } int32_t BufferQueueProducer::GetDefaultHeightRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { reply.WriteInt32(GetDefaultHeight()); return 0; } int32_t BufferQueueProducer::SetDefaultUsageRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint64_t usage = arguments.ReadUint64(); GSError sret = SetDefaultUsage(usage); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetDefaultUsageRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { reply.WriteUint64(GetDefaultUsage()); return 0; } int32_t BufferQueueProducer::GetUniqueIdRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { reply.WriteUint64(GetUniqueId()); return 0; } int32_t BufferQueueProducer::CleanCacheRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { bool cleanAll = arguments.ReadBool(); reply.WriteInt32(CleanCache(cleanAll)); return 0; } int32_t BufferQueueProducer::GoBackgroundRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { reply.WriteInt32(GoBackground()); return 0; } int32_t BufferQueueProducer::RegisterReleaseListenerRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr listenerObject = arguments.ReadRemoteObject(); if (listenerObject == nullptr) { reply.WriteInt32(GSERROR_INVALID_ARGUMENTS); return GSERROR_INVALID_ARGUMENTS; } sptr listener = iface_cast(listenerObject); GSError sret = RegisterReleaseListener(listener); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::UnRegisterReleaseListenerRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GSError sret = UnRegisterReleaseListener(); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetTransformRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GraphicTransformType transform = static_cast(arguments.ReadUint32()); GSError sret = SetTransform(transform); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::IsSupportedAllocRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::vector infos; ReadVerifyAllocInfo(arguments, infos); std::vector supporteds; GSError sret = IsSupportedAlloc(infos, supporteds); reply.WriteInt32(sret); if (sret == GSERROR_OK) { reply.WriteBoolVector(supporteds); } return 0; } int32_t BufferQueueProducer::ConnectRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GSError sret = Connect(); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::DisconnectRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GSError sret = Disconnect(); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetScalingModeRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence = arguments.ReadUint32(); ScalingMode scalingMode = static_cast(arguments.ReadInt32()); GSError sret = SetScalingMode(sequence, scalingMode); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetScalingModeV2Remote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { ScalingMode scalingMode = static_cast(arguments.ReadInt32()); GSError sret = SetScalingMode(scalingMode); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetBufferHoldRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { bool hold = arguments.ReadBool(); GSError sret = SetBufferHold(hold); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetMetaDataRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence = arguments.ReadUint32(); std::vector metaData; ReadHDRMetaData(arguments, metaData); GSError sret = SetMetaData(sequence, metaData); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetMetaDataSetRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence = arguments.ReadUint32(); GraphicHDRMetadataKey key = static_cast(arguments.ReadUint32()); std::vector metaData; ReadHDRMetaDataSet(arguments, metaData); GSError sret = SetMetaDataSet(sequence, key, metaData); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetTunnelHandleRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr handle = nullptr; if (arguments.ReadBool()) { handle = new SurfaceTunnelHandle(); ReadExtDataHandle(arguments, handle); } GSError sret = SetTunnelHandle(handle); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetPresentTimestampRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence = arguments.ReadUint32(); GraphicPresentTimestampType type = static_cast(arguments.ReadUint32()); int64_t time = 0; GSError sret = GetPresentTimestamp(sequence, type, time); reply.WriteInt32(sret); if (sret == GSERROR_OK) { reply.WriteInt64(time); } return 0; } int32_t BufferQueueProducer::GetTransformRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GraphicTransformType transform = GraphicTransformType::GRAPHIC_ROTATE_BUTT; auto ret = GetTransform(transform); if (ret != GSERROR_OK) { reply.WriteInt32(static_cast(ret)); return -1; } reply.WriteInt32(GSERROR_OK); reply.WriteUint32(static_cast(transform)); return 0; } int32_t BufferQueueProducer::SetTransformHintRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GraphicTransformType transformHint = static_cast(arguments.ReadUint32()); GSError sret = SetTransformHint(transformHint); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetTransformHintRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { GraphicTransformType transformHint = GraphicTransformType::GRAPHIC_ROTATE_BUTT; auto ret = GetTransformHint(transformHint); if (ret != GSERROR_OK) { reply.WriteInt32(static_cast(ret)); return -1; } reply.WriteInt32(GSERROR_OK); reply.WriteUint32(static_cast(transformHint)); return 0; } int32_t BufferQueueProducer::SetSurfaceSourceTypeRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { OHSurfaceSource sourceType = static_cast(arguments.ReadUint32()); GSError sret = SetSurfaceSourceType(sourceType); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetSurfaceSourceTypeRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { OHSurfaceSource sourceType = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT; auto ret = GetSurfaceSourceType(sourceType); if (ret != GSERROR_OK) { reply.WriteInt32(static_cast(ret)); return -1; } reply.WriteInt32(GSERROR_OK); reply.WriteUint32(static_cast(sourceType)); return 0; } int32_t BufferQueueProducer::SetSurfaceAppFrameworkTypeRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::string appFrameworkType = arguments.ReadString(); GSError sret = SetSurfaceAppFrameworkType(appFrameworkType); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::GetSurfaceAppFrameworkTypeRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { std::string appFrameworkType = ""; auto ret = GetSurfaceAppFrameworkType(appFrameworkType); if (ret != GSERROR_OK) { reply.WriteInt32(static_cast(ret)); return -1; } reply.WriteInt32(GSERROR_OK); reply.WriteString(appFrameworkType); return 0; } int32_t BufferQueueProducer::SetHdrWhitePointBrightnessRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { float brightness = arguments.ReadFloat(); GSError sret = SetHdrWhitePointBrightness(brightness); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::SetSdrWhitePointBrightnessRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { float brightness = arguments.ReadFloat(); GSError sret = SetSdrWhitePointBrightness(brightness); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::AcquireLastFlushedBufferRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr buffer; sptr fence; float matrix[BUFFER_MATRIX_SIZE]; bool isUseNewMatrix = arguments.ReadBool(); GSError sret = AcquireLastFlushedBuffer(buffer, fence, matrix, BUFFER_MATRIX_SIZE, isUseNewMatrix); reply.WriteInt32(sret); if (sret == GSERROR_OK) { uint32_t sequence = buffer->GetSeqNum(); WriteSurfaceBufferImpl(reply, sequence, buffer); buffer->WriteBufferRequestConfig(reply); fence->WriteToMessageParcel(reply); std::vector writeMatrixVector(matrix, matrix + sizeof(matrix) / sizeof(float)); reply.WriteFloatVector(writeMatrixVector); } return 0; } int32_t BufferQueueProducer::ReleaseLastFlushedBufferRemote( MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { uint32_t sequence = arguments.ReadUint32(); GSError sret = ReleaseLastFlushedBuffer(sequence); reply.WriteInt32(sret); return 0; } int32_t BufferQueueProducer::RequestAndDetachBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { RequestBufferReturnValue retval; sptr bedataimpl = new BufferExtraDataImpl; BufferRequestConfig config = {}; ReadRequestConfig(arguments, config); GSError sRet = RequestAndDetachBuffer(config, bedataimpl, retval); if (!reply.WriteInt32(sRet)) { return IPC_STUB_WRITE_PARCEL_ERR; } if (sRet == GSERROR_OK) { WriteSurfaceBufferImpl(reply, retval.sequence, retval.buffer); bedataimpl->WriteToParcel(reply); retval.fence->WriteToMessageParcel(reply); reply.WriteUInt32Vector(retval.deletingBuffers); } else { reply.WriteBool(retval.isConnected); } return ERR_NONE; } int32_t BufferQueueProducer::AttachAndFlushBufferRemote(MessageParcel &arguments, MessageParcel &reply, MessageOption &option) { sptr buffer = nullptr; auto ret = AttachBufferToQueueReadBuffer(arguments, reply, option, buffer); if (ret != ERR_NONE) { return ret; } BufferFlushConfigWithDamages config; sptr bedataimpl = new BufferExtraDataImpl; bedataimpl->ReadFromParcel(arguments); sptr fence = SyncFence::ReadFromMessageParcel(arguments); ReadFlushConfig(arguments, config); bool needMap = arguments.ReadBool(); GSError sRet = AttachAndFlushBuffer(buffer, bedataimpl, fence, config, needMap); reply.WriteInt32(sRet); return ERR_NONE; } GSError BufferQueueProducer::RequestAndDetachBuffer(const BufferRequestConfig& config, sptr& bedata, RequestBufferReturnValue& retval) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } retval.isConnected = false; auto ret = Connect(); if (ret != SURFACE_ERROR_OK) { return ret; } retval.isConnected = true; return bufferQueue_->RequestAndDetachBuffer(config, bedata, retval); } GSError BufferQueueProducer::AttachAndFlushBuffer(sptr& buffer, sptr& bedata, const sptr& fence, BufferFlushConfigWithDamages& config, bool needMap) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->AttachAndFlushBuffer(buffer, bedata, fence, config, needMap); } GSError BufferQueueProducer::AcquireLastFlushedBuffer(sptr &buffer, sptr &fence, float matrix[16], uint32_t matrixSize, bool isUseNewMatrix) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->AcquireLastFlushedBuffer(buffer, fence, matrix, matrixSize, isUseNewMatrix); } GSError BufferQueueProducer::ReleaseLastFlushedBuffer(uint32_t sequence) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->ReleaseLastFlushedBuffer(sequence); } GSError BufferQueueProducer::RequestBuffer(const BufferRequestConfig &config, sptr &bedata, RequestBufferReturnValue &retval) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } retval.isConnected = false; auto ret = Connect(); if (ret != SURFACE_ERROR_OK) { return ret; } retval.isConnected = true; return bufferQueue_->RequestBuffer(config, bedata, retval); } GSError BufferQueueProducer::RequestBuffers(const BufferRequestConfig &config, std::vector> &bedata, std::vector &retvalues) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } retvalues[0].isConnected = false; auto ret = Connect(); if (ret != SURFACE_ERROR_OK) { return ret; } bufferQueue_->SetBatchHandle(true); for (size_t i = 0; i < retvalues.size(); ++i) { ret = bufferQueue_->RequestBuffer(config, bedata[i], retvalues[i]); if (ret != GSERROR_OK) { retvalues.resize(i); break; } } bufferQueue_->SetBatchHandle(false); if (retvalues.size() == 0) { retvalues.resize(1); retvalues[0].isConnected = true; return ret; } return GSERROR_OK; } GSError BufferQueueProducer::GetProducerInitInfo(ProducerInitInfo &info) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->GetProducerInitInfo(info); } GSError BufferQueueProducer::CancelBuffer(uint32_t sequence, sptr bedata) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->CancelBuffer(sequence, bedata); } GSError BufferQueueProducer::FlushBuffer(uint32_t sequence, sptr bedata, sptr fence, BufferFlushConfigWithDamages &config) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->FlushBuffer(sequence, bedata, fence, config); } GSError BufferQueueProducer::FlushBuffers(const std::vector &sequences, const std::vector> &bedata, const std::vector> &fences, const std::vector &configs) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } GSError ret; for (size_t i = 0; i < sequences.size(); ++i) { ret = bufferQueue_->FlushBuffer(sequences[i], bedata[i], fences[i], configs[i]); if (ret != GSERROR_OK) { BLOGE("FlushBuffer failed: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_); return ret; } } return ret; } GSError BufferQueueProducer::GetLastFlushedBuffer(sptr& buffer, sptr& fence, float matrix[16], bool isUseNewMatrix) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->GetLastFlushedBuffer(buffer, fence, matrix, BUFFER_MATRIX_SIZE, isUseNewMatrix); } GSError BufferQueueProducer::AttachBufferToQueue(sptr buffer) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->AttachBufferToQueue(buffer, InvokerType::PRODUCER_INVOKER); } GSError BufferQueueProducer::DetachBufferFromQueue(sptr buffer) { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->DetachBufferFromQueue(buffer, InvokerType::PRODUCER_INVOKER); } GSError BufferQueueProducer::AttachBuffer(sptr& buffer) { int32_t timeOut = 0; return AttachBuffer(buffer, timeOut); } GSError BufferQueueProducer::AttachBuffer(sptr& buffer, int32_t timeOut) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->AttachBuffer(buffer, timeOut); } GSError BufferQueueProducer::DetachBuffer(sptr& buffer) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->DetachBuffer(buffer); } uint32_t BufferQueueProducer::GetQueueSize() { if (bufferQueue_ == nullptr) { return 0; } return bufferQueue_->GetQueueSize(); } GSError BufferQueueProducer::SetQueueSize(uint32_t queueSize) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetQueueSize(queueSize); } GSError BufferQueueProducer::GetName(std::string &name) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->GetName(name); } int32_t BufferQueueProducer::GetDefaultWidth() { if (bufferQueue_ == nullptr) { return 0; } return bufferQueue_->GetDefaultWidth(); } int32_t BufferQueueProducer::GetDefaultHeight() { if (bufferQueue_ == nullptr) { return 0; } return bufferQueue_->GetDefaultHeight(); } GSError BufferQueueProducer::SetDefaultUsage(uint64_t usage) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetDefaultUsage(usage); } uint64_t BufferQueueProducer::GetDefaultUsage() { if (bufferQueue_ == nullptr) { return 0; } return bufferQueue_->GetDefaultUsage(); } uint64_t BufferQueueProducer::GetUniqueId() { if (bufferQueue_ == nullptr) { return 0; } return bufferQueue_->GetUniqueId(); } GSError BufferQueueProducer::CleanCache(bool cleanAll) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } { std::lock_guard lock(mutex_); auto ret = CheckConnectLocked(); if (ret != GSERROR_OK) { return ret; } } return bufferQueue_->CleanCache(cleanAll); } GSError BufferQueueProducer::GoBackground() { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } { std::lock_guard lock(mutex_); auto ret = CheckConnectLocked(); if (ret != GSERROR_OK) { return ret; } } return bufferQueue_->SetProducerCacheCleanFlag(true); } GSError BufferQueueProducer::RegisterReleaseListener(sptr listener) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->RegisterProducerReleaseListener(listener); } GSError BufferQueueProducer::UnRegisterReleaseListener() { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->UnRegisterProducerReleaseListener(); } bool BufferQueueProducer::HandleDeathRecipient(sptr token) { std::lock_guard lock(mutex_); if (token_ != nullptr) { token_->RemoveDeathRecipient(producerSurfaceDeathRecipient_); } token_ = token; return token_->AddDeathRecipient(producerSurfaceDeathRecipient_); } GSError BufferQueueProducer::SetTransform(GraphicTransformType transform) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetTransform(transform); } GSError BufferQueueProducer::GetTransform(GraphicTransformType &transform) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { transform = GraphicTransformType::GRAPHIC_ROTATE_BUTT; return GSERROR_INVALID_ARGUMENTS; } transform = bufferQueue_->GetTransform(); return GSERROR_OK; } GSError BufferQueueProducer::SetTransformHint(GraphicTransformType transformHint) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetTransformHint(transformHint); } GSError BufferQueueProducer::GetTransformHint(GraphicTransformType &transformHint) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { transformHint = GraphicTransformType::GRAPHIC_ROTATE_BUTT; return GSERROR_INVALID_ARGUMENTS; } transformHint = bufferQueue_->GetTransformHint(); return GSERROR_OK; } GSError BufferQueueProducer::SetSurfaceSourceType(OHSurfaceSource sourceType) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetSurfaceSourceType(sourceType); } GSError BufferQueueProducer::GetSurfaceSourceType(OHSurfaceSource &sourceType) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { sourceType = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT; return GSERROR_INVALID_ARGUMENTS; } sourceType = bufferQueue_->GetSurfaceSourceType(); return GSERROR_OK; } GSError BufferQueueProducer::SetSurfaceAppFrameworkType(std::string appFrameworkType) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetSurfaceAppFrameworkType(appFrameworkType); } GSError BufferQueueProducer::GetSurfaceAppFrameworkType(std::string &appFrameworkType) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { appFrameworkType = ""; return GSERROR_INVALID_ARGUMENTS; } appFrameworkType = bufferQueue_->GetSurfaceAppFrameworkType(); return GSERROR_OK; } GSError BufferQueueProducer::SetHdrWhitePointBrightness(float brightness) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->SetHdrWhitePointBrightness(brightness); } GSError BufferQueueProducer::SetSdrWhitePointBrightness(float brightness) { std::lock_guard lock(mutex_); if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } return bufferQueue_->SetSdrWhitePointBrightness(brightness); } GSError BufferQueueProducer::IsSupportedAlloc(const std::vector &infos, std::vector &supporteds) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->IsSupportedAlloc(infos, supporteds); } GSError BufferQueueProducer::GetNameAndUniqueId(std::string& name, uint64_t& uniqueId) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } uniqueId = GetUniqueId(); return GetName(name); } GSError BufferQueueProducer::Connect() { std::lock_guard lock(mutex_); auto callingPid = GetCallingPid(); if (connectedPid_ != 0 && connectedPid_ != callingPid) { BLOGW("connected by: %{public}d, request by: %{public}d , uniqueId: %{public}" PRIu64 ".", connectedPid_, callingPid, uniqueId_); return SURFACE_ERROR_CONSUMER_IS_CONNECTED; } connectedPid_ = callingPid; return SURFACE_ERROR_OK; } GSError BufferQueueProducer::Disconnect() { if (bufferQueue_ == nullptr) { return SURFACE_ERROR_UNKOWN; } { std::lock_guard lock(mutex_); auto ret = CheckConnectLocked(); if (ret != GSERROR_OK) { return ret; } connectedPid_ = 0; } return bufferQueue_->CleanCache(false); } GSError BufferQueueProducer::SetScalingMode(uint32_t sequence, ScalingMode scalingMode) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetScalingMode(sequence, scalingMode); } GSError BufferQueueProducer::SetScalingMode(ScalingMode scalingMode) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetScalingMode(scalingMode); } GSError BufferQueueProducer::SetBufferHold(bool hold) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetBufferHold(hold); } GSError BufferQueueProducer::SetMetaData(uint32_t sequence, const std::vector &metaData) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetMetaData(sequence, metaData); } GSError BufferQueueProducer::SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key, const std::vector &metaData) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetMetaDataSet(sequence, key, metaData); } GSError BufferQueueProducer::SetTunnelHandle(const sptr &handle) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->SetTunnelHandle(handle); } GSError BufferQueueProducer::SetTunnelHandle(const GraphicExtDataHandle *handle) { sptr tunnelHandle = new SurfaceTunnelHandle(); if (tunnelHandle->SetHandle(handle) != GSERROR_OK) { return GSERROR_INVALID_OPERATING; } return bufferQueue_->SetTunnelHandle(tunnelHandle); } GSError BufferQueueProducer::GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type, int64_t &time) { if (bufferQueue_ == nullptr) { return GSERROR_INVALID_ARGUMENTS; } return bufferQueue_->GetPresentTimestamp(sequence, type, time); } bool BufferQueueProducer::GetStatus() const { if (bufferQueue_ == nullptr) { return false; } return bufferQueue_->GetStatus(); } void BufferQueueProducer::SetStatus(bool status) { if (bufferQueue_ == nullptr) { return; } bufferQueue_->SetStatus(status); } sptr BufferQueueProducer::GetNativeSurface() { return nullptr; } void BufferQueueProducer::OnBufferProducerRemoteDied() { if (bufferQueue_ == nullptr) { return; } { std::lock_guard lock(mutex_); if (connectedPid_ == 0) { BLOGD("no connections, uniqueId: %{public}" PRIu64 ".", uniqueId_); return; } connectedPid_ = 0; } bufferQueue_->CleanCache(false); } BufferQueueProducer::ProducerSurfaceDeathRecipient::ProducerSurfaceDeathRecipient( wptr producer) : producer_(producer) { } void BufferQueueProducer::ProducerSurfaceDeathRecipient::OnRemoteDied(const wptr& remoteObject) { auto remoteToken = remoteObject.promote(); if (remoteToken == nullptr) { BLOGW("can't promote remote object."); return; } auto producer = producer_.promote(); if (producer == nullptr) { BLOGD("producer is nullptr"); return; } if (producer->token_ != remoteToken) { BLOGD("token doesn't match, ignore it, uniqueId: %{public}" PRIu64 ".", producer->GetUniqueId()); return; } BLOGD("remote object died, uniqueId: %{public}" PRIu64 ".", producer->GetUniqueId()); producer->OnBufferProducerRemoteDied(); } }; // namespace OHOS