Select GL transport and draw call flush interval based on prop

bug: 140112486

Normally, different graphics methods would be communicated over the pipe
in the GL extension string, but if the transport medium itself is in
question, we need another method. Thus, we use Android's property_get
with the following property keys:

ro.kernel.qemu.gltransport # to control the transport type
ro.kernel.qemu.gltransport.drawFlushInterval # control draw call flush
interval

The default is to use goldfish pipe and have a flush interval of 800
draw calls.

Change-Id: Id1911e194d04f83379b576de01c93f7c2c680a4c
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 208173e..478b823 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -101,6 +101,7 @@
     m_ssbo_offset_align = 0;
     m_ubo_offset_align = 0;
 
+    m_drawCallFlushInterval = 800;
     m_drawCallFlushCount = 0;
     m_primitiveRestartEnabled = false;
     m_primitiveRestartIndex = 0;
@@ -1302,11 +1303,7 @@
 }
 
 void GL2Encoder::flushDrawCall() {
-    // This used to be every other draw call, but
-    // now that we are using real GPU buffers on host,
-    // set this to every 200 draw calls
-    // (tuned on z840 linux NVIDIA Quadro K2200)
-    if (m_drawCallFlushCount % 200 == 0) {
+    if (m_drawCallFlushCount % m_drawCallFlushInterval == 0) {
         m_stream->flush();
     }
     m_drawCallFlushCount++;
@@ -1463,6 +1460,7 @@
         ctx->sendVertexAttributes(0, count, false);
         ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, first, count);
     }
+    ctx->flushDrawCall();
 }
 
 void GL2Encoder::s_glDrawElementsNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h
index c617a36..9f1a444 100644
--- a/system/GLESv2_enc/GL2Encoder.h
+++ b/system/GLESv2_enc/GL2Encoder.h
@@ -28,6 +28,9 @@
 public:
     GL2Encoder(IOStream *stream, ChecksumCalculator* protocol);
     virtual ~GL2Encoder();
+    void setDrawCallFlushInterval(uint32_t interval) {
+        m_drawCallFlushInterval = interval;
+    }
     void setNoHostError(bool noHostError) {
         m_noHostError = noHostError;
     }
@@ -131,7 +134,8 @@
 
     FixedBuffer m_fixedBuffer;
 
-    int m_drawCallFlushCount;
+    uint32_t m_drawCallFlushInterval;
+    uint32_t m_drawCallFlushCount;
 
     bool m_primitiveRestartEnabled;
     GLuint m_primitiveRestartIndex;
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 9708829..16d3fd3 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -15,6 +15,8 @@
 */
 #include "HostConnection.h"
 
+#include "cutils/properties.h"
+
 #ifdef GOLDFISH_NO_GL
 struct gl_client_context_t {
     int placeholder;
@@ -73,11 +75,35 @@
 #define STREAM_BUFFER_SIZE  (4*1024*1024)
 #define STREAM_PORT_NUM     22468
 
-enum HostConnectionType {
-    HOST_CONNECTION_TCP = 0,
-    HOST_CONNECTION_QEMU_PIPE = 1,
-    HOST_CONNECTION_VIRTIO_GPU = 2,
-};
+static HostConnectionType getConnectionTypeFromProperty() {
+    char transportValue[PROPERTY_VALUE_MAX] = "";
+    property_get("ro.kernel.qemu.gltransport", transportValue, "");
+
+    bool isValid = transportValue[0] != '\0';
+    if (!isValid) return HOST_CONNECTION_QEMU_PIPE;
+
+    if (!strcmp("tcp", transportValue)) return HOST_CONNECTION_TCP;
+    if (!strcmp("pipe", transportValue)) return HOST_CONNECTION_QEMU_PIPE;
+    if (!strcmp("virtio-gpu", transportValue)) return HOST_CONNECTION_VIRTIO_GPU;
+    if (!strcmp("asg", transportValue)) return HOST_CONNECTION_ADDRESS_SPACE;
+
+    return HOST_CONNECTION_QEMU_PIPE;
+}
+
+static uint32_t getDrawCallFlushIntervalFromProperty() {
+    char flushValue[PROPERTY_VALUE_MAX] = "";
+    property_get("ro.kernel.qemu.gltransport.drawFlushInterval", flushValue, "");
+
+    bool isValid = flushValue[0] != '\0';
+    if (!isValid) return 800;
+
+    long interval = strtol(flushValue, 0, 10);
+
+    if (!interval) return 800;
+
+    return (uint32_t)interval;
+}
+
 
 class GoldfishGralloc : public Gralloc
 {
@@ -135,10 +161,12 @@
 HostConnection* HostConnection::connect(HostConnection* con) {
     if (!con) return con;
 
-    const enum HostConnectionType connType = HOST_CONNECTION_VIRTIO_GPU;
+    const enum HostConnectionType connType = getConnectionTypeFromProperty();
 
     switch (connType) {
         default:
+        case HOST_CONNECTION_ADDRESS_SPACE: // Not implemented yet
+            ALOGE("Trying to use address space graphics device, not implemented yet\n");
         case HOST_CONNECTION_QEMU_PIPE: {
             QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
             if (!stream) {
@@ -152,6 +180,7 @@
                 delete con;
                 return NULL;
             }
+            con->m_connectionType = HOST_CONNECTION_QEMU_PIPE;
             con->m_stream = stream;
             con->m_grallocHelper = &m_goldfishGralloc;
             con->m_processPipe = &m_goldfishProcessPipe;
@@ -171,6 +200,7 @@
                 delete con;
                 return NULL;
             }
+            con->m_connectionType = HOST_CONNECTION_TCP;
             con->m_stream = stream;
             con->m_grallocHelper = &m_goldfishGralloc;
             con->m_processPipe = &m_goldfishProcessPipe;
@@ -190,6 +220,7 @@
                 delete con;
                 return NULL;
             }
+            con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU;
             con->m_stream = stream;
             con->m_grallocHelper = stream->getGralloc();
             con->m_processPipe = stream->getProcessPipe();
@@ -271,6 +302,8 @@
             m_gl2Enc, getCurrentThreadId());
         m_gl2Enc->setContextAccessor(s_getGL2Context);
         m_gl2Enc->setNoHostError(m_noHostError);
+        m_gl2Enc->setDrawCallFlushInterval(
+            getDrawCallFlushIntervalFromProperty());
     }
     return m_gl2Enc;
 }
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index a6424ab..cfc5f08 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -127,6 +127,13 @@
 
 struct EGLThreadInfo;
 
+enum HostConnectionType {
+    HOST_CONNECTION_TCP = 0,
+    HOST_CONNECTION_QEMU_PIPE = 1,
+    HOST_CONNECTION_VIRTIO_GPU = 2,
+    HOST_CONNECTION_ADDRESS_SPACE = 3,
+};
+
 class HostConnection
 {
 public:
@@ -139,6 +146,10 @@
 
     ~HostConnection();
 
+    HostConnectionType connectionType() const {
+        return m_connectionType;
+    }
+
     GLEncoder *glEncoder();
     GL2Encoder *gl2Encoder();
     goldfish_vk::VkEncoder *vkEncoder();
@@ -195,6 +206,7 @@
     void queryAndSetYUVCache(ExtendedRCEncoderContext *mrcEnc);
 
 private:
+    HostConnectionType m_connectionType;
     IOStream *m_stream;
     GLEncoder   *m_glEnc;
     GL2Encoder  *m_gl2Enc;