Merge "Revert "goldfish-opengl: use VirtGpuDevice abstraction for ASG""
diff --git a/platform/include/virtgpu_gfxstream_protocol.h b/platform/include/virtgpu_gfxstream_protocol.h
deleted file mode 100644
index 6bf26a2..0000000
--- a/platform/include/virtgpu_gfxstream_protocol.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef VIRTGPU_GFXSTREAM_PROTOCOL_H
-#define VIRTGPU_GFXSTREAM_PROTOCOL_H
-
-#include <stdint.h>
-
-// Address Space Graphics contexts
-#define GFXSTREAM_CONTEXT_CREATE                0x1001
-#define GFXSTREAM_CONTEXT_PING                  0x1002
-#define GFXSTREAM_CONTEXT_PING_WITH_RESPONSE    0x1003
-
-// Native Sync FD
-#define GFXSTREAM_CREATE_EXPORT_SYNC            0x9000
-#define GFXSTREAM_CREATE_IMPORT_SYNC            0x9001
-
-// Vulkan Sync
-#define GFXSTREAM_CREATE_EXPORT_SYNC_VK         0xa000
-#define GFXSTREAM_CREATE_IMPORT_SYNC_VK         0xa001
-#define GFXSTREAM_CREATE_QSRI_EXPORT_VK         0xa002
-
-struct gfxstreamHeader {
-    uint32_t opCode;
-};
-
-struct gfxstreamContextCreate {
-    struct gfxstreamHeader hdr;
-    uint32_t resourceId;
-};
-
-struct gfxstreamContextPing {
-    struct gfxstreamHeader hdr;
-    uint32_t resourceId;
-};
-
-struct gfxstreamCreateExportSync {
-    struct gfxstreamHeader hdr;
-    uint32_t syncHandleLo;
-    uint32_t syncHandleHi;
-};
-
-struct gfxstreamCreateExportSyncVK {
-    struct gfxstreamHeader hdr;
-    uint32_t deviceHandleLo;
-    uint32_t deviceHandleHi;
-    uint32_t fenceHandleLo;
-    uint32_t fenceHandleHi;
-};
-
-struct gfxstreamCreateQSRIExportVK {
-    struct gfxstreamHeader hdr;
-    uint32_t imageHandleLo;
-    uint32_t imageHandleHi;
-};
-
-#endif
diff --git a/shared/GoldfishAddressSpace/Android.bp b/shared/GoldfishAddressSpace/Android.bp
index 4b477a1..26cc468 100644
--- a/shared/GoldfishAddressSpace/Android.bp
+++ b/shared/GoldfishAddressSpace/Android.bp
@@ -17,9 +17,6 @@
         "liblog",
         "libdrm",
     ],
-    static_libs: [
-        "libplatform",
-    ],
     export_include_dirs: [
         "include",
     ],
diff --git a/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl b/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl
index d6fd667..9e03ae4 100644
--- a/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl
+++ b/shared/GoldfishAddressSpace/include/goldfish_address_space_android.impl
@@ -27,8 +27,6 @@
 #include <cstring>
 
 #ifdef VIRTIO_GPU
-#include "VirtGpu.h"
-#include "virtgpu_gfxstream_protocol.h"
 #include <xf86drm.h>
 #endif
 
@@ -549,29 +547,255 @@
     return true;
 }
 
+#define CAPSET_GFXSTREAM 3
+
+
 address_space_handle_t virtgpu_address_space_open() {
     return -EINVAL;
 }
 
 void virtgpu_address_space_close(address_space_handle_t fd) {
-    // Handle opened by VirtioGpuDevice wrapper
+    close(fd);
 }
 
+// kVirtioGpuAddressSpaceContextCreateWithSubdevice | subdeviceType
+const uint32_t kVirtioGpuAddressSpaceContextCreateWithSubdevice = 0x1001;
+
+// kVirtioGpuAddressSpacePing | offset_lo | offset_hi | size_lo | size_hi | metadata_lo | metadata_hi | resourceId | wait_fd | wait_flags | direction
+// no output
+const uint32_t kVirtioGpuAddressSpacePing = 0x1002;
+
+// kVirtioGpuAddressSpacePingWithResponse | resp_resid | offset_lo | offset_hi | metadata_lo | metadata_hi | resourceId | wait_fd | wait_flags | direction
+// out: same as input then | out: error
+const uint32_t kVirtioGpuAddressSpacePingWithResponse = 0x1003;
+
+// Ping with no response
 bool virtgpu_address_space_ping(address_space_handle_t fd, struct address_space_ping* info) {
-    int ret;
-    struct VirtGpuExecBuffer exec = { 0 };
-    VirtGpuDevice& instance = VirtGpuDevice::getInstance();
-    struct gfxstreamContextPing ping = {0};
 
-    ping.hdr.opCode = GFXSTREAM_CONTEXT_PING;
-    ping.resourceId = info->resourceId;
+    uint32_t words[] = {
+        kVirtioGpuAddressSpacePing,
+        (uint32_t)(info->offset), (uint32_t)(info->offset >> 32),
+        (uint32_t)(info->size), (uint32_t)(info->size >> 32),
+        (uint32_t)(info->metadata), (uint32_t)(info->metadata >> 32),
+        (uint32_t)(info->resourceId), (uint32_t)(info->wait_fd),
+        (uint32_t)(info->wait_flags), (uint32_t)(info->direction),
+    };
 
-    exec.command = static_cast<void*>(&ping);
-    exec.command_size = sizeof(ping);
+    drm_virtgpu_execbuffer execbuffer = {
+        .flags = 0,
+        .size = sizeof(words),
+        .command = (uint64_t)(uintptr_t)(words),
+        .bo_handles = 0,
+        .num_bo_handles = 0,
+        .fence_fd = -1,
+    };
 
-    ret = instance.execBuffer(exec, nullptr);
-    if (ret)
+    int queue_work_err = drmIoctl(fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
+
+    if (queue_work_err) {
+        ALOGE("%s: failed with %d executing command buffer (%s)\n",  __func__,
+                queue_work_err, strerror(errno));
         return false;
+    }
+
+    return true;
+}
+
+bool virtgpu_address_space_create_context_with_subdevice(
+    address_space_handle_t fd,
+    uint32_t subdevice_type,
+    struct address_space_virtgpu_info* info_out) {
+
+    // response page
+    drm_virtgpu_resource_create create = {
+        .target     = PIPE_BUFFER,
+        .format     = VIRGL_FORMAT_R8_UNORM,
+        .bind       = VIRGL_BIND_CUSTOM,
+        .width      = 4096,
+        .height     = 1U,
+        .depth      = 1U,
+        .array_size = 0U,
+        .size       = 4096,
+        .stride     = 4096,
+    };
+
+    int ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &create);
+    if (ret) {
+        ALOGE("%s: failed with %d allocating command buffer (%s)\n",
+                __func__, ret, strerror(errno));
+        return false;
+    }
+
+    drm_virtgpu_map map;
+    memset(&map, 0, sizeof(map));
+    map.handle = create.bo_handle;
+
+    ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_MAP, &map);
+    if (ret) {
+        ALOGE("%s: failed with %d mapping command response buffer (%s)\n",
+            __func__, ret, strerror(errno));
+        return false;
+    }
+
+    void* ptr = static_cast<unsigned char*>(
+            mmap64(nullptr, 4096, PROT_WRITE, MAP_SHARED, fd, map.offset));
+
+    if (ptr == MAP_FAILED) {
+        ALOGE("%s: failed with %d mmap'ing command response buffer (%s)\n",
+                __func__, errno, strerror(errno));
+        return false;
+    }
+
+    info_out->fd = fd;
+    info_out->resp_bo = create.bo_handle;
+    info_out->resp_resid = create.res_handle;
+    info_out->resp_mapped_ptr = ptr;
+
+    ALOGD("%s: resp bo: %u resid %u mapped %p\n", __func__,
+            create.bo_handle, create.res_handle, ptr);
+
+    // Context creation command
+    uint32_t words[] = {
+        kVirtioGpuAddressSpaceContextCreateWithSubdevice,
+        subdevice_type,
+    };
+
+    drm_virtgpu_execbuffer execbuffer = {
+        .flags = 0,
+        .size = sizeof(words),
+        .command = (uint64_t)(uintptr_t)(words),
+        .bo_handles = 0,
+        .num_bo_handles = 0,
+        .fence_fd = -1,
+    };
+
+    int queue_work_err = drmIoctl(fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
+
+    if (queue_work_err) {
+        ALOGE("%s: failed with %d executing command buffer (%s)\n",  __func__,
+                queue_work_err, strerror(errno));
+        return false;
+    }
+
+    return true;
+}
+
+bool virtgpu_address_space_allocate_hostmem(
+    address_space_handle_t fd,
+    size_t size,
+    uint64_t hostmem_id,
+    struct address_space_virtgpu_hostmem_info* hostmem_info_out) {
+
+    struct drm_virtgpu_resource_create_blob drm_rc_blob = {};
+    drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST3D;
+    drm_rc_blob.blob_flags = VIRTGPU_BLOB_FLAG_USE_MAPPABLE;
+    drm_rc_blob.blob_id = hostmem_id;
+    drm_rc_blob.size = size;
+
+    int res = drmIoctl(
+            fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob);
+
+    if (res) {
+        ALOGE("%s: Failed to resource create v2: sterror: %s errno: %d\n", __func__,
+                strerror(errno), errno);
+        abort();
+    }
+
+    drm_virtgpu_map map;
+    memset(&map, 0, sizeof(map));
+    map.handle = drm_rc_blob.bo_handle;
+
+    res = drmIoctl(fd, DRM_IOCTL_VIRTGPU_MAP, &map);
+    if (res) {
+        ALOGE("%s: Failed to virtgpu map: sterror: %s errno: %d\n", __func__,
+                strerror(errno), errno);
+        abort();
+    }
+
+    void* directMappedAddr = mmap64(0, size, PROT_WRITE, MAP_SHARED, fd, map.offset);
+
+    if (directMappedAddr == MAP_FAILED) {
+        ALOGE("%s: mmap of virtio gpu resource failed\n", __func__);
+        abort();
+    }
+
+    hostmem_info_out->id = hostmem_id;
+    hostmem_info_out->bo = drm_rc_blob.bo_handle;
+    hostmem_info_out->ptr = directMappedAddr;
+    return true;
+}
+
+uint64_t buildu64(uint32_t lo, uint32_t hi) {
+    uint64_t res = (uint64_t)lo;
+    uint64_t hi64 = (uint64_t)hi;
+    return res | (hi64 << 32);
+}
+
+/* Used to retry DRM_IOCTL_VIRTGPU_WAIT, which can also return EBUSY. */
+#define TEMP_FAILURE_RETRY_BUSY(tag, exp) ({                                            \
+    __typeof__(exp) _rc;                                                                \
+    uint32_t busy_times = 0;                                                            \
+    do {                                                                                \
+        _rc = (exp);                                                                    \
+        if (errno == EBUSY) {                                                           \
+            ++busy_times;                                                               \
+            usleep(10000);                                                              \
+            ALOGE("%s:%s busy! waited %u times on EBUSY\n", __func__, tag, busy_times); \
+        }                                                                               \
+    } while (_rc != 0 && (errno == EINTR || errno == EBUSY));                           \
+    _rc; })
+
+// Ping with response
+bool virtgpu_address_space_ping_with_response(
+    struct address_space_virtgpu_info* info,
+    struct address_space_ping* ping) {
+
+    uint32_t words[] = {
+        kVirtioGpuAddressSpacePingWithResponse,
+        info->resp_resid,
+        (uint32_t)(ping->offset), (uint32_t)(ping->offset >> 32),
+        (uint32_t)(ping->size), (uint32_t)(ping->size >> 32),
+        (uint32_t)(ping->metadata), (uint32_t)(ping->metadata >> 32),
+        (uint32_t)(ping->resourceId), (uint32_t)(ping->wait_fd),
+        (uint32_t)(ping->wait_flags), (uint32_t)(ping->direction),
+    };
+
+    drm_virtgpu_execbuffer execbuffer = {
+        .flags = 0,
+        .size = sizeof(words),
+        .command = (uint64_t)(uintptr_t)(words),
+        .bo_handles = (uint64_t)(uintptr_t)(&info->resp_bo),
+        .num_bo_handles = 1,
+        .fence_fd = -1,
+    };
+
+    int queue_work_err = drmIoctl(info->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
+
+    if (queue_work_err) {
+        ALOGE("%s: failed with %d executing command buffer (%s)\n",  __func__,
+                queue_work_err, strerror(errno));
+        return false;
+    }
+
+    struct drm_virtgpu_3d_wait waitcmd;
+    memset(&waitcmd, 0, sizeof(waitcmd));
+    waitcmd.handle = info->resp_bo;
+
+    int ret = TEMP_FAILURE_RETRY_BUSY("DRM_IOCTL_VIRTGPU_WAIT", drmIoctl(info->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd));
+    if (ret) {
+        ALOGE("%s: DRM_IOCTL_VIRTGPU_WAIT failed with %d (%s)\n", __func__, errno, strerror(errno));
+        return false;
+    }
+
+    uint32_t* respWords = (uint32_t*)info->resp_mapped_ptr;
+
+    ping->offset = buildu64(respWords[0], respWords[1]);
+    ping->size = buildu64(respWords[2], respWords[3]);
+    ping->metadata = buildu64(respWords[4], respWords[5]);
+    ping->resourceId = respWords[6];
+    ping->wait_fd = respWords[7];
+    ping->wait_flags = respWords[8];
+    ping->direction = respWords[9];
 
     return true;
 }
diff --git a/shared/GoldfishAddressSpace/meson.build b/shared/GoldfishAddressSpace/meson.build
index 0326524..50fef3a 100644
--- a/shared/GoldfishAddressSpace/meson.build
+++ b/shared/GoldfishAddressSpace/meson.build
@@ -13,7 +13,6 @@
    cpp_args: cpp_args,
    include_directories: [inc_android_compat,
                          inc_goldfish_address_space,
-                         inc_system, inc_platform],
-   link_with: [lib_platform],
+                         inc_system],
    dependencies: drm_dep
 )
diff --git a/system/OpenglSystemCommon/AddressSpaceStream.cpp b/system/OpenglSystemCommon/AddressSpaceStream.cpp
index 1a407fc..b5a5da5 100644
--- a/system/OpenglSystemCommon/AddressSpaceStream.cpp
+++ b/system/OpenglSystemCommon/AddressSpaceStream.cpp
@@ -142,67 +142,111 @@
     AddressSpaceStream* res =
         new AddressSpaceStream(
             child_device_handle, version, context,
-            ringOffset, bufferOffset, ops);
+            ringOffset, bufferOffset, false /* not virtio */, ops);
 
     return res;
 }
 
 #if defined(VIRTIO_GPU) && !defined(HOST_BUILD)
-#include "VirtGpu.h"
-#include "virtgpu_gfxstream_protocol.h"
-
 AddressSpaceStream* createVirtioGpuAddressSpaceStream(const struct StreamCreate &streamCreate) {
     auto handle = reinterpret_cast<address_space_handle_t>(streamCreate.streamHandle);
+    struct address_space_virtgpu_info virtgpu_info;
 
-    VirtGpuBlobPtr pipe, blob;
-    VirtGpuBlobMappingPtr pipeMapping, blobMapping;
-    struct VirtGpuExecBuffer exec = { 0 };
-    struct VirtGpuCreateBlob blobCreate = { 0 };
-    struct gfxstreamContextCreate contextCreate = { 0 };
-
-    char* blobAddr, *bufferPtr;
-    int ret;
-
-    // HACK: constants that are currently used.
-    // Ideal solution would use virtio-gpu capabilities to report both ringSize and bufferSize
-    uint32_t ringSize = 12288;
-    uint32_t bufferSize = 1048576;
-
-    VirtGpuDevice& instance = VirtGpuDevice::getInstance();
-
-    blobCreate.blobId = 0;
-    blobCreate.blobMem = kBlobMemHost3d;
-    blobCreate.flags = kBlobFlagMappable;
-    blobCreate.size = ringSize + bufferSize;
-    blob = instance.createBlob(blobCreate);
-    if (!blob)
+    ALOGD("%s: create subdevice and get resp\n", __func__);
+    if (!virtgpu_address_space_create_context_with_subdevice(
+            handle, GoldfishAddressSpaceSubdeviceType::VirtioGpuGraphics,
+            &virtgpu_info)) {
+        ALOGE("AddressSpaceStream::create failed (create subdevice)\n");
+        if (virtgpu_info.resp_mapped_ptr) {
+            munmap(virtgpu_info.resp_mapped_ptr, 4096);
+        }
+        virtgpu_address_space_close(handle);
         return nullptr;
+    }
+    ALOGD("%s: create subdevice and get resp (done)\n", __func__);
 
-    // Context creation command
-    contextCreate.hdr.opCode = GFXSTREAM_CONTEXT_CREATE;
-    contextCreate.resourceId = blob->getResourceHandle();
+    struct address_space_ping request;
+    uint32_t ringSize = 0;
+    uint32_t bufferSize = 0;
 
-    exec.command = static_cast<void*>(&contextCreate);
-    exec.command_size = sizeof(contextCreate);
-
-    ret = instance.execBuffer(exec, blob);
-    if (ret)
+    request.metadata = ASG_GET_RING;
+    if (!virtgpu_address_space_ping_with_response(
+        &virtgpu_info, &request)) {
+        ALOGE("AddressSpaceStream::create failed (get ring version)\n");
+        if (virtgpu_info.resp_mapped_ptr) {
+            munmap(virtgpu_info.resp_mapped_ptr, 4096);
+        }
+        virtgpu_address_space_close(handle);
         return nullptr;
+    }
+    ringSize = request.size;
 
-    // Wait occurs on global timeline -- should we use context specific one?
-    ret = blob->wait();
-    if (ret)
+    request.metadata = ASG_GET_BUFFER;
+    if (!virtgpu_address_space_ping_with_response(
+        &virtgpu_info, &request)) {
+        ALOGE("AddressSpaceStream::create failed (get ring version)\n");
+        if (virtgpu_info.resp_mapped_ptr) {
+            munmap(virtgpu_info.resp_mapped_ptr, 4096);
+        }
+        virtgpu_address_space_close(handle);
         return nullptr;
+    }
+    bufferSize = request.size;
 
-    blobMapping = blob->createMapping();
-    if (!blobMapping)
+    request.metadata = ASG_SET_VERSION;
+    request.size = 1; // version 1
+
+    if (!virtgpu_address_space_ping_with_response(
+        &virtgpu_info, &request)) {
+        ALOGE("AddressSpaceStream::create failed (set version)\n");
+        if (virtgpu_info.resp_mapped_ptr) {
+            munmap(virtgpu_info.resp_mapped_ptr, 4096);
+        }
+        virtgpu_address_space_close(handle);
         return nullptr;
+    }
 
-    blobAddr = reinterpret_cast<char*>(blobMapping->asRawPtr());
+    ALOGD("%s: ping returned. context ring and buffer sizes %u %u\n", __func__,
+            ringSize, bufferSize);
 
-    bufferPtr = blobAddr + sizeof(struct asg_ring_storage);
+    uint64_t hostmem_id = request.metadata;
+    uint32_t version = request.size;
+    size_t hostmem_alloc_size =
+        (size_t)(ringSize + bufferSize);
+
+    ALOGD("%s: hostmem size: %zu\n", __func__, hostmem_alloc_size);
+
+    struct address_space_virtgpu_hostmem_info hostmem_info;
+    if (!virtgpu_address_space_allocate_hostmem(
+            handle,
+            hostmem_alloc_size,
+            hostmem_id,
+            &hostmem_info)) {
+        ALOGE("AddressSpaceStream::create failed (alloc hostmem)\n");
+        if (virtgpu_info.resp_mapped_ptr) {
+            munmap(virtgpu_info.resp_mapped_ptr, 4096);
+        }
+        virtgpu_address_space_close(handle);
+        return nullptr;
+    }
+
+    request.metadata = ASG_GET_CONFIG;
+    if (!virtgpu_address_space_ping_with_response(
+        &virtgpu_info, &request)) {
+        ALOGE("AddressSpaceStream::create failed (get config)\n");
+        if (virtgpu_info.resp_mapped_ptr) {
+            munmap(virtgpu_info.resp_mapped_ptr, 4096);
+        }
+        virtgpu_address_space_close(handle);
+        return nullptr;
+    }
+
+    char* ringPtr = (char*)hostmem_info.ptr;
+    char* bufferPtr = ((char*)hostmem_info.ptr) + sizeof(struct asg_ring_storage);
+
     struct asg_context context =
-        asg_context_create(blobAddr, bufferPtr, bufferSize);
+        asg_context_create(
+            (char*)ringPtr, (char*)bufferPtr, bufferSize);
 
     context.ring_config->transfer_mode = 1;
     context.ring_config->host_consumed_pos = 0;
@@ -214,13 +258,15 @@
         .ping = virtgpu_address_space_ping,
     };
 
+    if (virtgpu_info.resp_mapped_ptr) {
+        munmap(virtgpu_info.resp_mapped_ptr, 4096);
+    }
+
     AddressSpaceStream* res =
         new AddressSpaceStream(
-            handle, 1, context,
-            0, 0, ops);
+            handle, version, context,
+            0, 0, true /* is virtio */, ops);
 
-    res->setMapping(blobMapping);
-    res->setResourceId(contextCreate.resourceId);
     return res;
 }
 #endif // VIRTIO_GPU && !HOST_BUILD
@@ -232,8 +278,10 @@
     struct asg_context context,
     uint64_t ringOffset,
     uint64_t writeBufferOffset,
+    bool virtioMode,
     struct address_space_ops ops) :
     IOStream(context.ring_config->flush_interval),
+    m_virtioMode(virtioMode),
     m_ops(ops),
     m_tmpBuf(0),
     m_tmpBufSize(0),
@@ -266,19 +314,16 @@
     flush();
     ensureType3Finished();
     ensureType1Finished();
-    bool goldfish = true;
-
-#if defined(VIRTIO_GPU) && !defined(HOST_BUILD)
-    goldfish = false;
-#endif
-
-    if (goldfish) {
+    if (m_virtioMode) {
+        if (m_context.to_host) {
+            munmap(m_context.to_host, m_ringStorageSize);
+        }
+    } else {
         m_ops.unmap(m_context.to_host, sizeof(struct asg_ring_storage));
         m_ops.unmap(m_context.buffer, m_writeBufferSize);
         m_ops.unclaim_shared(m_handle, m_ringOffset);
         m_ops.unclaim_shared(m_handle, m_writeBufferOffset);
     }
-
     m_ops.close(m_handle);
     if (m_readBuf) free(m_readBuf);
     if (m_tmpBuf) free(m_tmpBuf);
diff --git a/system/OpenglSystemCommon/AddressSpaceStream.h b/system/OpenglSystemCommon/AddressSpaceStream.h
index 252afdf..9871c0c 100644
--- a/system/OpenglSystemCommon/AddressSpaceStream.h
+++ b/system/OpenglSystemCommon/AddressSpaceStream.h
@@ -26,7 +26,6 @@
 AddressSpaceStream* createAddressSpaceStream(size_t bufSize);
 
 #if defined(VIRTIO_GPU) && !defined(HOST_BUILD)
-#include "VirtGpu.h"
 struct StreamCreate {
    int streamHandle;
 };
@@ -42,6 +41,7 @@
         struct asg_context context,
         uint64_t ringOffset,
         uint64_t writeBufferOffset,
+        bool virtioMode,
         struct address_space_ops ops);
     ~AddressSpaceStream();
 
@@ -54,11 +54,14 @@
     virtual int writeFullyAsync(const void *buf, size_t len);
     virtual const unsigned char *commitBufferAndReadFully(size_t size, void *buf, size_t len);
 
-#if defined(VIRTIO_GPU) && !defined(HOST_BUILD)
-    void setMapping(VirtGpuBlobMappingPtr mapping) {
-        m_mapping = mapping;
-    }
+    int getRendernodeFd() const {
+#if defined(__Fuchsia__)
+        return -1;
+#else
+        if (!m_virtioMode) return -1;
+        return m_handle;
 #endif
+    }
 
     void setResourceId(uint32_t id) {
         m_resourceId = id;
@@ -78,9 +81,7 @@
     void backoff();
     void resetBackoff();
 
-#if defined(VIRTIO_GPU) && !defined(HOST_BUILD)
-    VirtGpuBlobMappingPtr m_mapping = nullptr;
-#endif
+    bool m_virtioMode;
     struct address_space_ops m_ops;
 
     unsigned char* m_tmpBuf;
diff --git a/system/OpenglSystemCommon/Android.mk b/system/OpenglSystemCommon/Android.mk
index d8baa72..f9cd67a 100644
--- a/system/OpenglSystemCommon/Android.mk
+++ b/system/OpenglSystemCommon/Android.mk
@@ -7,7 +7,6 @@
 $(call emugl-import,libqemupipe$(GOLDFISH_OPENGL_LIB_SUFFIX))
 $(call emugl-import,libgralloc_cb$(GOLDFISH_OPENGL_LIB_SUFFIX))
 else
-$(call emugl-export,STATIC_LIBRARIES,libplatform)
 $(call emugl-export,STATIC_LIBRARIES,libGoldfishAddressSpace libringbuffer)
 $(call emugl-export,STATIC_LIBRARIES,libqemupipe.ranchu)
 $(call emugl-export,HEADER_LIBRARIES,libgralloc_cb.ranchu)
diff --git a/system/OpenglSystemCommon/CMakeLists.txt b/system/OpenglSystemCommon/CMakeLists.txt
index bf70ce1..a9f1d18 100644
--- a/system/OpenglSystemCommon/CMakeLists.txt
+++ b/system/OpenglSystemCommon/CMakeLists.txt
@@ -1,7 +1,7 @@
 # This is an autogenerated file! Do not edit!
 # instead run make from .../device/generic/goldfish-opengl
 # which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/Android.mk" "c9c6a068c9340b11b10548288d78dc4c806674429f154cd16971c69a9fc7fd71")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/Android.mk" "401986affa6f80625f00675980f448fa434d724df34034781651daffaa8e6b70")
 set(OpenglSystemCommon_src FormatConversions.cpp HostConnection.cpp QemuPipeStream.cpp ProcessPipe.cpp ThreadInfo.cpp AddressSpaceStream.cpp)
 android_add_library(TARGET OpenglSystemCommon SHARED LICENSE Apache-2.0 SRC FormatConversions.cpp HostConnection.cpp QemuPipeStream.cpp ProcessPipe.cpp ThreadInfo.cpp AddressSpaceStream.cpp)
 target_include_directories(OpenglSystemCommon PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/shared/gralloc_cb/include ${GOLDFISH_DEVICE_ROOT}/shared/GoldfishAddressSpace/include ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include-types ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index e6ba15f..0014482 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -89,7 +89,6 @@
 
 #ifdef VIRTIO_GPU
 
-#include "VirtGpu.h"
 #include "VirtioGpuStream.h"
 #include "VirtioGpuPipeStream.h"
 #include "virtgpu_drm.h"
@@ -434,6 +433,42 @@
     }
 }
 
+#if defined(VIRTIO_GPU) && !defined(HOST_BUILD)
+int virtgpuOpen(uint32_t capset_id) {
+    int fd = drmOpenRender(128);
+    if (fd < 0) {
+        ALOGE("Failed to open rendernode: %s", strerror(errno));
+        return fd;
+    }
+
+    if (capset_id) {
+        int ret;
+        struct drm_virtgpu_context_init init = {0};
+        struct drm_virtgpu_context_set_param ctx_set_params[2] = {{0}};
+
+        ctx_set_params[0].param = VIRTGPU_CONTEXT_PARAM_NUM_RINGS;
+        ctx_set_params[0].value = 1;
+        init.num_params = 1;
+
+        // TODO(b/218538495): A KI in the 5.4 kernel will sometimes result in capsets not
+        // being properly queried.
+#if defined(__linux__) && !defined(__ANDROID__)
+        ctx_set_params[1].param = VIRTGPU_CONTEXT_PARAM_CAPSET_ID;
+        ctx_set_params[1].value = capset_id;
+        init.num_params++;
+#endif
+
+        init.ctx_set_params = (unsigned long long)&ctx_set_params[0];
+        ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_CONTEXT_INIT, &init);
+        if (ret) {
+            ALOGE("DRM_IOCTL_VIRTGPU_CONTEXT_INIT failed with %s, continuing without context...", strerror(errno));
+        }
+    }
+
+    return fd;
+}
+#endif
+
 // static
 std::unique_ptr<HostConnection> HostConnection::connect(uint32_t capset_id) {
     const enum HostConnectionType connType = getConnectionTypeFromProperty();
@@ -551,9 +586,7 @@
         }
         case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
             struct StreamCreate streamCreate = {0};
-            VirtGpuDevice& instance = VirtGpuDevice::getInstance((enum VirtGpuCapset)capset_id);
-            auto deviceHandle = instance.getDeviceHandle();
-            streamCreate.streamHandle = deviceHandle;
+            streamCreate.streamHandle = virtgpuOpen(capset_id);
             if (streamCreate.streamHandle < 0) {
                 ALOGE("Failed to open virtgpu for ASG host connection\n");
                 return nullptr;
@@ -566,15 +599,16 @@
             }
             con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE;
             con->m_grallocType = getGrallocTypeFromProperty();
+            auto rendernodeFd = stream->getRendernodeFd();
             con->m_stream = stream;
-            con->m_rendernodeFd = deviceHandle;
+            con->m_rendernodeFd = rendernodeFd;
             switch (con->m_grallocType) {
                 case GRALLOC_TYPE_RANCHU:
                     con->m_grallocHelper = &m_goldfishGralloc;
                     break;
                 case GRALLOC_TYPE_MINIGBM: {
                     MinigbmGralloc* m = new MinigbmGralloc;
-                    m->setFd(deviceHandle);
+                    m->setFd(rendernodeFd);
                     con->m_grallocHelper = m;
                     break;
                 }
diff --git a/system/OpenglSystemCommon/meson.build b/system/OpenglSystemCommon/meson.build
index 3a903bb..90f0193 100644
--- a/system/OpenglSystemCommon/meson.build
+++ b/system/OpenglSystemCommon/meson.build
@@ -19,8 +19,8 @@
                          inc_render_enc, inc_android_compat,
                          inc_qemu_pipe, inc_qemu_pipe_types, inc_gralloc,
                          inc_vulkan_enc, inc_goldfish_address_space,
-                         inc_system, inc_platform],
+                         inc_system],
    link_with: [lib_codec_common, lib_goldfish_address_space, lib_qemu_pipe,
-               lib_render_control_enc, lib_platform],
+               lib_render_control_enc],
    dependencies: drm_dep
 )
diff --git a/system/vulkan_enc/Android.mk b/system/vulkan_enc/Android.mk
index a55a13d..583d3bf 100644
--- a/system/vulkan_enc/Android.mk
+++ b/system/vulkan_enc/Android.mk
@@ -8,7 +8,6 @@
 $(call emugl-import,libGoldfishAddressSpace$(GOLDFISH_OPENGL_LIB_SUFFIX))
 else
 $(call emugl-export,SHARED_LIBRARIES,libandroidemu)
-$(call emugl-export,STATIC_LIBRARIES,libplatform)
 $(call emugl-export,STATIC_LIBRARIES,libGoldfishAddressSpace)
 endif
 
diff --git a/system/vulkan_enc/CMakeLists.txt b/system/vulkan_enc/CMakeLists.txt
index 86e3f73..c35e354 100644
--- a/system/vulkan_enc/CMakeLists.txt
+++ b/system/vulkan_enc/CMakeLists.txt
@@ -1,7 +1,7 @@
 # This is an autogenerated file! Do not edit!
 # instead run make from .../device/generic/goldfish-opengl
 # which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "0b078fea2dc389641c31049c67c3995a49dea555d40140e2aa6c286e435f0a1c")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "c24e604f7cd8a39732ec2aae658ded8a919a8e566deee75b74389ccd718e3a36")
 set(vulkan_enc_src AndroidHardwareBuffer.cpp CommandBufferStagingStream.cpp DescriptorSetVirtualization.cpp HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStreamGuest.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_reserved_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_counting_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp func_table.cpp)
 android_add_library(TARGET vulkan_enc SHARED LICENSE Apache-2.0 SRC AndroidHardwareBuffer.cpp CommandBufferStagingStream.cpp DescriptorSetVirtualization.cpp HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStreamGuest.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_reserved_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_counting_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp func_table.cpp)
 target_include_directories(vulkan_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/shared/GoldfishAddressSpace/include ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include-types ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include/vulkan)