1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <memory>
20 #include <optional>
21 
22 // see protocol.rs in crosvm
23 enum VirtioGpuFenceFlags : uint32_t {
24     kFlagNone = 0x0000,
25     kFlagFence = 0x0001,
26     kFlagRingIdx = 0x0002,
27     kFlagFenceShareable = 0x0004,
28 };
29 
30 constexpr enum VirtioGpuFenceFlags operator|(const enum VirtioGpuFenceFlags self,
31                                              const enum VirtioGpuFenceFlags other) {
32     return (enum VirtioGpuFenceFlags)(uint32_t(self) | uint32_t(other));
33 }
34 
35 namespace gfxstream {
36 
37 // Emulates parts of the Linux Virtio GPU kernel module and parts of
38 // a virtual machine manager to allow speaking directly to the Gfxstream
39 // host server via rutabaga.
40 class EmulatedVirtioGpu {
41   public:
42    static std::shared_ptr<EmulatedVirtioGpu> Get();
43    static uint32_t GetNumActiveUsers();
44 
45    bool Init(bool withGl, bool withVk, const std::string& features);
46 
47    bool GetCaps(uint32_t capsetId, uint32_t guestCapsSize, uint8_t* capset);
48 
49    std::optional<uint32_t> CreateContext(uint32_t contextInit);
50    void DestroyContext(uint32_t contextId);
51 
52    std::optional<uint32_t> CreateBlob(uint32_t contextId, uint32_t blobMem, uint32_t blobFlags,
53                                       uint64_t blobId, uint64_t blobSize);
54    std::optional<uint32_t> CreateVirglBlob(uint32_t contextId, uint32_t width, uint32_t height,
55                                            uint32_t virglFormat, uint32_t target, uint32_t bind,
56                                            uint32_t size);
57 
58    void DestroyResource(uint32_t contextId, uint32_t resourceId);
59 
60    uint8_t* Map(uint32_t resourceId);
61    void Unmap(uint32_t resourceId);
62 
63    int SubmitCmd(uint32_t contextId, uint32_t cmdSize, void* cmd, uint32_t ringIdx,
64                  VirtioGpuFenceFlags fenceFlags, uint32_t& fenceId,
65                  std::optional<uint32_t> blobResourceId);
66 
67    int Wait(uint32_t resourceId);
68 
69    int TransferFromHost(uint32_t contextId, uint32_t resourceId, uint32_t transferOffset,
70                         uint32_t transferSize);
71    int TransferFromHost(uint32_t contextId, uint32_t resourceId, uint32_t x, uint32_t y, uint32_t w,
72                         uint32_t h);
73 
74    int TransferToHost(uint32_t contextId, uint32_t resourceId, uint32_t transferOffset,
75                       uint32_t transferSize);
76    int TransferToHost(uint32_t contextId, uint32_t resourceId, uint32_t x, uint32_t y, uint32_t w,
77                       uint32_t h);
78 
79    void SignalEmulatedFence(int fenceId);
80 
81    int WaitOnEmulatedFence(int fenceAsFileDescriptor, int timeoutMilliseconds);
82 
83    void SnapshotSave(const std::string& directory);
84    void SnapshotRestore(const std::string& directory);
85 
86   private:
87     EmulatedVirtioGpu();
88 
89     class EmulatedVirtioGpuImpl;
90     std::unique_ptr<EmulatedVirtioGpuImpl> mImpl;
91 };
92 
93 }  // namespace gfxstream
94