xref: /aosp_15_r20/external/mesa3d/src/gfxstream/guest/connection-manager/GfxStreamConnectionManager.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2024 Google LLC
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #include "GfxStreamConnectionManager.h"
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include <cerrno>
9*61046927SAndroid Build Coastguard Worker 
10*61046927SAndroid Build Coastguard Worker #include "GoldfishAddressSpaceStream.h"
11*61046927SAndroid Build Coastguard Worker #include "QemuPipeStream.h"
12*61046927SAndroid Build Coastguard Worker #include "VirtGpu.h"
13*61046927SAndroid Build Coastguard Worker #include "VirtioGpuAddressSpaceStream.h"
14*61046927SAndroid Build Coastguard Worker #include "VirtioGpuPipeStream.h"
15*61046927SAndroid Build Coastguard Worker #include "util/log.h"
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker #define STREAM_BUFFER_SIZE (4 * 1024 * 1024)
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker struct ThreadInfo {
20*61046927SAndroid Build Coastguard Worker     std::unique_ptr<GfxStreamConnectionManager> mgr;
21*61046927SAndroid Build Coastguard Worker };
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker static thread_local ThreadInfo sThreadInfo;
24*61046927SAndroid Build Coastguard Worker 
GfxStreamConnectionManager(GfxStreamTransportType type,VirtGpuCapset capset)25*61046927SAndroid Build Coastguard Worker GfxStreamConnectionManager::GfxStreamConnectionManager(GfxStreamTransportType type,
26*61046927SAndroid Build Coastguard Worker                                                        VirtGpuCapset capset)
27*61046927SAndroid Build Coastguard Worker     : mTransportType(type), mCapset(capset) {}
28*61046927SAndroid Build Coastguard Worker 
~GfxStreamConnectionManager()29*61046927SAndroid Build Coastguard Worker GfxStreamConnectionManager::~GfxStreamConnectionManager() {}
30*61046927SAndroid Build Coastguard Worker 
initialize()31*61046927SAndroid Build Coastguard Worker bool GfxStreamConnectionManager::initialize() {
32*61046927SAndroid Build Coastguard Worker     switch (mTransportType) {
33*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_ADDRESS_SPACE: {
34*61046927SAndroid Build Coastguard Worker             mStream = createGoldfishAddressSpaceStream(STREAM_BUFFER_SIZE);
35*61046927SAndroid Build Coastguard Worker             if (!mStream) {
36*61046927SAndroid Build Coastguard Worker                 mesa_loge("Failed to create AddressSpaceStream for host connection\n");
37*61046927SAndroid Build Coastguard Worker                 return false;
38*61046927SAndroid Build Coastguard Worker             }
39*61046927SAndroid Build Coastguard Worker             break;
40*61046927SAndroid Build Coastguard Worker         }
41*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_QEMU_PIPE: {
42*61046927SAndroid Build Coastguard Worker             mStream = new QemuPipeStream(STREAM_BUFFER_SIZE);
43*61046927SAndroid Build Coastguard Worker             if (mStream->connect() < 0) {
44*61046927SAndroid Build Coastguard Worker                 mesa_loge("Failed to connect to host (QemuPipeStream)\n");
45*61046927SAndroid Build Coastguard Worker                 return false;
46*61046927SAndroid Build Coastguard Worker             }
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker             break;
49*61046927SAndroid Build Coastguard Worker         }
50*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_VIRTIO_GPU_PIPE: {
51*61046927SAndroid Build Coastguard Worker             VirtioGpuPipeStream* pipeStream =
52*61046927SAndroid Build Coastguard Worker                 new VirtioGpuPipeStream(STREAM_BUFFER_SIZE, INVALID_DESCRIPTOR);
53*61046927SAndroid Build Coastguard Worker             if (!pipeStream) {
54*61046927SAndroid Build Coastguard Worker                 mesa_loge("Failed to create VirtioGpu for host connection\n");
55*61046927SAndroid Build Coastguard Worker                 return false;
56*61046927SAndroid Build Coastguard Worker             }
57*61046927SAndroid Build Coastguard Worker             if (pipeStream->connect() < 0) {
58*61046927SAndroid Build Coastguard Worker                 mesa_loge("Failed to connect to host (VirtioGpu)\n");
59*61046927SAndroid Build Coastguard Worker                 return false;
60*61046927SAndroid Build Coastguard Worker             }
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker             mDescriptor = pipeStream->getRendernodeFd();
63*61046927SAndroid Build Coastguard Worker             VirtGpuDevice::getInstance(mCapset);
64*61046927SAndroid Build Coastguard Worker             mStream = pipeStream;
65*61046927SAndroid Build Coastguard Worker             break;
66*61046927SAndroid Build Coastguard Worker         }
67*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_VIRTIO_GPU_ADDRESS_SPACE: {
68*61046927SAndroid Build Coastguard Worker             // Use kCapsetGfxStreamVulkan for now, Ranchu HWC needs to be modified to pass in
69*61046927SAndroid Build Coastguard Worker             // right capset.
70*61046927SAndroid Build Coastguard Worker             auto device = VirtGpuDevice::getInstance(kCapsetGfxStreamVulkan);
71*61046927SAndroid Build Coastguard Worker             mDescriptor = device->getDeviceHandle();
72*61046927SAndroid Build Coastguard Worker             mStream = createVirtioGpuAddressSpaceStream(kCapsetGfxStreamVulkan);
73*61046927SAndroid Build Coastguard Worker             if (!mStream) {
74*61046927SAndroid Build Coastguard Worker                 mesa_loge("Failed to create virtgpu AddressSpaceStream\n");
75*61046927SAndroid Build Coastguard Worker                 return false;
76*61046927SAndroid Build Coastguard Worker             }
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker             break;
79*61046927SAndroid Build Coastguard Worker         }
80*61046927SAndroid Build Coastguard Worker         default:
81*61046927SAndroid Build Coastguard Worker             return false;
82*61046927SAndroid Build Coastguard Worker     }
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker     // send zero 'clientFlags' to the host.  This is actually part of the gfxstream protocol.
85*61046927SAndroid Build Coastguard Worker     unsigned int* pClientFlags = (unsigned int*)mStream->allocBuffer(sizeof(unsigned int));
86*61046927SAndroid Build Coastguard Worker     *pClientFlags = 0;
87*61046927SAndroid Build Coastguard Worker     mStream->commitBuffer(sizeof(unsigned int));
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker     return true;
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker 
getThreadLocalInstance(GfxStreamTransportType type,VirtGpuCapset capset)92*61046927SAndroid Build Coastguard Worker GfxStreamConnectionManager* GfxStreamConnectionManager::getThreadLocalInstance(
93*61046927SAndroid Build Coastguard Worker     GfxStreamTransportType type, VirtGpuCapset capset) {
94*61046927SAndroid Build Coastguard Worker     if (sThreadInfo.mgr == nullptr) {
95*61046927SAndroid Build Coastguard Worker         sThreadInfo.mgr = std::make_unique<GfxStreamConnectionManager>(type, capset);
96*61046927SAndroid Build Coastguard Worker         if (!sThreadInfo.mgr->initialize()) {
97*61046927SAndroid Build Coastguard Worker             sThreadInfo.mgr = nullptr;
98*61046927SAndroid Build Coastguard Worker             return nullptr;
99*61046927SAndroid Build Coastguard Worker         }
100*61046927SAndroid Build Coastguard Worker     }
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker     return sThreadInfo.mgr.get();
103*61046927SAndroid Build Coastguard Worker }
104*61046927SAndroid Build Coastguard Worker 
threadLocalExit()105*61046927SAndroid Build Coastguard Worker void GfxStreamConnectionManager::threadLocalExit() {
106*61046927SAndroid Build Coastguard Worker     if (sThreadInfo.mgr == nullptr) {
107*61046927SAndroid Build Coastguard Worker         return;
108*61046927SAndroid Build Coastguard Worker     }
109*61046927SAndroid Build Coastguard Worker 
110*61046927SAndroid Build Coastguard Worker     sThreadInfo.mgr.reset();
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker 
addConnection(GfxStreamConnectionType type,std::unique_ptr<GfxStreamConnection> connection)113*61046927SAndroid Build Coastguard Worker int32_t GfxStreamConnectionManager::addConnection(GfxStreamConnectionType type,
114*61046927SAndroid Build Coastguard Worker                                                   std::unique_ptr<GfxStreamConnection> connection) {
115*61046927SAndroid Build Coastguard Worker     if (mConnections.find(type) != mConnections.end()) {
116*61046927SAndroid Build Coastguard Worker         return -EINVAL;
117*61046927SAndroid Build Coastguard Worker     }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker     mConnections[type] = std::move(connection);
120*61046927SAndroid Build Coastguard Worker     return 0;
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker 
getEncoder(GfxStreamConnectionType type)123*61046927SAndroid Build Coastguard Worker void* GfxStreamConnectionManager::getEncoder(GfxStreamConnectionType type) {
124*61046927SAndroid Build Coastguard Worker     auto iterator = mConnections.find(type);
125*61046927SAndroid Build Coastguard Worker     if (iterator == mConnections.end()) {
126*61046927SAndroid Build Coastguard Worker         return nullptr;
127*61046927SAndroid Build Coastguard Worker     }
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker     return iterator->second->getEncoder();
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker 
getStream()132*61046927SAndroid Build Coastguard Worker gfxstream::guest::IOStream* GfxStreamConnectionManager::getStream() { return mStream; }
133*61046927SAndroid Build Coastguard Worker 
processPipeStream(GfxStreamTransportType transportType)134*61046927SAndroid Build Coastguard Worker gfxstream::guest::IOStream* GfxStreamConnectionManager::processPipeStream(
135*61046927SAndroid Build Coastguard Worker     GfxStreamTransportType transportType) {
136*61046927SAndroid Build Coastguard Worker     switch (transportType) {
137*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_ADDRESS_SPACE:
138*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_QEMU_PIPE:
139*61046927SAndroid Build Coastguard Worker             return new QemuPipeStream(STREAM_BUFFER_SIZE);
140*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_VIRTIO_GPU_ADDRESS_SPACE:
141*61046927SAndroid Build Coastguard Worker         case GFXSTREAM_TRANSPORT_VIRTIO_GPU_PIPE:
142*61046927SAndroid Build Coastguard Worker             return new VirtioGpuPipeStream(STREAM_BUFFER_SIZE, mDescriptor);
143*61046927SAndroid Build Coastguard Worker         default:
144*61046927SAndroid Build Coastguard Worker             return nullptr;
145*61046927SAndroid Build Coastguard Worker     }
146*61046927SAndroid Build Coastguard Worker }
147