1 // Copyright (C) 2024 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <stdint.h>
18 
19 #include <memory>
20 #include <unordered_map>
21 
22 extern "C" {
23 #include "gfxstream/virtio-gpu-gfxstream-renderer-unstable.h"
24 #include "gfxstream/virtio-gpu-gfxstream-renderer.h"
25 #include "host-common/goldfish_pipe.h"
26 }  // extern "C"
27 
28 #include "VirtioGpu.h"
29 #include "VirtioGpuContext.h"
30 #include "VirtioGpuFormatUtils.h"
31 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
32 #include "VirtioGpuFrontendSnapshot.pb.h"
33 #endif
34 #include "VirtioGpuResource.h"
35 #include "VirtioGpuTimelines.h"
36 #include "gfxstream/host/Features.h"
37 #include "host-common/address_space_device.h"
38 
39 namespace gfxstream {
40 namespace host {
41 
42 class CleanupThread;
43 
44 class VirtioGpuFrontend {
45    public:
46     VirtioGpuFrontend();
47 
48     int init(void* cookie, gfxstream::host::FeatureSet features,
49              stream_renderer_fence_callback fence_callback);
50 
51     void teardown();
52 
53     int createContext(VirtioGpuContextId ctx_id, uint32_t nlen, const char* name,
54                       uint32_t context_init);
55 
56     int destroyContext(VirtioGpuContextId handle);
57 
58     int addressSpaceProcessCmd(VirtioGpuContextId ctxId, uint32_t* dwords);
59 
60     int submitCmd(struct stream_renderer_command* cmd);
61 
62     int createFence(uint64_t fence_id, const VirtioGpuRing& ring);
63 
64     int acquireContextFence(uint32_t ctx_id, uint64_t fenceId);
65 
66     void poll();
67 
68     int createResource(struct stream_renderer_resource_create_args* args, struct iovec* iov,
69                        uint32_t num_iovs);
70     void unrefResource(uint32_t toUnrefId);
71 
72     int attachIov(int resId, iovec* iov, int num_iovs);
73     void detachIov(int resId);
74 
75     int transferReadIov(int resId, uint64_t offset, stream_renderer_box* box, struct iovec* iov,
76                         int iovec_cnt);
77     int transferWriteIov(int resId, uint64_t offset, stream_renderer_box* box, struct iovec* iov,
78                          int iovec_cnt);
79 
80     void getCapset(uint32_t set, uint32_t* max_size);
81     void fillCaps(uint32_t set, void* caps);
82 
83     void attachResource(uint32_t ctxId, uint32_t resId);
84     void detachResource(uint32_t ctxId, uint32_t toUnrefId);
85 
86     int getResourceInfo(uint32_t resId, struct stream_renderer_resource_info* info);
87 
88     void flushResource(uint32_t res_handle);
89 
90     int createRingBlob(VirtioGpuResource& entry, uint32_t res_handle,
91                        const struct stream_renderer_create_blob* create_blob,
92                        const struct stream_renderer_handle* handle);
93 
94     int createBlob(uint32_t ctx_id, uint32_t res_handle,
95                    const struct stream_renderer_create_blob* create_blob,
96                    const struct stream_renderer_handle* handle);
97 
98     int resourceMap(uint32_t resourceId, void** hvaOut, uint64_t* sizeOut);
99     int resourceUnmap(uint32_t res_handle);
100 
101     int platformImportResource(int res_handle, int res_info, void* resource);
102 
103     void* platformCreateSharedEglContext();
104 
105     int platformDestroySharedEglContext(void* context);
106 
107     int waitSyncResource(uint32_t res_handle);
108 
109     int resourceMapInfo(uint32_t resourceId, uint32_t* map_info);
110 
111     int exportBlob(uint32_t resourceId, struct stream_renderer_handle* handle);
112 
113     int exportFence(uint64_t fenceId, struct stream_renderer_handle* handle);
114     int vulkanInfo(uint32_t res_handle, struct stream_renderer_vulkan_info* vulkan_info);
115 
116 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
117     int snapshot(const char* directory);
118     int restore(const char* directory);
119 #endif  // GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
120 
121 #ifdef CONFIG_AEMU
122     void setServiceOps(const GoldfishPipeServiceOps* ops);
123 #endif  // CONFIG_AEMU
124 
125    private:
126     int destroyVirtioGpuObjects();
127 
128 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
129     int snapshotRenderer(const char* directory);
130     int snapshotFrontend(const char* directory);
131     int snapshotAsg(const char* directory);
132 
133     int restoreRenderer(const char* directory);
134     int restoreFrontend(const char* directory);
135     int restoreAsg(const char* directory);
136 #endif  // GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
137 
138     int resetPipe(VirtioGpuContextId contextId, GoldfishHostPipe* hostPipe);
139 
140     const GoldfishPipeServiceOps* ensureAndGetServiceOps();
141 
142     void* mCookie = nullptr;
143     gfxstream::host::FeatureSet mFeatures;
144     stream_renderer_fence_callback mFenceCallback;
145     uint32_t mPageSize = 4096;
146     struct ::address_space_device_control_ops* mAddressSpaceDeviceControlOps = nullptr;
147 
148     const GoldfishPipeServiceOps* mServiceOps = nullptr;
149 
150     // State that is preserved across snapshots:
151     //
152     // LINT.IfChange(virtio_gpu_frontend)
153     std::unordered_map<VirtioGpuContextId, VirtioGpuContext> mContexts;
154     std::unordered_map<VirtioGpuResourceId, VirtioGpuResource> mResources;
155     std::unordered_map<uint64_t, std::shared_ptr<SyncDescriptorInfo>> mSyncMap;
156     // When we wait for gpu or wait for gpu vulkan, the next (and subsequent)
157     // fences created for that context should not be signaled immediately.
158     // Rather, they should get in line.
159     std::unique_ptr<VirtioGpuTimelines> mVirtioGpuTimelines = nullptr;
160     // LINT.ThenChange(VirtioGpuFrontend.h:virtio_gpu_frontend)
161 
162     std::unique_ptr<CleanupThread> mCleanupThread;
163 };
164 
165 }  // namespace host
166 }  // namespace gfxstream
167