• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <optional>
21 #include <unordered_set>
22 
23 extern "C" {
24 #include "host-common/goldfish_pipe.h"
25 }  // extern "C"
26 
27 #include "ExternalObjectManager.h"
28 #include "VirtioGpu.h"
29 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
30 #include "VirtioGpuResourceSnapshot.pb.h"
31 #endif  // GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
32 #include "VirtioGpuRingBlob.h"
33 #include "gfxstream/host/Features.h"
34 #include "gfxstream/virtio-gpu-gfxstream-renderer-unstable.h"
35 #include "gfxstream/virtio-gpu-gfxstream-renderer.h"
36 
37 namespace gfxstream {
38 namespace host {
39 
40 // LINT.IfChange(virtio_gpu_resource_type)
41 enum class VirtioGpuResourceType {
42     UNKNOWN = 0,
43     // Used as a communication channel between the guest and the host
44     // which does not need an allocation on the host GPU.
45     PIPE = 1,
46     // Used as a GPU data buffer.
47     BUFFER = 2,
48     // Used as a GPU texture.
49     COLOR_BUFFER = 3,
50     // Used as a blob and not known to FrameBuffer.
51     BLOB = 4,
52 };
53 // LINT.ThenChange(VirtioGpuResourceSnapshot.proto:virtio_gpu_resource_type)
54 
55 class VirtioGpuResource {
56    public:
VirtioGpuResource()57     VirtioGpuResource() {}
58 
59     static std::optional<VirtioGpuResource> Create(
60         const struct stream_renderer_resource_create_args* args, struct iovec* iov,
61         uint32_t num_iovs);
62 
63     static std::optional<VirtioGpuResource> Create(
64         uint32_t res_handle, const struct stream_renderer_handle* import_handle,
65         const struct stream_renderer_import_data* import_data);
66 
67     static std::optional<VirtioGpuResource> Create(
68         const gfxstream::host::FeatureSet& features, uint32_t pageSize, uint32_t contextId,
69         uint32_t resourceId, const struct stream_renderer_resource_create_args* createArgs,
70         const struct stream_renderer_create_blob* createBlobArgs,
71         const struct stream_renderer_handle* handle);
72 
73     int Destroy();
74 
75     int ImportHandle(const stream_renderer_handle* handle,
76                      const stream_renderer_import_data* import_data);
77 
GetId()78     VirtioGpuResourceId GetId() const { return mId; }
79 
80     void AttachIov(struct iovec* iov, uint32_t num_iovs);
81     void DetachIov();
82 
83     void AttachToContext(VirtioGpuContextId contextId);
84     void DetachFromContext(VirtioGpuContextId contextId);
85     std::unordered_set<VirtioGpuContextId> GetAttachedContexts() const;
86 
87     int Map(void** outAddress, uint64_t* outSize);
88 
89     int GetInfo(struct stream_renderer_resource_info* outInfo) const;
90 
91     int GetVulkanInfo(struct stream_renderer_vulkan_info* outInfo) const;
92 
93     int GetCaching(uint32_t* outHvaCaching) const;
94 
SetHostPipe(GoldfishHostPipe * pipe)95     void SetHostPipe(GoldfishHostPipe* pipe) { mHostPipe = pipe; }
96 
97     // Corresponds to Virtio GPU "TransferFromHost" commands and VMM requests to
98     // copy into display buffers.
99     int TransferRead(const GoldfishPipeServiceOps* ops, uint64_t offset, stream_renderer_box* box,
100                      std::optional<std::vector<struct iovec>> iovs = std::nullopt);
101 
102     struct TransferWriteResult {
103         int status = 0;
104 
105         // If, while processing the first guest to host transfer for a PIPE resource
106         // which contains the pipe service name, the returned pipe service to replace
107         // the generic pipe.
108         VirtioGpuContextId contextId = -1;
109         GoldfishHostPipe* contextPipe = nullptr;
110     };
111     // Corresponds to Virtio GPU "TransferToHost" commands.
112     TransferWriteResult TransferWrite(const GoldfishPipeServiceOps* ops, uint64_t offset,
113                                       stream_renderer_box* box,
114                                       std::optional<std::vector<struct iovec>> iovs = std::nullopt);
115 
116     int ExportBlob(struct stream_renderer_handle* outHandle);
117 
118     std::shared_ptr<RingBlob> ShareRingBlob();
119 
120 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
121     std::optional<gfxstream::host::snapshot::VirtioGpuResourceSnapshot> Snapshot() const;
122 
123     static std::optional<VirtioGpuResource> Restore(
124         const gfxstream::host::snapshot::VirtioGpuResourceSnapshot& snapshot);
125 #endif
126 
127    private:
128     int ReadFromPipeToLinear(const GoldfishPipeServiceOps* ops, uint64_t offset,
129                              stream_renderer_box* box);
130     TransferWriteResult WriteToPipeFromLinear(const GoldfishPipeServiceOps* ops, uint64_t offset,
131                                               stream_renderer_box* box);
132 
133     int ReadFromBufferToLinear(uint64_t offset, stream_renderer_box* box);
134     int WriteToBufferFromLinear(uint64_t offset, stream_renderer_box* box);
135 
136     int ReadFromColorBufferToLinear(uint64_t offset, stream_renderer_box* box);
137     int WriteToColorBufferFromLinear(uint64_t offset, stream_renderer_box* box);
138 
139     // If `iovs` provided, copy from this resource's linear buffer to the given `iovs`.
140     // Otherwise, copy from this resource's linear buffer into its previously attached
141     // iovs.
142     int TransferToIov(uint64_t offset, const stream_renderer_box* box,
143                       std::optional<std::vector<struct iovec>> iovs = std::nullopt);
144 
145     // If `iovs` provided, copy from the given `iovs` to this resources linear buffer.
146     // Otherwise, copy from this resource's previously attached iovs into its linear
147     // buffer.
148     int TransferFromIov(uint64_t offset, const stream_renderer_box* box,
149                         std::optional<std::vector<struct iovec>> iovs = std::nullopt);
150 
151     enum TransferDirection {
152         IOV_TO_LINEAR = 0,
153         LINEAR_TO_IOV = 1,
154     };
155     int TransferWithIov(uint64_t offset, const stream_renderer_box* box,
156                         const std::vector<struct iovec>& iovs, TransferDirection direction);
157 
158     // LINT.IfChange(virtio_gpu_resource)
159     VirtioGpuResourceId mId = -1;
160     VirtioGpuResourceType mResourceType = VirtioGpuResourceType::UNKNOWN;
161     std::optional<struct stream_renderer_resource_create_args> mCreateArgs;
162     std::optional<struct stream_renderer_create_blob> mCreateBlobArgs;
163     std::vector<struct iovec> mIovs;
164     std::vector<char> mLinear;
165     GoldfishHostPipe* mHostPipe = nullptr;
166     std::optional<VirtioGpuContextId> mLatestAttachedContext;
167     std::unordered_set<VirtioGpuContextId> mAttachedToContexts;
168 
169     // If this resource is a blob resource, the source of the external memory.
170     //
171     //   * For ring blobs, blobs that are used soley for guest and host
172     //     communication, the external memory is allocated by this resource
173     //     in the frontend.
174     //
175     //   * For non ring blobs, the memory from the backend as either an external
176     //     memory handle (`BlobDescriptorInfo`) or a raw mapping.
177     using RingBlobMemory = std::shared_ptr<RingBlob>;
178     using ExternalMemoryInfo = std::shared_ptr<BlobDescriptorInfo>;
179     using ExternalMemoryMapping = HostMemInfo;
180 
181     using BlobMemory = std::variant<RingBlobMemory, ExternalMemoryInfo, ExternalMemoryMapping>;
182     std::optional<BlobMemory> mBlobMemory;
183     // LINT.ThenChange(VirtioGpuResourceSnapshot.proto:virtio_gpu_resource)
184 };
185 
186 }  // namespace host
187 }  // namespace gfxstream