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