Files
BPI-CM9-Linux/aml-comp/vendor/amlogic/meson_videoserver/BinderServer.cpp
T
2026-08-24 10:03:24 +08:00

232 lines
7.1 KiB
C++

/*
* Copyright (C) 2024 Amlogic Corporation.
*
* 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 "BinderServer.h"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "binderInfo.h"
BinderServer::BinderServer()
{
mSCallback = std::make_shared<ServerCallback>();
mServerFunc.emplace(CMD_SEND_CLIENT, &ServerCallback::registerCallback);
mServerFunc.emplace(CMD_CREATE_LAYER, &ServerCallback::createLayer);
mServerFunc.emplace(CMD_DESTROY_LAYER, &ServerCallback::destroyLayer);
mServerFunc.emplace(CMD_SET_TUNNEL_ID, &ServerCallback::setTunnelId);
mServerFunc.emplace(CMD_SET_LAYER_INDEX, &ServerCallback::setLayerIndex);
mServerFunc.emplace(CMD_SET_LAYER_ZORDER, &ServerCallback::setLayerZorder);
mServerFunc.emplace(CMD_SET_SOURCE_CROP, &ServerCallback::setSourceCrop);
mServerFunc.emplace(CMD_SET_DISPLAY_FRAME, &ServerCallback::setDisplayFrame);
mServerFunc.emplace(CMD_GET_DELAY_LATENCY, &ServerCallback::getDelayLatency);
mServerFunc.emplace(CMD_SET_MAIN_PLANE, &ServerCallback::setToMainPlane);
mServerFunc.emplace(CMD_GET_UI_SIZE, &ServerCallback::getUiSize);
}
void BinderServer::ServiceDeathRecipient::binderDied(const wp<IBinder>& who)
{
if (mCb != NULL)
mCb->removeClient(mClientId);
}
int BinderServer::ServerCallback::registerCallback(const Parcel& data, Parcel* reply)
{
sp<IBinder> binder = data.readStrongBinder();
int callingPid = IPCThreadState::self()->getCallingPid();
sp<ServiceDeathRecipient> deathRecip = new ServiceDeathRecipient(this, callingPid);
std::shared_ptr<compositorClient> client = std::make_shared<compositorClient>(mMesonCompositor);
if (binder != NULL)
binder->linkToDeath(deathRecip);
mClients.emplace(callingPid, std::make_pair(client, deathRecip));
mBinders.emplace(callingPid, binder);
return 0;
}
int BinderServer::ServerCallback::createLayer(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int32_t id = 0;
int ret;
int callingPid = IPCThreadState::self()->getCallingPid();
ret = mMesonCompositor->createLayer(displayId, &id);
if (!ret) {
auto client = mClients.find(callingPid);
if (client != mClients.end()) {
auto info = client->second;
auto [cc, deathRecipient] = info;
if (cc.get())
cc->addDisplay(displayId, id);
}
}
reply->writeInt32(id);
return ret;
}
int BinderServer::ServerCallback::destroyLayer(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
int callingPid = IPCThreadState::self()->getCallingPid();
auto client = mClients.find(callingPid);
if (client != mClients.end()) {
auto info = client->second;
auto [cc, deathRecipient] = info;
if (cc.get())
cc->removeDisplay(displayId, layerId);
}
return mMesonCompositor->destroyLayer(displayId, layerId);
}
int BinderServer::ServerCallback::setTunnelId(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
int tunnelId = data.readInt32();
return mMesonCompositor->setTunnelId(displayId, layerId, tunnelId);
}
int BinderServer::ServerCallback::setLayerIndex(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
int index = data.readInt32();
return mMesonCompositor->setLayerIndex(displayId, layerId, index);
}
int BinderServer::ServerCallback::setLayerZorder(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
int zorder = data.readInt32();
return mMesonCompositor->setLayerZorder(displayId, layerId, zorder);
}
int BinderServer::ServerCallback::setSourceCrop(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
struct rect crop = { 0 };
crop.x = data.readInt32();
crop.y = data.readInt32();
crop.w = data.readInt32();
crop.h = data.readInt32();
return mMesonCompositor->setSourceCrop(displayId, layerId, crop);
}
int BinderServer::ServerCallback::setDisplayFrame(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
struct rect frame = { 0 };
frame.x = data.readInt32();
frame.y = data.readInt32();
frame.w = data.readInt32();
frame.h = data.readInt32();
return mMesonCompositor->setDisplayFrame(displayId, layerId, frame);
}
int BinderServer::ServerCallback::getDelayLatency(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
int layerId = data.readInt32();
int latency;
latency = mMesonCompositor->getDelayLatency(displayId, layerId);
reply->writeInt32(latency);
return 0;
}
int BinderServer::ServerCallback::setToMainPlane(const Parcel& data, Parcel* reply)
{
int displayId = data.readInt32();
return mMesonCompositor->setToMainPlane(displayId);
}
int BinderServer::ServerCallback::getUiSize(const Parcel& data, Parcel* reply)
{
int32_t displayId = data.readInt32();
int32_t width = 0;
int32_t height = 0;
int ret;
ret = mMesonCompositor->getUiSize(displayId, &width, &height);
if (!ret && reply != NULL) {
reply->writeInt32(width);
reply->writeInt32(height);
}
return ret;
}
void BinderServer::ServerCallback::setMesonCompositor(std::shared_ptr<mesonVideoCompositor>& c)
{
mMesonCompositor = c;
}
void BinderServer::ServerCallback::removeClient(int clientId)
{
auto client = mClients.find(clientId);
if (client != mClients.end()) {
auto [cc, deathRecipient] = client->second;
if (cc.get()) cc.reset();
if (deathRecipient != NULL) deathRecipient.clear();
mClients.erase(client);
}
mBinders.erase(clientId);
}
status_t BinderServer::onTransact(uint32_t code,
const Parcel& data, Parcel* reply,
uint32_t flags) {
auto cb = mServerFunc.find(code);
if (cb == mServerFunc.end())
return BBinder::onTransact(code, data, reply, flags);
return (mSCallback.get()->*(cb->second))(data, reply);
}
void BinderServer::setMesonCompositor(std::shared_ptr<mesonVideoCompositor>& c)
{
if (mSCallback.get())
mSCallback->setMesonCompositor(c);
}
void BinderServer::run(std::shared_ptr<BinderServer> server)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> serviceManager = defaultServiceManager();
serviceManager->addService(String16("compositor-service"), server.get());
proc->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}