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