minigbm interop

status: boots to home screen with minigbm,
run apps, recents

bug: 146066070

Change-Id: Ie789dbcc0c7505337da3a4bfbc1f09a6819e28dc
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index 90b5f53..13bd8ad 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -131,4 +131,10 @@
     HOST_CONNECTION_VIRTIO_GPU_PIPE = 4,
 };
 
+enum GrallocType {
+    GRALLOC_TYPE_RANCHU = 0,
+    GRALLOC_TYPE_MINIGBM = 1,
+    GRALLOC_TYPE_DYN_ALLOC_MINIGBM = 2,
+};
+
 #endif // __COMMON_EMULATOR_FEATURE_INFO_H
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 09e2e9a..988f1c1 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -70,8 +70,14 @@
 #include "gralloc_cb.h"
 
 #ifdef VIRTIO_GPU
+
 #include "VirtioGpuStream.h"
 #include "VirtioGpuPipeStream.h"
+
+#include <cros_gralloc_handle.h>
+#include <drm/virtgpu_drm.h>
+#include <xf86drm.h>
+
 #endif
 
 #undef LOG_TAG
@@ -125,21 +131,202 @@
     return (uint32_t)interval;
 }
 
+static GrallocType getGrallocTypeFromProperty() {
+    char prop[PROPERTY_VALUE_MAX] = "";
+    property_get("ro.boot.hardware.gralloc", prop, "");
+
+    bool isValid = prop[0] != '\0';
+
+    if (!isValid) return GRALLOC_TYPE_RANCHU;
+
+    if (!strcmp("ranchu", prop)) return GRALLOC_TYPE_RANCHU;
+    if (!strcmp("minigbm", prop)) return GRALLOC_TYPE_MINIGBM;
+    return GRALLOC_TYPE_RANCHU;
+}
 
 class GoldfishGralloc : public Gralloc
 {
 public:
-    uint32_t getHostHandle(native_handle_t const* handle)
+    virtual uint32_t createColorBuffer(
+        ExtendedRCEncoderContext* rcEnc,
+        int width, int height, uint32_t glformat) {
+        return rcEnc->rcCreateColorBuffer(
+            rcEnc, width, height, glformat);
+    }
+
+    virtual uint32_t getHostHandle(native_handle_t const* handle)
     {
         return cb_handle_t::from(handle)->hostHandle;
     }
 
-    int getFormat(native_handle_t const* handle)
+    virtual int getFormat(native_handle_t const* handle)
     {
         return cb_handle_t::from(handle)->format;
     }
+
+    virtual size_t getAllocatedSize(native_handle_t const* handle)
+    {
+        return static_cast<size_t>(cb_handle_t::from(handle)->allocatedSize());
+    }
 };
 
+static inline uint32_t align_up(uint32_t n, uint32_t a) {
+    return ((n + a - 1) / a) * a;
+}
+
+#ifdef VIRTIO_GPU
+
+class MinigbmGralloc : public Gralloc {
+public:
+    virtual uint32_t createColorBuffer(
+        ExtendedRCEncoderContext*,
+        int width, int height, uint32_t glformat) {
+
+        // Only supported format for pbuffers in gfxstream
+        // should be RGBA8
+        const uint32_t kGlRGBA = 0x1908;
+        const uint32_t kVirglFormatRGBA = 67; // VIRGL_FORMAT_R8G8B8A8_UNORM;
+        uint32_t virtgpu_format = 0;
+        uint32_t bpp = 0;
+        switch (glformat) {
+            case kGlRGBA:
+                virtgpu_format = kVirglFormatRGBA;
+                bpp = 4;
+                break;
+            default:
+                ALOGE("%s: error, unsupported format: 0x%x\n", __func__,
+                      glformat);
+                abort();
+        }
+        const uint32_t kPipeTexture2D = 2; // PIPE_TEXTURE_2D
+        const uint32_t kBindRenderTarget = 1 << 1; // VIRGL_BIND_RENDER_TARGET
+        struct drm_virtgpu_resource_create res_create;
+        memset(&res_create, 0, sizeof(res_create));
+        res_create.target = kPipeTexture2D;
+        res_create.format = virtgpu_format;
+        res_create.bind = kBindRenderTarget;
+        res_create.width = width;
+        res_create.height = height;
+        res_create.depth = 1;
+        res_create.array_size = 1;
+        res_create.last_level = 0;
+        res_create.nr_samples = 0;
+        res_create.stride = bpp * width;
+        res_create.size = align_up(bpp * width * height, PAGE_SIZE);
+
+        int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create);
+        if (ret) {
+            ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s (%d)\n", __func__,
+                  strerror(errno), errno);
+            abort();
+        }
+
+        return res_create.res_handle;
+    }
+
+    virtual uint32_t getHostHandle(native_handle_t const* handle) {
+        struct drm_virtgpu_resource_info info;
+        if (!getResInfo(handle, &info)) {
+            ALOGE("%s: failed to get resource info\n", __func__);
+            return 0;
+        }
+
+        return info.res_handle;
+    }
+
+    virtual int getFormat(native_handle_t const* handle) {
+        return ((cros_gralloc_handle *)handle)->droid_format;
+    }
+
+    virtual size_t getAllocatedSize(native_handle_t const* handle) {
+        struct drm_virtgpu_resource_info info;
+        if (!getResInfo(handle, &info)) {
+            ALOGE("%s: failed to get resource info\n", __func__);
+            return 0;
+        }
+
+        return info.size;
+    }
+
+    void setFd(int fd) { m_fd = fd; }
+
+private:
+
+    bool getResInfo(native_handle_t const* handle,
+                    struct drm_virtgpu_resource_info* info) {
+        memset(info, 0x0, sizeof(*info));
+        if (m_fd < 0) {
+            ALOGE("%s: Error, rendernode fd missing\n", __func__);
+            return false;
+        }
+
+        struct drm_gem_close gem_close;
+        memset(&gem_close, 0x0, sizeof(gem_close));
+
+        cros_gralloc_handle const* cros_handle =
+            reinterpret_cast<cros_gralloc_handle const*>(handle);
+
+        uint32_t prime_handle;
+        int ret = drmPrimeFDToHandle(m_fd, cros_handle->fds[0], &prime_handle);
+        if (ret) {
+            ALOGE("%s: DRM_IOCTL_PRIME_FD_TO_HANDLE failed: %s (errno %d)\n",
+                  __func__, strerror(errno), errno);
+            return false;
+        }
+
+        info->bo_handle = prime_handle;
+        gem_close.handle = prime_handle;
+
+        ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO, info);
+        if (ret) {
+            ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed: %s (errno %d)\n",
+                  __func__, strerror(errno), errno);
+            drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+            return false;
+        }
+
+        drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+        return true;
+    }
+
+    int m_fd = -1;
+};
+
+#else
+
+class MinigbmGralloc : public Gralloc {
+public:
+    virtual uint32_t createColorBuffer(
+        ExtendedRCEncoderContext*,
+        int width, int height, uint32_t glformat) {
+        ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+        return 0;
+    }
+
+    virtual uint32_t getHostHandle(native_handle_t const* handle) {
+        ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+        return 0;
+    }
+
+    virtual int getFormat(native_handle_t const* handle) {
+        ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+        return 0;
+    }
+
+    virtual size_t getAllocatedSize(native_handle_t const* handle) {
+        ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+        return 0;
+    }
+
+    void setFd(int fd) { m_fd = fd; }
+
+private:
+
+    int m_fd = -1;
+};
+
+#endif
+
 class GoldfishProcessPipe : public ProcessPipe
 {
 public:
@@ -170,6 +357,9 @@
     if (m_rcEnc) {
         (void) m_rcEnc->rcGetRendererVersion(m_rcEnc);
     }
+    if (m_grallocType == GRALLOC_TYPE_MINIGBM) {
+        delete m_grallocHelper;
+    }
     delete m_stream;
     delete m_glEnc;
     delete m_gl2Enc;
@@ -192,6 +382,7 @@
                 return NULL;
             }
             con->m_connectionType = HOST_CONNECTION_ADDRESS_SPACE;
+            con->m_grallocType = GRALLOC_TYPE_RANCHU;
             con->m_stream = stream;
             con->m_grallocHelper = &m_goldfishGralloc;
             con->m_processPipe = &m_goldfishProcessPipe;
@@ -211,6 +402,7 @@
                 return NULL;
             }
             con->m_connectionType = HOST_CONNECTION_QEMU_PIPE;
+            con->m_grallocType = GRALLOC_TYPE_RANCHU;
             con->m_stream = stream;
             con->m_grallocHelper = &m_goldfishGralloc;
             con->m_processPipe = &m_goldfishProcessPipe;
@@ -237,6 +429,7 @@
                 return NULL;
             }
             con->m_connectionType = HOST_CONNECTION_TCP;
+            con->m_grallocType = GRALLOC_TYPE_RANCHU;
             con->m_stream = stream;
             con->m_grallocHelper = &m_goldfishGralloc;
             con->m_processPipe = &m_goldfishProcessPipe;
@@ -258,8 +451,11 @@
                 return NULL;
             }
             con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU;
+            con->m_grallocType = GRALLOC_TYPE_MINIGBM;
             con->m_stream = stream;
-            con->m_grallocHelper = stream->getGralloc();
+            MinigbmGralloc* m = new MinigbmGralloc;
+            m->setFd(stream->getRendernodeFd());
+            con->m_grallocHelper = m;
             con->m_processPipe = stream->getProcessPipe();
             break;
         }
@@ -277,8 +473,22 @@
                 return NULL;
             }
             con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU_PIPE;
+            con->m_grallocType = getGrallocTypeFromProperty();
             con->m_stream = stream;
-            con->m_grallocHelper = &m_goldfishGralloc;
+            switch (con->m_grallocType) {
+                case GRALLOC_TYPE_RANCHU:
+                    con->m_grallocHelper = &m_goldfishGralloc;
+                    break;
+                case GRALLOC_TYPE_MINIGBM: {
+                    MinigbmGralloc* m = new MinigbmGralloc;
+                    m->setFd(stream->getRendernodeFd());
+                    con->m_grallocHelper = m;
+                    break;
+                }
+                default:
+                    ALOGE("Fatal: Unknown gralloc type 0x%x\n", con->m_grallocType);
+                    abort();
+            }
             con->m_processPipe = &m_goldfishProcessPipe;
             break;
         }
@@ -333,7 +543,7 @@
     }
 }
 
-// static 
+// static
 HostConnection *HostConnection::createUnique() {
     ALOGD("%s: call\n", __func__);
     return connect(new HostConnection());
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index fe89fb0..501c254 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -114,8 +114,11 @@
 // Abstraction for gralloc handle conversion
 class Gralloc {
 public:
+    virtual uint32_t createColorBuffer(
+        ExtendedRCEncoderContext* rcEnc, int width, int height, uint32_t glformat);
     virtual uint32_t getHostHandle(native_handle_t const* handle) = 0;
     virtual int getFormat(native_handle_t const* handle) = 0;
+    virtual size_t getAllocatedSize(native_handle_t const* handle) = 0;
     virtual ~Gralloc() {}
 };
 
@@ -202,6 +205,7 @@
 
 private:
     HostConnectionType m_connectionType;
+    GrallocType m_grallocType;
     IOStream *m_stream;
     GLEncoder   *m_glEnc;
     GL2Encoder  *m_gl2Enc;
diff --git a/system/OpenglSystemCommon/VirtioGpuPipeStream.h b/system/OpenglSystemCommon/VirtioGpuPipeStream.h
index 31366f3..3f3c537 100644
--- a/system/OpenglSystemCommon/VirtioGpuPipeStream.h
+++ b/system/OpenglSystemCommon/VirtioGpuPipeStream.h
@@ -43,6 +43,7 @@
     virtual const unsigned char *read( void *buf, size_t *inout_len);
 
     bool valid() { return m_fd >= 0; }
+    int getRendernodeFd() { return m_fd; }
     int recv(void *buf, size_t len);
 
     virtual int writeFully(const void *buf, size_t len);
diff --git a/system/OpenglSystemCommon/VirtioGpuStream.cpp b/system/OpenglSystemCommon/VirtioGpuStream.cpp
index 341ecea..a0876dc 100644
--- a/system/OpenglSystemCommon/VirtioGpuStream.cpp
+++ b/system/OpenglSystemCommon/VirtioGpuStream.cpp
@@ -52,24 +52,6 @@
     unsigned char buf[0];
 } __attribute__((packed));
 
-uint32_t CrosGralloc::getHostHandle(native_handle_t const* handle_)
-{
-    uint32_t id = 0;
-
-    if (m_fd >= 0) {
-        cros_gralloc_handle const* handle =
-          reinterpret_cast<cros_gralloc_handle const*>(handle_);
-        drmPrimeFDToHandle(m_fd, handle->fds[0], &id);
-    }
-
-    return id;
-}
-
-int CrosGralloc::getFormat(native_handle_t const* handle)
-{
-    return ((cros_gralloc_handle *)handle)->droid_format;
-}
-
 bool VirtioGpuProcessPipe::processPipeInit(HostConnectionType, renderControl_encoder_context_t *rcEnc)
 {
   union {
@@ -187,7 +169,6 @@
         }
     }
 
-    m_gralloc.setFd(m_fd);
     return 0;
 }
 
diff --git a/system/OpenglSystemCommon/VirtioGpuStream.h b/system/OpenglSystemCommon/VirtioGpuStream.h
index 98c1025..1c7a496 100644
--- a/system/OpenglSystemCommon/VirtioGpuStream.h
+++ b/system/OpenglSystemCommon/VirtioGpuStream.h
@@ -27,19 +27,6 @@
 
 struct VirtioGpuCmd;
 
-class CrosGralloc : public Gralloc
-{
-    friend class VirtioGpuStream;
-
-public:
-    virtual uint32_t getHostHandle(native_handle_t const* handle);
-    virtual int getFormat(native_handle_t const* handle);
-
-private:
-    inline void setFd(int fd) { m_fd = fd; }
-    int m_fd = -1;
-};
-
 class VirtioGpuProcessPipe : public ProcessPipe
 {
 public:
@@ -53,7 +40,6 @@
     ~VirtioGpuStream();
 
     int connect();
-    Gralloc *getGralloc() { return &m_gralloc; }
     ProcessPipe *getProcessPipe() { return &m_processPipe; }
 
     // override IOStream so we can see non-rounded allocation sizes
@@ -83,6 +69,8 @@
         return m_fd >= 0 && m_cmdResp_bo > 0 && m_cmdResp;
     }
 
+    int getRendernodeFd() { return m_fd; }
+
 private:
     // rendernode fd
     int m_fd;
@@ -115,9 +103,6 @@
     // bytes of an alloc flushed through flush() API
     size_t m_allocFlushSize;
 
-    // CrOS gralloc interface
-    CrosGralloc m_gralloc;
-
     // Fake process pipe implementation
     VirtioGpuProcessPipe m_processPipe;
 
diff --git a/system/cbmanager/hidl.cpp b/system/cbmanager/hidl.cpp
index c5a49eb..a0fb34a 100644
--- a/system/cbmanager/hidl.cpp
+++ b/system/cbmanager/hidl.cpp
@@ -41,8 +41,8 @@
                         sp<IAllocator2ns::IAllocator> allocator)
       : mMapper(mapper), mAllocator(allocator) {}
 
-    cb_handle_t* allocateBuffer(int width, int height,
-                                PixelFormat format, BufferUsageBits usage) {
+    native_handle_t* allocateBuffer(int width, int height,
+                                    PixelFormat format, BufferUsageBits usage) {
         using IMapper2ns::Error;
         using IMapper2ns::BufferDescriptor;
 
@@ -78,11 +78,11 @@
             RETURN_ERROR(nullptr);
         }
 
-        cb_handle_t *buf = nullptr;
+        native_handle_t *buf = nullptr;
         mMapper->importBuffer(raw_handle, [&](const Error &_error,
                                               void *_buf) {
             hidl_err = _error;
-            buf = cb_handle_t::from(_buf);
+            buf = static_cast<native_handle_t*>(_buf);
         });
         if (hidl_err != Error::NONE) {
             RETURN_ERROR(nullptr);
@@ -91,17 +91,17 @@
         RETURN(buf);
     }
 
-    void freeBuffer(const cb_handle_t* _h) {
+    void freeBuffer(const native_handle_t* _h) {
         using IMapper2ns::Error;
 
-        cb_handle_t* h = const_cast<cb_handle_t*>(_h);
+        native_handle_t* h = const_cast<native_handle_t*>(_h);
 
         mMapper->freeBuffer(h);
         native_handle_close(h);
         native_handle_delete(h);
     }
 
-    int lockBuffer(cb_handle_t& handle,
+    int lockBuffer(native_handle_t& handle,
                    BufferUsageBits usage,
                    int left, int top, int width, int height,
                    void** vaddr) {
@@ -128,7 +128,7 @@
         }
     }
 
-    int lockYCbCrBuffer(cb_handle_t& handle,
+    int lockYCbCrBuffer(native_handle_t& handle,
                         BufferUsageBits usage,
                         int left, int top, int width, int height,
                         YCbCrLayout* ycbcr) {
@@ -155,7 +155,7 @@
         }
     }
 
-    int unlockBuffer(cb_handle_t& handle) {
+    int unlockBuffer(native_handle_t& handle) {
         using IMapper2ns::Error;
 
         Error hidl_err = Error::NONE;
diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp
index 859702d..5940b79 100644
--- a/system/egl/egl.cpp
+++ b/system/egl/egl.cpp
@@ -675,7 +675,7 @@
         return EGL_FALSE;
     }
 
-    rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat);
+    rcColorBuffer = grallocHelper->createColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat);
     if (!rcColorBuffer) {
         ALOGE("rcCreateColorBuffer returned 0");
         return EGL_FALSE;
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp
index 8006563..f2fb947 100644
--- a/system/hwc2/EmuHWC2.cpp
+++ b/system/hwc2/EmuHWC2.cpp
@@ -389,7 +389,7 @@
     return Error::None;
 }
 
-const cb_handle_t* EmuHWC2::allocateDisplayColorBuffer() {
+const native_handle_t* EmuHWC2::allocateDisplayColorBuffer() {
     typedef CbManager::BufferUsage BufferUsage;
 
     return mCbManager.allocateBuffer(
@@ -399,7 +399,7 @@
         (BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_RENDER_TARGET));
 }
 
-void EmuHWC2::freeDisplayColorBuffer(const cb_handle_t* h) {
+void EmuHWC2::freeDisplayColorBuffer(const native_handle_t* h) {
     mCbManager.freeBuffer(h);
 }
 
@@ -809,10 +809,10 @@
                     ALOGV("%s: acquire fence not set for layer %u",
                           __FUNCTION__, (uint32_t)layer->getId());
                 }
-                const cb_handle_t *cb =
-                    cb_handle_t::from(layer->getLayerBuffer().getBuffer());
+                const native_handle_t *cb =
+                    layer->getLayerBuffer().getBuffer();
                 if (cb != nullptr) {
-                    l->cbHandle = cb->hostHandle;
+                    l->cbHandle = hostCon->grallocHelper()->getHostHandle(cb);
                 }
                 else {
                     ALOGE("%s null buffer for layer %d", __FUNCTION__,
@@ -840,12 +840,12 @@
         }
         if (hostCompositionV1) {
             p->version = 1;
-            p->targetHandle = mTargetCb->hostHandle;
+            p->targetHandle = hostCon->grallocHelper()->getHostHandle(mTargetCb);
             p->numLayers = numLayer;
         } else {
             p2->version = 2;
             p2->displayId = mHostDisplayId;
-            p2->targetHandle = mTargetCb->hostHandle;
+            p2->targetHandle = hostCon->grallocHelper()->getHostHandle(mTargetCb);
             p2->numLayers = numLayer;
         }
 
@@ -920,9 +920,6 @@
         int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
     ALOGVV("%s", __FUNCTION__);
 
-    const cb_handle_t *cb = cb_handle_t::from(target);
-    ALOGV("%s: display(%u) buffer handle %p cb %d, acquireFence %d", __FUNCTION__,
-          (uint32_t)mId, target, cb->hostHandle, acquireFence);
     std::unique_lock<std::mutex> lock(mStateMutex);
     mClientTarget.setBuffer(target);
     mClientTarget.setFence(acquireFence);
@@ -1307,11 +1304,10 @@
 void EmuHWC2::Display::post(HostConnection *hostCon,
                             ExtendedRCEncoderContext *rcEnc,
                             buffer_handle_t h) {
-    const cb_handle_t* cb = cb_handle_t::from(h);
-    assert(cb && "cb_handle_t::from(h) failed");
+    assert(cb && "native_handle_t::from(h) failed");
 
     hostCon->lock();
-    rcEnc->rcFBPost(rcEnc, cb->hostHandle);
+    rcEnc->rcFBPost(rcEnc, hostCon->grallocHelper()->getHostHandle(h));
     hostCon->unlock();
 }
 
diff --git a/system/hwc2/EmuHWC2.h b/system/hwc2/EmuHWC2.h
index 3428ec0..8cb71c1 100644
--- a/system/hwc2/EmuHWC2.h
+++ b/system/hwc2/EmuHWC2.h
@@ -34,7 +34,8 @@
 #include <unordered_map>
 #include <set>
 
-#include "gralloc_cb.h"
+#include <cutils/native_handle.h>
+
 #include "cbmanager.h"
 #include "MiniFence.h"
 #include "HostConnection.h"
@@ -373,7 +374,7 @@
         std::unique_ptr<ComposeMsg> mComposeMsg;
         std::unique_ptr<ComposeMsg_v2> mComposeMsg_v2;
         int mSyncDeviceFd;
-        const cb_handle_t* mTargetCb;
+        const native_handle_t* mTargetCb;
     };
 
     template<typename MF, MF memFunc, typename ...Args>
@@ -463,8 +464,8 @@
             hwc2_layer_t layerId);
 
     HWC2::Error initDisplayParameters();
-    const cb_handle_t* allocateDisplayColorBuffer();
-    void freeDisplayColorBuffer(const cb_handle_t* h);
+    const native_handle_t* allocateDisplayColorBuffer();
+    void freeDisplayColorBuffer(const native_handle_t* h);
 
     CbManager mCbManager;
     std::unordered_set<HWC2::Capability> mCapabilities;
diff --git a/system/include/cbmanager.h b/system/include/cbmanager.h
index ee33974..4bddedb 100644
--- a/system/include/cbmanager.h
+++ b/system/include/cbmanager.h
@@ -17,9 +17,13 @@
 #ifndef ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
 #define ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
 
+#include <cutils/native_handle.h>
+#include <log/log.h>
+
 #include <memory>
 #include <android/hardware/graphics/common/1.0/types.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
 #include "gralloc_cb.h"
 
 namespace android {
@@ -36,34 +40,35 @@
     class CbManagerImpl {
     public:
         virtual ~CbManagerImpl() {}
-        virtual cb_handle_t* allocateBuffer(int width,
-                                            int height,
-                                            PixelFormat format,
-                                            BufferUsageBits usage) = 0;
-        virtual void freeBuffer(const cb_handle_t* h) = 0;
+        virtual native_handle_t* allocateBuffer(int width,
+                                                int height,
+                                                PixelFormat format,
+                                                BufferUsageBits usage) = 0;
+        virtual void freeBuffer(const native_handle_t* h) = 0;
 
-        virtual int lockBuffer(cb_handle_t& handle,
+        virtual int lockBuffer(native_handle_t& handle,
              BufferUsageBits usage,
              int left, int top, int width, int height,
              void** vaddr) = 0;
 
-        virtual int lockYCbCrBuffer(cb_handle_t& handle,
+        virtual int lockYCbCrBuffer(native_handle_t& handle,
              BufferUsageBits usage,
              int left, int top, int width, int height,
              YCbCrLayout* ycbcr) = 0;
 
-        virtual int unlockBuffer(cb_handle_t& handle) = 0;
+        virtual int unlockBuffer(native_handle_t& handle) = 0;
     };
 
-    cb_handle_t* allocateBuffer(int width, int height, PixelFormat format, BufferUsageBits usage) {
+    native_handle_t* allocateBuffer(
+        int width, int height, PixelFormat format, BufferUsageBits usage) {
         return mImpl->allocateBuffer(width, height, format, usage);
     }
 
-    void freeBuffer(const cb_handle_t* h) {
+    void freeBuffer(const native_handle_t* h) {
         mImpl->freeBuffer(h);
     }
 
-    int lockBuffer(cb_handle_t& handle,
+    int lockBuffer(native_handle_t& handle,
              BufferUsageBits usage,
              int left, int top, int width, int height,
              void** vaddr) {
@@ -74,7 +79,7 @@
              BufferUsageBits usage,
              int left, int top, int width, int height,
              void** vaddr) {
-        cb_handle_t* cb = cb_handle_t::from_unconst(h);
+        native_handle_t* cb = const_cast<native_handle_t*>(h);
         if (cb) {
             return lockBuffer(*cb, usage, left, top, width, height, vaddr);
         } else {
@@ -83,7 +88,7 @@
     }
 
 
-    int lockYCbCrBuffer(cb_handle_t& handle,
+    int lockYCbCrBuffer(native_handle_t& handle,
                         BufferUsageBits usage,
                         int left, int top, int width, int height,
                         YCbCrLayout* ycbcr) {
@@ -94,7 +99,7 @@
                         BufferUsageBits usage,
                         int left, int top, int width, int height,
                         YCbCrLayout* ycbcr) {
-        cb_handle_t* cb = cb_handle_t::from_unconst(h);
+        native_handle_t* cb = const_cast<native_handle_t*>(h);
         if (cb) {
             return lockYCbCrBuffer(*cb, usage, left, top, width, height, ycbcr);
         } else {
@@ -102,12 +107,12 @@
         }
     }
 
-    int unlockBuffer(cb_handle_t& handle) {
+    int unlockBuffer(native_handle_t& handle) {
         return mImpl->unlockBuffer(handle);
     }
 
     int unlockBuffer(buffer_handle_t h) {
-        cb_handle_t* cb = cb_handle_t::from_unconst(h);
+        native_handle_t* cb = const_cast<native_handle_t*>(h);
         if (cb) {
             return unlockBuffer(*cb);
         } else {
@@ -115,8 +120,17 @@
         }
     }
 
+    // Specific to goldfish, for obtaining offsets
+    // into host coherent memory
+    // (requires address space devce)
     static uint64_t getOffset(const buffer_handle_t h) {
         const cb_handle_t* cb = cb_handle_t::from(h);
+        if (!cb->isValid()) {
+            ALOGE("%s: FATAL: using incompatible native_handle_t for "
+                  "host coherent mapping offset",
+                  __func__);
+            abort();
+        }
         return cb ? cb->getMmapedOffset() : -1;
     }
 
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
index 0a71d6d..a40a3a7 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -14,7 +14,8 @@
 // limitations under the License.
 #include "AndroidHardwareBuffer.h"
 
-#include "gralloc_cb.h"
+#include "../OpenglSystemCommon/HostConnection.h"
+
 #include "vk_format_info.h"
 #include "vk_util.h"
 
@@ -53,6 +54,7 @@
 }
 
 VkResult getAndroidHardwareBufferPropertiesANDROID(
+    Gralloc* grallocHelper,
     const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
     VkDevice,
     const AHardwareBuffer* buffer,
@@ -111,12 +113,8 @@
 
     const native_handle_t *handle =
        AHardwareBuffer_getNativeHandle(buffer);
-    const cb_handle_t* cb_handle = cb_handle_t::from(handle);
-    if (!cb_handle) {
-        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
-    }
-
-    uint32_t colorBufferHandle = cb_handle->hostHandle;
+    uint32_t colorBufferHandle =
+        grallocHelper->getHostHandle(handle);
     if (!colorBufferHandle) {
         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
     }
@@ -131,7 +129,8 @@
     }
 
     pProperties->memoryTypeBits = memoryTypeBits;
-    pProperties->allocationSize = cb_handle->allocatedSize();
+    pProperties->allocationSize =
+        grallocHelper->getAllocatedSize(handle);
 
     return VK_SUCCESS;
 }
@@ -158,6 +157,7 @@
 }
 
 VkResult importAndroidHardwareBuffer(
+    Gralloc* grallocHelper,
     const VkImportAndroidHardwareBufferInfoANDROID* info,
     struct AHardwareBuffer **importOut) {
 
@@ -165,14 +165,9 @@
         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
     }
 
-    const native_handle_t *handle =
-       AHardwareBuffer_getNativeHandle(info->buffer);
-    const cb_handle_t* cb_handle = cb_handle_t::from(handle);
-    if (!cb_handle) {
-        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
-    }
-
-    uint32_t colorBufferHandle = cb_handle->hostHandle;
+    uint32_t colorBufferHandle =
+        grallocHelper->getHostHandle(
+            AHardwareBuffer_getNativeHandle(info->buffer));
     if (!colorBufferHandle) {
         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
     }
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.h b/system/vulkan_enc/AndroidHardwareBuffer.h
index 81e8cd9..6cd72bc 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.h
+++ b/system/vulkan_enc/AndroidHardwareBuffer.h
@@ -22,6 +22,8 @@
 // Structure similar to
 // https://github.com/mesa3d/mesa/blob/master/src/intel/vulkan/anv_android.c
 
+class Gralloc;
+
 namespace goldfish_vk {
 
 uint64_t
@@ -30,6 +32,7 @@
     const VkImageUsageFlags vk_usage);
 
 VkResult getAndroidHardwareBufferPropertiesANDROID(
+    Gralloc* grallocHelper,
     const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
     VkDevice device,
     const AHardwareBuffer* buffer,
@@ -39,6 +42,7 @@
     struct AHardwareBuffer **pBuffer);
 
 VkResult importAndroidHardwareBuffer(
+    Gralloc* grallocHelper,
     const VkImportAndroidHardwareBufferInfoANDROID* info,
     struct AHardwareBuffer **importOut);
 
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index cfc165a..1210bc6 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -101,7 +101,6 @@
 #include "android/base/AlignedBuf.h"
 #include "android/base/synchronization/AndroidLock.h"
 
-#include "gralloc_cb.h"
 #include "goldfish_address_space.h"
 #include "goldfish_vk_private_defs.h"
 #include "vk_format_info.h"
@@ -1237,7 +1236,10 @@
         VkDevice device,
         const AHardwareBuffer* buffer,
         VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
+        auto grallocHelper =
+            mThreadingCallbacks.hostConnectionGetFunc()->grallocHelper();
         return getAndroidHardwareBufferPropertiesANDROID(
+            grallocHelper,
             &mHostVisibleMemoryVirtInfo,
             device, buffer, pProperties);
     }
@@ -1822,15 +1824,15 @@
             ahw = importAhbInfoPtr->buffer;
             // We still need to acquire the AHardwareBuffer.
             importAndroidHardwareBuffer(
+                mThreadingCallbacks.hostConnectionGetFunc()->grallocHelper(),
                 importAhbInfoPtr, nullptr);
         }
 
         if (ahw) {
-            ALOGD("%s: Import AHardwareBulffer", __func__);
-            const native_handle_t *handle =
-                AHardwareBuffer_getNativeHandle(ahw);
-            const cb_handle_t* cb_handle = cb_handle_t::from(handle);
-            importCbInfo.colorBuffer = cb_handle->hostHandle;
+            ALOGD("%s: Import AHardwareBuffer", __func__);
+            importCbInfo.colorBuffer =
+                mThreadingCallbacks.hostConnectionGetFunc()->grallocHelper()->
+                    getHostHandle(AHardwareBuffer_getNativeHandle(ahw));
             vk_append_struct(&structChainIter, &importCbInfo);
         }
 
@@ -3456,8 +3458,7 @@
             return;
         }
 
-        const cb_handle_t* cb_handle = cb_handle_t::from(nativeInfo->handle);
-        if (!cb_handle) return;
+        if (!nativeInfo->handle) return;
 
         VkNativeBufferANDROID* nativeInfoOut =
             reinterpret_cast<VkNativeBufferANDROID*>(
@@ -3469,7 +3470,10 @@
             abort();
         }
 
-        *(uint32_t*)(nativeInfoOut->handle) = cb_handle->hostHandle;
+        *(uint32_t*)(nativeInfoOut->handle) =
+            mThreadingCallbacks.hostConnectionGetFunc()->
+                grallocHelper()->getHostHandle(
+                    (const native_handle_t*)nativeInfo->handle);
     }
 
     void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int*) {