1 /*
2  * Copyright 2024 Google LLC
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include "GfxStreamRenderControl.h"
7 
8 #include <mutex>
9 
10 #include "GfxStreamRenderControlConnection.h"
11 
12 #if defined(__ANDROID__)
13 #include "android-base/properties.h"
14 #endif
15 
16 constexpr const auto kEglProp = "ro.hardware.egl";
17 
18 static uint64_t sProcUID = 0;
19 static std::mutex sNeedInitMutex;
20 static bool sNeedInit = true;
21 static gfxstream::guest::IOStream* sProcessStream = nullptr;
22 
renderControlGetTransport()23 GfxStreamTransportType renderControlGetTransport() {
24 #if defined(__Fuchsia__) || defined(LINUX_GUEST_BUILD)
25     return GFXSTREAM_TRANSPORT_VIRTIO_GPU_ADDRESS_SPACE;
26 #else
27     std::string transport;
28 
29 #if defined(__ANDROID__)
30     transport = android::base::GetProperty("ro.boot.hardware.gltransport", "");
31 #else
32     const char* transport_envvar = getenv("GFXSTREAM_TRANSPORT");
33     if (transport_envvar != nullptr) {
34         transport = std::string(transport_envvar);
35     }
36 #endif
37 
38     if (transport.empty()) {
39 #if defined(__ANDROID__)
40         return GFXSTREAM_TRANSPORT_QEMU_PIPE;
41 #else
42         return GFXSTREAM_TRANSPORT_VIRTIO_GPU_ADDRESS_SPACE;
43 #endif
44     }
45 
46     if (transport == "asg") {
47         return GFXSTREAM_TRANSPORT_ADDRESS_SPACE;
48     }
49     if (transport == "pipe") {
50         return GFXSTREAM_TRANSPORT_QEMU_PIPE;
51     }
52 
53     if (transport == "virtio-gpu-asg" || transport == "virtio-gpu-pipe") {
54         std::string egl;
55 #if defined(__ANDROID__)
56         egl = android::base::GetProperty(kEglProp, "");
57 #endif
58         return GFXSTREAM_TRANSPORT_VIRTIO_GPU_ADDRESS_SPACE;
59     }
60 
61     return GFXSTREAM_TRANSPORT_QEMU_PIPE;
62 #endif
63 }
64 
getPuid(GfxStreamConnectionManager * mgr)65 static uint64_t getPuid(GfxStreamConnectionManager* mgr) {
66     std::lock_guard<std::mutex> lock(sNeedInitMutex);
67 
68     if (sNeedInit) {
69         GfxStreamTransportType transport = renderControlGetTransport();
70         sProcessStream = mgr->processPipeStream(transport);
71         sProcUID = sProcessStream->processPipeInit();
72         sNeedInit = false;
73     }
74 
75     return sProcUID;
76 }
77 
renderControlInit(GfxStreamConnectionManager * mgr,void * vkInfo)78 int32_t renderControlInit(GfxStreamConnectionManager* mgr, void* vkInfo) {
79     ExtendedRCEncoderContext* rcEnc =
80         (ExtendedRCEncoderContext*)mgr->getEncoder(GFXSTREAM_CONNECTION_RENDER_CONTROL);
81 
82     if (!rcEnc) {
83         uint64_t puid = getPuid(mgr);
84         auto stream = mgr->getStream();
85 
86         auto rcConnection = std::make_unique<GfxStreamRenderControlConnection>(stream);
87         rcEnc = (ExtendedRCEncoderContext*)rcConnection->getEncoder();
88         gfxstream::guest::ChecksumCalculator* calc = rcConnection->getCheckSumHelper();
89 
90         rcEnc->setChecksumHelper(calc);
91         rcEnc->queryAndSetSyncImpl();
92         rcEnc->queryAndSetDmaImpl();
93         rcEnc->queryAndSetGLESMaxVersion();
94         rcEnc->queryAndSetHostCompositionImpl();
95         rcEnc->queryAndSetDirectMemSupport();
96         rcEnc->queryAndSetVulkanSupport();
97         rcEnc->queryAndSetDeferredVulkanCommandsSupport();
98         rcEnc->queryAndSetVulkanNullOptionalStringsSupport();
99         rcEnc->queryAndSetVulkanCreateResourcesWithRequirementsSupport();
100         rcEnc->queryAndSetVulkanIgnoredHandles();
101         rcEnc->queryAndSetYUVCache();
102         rcEnc->queryAndSetAsyncUnmapBuffer();
103         rcEnc->queryAndSetVirtioGpuNext();
104         rcEnc->queryHasSharedSlotsHostMemoryAllocator();
105         rcEnc->queryAndSetVulkanFreeMemorySync();
106         rcEnc->queryAndSetVirtioGpuNativeSync();
107         rcEnc->queryAndSetVulkanShaderFloat16Int8Support();
108         rcEnc->queryAndSetVulkanAsyncQueueSubmitSupport();
109         rcEnc->queryAndSetHostSideTracingSupport();
110         rcEnc->queryAndSetAsyncFrameCommands();
111         rcEnc->queryAndSetVulkanQueueSubmitWithCommandsSupport();
112         rcEnc->queryAndSetVulkanBatchedDescriptorSetUpdateSupport();
113         rcEnc->queryAndSetSyncBufferData();
114         rcEnc->queryAndSetVulkanAsyncQsri();
115         rcEnc->queryAndSetReadColorBufferDma();
116         rcEnc->queryAndSetHWCMultiConfigs();
117         rcEnc->queryAndSetVulkanAuxCommandBufferMemory();
118         rcEnc->queryVersion();
119 
120         rcEnc->rcSetPuid(rcEnc, puid);
121 
122         if (vkInfo) {
123             rcEnc->setVulkanFeatureInfo(vkInfo);
124         }
125 
126         int32_t ret =
127             mgr->addConnection(GFXSTREAM_CONNECTION_RENDER_CONTROL, std::move(rcConnection));
128         if (ret) {
129             return ret;
130         }
131     }
132 
133     return 0;
134 }
135