[vulkan] Allow delivery of rc strings in a compact struct format

bug: 111137294
bug: 121377497

This CL moves the RenderControl features such as sync, dma, gles3, host
composition, direct mem, etc. to a separate file that organizes them
into a struct.

For Vulkan, we can pass this struct to the Vulkan ResourceTracker
to let it decide to use GLDirectMem or not.

Change-Id: Iee24df62412460cbabe0fe23423cd39391698c90
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
new file mode 100644
index 0000000..ba4111e
--- /dev/null
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -0,0 +1,98 @@
+// Copyright (C) 2018 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 __COMMON_EMULATOR_FEATURE_INFO_H
+#define __COMMON_EMULATOR_FEATURE_INFO_H
+
+// SyncImpl determines the presence of host/guest OpenGL fence sync
+// capabilities. It corresponds exactly to EGL_ANDROID_native_fence_sync
+// capability, but for the emulator, we need to make sure that
+// OpenGL pipe protocols match, so we use a special extension name
+// here.
+// SYNC_IMPL_NONE means that the native fence sync capability is
+// not present, and we will end up using the equivalent of glFinish
+// in order to preserve buffer swapping order.
+// SYNC_IMPL_NATIVE_SYNC means that we do have native fence sync
+// capability, and we will use a fence fd to synchronize buffer swaps.
+enum SyncImpl {
+    SYNC_IMPL_NONE = 0,
+    SYNC_IMPL_NATIVE_SYNC_V2 = 1,
+    SYNC_IMPL_NATIVE_SYNC_V3 = 2,
+};
+
+// Interface:
+// Use the highest of v2 or v3 that show up, making us
+// SYNC_IMPL_NATIVE_SYNC_V2 or SYNC_IMPL_NATIVE_SYNC_V3.
+static const char kRCNativeSyncV2[] = "ANDROID_EMU_native_sync_v2";
+static const char kRCNativeSyncV3[] = "ANDROID_EMU_native_sync_v3";
+
+// DMA for OpenGL
+enum DmaImpl {
+    DMA_IMPL_NONE = 0,
+    DMA_IMPL_v1 = 1,
+};
+
+static const char kDmaExtStr_v1[] = "ANDROID_EMU_dma_v1";
+
+// OpenGL ES max supported version
+enum GLESMaxVersion {
+    GLES_MAX_VERSION_2 = 0,
+    GLES_MAX_VERSION_3_0 = 1,
+    GLES_MAX_VERSION_3_1 = 2,
+    GLES_MAX_VERSION_3_2 = 3,
+};
+
+static const char kGLESMaxVersion_2[] = "ANDROID_EMU_gles_max_version_2";
+static const char kGLESMaxVersion_3_0[] = "ANDROID_EMU_gles_max_version_3_0";
+static const char kGLESMaxVersion_3_1[] = "ANDROID_EMU_gles_max_version_3_1";
+static const char kGLESMaxVersion_3_2[] = "ANDROID_EMU_gles_max_version_3_2";
+
+enum HostComposition {
+    HOST_COMPOSITION_NONE = 0,
+    HOST_COMPOSITION_V1,
+};
+
+static const char kHostCompositionV1[] = "ANDROID_EMU_host_composition_v1";
+
+// No querying errors from host extension
+static const char kGLESNoHostError[] = "ANDROID_EMU_gles_no_host_error";
+
+// Host to guest memory mapping
+static const char kGLDirectMem[] = "ANDROID_EMU_direct_mem";
+
+// Vulkan host support
+// To be delivered/enabled when at least the following is working/available:
+// - HOST_COHERENT memory mapping
+// - Full gralloc interop: External memory, AHB
+static const char kVulkan[] = "ANDROID_EMU_vulkan";
+
+// Struct describing available emulator features
+struct EmulatorFeatureInfo {
+
+    EmulatorFeatureInfo() :
+        syncImpl(SYNC_IMPL_NONE),
+        dmaImpl(DMA_IMPL_NONE),
+        hostComposition(HOST_COMPOSITION_NONE),
+        glesMaxVersion(GLES_MAX_VERSION_2),
+        hasDirectMem(false),
+        hasVulkan(false) { }
+
+    SyncImpl syncImpl;
+    DmaImpl dmaImpl;
+    HostComposition hostComposition;
+    GLESMaxVersion glesMaxVersion;
+    bool hasDirectMem;
+    bool hasVulkan;
+};
+
+#endif // __COMMON_EMULATOR_FEATURE_INFO_H
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index c14e12d..28305d3 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -250,6 +250,8 @@
         queryAndSetGLESMaxVersion(m_rcEnc);
         queryAndSetNoErrorState(m_rcEnc);
         queryAndSetHostCompositionImpl(m_rcEnc);
+        queryAndSetDirectMemSupport(m_rcEnc);
+        queryAndSetVulkanSupport(m_rcEnc);
         if (m_processPipe) {
             m_processPipe->processPipeInit(m_rcEnc);
         }
@@ -384,3 +386,17 @@
         m_noHostError = true;
     }
 }
+
+void HostConnection::queryAndSetDirectMemSupport(ExtendedRCEncoderContext* rcEnc) {
+    std::string glExtensions = queryGLExtensions(rcEnc);
+    if (glExtensions.find(kGLDirectMem) != std::string::npos) {
+        rcEnc->featureInfo()->hasDirectMem = true;
+    }
+}
+
+void HostConnection::queryAndSetVulkanSupport(ExtendedRCEncoderContext* rcEnc) {
+    std::string glExtensions = queryGLExtensions(rcEnc);
+    if (glExtensions.find(kVulkan) != std::string::npos) {
+        rcEnc->featureInfo()->hasVulkan = true;
+    }
+}
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index ac2f330..2a4037f 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -16,6 +16,7 @@
 #ifndef __COMMON_HOST_CONNECTION_H
 #define __COMMON_HOST_CONNECTION_H
 
+#include "EmulatorFeatureInfo.h"
 #include "IOStream.h"
 #include "renderControl_enc.h"
 #include "ChecksumCalculator.h"
@@ -33,75 +34,22 @@
 class VkEncoder;
 }
 
-// SyncImpl determines the presence of host/guest OpenGL fence sync
-// capabilities. It corresponds exactly to EGL_ANDROID_native_fence_sync
-// capability, but for the emulator, we need to make sure that
-// OpenGL pipe protocols match, so we use a special extension name
-// here.
-// SYNC_IMPL_NONE means that the native fence sync capability is
-// not present, and we will end up using the equivalent of glFinish
-// in order to preserve buffer swapping order.
-// SYNC_IMPL_NATIVE_SYNC means that we do have native fence sync
-// capability, and we will use a fence fd to synchronize buffer swaps.
-enum SyncImpl {
-    SYNC_IMPL_NONE = 0,
-    SYNC_IMPL_NATIVE_SYNC_V2 = 1,
-    SYNC_IMPL_NATIVE_SYNC_V3 = 2,
-};
-
-// Interface:
-// Use the highest of v2 or v3 that show up, making us
-// SYNC_IMPL_NATIVE_SYNC_V2 or SYNC_IMPL_NATIVE_SYNC_V3.
-static const char kRCNativeSyncV2[] = "ANDROID_EMU_native_sync_v2";
-static const char kRCNativeSyncV3[] = "ANDROID_EMU_native_sync_v3";
-
-// DMA for OpenGL
-enum DmaImpl {
-    DMA_IMPL_NONE = 0,
-    DMA_IMPL_v1 = 1,
-};
-
-static const char kDmaExtStr_v1[] = "ANDROID_EMU_dma_v1";
-
-// OpenGL ES max supported version
-enum GLESMaxVersion {
-    GLES_MAX_VERSION_2 = 0,
-    GLES_MAX_VERSION_3_0 = 1,
-    GLES_MAX_VERSION_3_1 = 2,
-    GLES_MAX_VERSION_3_2 = 3,
-};
-
-static const char kGLESMaxVersion_2[] = "ANDROID_EMU_gles_max_version_2";
-static const char kGLESMaxVersion_3_0[] = "ANDROID_EMU_gles_max_version_3_0";
-static const char kGLESMaxVersion_3_1[] = "ANDROID_EMU_gles_max_version_3_1";
-static const char kGLESMaxVersion_3_2[] = "ANDROID_EMU_gles_max_version_3_2";
-
-enum HostComposition {
-    HOST_COMPOSITION_NONE = 0,
-    HOST_COMPOSITION_V1,
-};
-static const char kHostCompositionV1[] = "ANDROID_EMU_host_composition_v1";
-
-// No querying errors from host extension
-static const char kGLESNoHostError[] = "ANDROID_EMU_gles_no_host_error";
-
 // ExtendedRCEncoderContext is an extended version of renderControl_encoder_context_t
-// that will be used to track SyncImpl.
+// that will be used to track available emulator features.
 class ExtendedRCEncoderContext : public renderControl_encoder_context_t {
 public:
     ExtendedRCEncoderContext(IOStream *stream, ChecksumCalculator *checksumCalculator)
-        : renderControl_encoder_context_t(stream, checksumCalculator) {
-        m_dmaCxt = NULL;
-        }
-    void setSyncImpl(SyncImpl syncImpl) { m_syncImpl = syncImpl; }
-    void setDmaImpl(DmaImpl dmaImpl) { m_dmaImpl = dmaImpl; }
+        : renderControl_encoder_context_t(stream, checksumCalculator),
+          m_dmaCxt(NULL) { }
+    void setSyncImpl(SyncImpl syncImpl) { m_featureInfo.syncImpl = syncImpl; }
+    void setDmaImpl(DmaImpl dmaImpl) { m_featureInfo.dmaImpl = dmaImpl; }
     void setHostComposition(HostComposition hostComposition) {
-        m_hostComposition = hostComposition; }
-    bool hasNativeSync() const { return m_syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; }
-    bool hasNativeSyncV3() const { return m_syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; }
+        m_featureInfo.hostComposition = hostComposition; }
+    bool hasNativeSync() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; }
+    bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; }
     bool hasHostCompositionV1() const {
-        return m_hostComposition == HOST_COMPOSITION_V1; }
-    DmaImpl getDmaVersion() const { return m_dmaImpl; }
+        return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; }
+    DmaImpl getDmaVersion() const { return m_featureInfo.dmaImpl; }
     void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; }
     virtual uint64_t lockAndWriteDma(void* data, uint32_t size) {
         ALOGV("%s: call", __FUNCTION__);
@@ -116,14 +64,14 @@
         ALOGV("%s: paddr=0x%llx", __FUNCTION__, (unsigned long long)paddr);
         return paddr;
     }
-    void setGLESMaxVersion(GLESMaxVersion ver) { m_glesMaxVersion = ver; }
-    GLESMaxVersion getGLESMaxVersion() const { return m_glesMaxVersion; }
+    void setGLESMaxVersion(GLESMaxVersion ver) { m_featureInfo.glesMaxVersion = ver; }
+    GLESMaxVersion getGLESMaxVersion() const { return m_featureInfo.glesMaxVersion; }
+
+    const EmulatorFeatureInfo* featureInfo_const() const { return &m_featureInfo; }
+    EmulatorFeatureInfo* featureInfo() { return &m_featureInfo; }
 private:
-    SyncImpl m_syncImpl;
-    DmaImpl m_dmaImpl;
-    HostComposition m_hostComposition;
+    EmulatorFeatureInfo m_featureInfo;
     struct goldfish_dma_context* m_dmaCxt;
-    GLESMaxVersion m_glesMaxVersion;
 };
 
 // Abstraction for gralloc handle conversion
@@ -184,6 +132,8 @@
     void queryAndSetGLESMaxVersion(ExtendedRCEncoderContext *rcEnc);
     void queryAndSetNoErrorState(ExtendedRCEncoderContext *rcEnc);
     void queryAndSetHostCompositionImpl(ExtendedRCEncoderContext *rcEnc);
+    void queryAndSetDirectMemSupport(ExtendedRCEncoderContext *rcEnc);
+    void queryAndSetVulkanSupport(ExtendedRCEncoderContext *rcEnc);
 
 private:
     IOStream *m_stream;