emulator opengl - encode glShaderSource

glShaderSource strings are concatenated into a single string
before sent over the wire protocol. The wire protocol transfer is
done using a special api call 'glShaderString'

Change-Id: I90c157df66fe82fee17c460a1e7852d370c77088
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
index 5979193..206b5f5 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
@@ -363,24 +363,37 @@
     return pixelsize;
 }
 
-
-int glUtilsSumArrayValues(GLint *array, GLsizei count)
+// pack a list of strings into one.
+void glUtilsPackStrings(char *ptr,  char **strings,  GLint *length, GLsizei count)
 {
-    int sum = 0;
+    char *p = ptr;
+    *p = '\0';
     for (int i = 0; i < count; i++) {
-        sum += *array;
-        array++;
+        int l;
+        if (length == NULL || length[i] < 0) {
+            l = strlen(strings[i]);
+            strcat(p, strings[i]);
+        } else {
+            l = length[i];
+            strncat(p, strings[i], l);
+        }
+        p += l;
     }
-    return sum;
 }
 
-void glUtilsPackStrings(void *ptr, char **strings, GLint *length, GLsizei count)
+// claculate the length of a list of strings
+int glUtilsCalcShaderSourceLen( char **strings,  GLint *length, GLsizei count)
 {
-    unsigned char *p = (unsigned char *)ptr;
+    int len = 0;
     for (int i = 0; i < count; i++) {
-        memcpy(p, *strings, *length);
-        p += *length;
-        strings++;
-        length++;
+        int l;
+        if (length == NULL || length[i] < 0) {
+            l = strlen(strings[i]);
+        } else {
+            l = length[i];
+        }
+        len += l;
     }
+    return len;
+
 }
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
index 3a1ec54..c66c568 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
@@ -52,8 +52,8 @@
                            int size, GLenum type, unsigned int stride,
                            unsigned int datalen);
     int glUtilsPixelBitSize(GLenum format, GLenum type);
-    int    glUtilsSumArrayValues(GLint *array, GLsizei count);
-    void   glUtilsPackStrings(void *ptr, char **strings, GLint *length, GLsizei count);
+    void   glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count);
+    int glUtilsCalcShaderSourceLen(char **strings, GLint *length, GLsizei count);
 #ifdef __cplusplus
 };
 #endif
diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp
index 846e475..8c982ce 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp
+++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp
@@ -25,6 +25,7 @@
     m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv);
     m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv);
     m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
+    set_glShaderSource(s_glShaderSource);
 }
 
 GL2Encoder::~GL2Encoder()
@@ -322,3 +323,15 @@
     }
     return m_compressedTextureFormats;
 }
+
+void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, GLstr *string, GLint *length)
+{
+
+    int len = glUtilsCalcShaderSourceLen(string, length, count);
+    char *str = new char[len + 1];
+    glUtilsPackStrings(str, string, length, count);
+
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    ctx->glShaderString(ctx, shader, str, len + 1);
+    delete str;
+}
diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h
index 897a011..f628aca 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h
+++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h
@@ -91,5 +91,6 @@
     glGetVertexAttribPointerv_client_proc_t m_glGetVertexAttribPointerv;
     static void s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer);
 
+    static void s_glShaderSource(void *self, GLuint shader, GLsizei count, GLstr *string, GLint *length);
 };
 #endif
diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
index bce9b51..ac32a7b 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
+++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
@@ -344,11 +344,12 @@
 glMultiDrawElementsEXT
 	flag unsupported
 
+
+# handled by encoder
 #void glShaderSource(GLuint shader, GLsizei count, GLstr *string, const GLint *length)
 glShaderSource
-   len length (count * sizeof(GLint))
-   len string (glUtilsSumArrayValues(length, count)) 
-   custom_pack string glUtilsPackStrings(ptr, string, length, count)
+	flag unsupported
+
 
 
 #void glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups)