aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/shared
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl/shared')
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Android.mk54
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h37
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/FixedBuffer.h53
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp417
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLClientState.h441
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h69
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLErrorLog.h34
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp469
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h143
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Makefile13
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h167
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp168
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/SocketStream.h50
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp91
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TcpStream.h32
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp69
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h22
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp137
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/UnixStream.h31
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp239
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h41
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/codec_defs.h23
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp471
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/glUtils.h95
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h62
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/Android.mk57
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp79
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h71
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcess.h62
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp210
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp171
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThread.h60
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp94
-rw-r--r--emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp101
34 files changed, 4333 insertions, 0 deletions
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Android.mk b/emulator/opengl/shared/OpenglCodecCommon/Android.mk
new file mode 100644
index 0000000..7deb058
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/Android.mk
@@ -0,0 +1,54 @@
+# This build script corresponds to a library containing many definitions
+# common to both the guest and the host. They relate to
+#
+LOCAL_PATH := $(call my-dir)
+
+commonSources := \
+ GLClientState.cpp \
+ GLSharedGroup.cpp \
+ glUtils.cpp \
+ SocketStream.cpp \
+ TcpStream.cpp \
+ TimeUtils.cpp
+
+host_commonSources := $(commonSources)
+
+ifeq ($(HOST_OS),windows)
+ host_commonSources += Win32PipeStream.cpp
+else
+ host_commonSources += UnixStream.cpp
+endif
+
+
+### CodecCommon guest ##############################################
+$(call emugl-begin-static-library,libOpenglCodecCommon)
+
+LOCAL_SRC_FILES := $(commonSources)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"eglCodecCommon\"
+
+$(call emugl-export,SHARED_LIBRARIES,libcutils libutils)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-end-module)
+
+
+### OpenglCodecCommon host ##############################################
+$(call emugl-begin-host-static-library,libOpenglCodecCommon)
+
+LOCAL_SRC_FILES := $(host_commonSources)
+
+$(call emugl-export,STATIC_LIBRARIES,libcutils)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-end-module)
+
+
+### OpenglCodecCommon host, 64-bit #########################################
+$(call emugl-begin-host-static-library,lib64OpenglCodecCommon)
+
+LOCAL_SRC_FILES := $(host_commonSources)
+
+$(call emugl-export,STATIC_LIBRARIES,lib64cutils)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-export,CFLAGS,-m64)
+$(call emugl-end-module)
+
diff --git a/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h b/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h
new file mode 100644
index 0000000..6f41fd7
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/ErrorLog.h
@@ -0,0 +1,37 @@
+/*
+* Copyright (C) 2011 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 _ERROR_LOG_H_
+#define _ERROR_LOG_H_
+
+#if (HAVE_ANDROID_OS == 1)
+# include <cutils/log.h>
+# define ERR(...) ALOGE(__VA_ARGS__)
+# ifdef EMUGL_DEBUG
+# define DBG(...) ALOGD(__VA_ARGS__)
+# else
+# define DBG(...) ((void)0)
+# endif
+#else
+# include <stdio.h>
+# define ERR(...) fprintf(stderr, __VA_ARGS__)
+# ifdef EMUGL_DEBUG
+# define DBG(...) fprintf(stderr, __VA_ARGS__)
+# else
+# define DBG(...) ((void)0)
+# endif
+#endif
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/FixedBuffer.h b/emulator/opengl/shared/OpenglCodecCommon/FixedBuffer.h
new file mode 100644
index 0000000..30b9a80
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/FixedBuffer.h
@@ -0,0 +1,53 @@
+/*
+* Copyright (C) 2011 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 _FIXED_BUFFER_H
+#define _FIXED_BUFFER_H
+
+class FixedBuffer {
+public:
+ FixedBuffer(size_t initialSize = 0) {
+ m_buffer = NULL;
+ m_bufferLen = 0;
+ alloc(m_bufferLen);
+ }
+
+ ~FixedBuffer() {
+ delete [] m_buffer;
+ m_bufferLen = 0;
+ }
+
+ void * alloc(size_t size) {
+ if (m_bufferLen >= size)
+ return (void *)(m_buffer);
+
+ if (m_buffer != NULL)
+ delete[] m_buffer;
+
+ m_bufferLen = size;
+ m_buffer = new unsigned char[m_bufferLen];
+ if (m_buffer == NULL)
+ m_bufferLen = 0;
+
+ return m_buffer;
+ }
+ void *ptr() { return m_buffer; }
+ size_t len() { return m_bufferLen; }
+private:
+ unsigned char *m_buffer;
+ size_t m_bufferLen;
+};
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp
new file mode 100644
index 0000000..9795490
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.cpp
@@ -0,0 +1,417 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "GLClientState.h"
+#include "ErrorLog.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "glUtils.h"
+#include <cutils/log.h>
+
+#ifndef MAX
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+GLClientState::GLClientState(int nLocations)
+{
+ if (nLocations < LAST_LOCATION) {
+ nLocations = LAST_LOCATION;
+ }
+ m_nLocations = nLocations;
+ m_states = new VertexAttribState[m_nLocations];
+ for (int i = 0; i < m_nLocations; i++) {
+ m_states[i].enabled = 0;
+ m_states[i].enableDirty = false;
+ }
+ m_currentArrayVbo = 0;
+ m_currentIndexVbo = 0;
+ // init gl constans;
+ m_states[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
+ m_states[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
+ m_states[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
+ m_states[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
+ m_states[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+ m_states[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
+ m_states[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
+ m_activeTexture = 0;
+ m_currentProgram = 0;
+
+ m_pixelStore.unpack_alignment = 4;
+ m_pixelStore.pack_alignment = 4;
+
+ memset(m_tex.unit, 0, sizeof(m_tex.unit));
+ m_tex.activeUnit = &m_tex.unit[0];
+ m_tex.textures = NULL;
+ m_tex.numTextures = 0;
+ m_tex.allocTextures = 0;
+}
+
+GLClientState::~GLClientState()
+{
+ delete m_states;
+}
+
+void GLClientState::enable(int location, int state)
+{
+ if (!validLocation(location)) {
+ return;
+ }
+
+ m_states[location].enableDirty |= (state != m_states[location].enabled);
+ m_states[location].enabled = state;
+}
+
+void GLClientState::setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data)
+{
+ if (!validLocation(location)) {
+ return;
+ }
+ m_states[location].size = size;
+ m_states[location].type = type;
+ m_states[location].stride = stride;
+ m_states[location].data = (void*)data;
+ m_states[location].bufferObject = m_currentArrayVbo;
+ m_states[location].elementSize = glSizeof(type) * size;
+ m_states[location].normalized = normalized;
+}
+
+void GLClientState::setBufferObject(int location, GLuint id)
+{
+ if (!validLocation(location)) {
+ return;
+ }
+
+ m_states[location].bufferObject = id;
+}
+
+const GLClientState::VertexAttribState * GLClientState::getState(int location)
+{
+ if (!validLocation(location)) {
+ return NULL;
+ }
+ return & m_states[location];
+}
+
+const GLClientState::VertexAttribState * GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
+{
+ if (!validLocation(location)) {
+ return NULL;
+ }
+
+ if (enableChanged) {
+ *enableChanged = m_states[location].enableDirty;
+ }
+
+ m_states[location].enableDirty = false;
+ return & m_states[location];
+}
+
+int GLClientState::getLocation(GLenum loc)
+{
+ int retval;
+
+ switch(loc) {
+ case GL_VERTEX_ARRAY:
+ retval = int(VERTEX_LOCATION);
+ break;
+ case GL_NORMAL_ARRAY:
+ retval = int(NORMAL_LOCATION);
+ break;
+ case GL_COLOR_ARRAY:
+ retval = int(COLOR_LOCATION);
+ break;
+ case GL_POINT_SIZE_ARRAY_OES:
+ retval = int(POINTSIZE_LOCATION);
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ retval = int (TEXCOORD0_LOCATION + m_activeTexture);
+ break;
+ case GL_MATRIX_INDEX_ARRAY_OES:
+ retval = int (MATRIXINDEX_LOCATION);
+ break;
+ case GL_WEIGHT_ARRAY_OES:
+ retval = int (WEIGHT_LOCATION);
+ break;
+ default:
+ retval = loc;
+ }
+ return retval;
+}
+
+void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
+{
+ const GLClientState::VertexAttribState *state = NULL;
+ switch (pname) {
+ case GL_VERTEX_ARRAY_POINTER: {
+ state = getState(GLClientState::VERTEX_LOCATION);
+ break;
+ }
+ case GL_NORMAL_ARRAY_POINTER: {
+ state = getState(GLClientState::NORMAL_LOCATION);
+ break;
+ }
+ case GL_COLOR_ARRAY_POINTER: {
+ state = getState(GLClientState::COLOR_LOCATION);
+ break;
+ }
+ case GL_TEXTURE_COORD_ARRAY_POINTER: {
+ state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+ break;
+ }
+ case GL_POINT_SIZE_ARRAY_POINTER_OES: {
+ state = getState(GLClientState::POINTSIZE_LOCATION);
+ break;
+ }
+ case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
+ state = getState(GLClientState::MATRIXINDEX_LOCATION);
+ break;
+ }
+ case GL_WEIGHT_ARRAY_POINTER_OES: {
+ state = getState(GLClientState::WEIGHT_LOCATION);
+ break;
+ }
+ }
+ if (state && params)
+ *params = state->data;
+}
+
+int GLClientState::setPixelStore(GLenum param, GLint value)
+{
+ int retval = 0;
+ switch(param) {
+ case GL_UNPACK_ALIGNMENT:
+ if (value == 1 || value == 2 || value == 4 || value == 8) {
+ m_pixelStore.unpack_alignment = value;
+ } else {
+ retval = GL_INVALID_VALUE;
+ }
+ break;
+ case GL_PACK_ALIGNMENT:
+ if (value == 1 || value == 2 || value == 4 || value == 8) {
+ m_pixelStore.pack_alignment = value;
+ } else {
+ retval = GL_INVALID_VALUE;
+ }
+ break;
+ default:
+ retval = GL_INVALID_ENUM;
+ }
+ return retval;
+}
+
+
+
+
+size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const
+{
+ int pixelsize = glUtilsPixelBitSize(format, type) >> 3;
+
+ int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment;
+
+ if (pixelsize == 0 ) {
+ ERR("unknown pixel size: width: %d height: %d format: %d type: %d pack: %d align: %d\n",
+ width, height, format, type, pack, alignment);
+ }
+ size_t linesize = pixelsize * width;
+ size_t aligned_linesize = int(linesize / alignment) * alignment;
+ if (aligned_linesize < linesize) {
+ aligned_linesize += alignment;
+ }
+ return aligned_linesize * height;
+}
+
+GLenum GLClientState::setActiveTextureUnit(GLenum texture)
+{
+ GLuint unit = texture - GL_TEXTURE0;
+ if (unit >= MAX_TEXTURE_UNITS) {
+ return GL_INVALID_OPERATION;
+ }
+ m_tex.activeUnit = &m_tex.unit[unit];
+ return GL_NO_ERROR;
+}
+
+GLenum GLClientState::getActiveTextureUnit() const
+{
+ return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
+}
+
+void GLClientState::enableTextureTarget(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
+ break;
+ case GL_TEXTURE_EXTERNAL_OES:
+ m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
+ break;
+ }
+}
+
+void GLClientState::disableTextureTarget(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
+ break;
+ case GL_TEXTURE_EXTERNAL_OES:
+ m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
+ break;
+ }
+}
+
+GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
+{
+ unsigned int enables = m_tex.activeUnit->enables;
+ if (enables & (1u << TEXTURE_EXTERNAL)) {
+ return GL_TEXTURE_EXTERNAL_OES;
+ } else if (enables & (1u << TEXTURE_2D)) {
+ return GL_TEXTURE_2D;
+ } else {
+ return allDisabled;
+ }
+}
+
+int GLClientState::compareTexId(const void* pid, const void* prec)
+{
+ const GLuint* id = (const GLuint*)pid;
+ const TextureRec* rec = (const TextureRec*)prec;
+ return (GLint)(*id) - (GLint)rec->id;
+}
+
+GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
+ GLboolean* firstUse)
+{
+ GLboolean first = GL_FALSE;
+ TextureRec* texrec = NULL;
+ if (texture != 0) {
+ if (m_tex.textures) {
+ texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
+ m_tex.numTextures, sizeof(TextureRec), compareTexId);
+ }
+ if (!texrec) {
+ if (!(texrec = addTextureRec(texture, target))) {
+ return GL_OUT_OF_MEMORY;
+ }
+ first = GL_TRUE;
+ }
+ if (target != texrec->target) {
+ return GL_INVALID_OPERATION;
+ }
+ }
+
+ switch (target) {
+ case GL_TEXTURE_2D:
+ m_tex.activeUnit->texture[TEXTURE_2D] = texture;
+ break;
+ case GL_TEXTURE_EXTERNAL_OES:
+ m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
+ break;
+ }
+
+ if (firstUse) {
+ *firstUse = first;
+ }
+
+ return GL_NO_ERROR;
+}
+
+GLClientState::TextureRec* GLClientState::addTextureRec(GLuint id,
+ GLenum target)
+{
+ if (m_tex.numTextures == m_tex.allocTextures) {
+ const GLuint MAX_TEXTURES = 0xFFFFFFFFu;
+
+ GLuint newAlloc;
+ if (MAX_TEXTURES - m_tex.allocTextures >= m_tex.allocTextures) {
+ newAlloc = MAX(4, 2 * m_tex.allocTextures);
+ } else {
+ if (m_tex.allocTextures == MAX_TEXTURES) {
+ return NULL;
+ }
+ newAlloc = MAX_TEXTURES;
+ }
+
+ TextureRec* newTextures = (TextureRec*)realloc(m_tex.textures,
+ newAlloc * sizeof(TextureRec));
+ if (!newTextures) {
+ return NULL;
+ }
+
+ m_tex.textures = newTextures;
+ m_tex.allocTextures = newAlloc;
+ }
+
+ TextureRec* tex = m_tex.textures + m_tex.numTextures;
+ TextureRec* prev = tex - 1;
+ while (tex != m_tex.textures && id < prev->id) {
+ *tex-- = *prev--;
+ }
+ tex->id = id;
+ tex->target = target;
+ m_tex.numTextures++;
+
+ return tex;
+}
+
+GLuint GLClientState::getBoundTexture(GLenum target) const
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ return m_tex.activeUnit->texture[TEXTURE_2D];
+ case GL_TEXTURE_EXTERNAL_OES:
+ return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
+ default:
+ return 0;
+ }
+}
+
+void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
+{
+ // Updating the textures array could be made more efficient when deleting
+ // several textures:
+ // - compacting the array could be done in a single pass once the deleted
+ // textures are marked, or
+ // - could swap deleted textures to the end and re-sort.
+ TextureRec* texrec;
+ for (const GLuint* texture = textures; texture != textures + n; texture++) {
+ texrec = (TextureRec*)bsearch(texture, m_tex.textures,
+ m_tex.numTextures, sizeof(TextureRec), compareTexId);
+ if (texrec) {
+ const TextureRec* end = m_tex.textures + m_tex.numTextures;
+ memmove(texrec, texrec + 1,
+ (end - texrec - 1) * sizeof(TextureRec));
+ m_tex.numTextures--;
+
+ for (TextureUnit* unit = m_tex.unit;
+ unit != m_tex.unit + MAX_TEXTURE_UNITS;
+ unit++)
+ {
+ if (unit->texture[TEXTURE_2D] == *texture) {
+ unit->texture[TEXTURE_2D] = 0;
+ } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
+ unit->texture[TEXTURE_EXTERNAL] = 0;
+ }
+ }
+ }
+ }
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h
new file mode 100644
index 0000000..c86329b
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h
@@ -0,0 +1,441 @@
+/*
+* Copyright (C) 2011 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 _GL_CLIENT_STATE_H_
+#define _GL_CLIENT_STATE_H_
+
+#define GL_API
+#ifndef ANDROID
+#define GL_APIENTRY
+#define GL_APIENTRYP
+#endif
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ErrorLog.h"
+#include "codec_defs.h"
+
+class GLClientState {
+public:
+ typedef enum {
+ VERTEX_LOCATION = 0,
+ NORMAL_LOCATION = 1,
+ COLOR_LOCATION = 2,
+ POINTSIZE_LOCATION = 3,
+ TEXCOORD0_LOCATION = 4,
+ TEXCOORD1_LOCATION = 5,
+ TEXCOORD2_LOCATION = 6,
+ TEXCOORD3_LOCATION = 7,
+ TEXCOORD4_LOCATION = 8,
+ TEXCOORD5_LOCATION = 9,
+ TEXCOORD6_LOCATION = 10,
+ TEXCOORD7_LOCATION = 11,
+ MATRIXINDEX_LOCATION = 12,
+ WEIGHT_LOCATION = 13,
+ LAST_LOCATION = 14
+ } StateLocation;
+
+ typedef struct {
+ GLint enabled;
+ GLint size;
+ GLenum type;
+ GLsizei stride;
+ void *data;
+ GLuint bufferObject;
+ GLenum glConst;
+ unsigned int elementSize;
+ bool enableDirty; // true if any enable state has changed since last draw
+ bool normalized;
+ } VertexAttribState;
+
+ typedef struct {
+ int unpack_alignment;
+ int pack_alignment;
+ } PixelStoreState;
+
+ enum {
+ MAX_TEXTURE_UNITS = 32,
+ };
+
+public:
+ GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
+ ~GLClientState();
+ int nLocations() { return m_nLocations; }
+ const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
+ int setPixelStore(GLenum param, GLint value);
+ GLuint currentArrayVbo() { return m_currentArrayVbo; }
+ GLuint currentIndexVbo() { return m_currentIndexVbo; }
+ void enable(int location, int state);
+ void setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
+ void setBufferObject(int location, GLuint id);
+ const VertexAttribState *getState(int location);
+ const VertexAttribState *getStateAndEnableDirty(int location, bool *enableChanged);
+ int getLocation(GLenum loc);
+ void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
+ int getActiveTexture() const { return m_activeTexture; }
+
+ int bindBuffer(GLenum target, GLuint id)
+ {
+ int err = 0;
+ switch(target) {
+ case GL_ARRAY_BUFFER:
+ m_currentArrayVbo = id;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER:
+ m_currentIndexVbo = id;
+ break;
+ default:
+ err = -1;
+ }
+ return err;
+ }
+
+ int getBuffer(GLenum target)
+ {
+ int ret=0;
+ switch (target) {
+ case GL_ARRAY_BUFFER:
+ ret = m_currentArrayVbo;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER:
+ ret = m_currentIndexVbo;
+ break;
+ default:
+ ret = -1;
+ }
+ return ret;
+ }
+ size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const;
+
+ void setCurrentProgram(GLint program) { m_currentProgram = program; }
+ GLint currentProgram() const { return m_currentProgram; }
+
+ /* OES_EGL_image_external
+ *
+ * These functions manipulate GL state which interacts with the
+ * OES_EGL_image_external extension, to support client-side emulation on
+ * top of host implementations that don't have it.
+ *
+ * Most of these calls should only be used with TEXTURE_2D or
+ * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
+ * targets should bypass this. An exception is bindTexture(), which should
+ * see all glBindTexture() calls for any target.
+ */
+
+ // glActiveTexture(GL_TEXTURE0 + i)
+ // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
+ GLenum setActiveTextureUnit(GLenum texture);
+ GLenum getActiveTextureUnit() const;
+
+ // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
+ void enableTextureTarget(GLenum target);
+
+ // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
+ void disableTextureTarget(GLenum target);
+
+ // Implements the target priority logic:
+ // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
+ // * Return GL_TEXTURE_2D if enabled, else
+ // * Return the allDisabled value.
+ // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
+ // simpler; for other cases passing a recognizable enum like GL_ZERO or
+ // GL_INVALID_ENUM is appropriate.
+ GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
+
+ // glBindTexture(GL_TEXTURE_*, ...)
+ // Set the target binding of the active texture unit to texture. Returns
+ // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
+ // previously been bound to a different target. If firstUse is not NULL,
+ // it is set to indicate whether this is the first use of the texture.
+ // For accurate error detection, bindTexture should be called for *all*
+ // targets, not just 2D and EXTERNAL_OES.
+ GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
+
+ // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
+ GLuint getBoundTexture(GLenum target) const;
+
+ // glDeleteTextures(...)
+ // Remove references to the to-be-deleted textures.
+ void deleteTextures(GLsizei n, const GLuint* textures);
+
+private:
+ PixelStoreState m_pixelStore;
+ VertexAttribState *m_states;
+ int m_nLocations;
+ GLuint m_currentArrayVbo;
+ GLuint m_currentIndexVbo;
+ int m_activeTexture;
+ GLint m_currentProgram;
+
+ bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
+
+ enum TextureTarget {
+ TEXTURE_2D = 0,
+ TEXTURE_EXTERNAL = 1,
+ TEXTURE_TARGET_COUNT
+ };
+ struct TextureUnit {
+ unsigned int enables;
+ GLuint texture[TEXTURE_TARGET_COUNT];
+ };
+ struct TextureRec {
+ GLuint id;
+ GLenum target;
+ };
+ struct TextureState {
+ TextureUnit unit[MAX_TEXTURE_UNITS];
+ TextureUnit* activeUnit;
+ TextureRec* textures;
+ GLuint numTextures;
+ GLuint allocTextures;
+ };
+ TextureState m_tex;
+
+ static int compareTexId(const void* pid, const void* prec);
+ TextureRec* addTextureRec(GLuint id, GLenum target);
+
+public:
+ void getClientStatePointer(GLenum pname, GLvoid** params);
+
+ template <class T>
+ int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
+ {
+ bool handled = true;
+ const VertexAttribState *vertexAttrib = getState(index);
+ if (vertexAttrib == NULL) {
+ ERR("getVeterxAttriParameter for non existant index %d\n", index);
+ // set gl error;
+ return handled;
+ }
+
+ switch(param) {
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ *ptr = (T)(vertexAttrib->bufferObject);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ *ptr = (T)(vertexAttrib->enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ *ptr = (T)(vertexAttrib->size);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ *ptr = (T)(vertexAttrib->stride);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ *ptr = (T)(vertexAttrib->type);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ *ptr = (T)(vertexAttrib->normalized);
+ break;
+ case GL_CURRENT_VERTEX_ATTRIB:
+ handled = false;
+ break;
+ default:
+ handled = false;
+ ERR("unknown vertex-attrib parameter param %d\n", param);
+ }
+ return handled;
+ }
+
+ template <class T>
+ bool getClientStateParameter(GLenum param, T* ptr)
+ {
+ bool isClientStateParam = false;
+ switch (param) {
+ case GL_CLIENT_ACTIVE_TEXTURE: {
+ GLint tex = getActiveTexture() + GL_TEXTURE0;
+ *ptr = tex;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_VERTEX_ARRAY_SIZE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+ *ptr = state->size;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_VERTEX_ARRAY_TYPE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_VERTEX_ARRAY_STRIDE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_COLOR_ARRAY_SIZE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+ *ptr = state->size;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_COLOR_ARRAY_TYPE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_COLOR_ARRAY_STRIDE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_NORMAL_ARRAY_TYPE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_NORMAL_ARRAY_STRIDE: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_TEXTURE_COORD_ARRAY_SIZE: {
+ const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+ *ptr = state->size;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_TEXTURE_COORD_ARRAY_TYPE: {
+ const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_TEXTURE_COORD_ARRAY_STRIDE: {
+ const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_POINT_SIZE_ARRAY_TYPE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+ *ptr = state->size;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_WEIGHT_ARRAY_SIZE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+ *ptr = state->size;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_WEIGHT_ARRAY_TYPE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+ *ptr = state->type;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_WEIGHT_ARRAY_STRIDE_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+ *ptr = state->stride;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_VERTEX_ARRAY_BUFFER_BINDING: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_NORMAL_ARRAY_BUFFER_BINDING: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_COLOR_ARRAY_BUFFER_BINDING: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
+ const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
+ const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+ *ptr = state->bufferObject;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_ARRAY_BUFFER_BINDING: {
+ int buffer = getBuffer(GL_ARRAY_BUFFER);
+ *ptr = buffer;
+ isClientStateParam = true;
+ break;
+ }
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
+ int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
+ *ptr = buffer;
+ isClientStateParam = true;
+ break;
+ }
+ }
+ return isClientStateParam;
+ }
+
+};
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h b/emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
new file mode 100644
index 0000000..23785ae
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
@@ -0,0 +1,69 @@
+/*
+* Copyright (C) 2011 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 _GL_DECODER_CONTEXT_DATA_H_
+#define _GL_DECODER_CONTEXT_DATA_H_
+
+#include <assert.h>
+#include <string.h>
+#include "FixedBuffer.h"
+#include "codec_defs.h"
+
+class GLDecoderContextData {
+public:
+ typedef enum {
+ VERTEX_LOCATION = 0,
+ NORMAL_LOCATION = 1,
+ COLOR_LOCATION = 2,
+ POINTSIZE_LOCATION = 3,
+ TEXCOORD0_LOCATION = 4,
+ TEXCOORD1_LOCATION = 5,
+ TEXCOORD2_LOCATION = 6,
+ TEXCOORD3_LOCATION = 7,
+ TEXCOORD4_LOCATION = 8,
+ TEXCOORD5_LOCATION = 9,
+ TEXCOORD6_LOCATION = 10,
+ TEXCOORD7_LOCATION = 11,
+ MATRIXINDEX_LOCATION = 12,
+ WEIGHT_LOCATION = 13,
+ LAST_LOCATION = 14
+ } PointerDataLocation;
+
+ GLDecoderContextData(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES) :
+ m_nLocations(nLocations)
+ {
+ m_pointerData = new FixedBuffer[m_nLocations];
+ }
+
+ ~GLDecoderContextData() {
+ delete [] m_pointerData;
+ }
+
+ void storePointerData(unsigned int loc, void *data, size_t len) {
+
+ assert(loc < m_nLocations);
+ m_pointerData[loc].alloc(len);
+ memcpy(m_pointerData[loc].ptr(), data, len);
+ }
+ void *pointerData(unsigned int loc) {
+ assert(loc < m_nLocations);
+ return m_pointerData[loc].ptr();
+ }
+private:
+ FixedBuffer *m_pointerData;
+ int m_nLocations;
+};
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLErrorLog.h b/emulator/opengl/shared/OpenglCodecCommon/GLErrorLog.h
new file mode 100644
index 0000000..5654aea
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLErrorLog.h
@@ -0,0 +1,34 @@
+/*
+* Copyright 2011 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 __GL_ERROR_LOG_H__
+#define __GL_ERROR_LOG_H__
+
+#include "ErrorLog.h"
+
+#ifdef CHECK_GL_ERROR
+void dbg(){}
+#define GET_GL_ERROR(gl) \
+ { \
+ int err = gl.glGetError(); \
+ if (err) { dbg(); ERR("Error: 0x%X in %s (%s:%d)\n", err, __FUNCTION__, __FILE__, __LINE__); } \
+ }
+
+#else
+#define GET_GL_ERROR(gl)
+#endif
+
+#endif //__GL_ERROR_LOG_H__
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
new file mode 100644
index 0000000..8504f7f
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
@@ -0,0 +1,469 @@
+/*
+* Copyright (C) 2011 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.
+*/
+
+#include "GLSharedGroup.h"
+
+/**** BufferData ****/
+
+BufferData::BufferData() : m_size(0) {};
+BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size)
+{
+ void * buffer = NULL;
+ if (size>0) buffer = m_fixedBuffer.alloc(size);
+ if (data) memcpy(buffer, data, size);
+}
+
+/**** ProgramData ****/
+ProgramData::ProgramData() : m_numIndexes(0),
+ m_initialized(false),
+ m_locShiftWAR(false)
+{
+ m_Indexes = NULL;
+}
+
+void ProgramData::initProgramData(GLuint numIndexes)
+{
+ m_initialized = true;
+ m_numIndexes = numIndexes;
+ delete[] m_Indexes;
+ m_Indexes = new IndexInfo[numIndexes];
+ m_locShiftWAR = false;
+}
+
+bool ProgramData::isInitialized()
+{
+ return m_initialized;
+}
+
+ProgramData::~ProgramData()
+{
+ delete[] m_Indexes;
+ m_Indexes = NULL;
+}
+
+void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type)
+{
+ if (index>=m_numIndexes)
+ return;
+ m_Indexes[index].base = base;
+ m_Indexes[index].size = size;
+ m_Indexes[index].type = type;
+ if (index > 0) {
+ m_Indexes[index].appBase = m_Indexes[index-1].appBase +
+ m_Indexes[index-1].size;
+ }
+ else {
+ m_Indexes[index].appBase = 0;
+ }
+ m_Indexes[index].hostLocsPerElement = 1;
+ m_Indexes[index].flags = 0;
+ m_Indexes[index].samplerValue = 0;
+}
+
+void ProgramData::setIndexFlags(GLuint index, GLuint flags)
+{
+ if (index >= m_numIndexes)
+ return;
+ m_Indexes[index].flags |= flags;
+}
+
+GLuint ProgramData::getIndexForLocation(GLint location)
+{
+ GLuint index = m_numIndexes;
+ GLint minDist = -1;
+ for (GLuint i=0;i<m_numIndexes;++i)
+ {
+ GLint dist = location - m_Indexes[i].base;
+ if (dist >= 0 &&
+ (minDist < 0 || dist < minDist)) {
+ index = i;
+ minDist = dist;
+ }
+ }
+ return index;
+}
+
+GLenum ProgramData::getTypeForLocation(GLint location)
+{
+ GLuint index = getIndexForLocation(location);
+ if (index<m_numIndexes) {
+ return m_Indexes[index].type;
+ }
+ return 0;
+}
+
+void ProgramData::setupLocationShiftWAR()
+{
+ m_locShiftWAR = false;
+ for (GLuint i=0; i<m_numIndexes; i++) {
+ if (0 != (m_Indexes[i].base & 0xffff)) {
+ return;
+ }
+ }
+ // if we have one uniform at location 0, we do not need the WAR.
+ if (m_numIndexes > 1) {
+ m_locShiftWAR = true;
+ }
+}
+
+GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
+{
+ if (!m_locShiftWAR) return hostLoc;
+
+ GLuint index = getIndexForLocation(hostLoc);
+ if (index<m_numIndexes) {
+ if (arrIndex > 0) {
+ m_Indexes[index].hostLocsPerElement =
+ (hostLoc - m_Indexes[index].base) / arrIndex;
+ }
+ return m_Indexes[index].appBase + arrIndex;
+ }
+ return -1;
+}
+
+GLint ProgramData::locationWARAppToHost(GLint appLoc)
+{
+ if (!m_locShiftWAR) return appLoc;
+
+ for(GLuint i=0; i<m_numIndexes; i++) {
+ GLint elemIndex = appLoc - m_Indexes[i].appBase;
+ if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
+ return m_Indexes[i].base +
+ elemIndex * m_Indexes[i].hostLocsPerElement;
+ }
+ }
+ return -1;
+}
+
+GLint ProgramData::getNextSamplerUniform(GLint index, GLint* val, GLenum* target)
+{
+ for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) {
+ if (m_Indexes[i].type == GL_SAMPLER_2D) {
+ if (val) *val = m_Indexes[i].samplerValue;
+ if (target) {
+ if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
+ *target = GL_TEXTURE_EXTERNAL_OES;
+ } else {
+ *target = GL_TEXTURE_2D;
+ }
+ }
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target)
+{
+ for (GLuint i = 0; i < m_numIndexes; i++) {
+ GLint elemIndex = appLoc - m_Indexes[i].appBase;
+ if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
+ if (m_Indexes[i].type == GL_TEXTURE_2D) {
+ m_Indexes[i].samplerValue = val;
+ if (target) {
+ if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
+ *target = GL_TEXTURE_EXTERNAL_OES;
+ } else {
+ *target = GL_TEXTURE_2D;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool ProgramData::attachShader(GLuint shader)
+{
+ size_t n = m_shaders.size();
+ for (size_t i = 0; i < n; i++) {
+ if (m_shaders[i] == shader) {
+ return false;
+ }
+ }
+ // AKA m_shaders.push_back(), but that has an ambiguous call to insertAt()
+ // due to the default parameters. This is the desired insertAt() overload.
+ m_shaders.insertAt(shader, m_shaders.size(), 1);
+ return true;
+}
+
+bool ProgramData::detachShader(GLuint shader)
+{
+ size_t n = m_shaders.size();
+ for (size_t i = 0; i < n; i++) {
+ if (m_shaders[i] == shader) {
+ m_shaders.removeAt(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+/***** GLSharedGroup ****/
+
+GLSharedGroup::GLSharedGroup() :
+ m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
+ m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
+ m_shaders(android::DefaultKeyedVector<GLuint, ShaderData*>(NULL))
+{
+}
+
+GLSharedGroup::~GLSharedGroup()
+{
+ m_buffers.clear();
+ m_programs.clear();
+}
+
+BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
+{
+ android::AutoMutex _lock(m_lock);
+ return m_buffers.valueFor(bufferId);
+}
+
+void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
+{
+ android::AutoMutex _lock(m_lock);
+ m_buffers.add(bufferId, new BufferData(size, data));
+}
+
+void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
+{
+ android::AutoMutex _lock(m_lock);
+ m_buffers.replaceValueFor(bufferId, new BufferData(size, data));
+}
+
+GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
+{
+ android::AutoMutex _lock(m_lock);
+ BufferData * buf = m_buffers.valueFor(bufferId);
+ if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE;
+
+ //it's safe to update now
+ memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
+ return GL_NO_ERROR;
+}
+
+void GLSharedGroup::deleteBufferData(GLuint bufferId)
+{
+ android::AutoMutex _lock(m_lock);
+ m_buffers.removeItem(bufferId);
+}
+
+void GLSharedGroup::addProgramData(GLuint program)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData *pData = m_programs.valueFor(program);
+ if (pData)
+ {
+ m_programs.removeItem(program);
+ delete pData;
+ }
+
+ m_programs.add(program,new ProgramData());
+}
+
+void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData *pData = m_programs.valueFor(program);
+ if (pData)
+ {
+ pData->initProgramData(numIndexes);
+ }
+}
+
+bool GLSharedGroup::isProgramInitialized(GLuint program)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ if (pData)
+ {
+ return pData->isInitialized();
+ }
+ return false;
+}
+
+void GLSharedGroup::deleteProgramData(GLuint program)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData *pData = m_programs.valueFor(program);
+ if (pData)
+ delete pData;
+ m_programs.removeItem(program);
+}
+
+void GLSharedGroup::attachShader(GLuint program, GLuint shader)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* programData = m_programs.valueFor(program);
+ ssize_t idx = m_shaders.indexOfKey(shader);
+ if (programData && idx >= 0) {
+ if (programData->attachShader(shader)) {
+ refShaderDataLocked(idx);
+ }
+ }
+}
+
+void GLSharedGroup::detachShader(GLuint program, GLuint shader)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* programData = m_programs.valueFor(program);
+ ssize_t idx = m_shaders.indexOfKey(shader);
+ if (programData && idx >= 0) {
+ if (programData->detachShader(shader)) {
+ unrefShaderDataLocked(idx);
+ }
+ }
+}
+
+void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ if (pData)
+ {
+ pData->setIndexInfo(index,base,size,type);
+
+ if (type == GL_SAMPLER_2D) {
+ size_t n = pData->getNumShaders();
+ for (size_t i = 0; i < n; i++) {
+ GLuint shaderId = pData->getShader(i);
+ ShaderData* shader = m_shaders.valueFor(shaderId);
+ if (!shader) continue;
+ ShaderData::StringList::iterator nameIter = shader->samplerExternalNames.begin();
+ ShaderData::StringList::iterator nameEnd = shader->samplerExternalNames.end();
+ while (nameIter != nameEnd) {
+ if (*nameIter == name) {
+ pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
+ break;
+ }
+ ++nameIter;
+ }
+ }
+ }
+ }
+}
+
+GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ GLenum type=0;
+ if (pData)
+ {
+ type = pData->getTypeForLocation(location);
+ }
+ return type;
+}
+
+bool GLSharedGroup::isProgram(GLuint program)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ return (pData!=NULL);
+}
+
+void GLSharedGroup::setupLocationShiftWAR(GLuint program)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ if (pData) pData->setupLocationShiftWAR();
+}
+
+GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
+ else return hostLoc;
+}
+
+GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ if (pData) return pData->locationWARAppToHost(appLoc);
+ else return appLoc;
+}
+
+bool GLSharedGroup::needUniformLocationWAR(GLuint program)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ if (pData) return pData->needUniformLocationWAR();
+ return false;
+}
+
+GLint GLSharedGroup::getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ return pData ? pData->getNextSamplerUniform(index, val, target) : -1;
+}
+
+bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target)
+{
+ android::AutoMutex _lock(m_lock);
+ ProgramData* pData = m_programs.valueFor(program);
+ return pData ? pData->setSamplerUniform(appLoc, val, target) : false;
+}
+
+bool GLSharedGroup::addShaderData(GLuint shader)
+{
+ android::AutoMutex _lock(m_lock);
+ ShaderData* data = new ShaderData;
+ if (data) {
+ if (m_shaders.add(shader, data) < 0) {
+ delete data;
+ data = NULL;
+ }
+ data->refcount = 1;
+ }
+ return data != NULL;
+}
+
+ShaderData* GLSharedGroup::getShaderData(GLuint shader)
+{
+ android::AutoMutex _lock(m_lock);
+ return m_shaders.valueFor(shader);
+}
+
+void GLSharedGroup::unrefShaderData(GLuint shader)
+{
+ android::AutoMutex _lock(m_lock);
+ ssize_t idx = m_shaders.indexOfKey(shader);
+ if (idx >= 0) {
+ unrefShaderDataLocked(idx);
+ }
+}
+
+void GLSharedGroup::refShaderDataLocked(ssize_t shaderIdx)
+{
+ assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
+ ShaderData* data = m_shaders.valueAt(shaderIdx);
+ data->refcount++;
+}
+
+void GLSharedGroup::unrefShaderDataLocked(ssize_t shaderIdx)
+{
+ assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
+ ShaderData* data = m_shaders.valueAt(shaderIdx);
+ if (--data->refcount == 0) {
+ delete data;
+ m_shaders.removeItemsAt(shaderIdx);
+ }
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
new file mode 100644
index 0000000..61b8f00
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -0,0 +1,143 @@
+/*
+* Copyright (C) 2011 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 _GL_SHARED_GROUP_H_
+#define _GL_SHARED_GROUP_H_
+
+#define GL_API
+#ifndef ANDROID
+#define GL_APIENTRY
+#define GL_APIENTRYP
+#endif
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ErrorLog.h"
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+#include "FixedBuffer.h"
+#include "SmartPtr.h"
+
+struct BufferData {
+ BufferData();
+ BufferData(GLsizeiptr size, void * data);
+ GLsizeiptr m_size;
+ FixedBuffer m_fixedBuffer;
+};
+
+class ProgramData {
+private:
+ typedef struct _IndexInfo {
+ GLint base;
+ GLint size;
+ GLenum type;
+ GLint appBase;
+ GLint hostLocsPerElement;
+ GLuint flags;
+ GLint samplerValue; // only set for sampler uniforms
+ } IndexInfo;
+
+ GLuint m_numIndexes;
+ IndexInfo* m_Indexes;
+ bool m_initialized;
+ bool m_locShiftWAR;
+
+ android::Vector<GLuint> m_shaders;
+
+public:
+ enum {
+ INDEX_FLAG_SAMPLER_EXTERNAL = 0x00000001,
+ };
+
+ ProgramData();
+ void initProgramData(GLuint numIndexes);
+ bool isInitialized();
+ virtual ~ProgramData();
+ void setIndexInfo(GLuint index, GLint base, GLint size, GLenum type);
+ void setIndexFlags(GLuint index, GLuint flags);
+ GLuint getIndexForLocation(GLint location);
+ GLenum getTypeForLocation(GLint location);
+
+ bool needUniformLocationWAR() const { return m_locShiftWAR; }
+ void setupLocationShiftWAR();
+ GLint locationWARHostToApp(GLint hostLoc, GLint arrIndex);
+ GLint locationWARAppToHost(GLint appLoc);
+
+ GLint getNextSamplerUniform(GLint index, GLint* val, GLenum* target);
+ bool setSamplerUniform(GLint appLoc, GLint val, GLenum* target);
+
+ bool attachShader(GLuint shader);
+ bool detachShader(GLuint shader);
+ size_t getNumShaders() const { return m_shaders.size(); }
+ GLuint getShader(size_t i) const { return m_shaders[i]; }
+};
+
+struct ShaderData {
+ typedef android::List<android::String8> StringList;
+ StringList samplerExternalNames;
+ int refcount;
+};
+
+class GLSharedGroup {
+private:
+ android::DefaultKeyedVector<GLuint, BufferData*> m_buffers;
+ android::DefaultKeyedVector<GLuint, ProgramData*> m_programs;
+ android::DefaultKeyedVector<GLuint, ShaderData*> m_shaders;
+ mutable android::Mutex m_lock;
+
+ void refShaderDataLocked(ssize_t shaderIdx);
+ void unrefShaderDataLocked(ssize_t shaderIdx);
+
+public:
+ GLSharedGroup();
+ ~GLSharedGroup();
+ BufferData * getBufferData(GLuint bufferId);
+ void addBufferData(GLuint bufferId, GLsizeiptr size, void * data);
+ void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data);
+ GLenum subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data);
+ void deleteBufferData(GLuint);
+
+ bool isProgram(GLuint program);
+ bool isProgramInitialized(GLuint program);
+ void addProgramData(GLuint program);
+ void initProgramData(GLuint program, GLuint numIndexes);
+ void attachShader(GLuint program, GLuint shader);
+ void detachShader(GLuint program, GLuint shader);
+ void deleteProgramData(GLuint program);
+ void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name);
+ GLenum getProgramUniformType(GLuint program, GLint location);
+ void setupLocationShiftWAR(GLuint program);
+ GLint locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex);
+ GLint locationWARAppToHost(GLuint program, GLint appLoc);
+ bool needUniformLocationWAR(GLuint program);
+ GLint getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const;
+ bool setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target);
+
+ bool addShaderData(GLuint shader);
+ // caller must hold a reference to the shader as long as it holds the pointer
+ ShaderData* getShaderData(GLuint shader);
+ void unrefShaderData(GLuint shader);
+};
+
+typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr;
+
+#endif //_GL_SHARED_GROUP_H_
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Makefile b/emulator/opengl/shared/OpenglCodecCommon/Makefile
new file mode 100644
index 0000000..e8bf431
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/Makefile
@@ -0,0 +1,13 @@
+
+ROOT=../..
+
+include $(ROOT)/make/commondefs
+
+CXXFILES = TcpStream.cpp GLClientState.cpp glUtils.cpp
+CXXINCS += -I$(ROOT)/libs/GLESv1 -I$(ROOT)/include
+
+LIBRARY_NAME = libcodecCommon.a
+
+include $(COMMONRULES)
+
+
diff --git a/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h b/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h
new file mode 100644
index 0000000..4bdfbe4
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/SmartPtr.h
@@ -0,0 +1,167 @@
+/*
+* Copyright (C) 2011 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 __SMART_PTR_H
+#define __SMART_PTR_H
+
+#include <cutils/threads.h>
+#include <cutils/atomic.h>
+
+template <class T, bool threadSafe = false>
+class SmartPtr
+{
+public:
+ explicit SmartPtr(T* ptr = (T*)NULL) {
+ if (threadSafe) {
+ m_lock = new mutex_t;
+ mutex_init(m_lock);
+ }
+ else m_lock = NULL;
+
+ m_ptr = ptr;
+ if (ptr)
+ m_pRefCount = new int32_t(1);
+ else
+ m_pRefCount = NULL;
+ }
+
+ SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) {
+ if (threadSafe) {
+ m_lock = new mutex_t;
+ mutex_init(m_lock);
+ }
+ else m_lock = NULL;
+
+ m_pRefCount = rhs.m_pRefCount;
+ m_ptr = rhs.m_ptr;
+ use();
+ }
+
+ SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) {
+ if (threadSafe) {
+ m_lock = new mutex_t;
+ mutex_init(m_lock);
+ }
+ else m_lock = NULL;
+
+ if (rhs.m_lock) mutex_lock(rhs.m_lock);
+ m_pRefCount = rhs.m_pRefCount;
+ m_ptr = rhs.m_ptr;
+ use();
+ if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+ }
+
+ ~SmartPtr() {
+ if (m_lock) mutex_lock(m_lock);
+ release();
+ if (m_lock)
+ {
+ mutex_unlock(m_lock);
+ mutex_destroy(m_lock);
+ delete m_lock;
+ }
+ }
+
+ T* Ptr() const {
+ return m_ptr;
+ }
+
+ const T* constPtr() const
+ {
+ return m_ptr;
+ }
+
+ T* operator->() const {
+ return m_ptr;
+ }
+
+ T& operator*() const {
+ return *m_ptr;
+ }
+
+ operator void*() const {
+ return (void *)m_ptr;
+ }
+
+ // This gives STL lists something to compare.
+ bool operator <(const SmartPtr<T>& t1) const {
+ return m_ptr < t1.m_ptr;
+ }
+
+ SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs)
+ {
+ if (m_ptr == rhs.m_ptr)
+ return *this;
+
+ if (m_lock) mutex_lock(m_lock);
+ release();
+ m_pRefCount = rhs.m_pRefCount;
+ m_ptr = rhs.m_ptr;
+ use();
+ if (m_lock) mutex_unlock(m_lock);
+
+ return *this;
+ }
+
+ SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs)
+ {
+ if (m_ptr == rhs.m_ptr)
+ return *this;
+
+ if (m_lock) mutex_lock(m_lock);
+ release();
+ if (rhs.m_lock) mutex_lock(rhs.m_lock);
+ m_pRefCount = rhs.m_pRefCount;
+ m_ptr = rhs.m_ptr;
+ use();
+ if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+ if (m_lock) mutex_unlock(m_lock);
+
+ return *this;
+ }
+
+private:
+ int32_t *m_pRefCount;
+ mutex_t *m_lock;
+ T* m_ptr;
+
+ // Increment the reference count on this pointer by 1.
+ int use() {
+ if (!m_pRefCount) return 0;
+ return android_atomic_inc(m_pRefCount) + 1;
+ }
+
+ // Decrement the reference count on the pointer by 1.
+ // If the reference count goes to (or below) 0, the pointer is deleted.
+ int release() {
+ if (!m_pRefCount) return 0;
+
+ int iVal = android_atomic_dec(m_pRefCount);
+ if (iVal > 1)
+ return iVal - 1;
+
+ delete m_pRefCount;
+ m_pRefCount = NULL;
+
+ if (m_ptr) {
+ delete m_ptr;
+ m_ptr = NULL;
+ }
+ return 0;
+ }
+
+};
+
+#endif // of __SMART_PTR_H
diff --git a/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
new file mode 100644
index 0000000..f7a2314
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
@@ -0,0 +1,168 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "SocketStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#else
+#include <ws2tcpip.h>
+#endif
+
+SocketStream::SocketStream(size_t bufSize) :
+ IOStream(bufSize),
+ m_sock(-1),
+ m_bufsize(bufSize),
+ m_buf(NULL)
+{
+}
+
+SocketStream::SocketStream(int sock, size_t bufSize) :
+ IOStream(bufSize),
+ m_sock(sock),
+ m_bufsize(bufSize),
+ m_buf(NULL)
+{
+}
+
+SocketStream::~SocketStream()
+{
+ if (m_sock >= 0) {
+#ifdef _WIN32
+ closesocket(m_sock);
+#else
+ ::close(m_sock);
+#endif
+ }
+ if (m_buf != NULL) {
+ free(m_buf);
+ m_buf = NULL;
+ }
+}
+
+
+void *SocketStream::allocBuffer(size_t minSize)
+{
+ size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
+ if (!m_buf) {
+ m_buf = (unsigned char *)malloc(allocSize);
+ }
+ else if (m_bufsize < allocSize) {
+ unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
+ if (p != NULL) {
+ m_buf = p;
+ m_bufsize = allocSize;
+ } else {
+ ERR("%s: realloc (%zu) failed\n", __FUNCTION__, allocSize);
+ free(m_buf);
+ m_buf = NULL;
+ m_bufsize = 0;
+ }
+ }
+
+ return m_buf;
+};
+
+int SocketStream::commitBuffer(size_t size)
+{
+ return writeFully(m_buf, size);
+}
+
+int SocketStream::writeFully(const void* buffer, size_t size)
+{
+ if (!valid()) return -1;
+
+ size_t res = size;
+ int retval = 0;
+
+ while (res > 0) {
+ ssize_t stat = ::send(m_sock, (const char *)buffer + (size - res), res, 0);
+ if (stat < 0) {
+ if (errno != EINTR) {
+ retval = stat;
+ ERR("%s: failed: %s\n", __FUNCTION__, strerror(errno));
+ break;
+ }
+ } else {
+ res -= stat;
+ }
+ }
+ return retval;
+}
+
+const unsigned char *SocketStream::readFully(void *buf, size_t len)
+{
+ const unsigned char* ret = NULL;
+ if (!valid()) return NULL;
+ if (!buf) {
+ return NULL; // do not allow NULL buf in that implementation
+ }
+ size_t res = len;
+ while (res > 0) {
+ ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0);
+ if (stat > 0) {
+ res -= stat;
+ continue;
+ }
+ if (stat == 0 || errno != EINTR) { // client shutdown or error
+ return NULL;
+ }
+ }
+ return (const unsigned char *)buf;
+}
+
+const unsigned char *SocketStream::read( void *buf, size_t *inout_len)
+{
+ if (!valid()) return NULL;
+ if (!buf) {
+ return NULL; // do not allow NULL buf in that implementation
+ }
+
+ int n;
+ do {
+ n = recv(buf, *inout_len);
+ } while( n < 0 && errno == EINTR );
+
+ if (n > 0) {
+ *inout_len = n;
+ return (const unsigned char *)buf;
+ }
+
+ return NULL;
+}
+
+int SocketStream::recv(void *buf, size_t len)
+{
+ if (!valid()) return int(ERR_INVALID_SOCKET);
+ int res = 0;
+ while(true) {
+ res = ::recv(m_sock, (char *)buf, len, 0);
+ if (res < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ }
+ break;
+ }
+ return res;
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
new file mode 100644
index 0000000..3a501b4
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
@@ -0,0 +1,50 @@
+/*
+* Copyright (C) 2011 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 __SOCKET_STREAM_H
+#define __SOCKET_STREAM_H
+
+#include <stdlib.h>
+#include "IOStream.h"
+
+class SocketStream : public IOStream {
+public:
+ typedef enum { ERR_INVALID_SOCKET = -1000 } SocketStreamError;
+
+ explicit SocketStream(size_t bufsize = 10000);
+ virtual ~SocketStream();
+
+ virtual int listen(unsigned short port) = 0;
+ virtual SocketStream *accept() = 0;
+ virtual int connect(unsigned short port) = 0;
+
+ virtual void *allocBuffer(size_t minSize);
+ virtual int commitBuffer(size_t size);
+ virtual const unsigned char *readFully(void *buf, size_t len);
+ virtual const unsigned char *read(void *buf, size_t *inout_len);
+
+ bool valid() { return m_sock >= 0; }
+ virtual int recv(void *buf, size_t len);
+ virtual int writeFully(const void *buf, size_t len);
+
+protected:
+ int m_sock;
+ size_t m_bufsize;
+ unsigned char *m_buf;
+
+ SocketStream(int sock, size_t bufSize);
+};
+
+#endif /* __SOCKET_STREAM_H */
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
new file mode 100644
index 0000000..4da2cec
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
@@ -0,0 +1,91 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "TcpStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#else
+#include <ws2tcpip.h>
+#endif
+
+TcpStream::TcpStream(size_t bufSize) :
+ SocketStream(bufSize)
+{
+}
+
+TcpStream::TcpStream(int sock, size_t bufSize) :
+ SocketStream(sock, bufSize)
+{
+ // disable Nagle algorithm to improve bandwidth of small
+ // packets which are quite common in our implementation.
+#ifdef _WIN32
+ DWORD flag;
+#else
+ int flag;
+#endif
+ flag = 1;
+ setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
+}
+
+int TcpStream::listen(unsigned short port)
+{
+ m_sock = socket_loopback_server(port, SOCK_STREAM);
+ if (!valid()) return int(ERR_INVALID_SOCKET);
+
+ return 0;
+}
+
+SocketStream * TcpStream::accept()
+{
+ int clientSock = -1;
+
+ while (true) {
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(addr);
+ clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
+
+ if (clientSock < 0 && errno == EINTR) {
+ continue;
+ }
+ break;
+ }
+
+ TcpStream *clientStream = NULL;
+
+ if (clientSock >= 0) {
+ clientStream = new TcpStream(clientSock, m_bufsize);
+ }
+ return clientStream;
+}
+
+int TcpStream::connect(unsigned short port)
+{
+ return connect("127.0.0.1",port);
+}
+
+int TcpStream::connect(const char* hostname, unsigned short port)
+{
+ m_sock = socket_network_client(hostname, port, SOCK_STREAM);
+ if (!valid()) return -1;
+ return 0;
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
new file mode 100644
index 0000000..811a871
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (C) 2011 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 __TCP_STREAM_H
+#define __TCP_STREAM_H
+
+#include "SocketStream.h"
+
+class TcpStream : public SocketStream {
+public:
+ explicit TcpStream(size_t bufsize = 10000);
+ virtual int listen(unsigned short port);
+ virtual SocketStream *accept();
+ virtual int connect(unsigned short port);
+ int connect(const char* hostname, unsigned short port);
+private:
+ TcpStream(int sock, size_t bufSize);
+};
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp b/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
new file mode 100644
index 0000000..50aeb03
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
@@ -0,0 +1,69 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "TimeUtils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <time.h>
+#include <stdio.h>
+#elif defined(__linux__)
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+long long GetCurrentTimeMS()
+{
+#ifdef _WIN32
+ static LARGE_INTEGER freq;
+ static bool bNotInit = true;
+ if ( bNotInit ) {
+ bNotInit = (QueryPerformanceFrequency( &freq ) == FALSE);
+ }
+ LARGE_INTEGER currVal;
+ QueryPerformanceCounter( &currVal );
+
+ return currVal.QuadPart / (freq.QuadPart / 1000);
+
+#elif defined(__linux__)
+
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ long long iDiff = (now.tv_sec * 1000LL) + now.tv_nsec/1000000LL;
+ return iDiff;
+
+#else /* Others, e.g. OS X */
+
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ long long iDiff = (now.tv_sec * 1000LL) + now.tv_usec/1000LL;
+ return iDiff;
+
+#endif
+}
+
+void TimeSleepMS(int p_mili)
+{
+#ifdef _WIN32
+ Sleep(p_mili);
+#else
+ usleep(p_mili * 1000);
+#endif
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h b/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h
new file mode 100644
index 0000000..bc4fd1c
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/TimeUtils.h
@@ -0,0 +1,22 @@
+/*
+* Copyright (C) 2011 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 _TIME_UTILS_H
+#define _TIME_UTILS_H
+
+long long GetCurrentTimeMS();
+void TimeSleepMS(int p_mili);
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
new file mode 100644
index 0000000..8e463a3
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
@@ -0,0 +1,137 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "UnixStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+/* Not all systems define PATH_MAX, those who don't generally don't
+ * have a limit on the maximum path size, so use a value that is
+ * large enough for our very limited needs.
+ */
+#ifndef PATH_MAX
+#define PATH_MAX 128
+#endif
+
+UnixStream::UnixStream(size_t bufSize) :
+ SocketStream(bufSize)
+{
+}
+
+UnixStream::UnixStream(int sock, size_t bufSize) :
+ SocketStream(sock, bufSize)
+{
+}
+
+/* Initialize a sockaddr_un with the appropriate values corresponding
+ * to a given 'virtual port'. Returns 0 on success, -1 on error.
+ */
+static int
+make_unix_path(char *path, size_t pathlen, int port_number)
+{
+ char tmp[PATH_MAX]; // temp directory
+ int ret = 0;
+
+ // First, create user-specific temp directory if needed
+ const char* user = getenv("USER");
+ if (user != NULL) {
+ struct stat st;
+ snprintf(tmp, sizeof(tmp), "/tmp/android-%s", user);
+ do {
+ ret = ::lstat(tmp, &st);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0 && errno == ENOENT) {
+ do {
+ ret = ::mkdir(tmp, 0766);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0) {
+ ERR("Could not create temp directory: %s", tmp);
+ user = NULL; // will fall-back to /tmp
+ }
+ }
+ else if (ret < 0) {
+ user = NULL; // will fallback to /tmp
+ }
+ }
+
+ if (user == NULL) { // fallback to /tmp in case of error
+ snprintf(tmp, sizeof(tmp), "/tmp");
+ }
+
+ // Now, initialize it properly
+ snprintf(path, pathlen, "%s/qemu-gles-%d", tmp, port_number);
+ return 0;
+}
+
+
+int UnixStream::listen(unsigned short port)
+{
+ char path[PATH_MAX];
+
+ if (make_unix_path(path, sizeof(path), port) < 0) {
+ return -1;
+ }
+
+ m_sock = socket_local_server(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+ if (!valid()) return int(ERR_INVALID_SOCKET);
+
+ return 0;
+}
+
+SocketStream * UnixStream::accept()
+{
+ int clientSock = -1;
+
+ while (true) {
+ struct sockaddr_un addr;
+ socklen_t len = sizeof(addr);
+ clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
+
+ if (clientSock < 0 && errno == EINTR) {
+ continue;
+ }
+ break;
+ }
+
+ UnixStream *clientStream = NULL;
+
+ if (clientSock >= 0) {
+ clientStream = new UnixStream(clientSock, m_bufsize);
+ }
+ return clientStream;
+}
+
+int UnixStream::connect(unsigned short port)
+{
+ char path[PATH_MAX];
+
+ if (make_unix_path(path, sizeof(path), port) < 0)
+ return -1;
+
+ m_sock = socket_local_client(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+ if (!valid()) return -1;
+
+ return 0;
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
new file mode 100644
index 0000000..c184b19
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
@@ -0,0 +1,31 @@
+/*
+* Copyright (C) 2011 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 __UNIX_STREAM_H
+#define __UNIX_STREAM_H
+
+#include "SocketStream.h"
+
+class UnixStream : public SocketStream {
+public:
+ explicit UnixStream(size_t bufsize = 10000);
+ virtual int listen(unsigned short port);
+ virtual SocketStream *accept();
+ virtual int connect(unsigned short port);
+private:
+ UnixStream(int sock, size_t bufSize);
+};
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
new file mode 100644
index 0000000..e1a0b9b
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
@@ -0,0 +1,239 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "Win32PipeStream.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <windows.h>
+
+#ifndef _WIN32
+#error ONLY BUILD THIS SOURCE FILE FOR WINDOWS!
+#endif
+
+/* The official documentation states that the name of a given named
+ * pipe cannot be more than 256 characters long.
+ */
+#define NAMED_PIPE_MAX 256
+
+Win32PipeStream::Win32PipeStream(size_t bufSize) :
+ SocketStream(bufSize),
+ m_pipe(INVALID_HANDLE_VALUE)
+{
+}
+
+Win32PipeStream::Win32PipeStream(HANDLE pipe, size_t bufSize) :
+ SocketStream(-1, bufSize),
+ m_pipe(pipe)
+{
+}
+
+Win32PipeStream::~Win32PipeStream()
+{
+ if (m_pipe != INVALID_HANDLE_VALUE) {
+ CloseHandle(m_pipe);
+ m_pipe = INVALID_HANDLE_VALUE;
+ }
+}
+
+/* Initialize the pipe name corresponding to a given port
+ */
+static void
+make_pipe_name(char *path, size_t pathlen, int port_number)
+{
+ snprintf(path, pathlen, "\\\\.\\pipe\\qemu-gles-%d", port_number);
+}
+
+
+/* Technical note: Named pipes work differently from BSD Sockets.
+ * One does not create/bind a pipe, and collect a new handle each
+ * time a client connects with accept().
+ *
+ * Instead, the server creates a new pipe instance each time it wants
+ * to get a new client connection, then calls ConnectNamedPipe() to
+ * wait for a connection.
+ *
+ * So listen() is a no-op, and accept() really creates the pipe handle.
+ *
+ * Also, connect() must create a pipe handle with CreateFile() and
+ * wait for a server instance with WaitNamedPipe()
+ */
+int Win32PipeStream::listen(unsigned short port)
+{
+ // just save the port number for accept()
+ m_port = port;
+ return 0;
+}
+
+SocketStream * Win32PipeStream::accept()
+{
+ char path[NAMED_PIPE_MAX+1];
+ SocketStream* clientStream;
+ HANDLE pipe;
+
+ make_pipe_name(path, sizeof(path), m_port);
+
+ pipe = ::CreateNamedPipe(
+ path, // pipe name
+ PIPE_ACCESS_DUPLEX, // read-write access
+ PIPE_TYPE_BYTE | // byte-oriented writes
+ PIPE_READMODE_BYTE | // byte-oriented reads
+ PIPE_WAIT, // blocking operations
+ PIPE_UNLIMITED_INSTANCES, // no limit on clients
+ 4096, // input buffer size
+ 4096, // output buffer size
+ 0, // client time-out
+ NULL); // default security attributes
+
+ if (pipe == INVALID_HANDLE_VALUE) {
+ ERR("%s: CreateNamedPipe failed %d\n", __FUNCTION__, (int)GetLastError());
+ return NULL;
+ }
+
+ // Stupid Win32 API design: If a client is already connected, then
+ // ConnectNamedPipe will return 0, and GetLastError() will return
+ // ERROR_PIPE_CONNECTED. This is not an error! It just means that the
+ // function didn't have to wait.
+ //
+ if (::ConnectNamedPipe(pipe, NULL) == 0 && GetLastError() != ERROR_PIPE_CONNECTED) {
+ ERR("%s: ConnectNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
+ CloseHandle(pipe);
+ return NULL;
+ }
+
+ clientStream = new Win32PipeStream(pipe, m_bufsize);
+ return clientStream;
+}
+
+int Win32PipeStream::connect(unsigned short port)
+{
+ char path[NAMED_PIPE_MAX+1];
+ HANDLE pipe;
+ int tries = 10;
+
+ make_pipe_name(path, sizeof(path), port);
+
+ /* We're going to loop in order to wait for the pipe server to
+ * be setup properly.
+ */
+ for (; tries > 0; tries--) {
+ pipe = ::CreateFile(
+ path, // pipe name
+ GENERIC_READ | GENERIC_WRITE, // read & write
+ 0, // no sharing
+ NULL, // default security attrs
+ OPEN_EXISTING, // open existing pipe
+ 0, // default attributes
+ NULL); // no template file
+
+ /* If we have a valid pipe handle, break from the loop */
+ if (pipe != INVALID_HANDLE_VALUE) {
+ break;
+ }
+
+ /* We can get here if the pipe is busy, i.e. if the server hasn't
+ * create a new pipe instance to service our request. In which case
+ * GetLastError() will return ERROR_PIPE_BUSY.
+ *
+ * If so, then use WaitNamedPipe() to wait for a decent time
+ * to try again.
+ */
+ if (GetLastError() != ERROR_PIPE_BUSY) {
+ /* Not ERROR_PIPE_BUSY */
+ ERR("%s: CreateFile failed: %d\n", __FUNCTION__, (int)GetLastError());
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Wait for 5 seconds */
+ if ( !WaitNamedPipe(path, 5000) ) {
+ ERR("%s: WaitNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ m_pipe = pipe;
+ return 0;
+}
+
+/* Special buffer methods, since we can't use socket functions here */
+
+int Win32PipeStream::commitBuffer(size_t size)
+{
+ if (m_pipe == INVALID_HANDLE_VALUE)
+ return -1;
+
+ size_t res = size;
+ int retval = 0;
+
+ while (res > 0) {
+ DWORD written;
+ if (! ::WriteFile(m_pipe, (const char *)m_buf + (size - res), res, &written, NULL)) {
+ retval = -1;
+ ERR("%s: failed: %d\n", __FUNCTION__, (int)GetLastError());
+ break;
+ }
+ res -= written;
+ }
+ return retval;
+}
+
+const unsigned char *Win32PipeStream::readFully(void *buf, size_t len)
+{
+ const unsigned char* ret = NULL;
+
+ if (m_pipe == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ if (!buf) {
+ return NULL; // do not allow NULL buf in that implementation
+ }
+
+ size_t res = len;
+ while (res > 0) {
+ DWORD readcount = 0;
+ if (! ::ReadFile(m_pipe, (char *)buf + (len - res), res, &readcount, NULL) || readcount == 0) {
+ errno = (int)GetLastError();
+ return NULL;
+ }
+ res -= readcount;
+ }
+ return (const unsigned char *)buf;
+}
+
+const unsigned char *Win32PipeStream::read( void *buf, size_t *inout_len)
+{
+ size_t len = *inout_len;
+ DWORD readcount;
+
+ if (m_pipe == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ if (!buf) {
+ return NULL; // do not allow NULL buf in that implementation
+ }
+
+ if (!::ReadFile(m_pipe, (char *)buf, len, &readcount, NULL)) {
+ errno = (int)GetLastError();
+ return NULL;
+ }
+
+ *inout_len = (size_t)readcount;
+ return (const unsigned char *)buf;
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
new file mode 100644
index 0000000..4114545
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
@@ -0,0 +1,41 @@
+/*
+* Copyright (C) 2011 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 __WIN32_PIPE_STREAM_H
+#define __WIN32_PIPE_STREAM_H
+
+#include "SocketStream.h"
+#include <windows.h>
+
+class Win32PipeStream : public SocketStream {
+public:
+ explicit Win32PipeStream(size_t bufsize = 10000);
+ virtual ~Win32PipeStream();
+ virtual int listen(unsigned short port);
+ virtual SocketStream *accept();
+ virtual int connect(unsigned short port);
+
+ virtual int commitBuffer(size_t size);
+ virtual const unsigned char *readFully(void *buf, size_t len);
+ virtual const unsigned char *read(void *buf, size_t *inout_len);
+
+private:
+ Win32PipeStream(HANDLE pipe, size_t bufSize);
+ HANDLE m_pipe;
+ int m_port;
+};
+
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/codec_defs.h b/emulator/opengl/shared/OpenglCodecCommon/codec_defs.h
new file mode 100644
index 0000000..f19f514
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/codec_defs.h
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2011 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 _CODEC_DEFS_H
+#define _CODEC_DEFS_H
+
+#define CODEC_SERVER_PORT 22468
+
+#define CODEC_MAX_VERTEX_ATTRIBUTES 64
+
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp b/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
new file mode 100644
index 0000000..4b7fc89
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
@@ -0,0 +1,471 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "glUtils.h"
+#include <string.h>
+#include "ErrorLog.h"
+#include <IOStream.h>
+
+size_t glSizeof(GLenum type)
+{
+ size_t retval = 0;
+ switch(type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ retval = 1;
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_HALF_FLOAT_OES:
+ retval = 2;
+ break;
+ case GL_INT:
+ case GL_FLOAT:
+ case GL_FIXED:
+ case GL_BOOL:
+ retval = 4;
+ break;
+#ifdef GL_DOUBLE
+ case GL_DOUBLE:
+ retval = 8;
+ break;
+#endif
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ retval = 8;
+ break;
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ case GL_FLOAT_VEC3:
+ retval = 12;
+ break;
+ case GL_FLOAT_VEC4:
+ case GL_BOOL_VEC4:
+ case GL_INT_VEC4:
+ case GL_FLOAT_MAT2:
+ retval = 16;
+ break;
+ case GL_FLOAT_MAT3:
+ retval = 36;
+ break;
+ case GL_FLOAT_MAT4:
+ retval = 64;
+ break;
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ retval = 4;
+ break;
+ default:
+ ERR("**** ERROR unknown type 0x%x (%s,%d)\n", type, __FUNCTION__,__LINE__);
+ }
+ return retval;
+
+}
+
+size_t glUtilsParamSize(GLenum param)
+{
+ size_t s = 0;
+
+ switch(param)
+ {
+ case GL_DEPTH_TEST:
+ case GL_DEPTH_FUNC:
+ case GL_DEPTH_BITS:
+ case GL_MAX_CLIP_PLANES:
+ case GL_GREEN_BITS:
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ case GL_MAX_TEXTURE_SIZE:
+ case GL_TEXTURE_GEN_MODE_OES:
+ case GL_TEXTURE_ENV_MODE:
+ case GL_FOG_MODE:
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ case GL_SPOT_EXPONENT:
+ case GL_CONSTANT_ATTENUATION:
+ case GL_LINEAR_ATTENUATION:
+ case GL_QUADRATIC_ATTENUATION:
+ case GL_SHININESS:
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ case GL_POINT_SIZE:
+ case GL_POINT_SIZE_MIN:
+ case GL_POINT_SIZE_MAX:
+ case GL_POINT_FADE_THRESHOLD_SIZE:
+ case GL_CULL_FACE_MODE:
+ case GL_FRONT_FACE:
+ case GL_SHADE_MODEL:
+ case GL_DEPTH_WRITEMASK:
+ case GL_DEPTH_CLEAR_VALUE:
+ case GL_STENCIL_FAIL:
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ case GL_STENCIL_REF:
+ case GL_STENCIL_WRITEMASK:
+ case GL_MATRIX_MODE:
+ case GL_MODELVIEW_STACK_DEPTH:
+ case GL_PROJECTION_STACK_DEPTH:
+ case GL_TEXTURE_STACK_DEPTH:
+ case GL_ALPHA_TEST_FUNC:
+ case GL_ALPHA_TEST_REF:
+ case GL_ALPHA_TEST:
+ case GL_BLEND_DST:
+ case GL_BLEND_SRC:
+ case GL_BLEND:
+ case GL_LOGIC_OP_MODE:
+ case GL_SCISSOR_TEST:
+ case GL_MAX_TEXTURE_UNITS:
+ case GL_ACTIVE_TEXTURE:
+ case GL_ALPHA_BITS:
+ case GL_ARRAY_BUFFER_BINDING:
+ case GL_BLUE_BITS:
+ case GL_CLIENT_ACTIVE_TEXTURE:
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ case GL_COLOR_ARRAY:
+ case GL_COLOR_ARRAY_BUFFER_BINDING:
+ case GL_COLOR_ARRAY_SIZE:
+ case GL_COLOR_ARRAY_STRIDE:
+ case GL_COLOR_ARRAY_TYPE:
+ case GL_COLOR_LOGIC_OP:
+ case GL_COLOR_MATERIAL:
+ case GL_PACK_ALIGNMENT:
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+ case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+ case GL_POINT_SIZE_ARRAY_TYPE_OES:
+ case GL_POINT_SMOOTH:
+ case GL_POINT_SMOOTH_HINT:
+ case GL_POINT_SPRITE_OES:
+ case GL_COORD_REPLACE_OES:
+ case GL_COMBINE_ALPHA:
+ case GL_SRC0_RGB:
+ case GL_SRC1_RGB:
+ case GL_SRC2_RGB:
+ case GL_OPERAND0_RGB:
+ case GL_OPERAND1_RGB:
+ case GL_OPERAND2_RGB:
+ case GL_SRC0_ALPHA:
+ case GL_SRC1_ALPHA:
+ case GL_SRC2_ALPHA:
+ case GL_OPERAND0_ALPHA:
+ case GL_OPERAND1_ALPHA:
+ case GL_OPERAND2_ALPHA:
+ case GL_RGB_SCALE:
+ case GL_ALPHA_SCALE:
+ case GL_COMBINE_RGB:
+ case GL_POLYGON_OFFSET_FACTOR:
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_POLYGON_OFFSET_UNITS:
+ case GL_RED_BITS:
+ case GL_RESCALE_NORMAL:
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ case GL_SAMPLE_ALPHA_TO_ONE:
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLE_COVERAGE:
+ case GL_SAMPLE_COVERAGE_INVERT:
+ case GL_SAMPLE_COVERAGE_VALUE:
+ case GL_SAMPLES:
+ case GL_STENCIL_BITS:
+ case GL_STENCIL_CLEAR_VALUE:
+ case GL_STENCIL_FUNC:
+ case GL_STENCIL_TEST:
+ case GL_STENCIL_VALUE_MASK:
+ case GL_STENCIL_BACK_FUNC:
+ case GL_STENCIL_BACK_VALUE_MASK:
+ case GL_STENCIL_BACK_REF:
+ case GL_STENCIL_BACK_FAIL:
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ case GL_STENCIL_BACK_WRITEMASK:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_BINDING_2D:
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_TEXTURE_BINDING_EXTERNAL_OES:
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ case GL_UNPACK_ALIGNMENT:
+ case GL_VERTEX_ARRAY:
+ case GL_VERTEX_ARRAY_BUFFER_BINDING:
+ case GL_VERTEX_ARRAY_SIZE:
+ case GL_VERTEX_ARRAY_STRIDE:
+ case GL_VERTEX_ARRAY_TYPE:
+ case GL_SPOT_CUTOFF:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_GENERATE_MIPMAP:
+ case GL_GENERATE_MIPMAP_HINT:
+ case GL_RENDERBUFFER_WIDTH_OES:
+ case GL_RENDERBUFFER_HEIGHT_OES:
+ case GL_RENDERBUFFER_INTERNAL_FORMAT_OES:
+ case GL_RENDERBUFFER_RED_SIZE_OES:
+ case GL_RENDERBUFFER_GREEN_SIZE_OES:
+ case GL_RENDERBUFFER_BLUE_SIZE_OES:
+ case GL_RENDERBUFFER_ALPHA_SIZE_OES:
+ case GL_RENDERBUFFER_DEPTH_SIZE_OES:
+ case GL_RENDERBUFFER_STENCIL_SIZE_OES:
+ case GL_RENDERBUFFER_BINDING:
+ case GL_FRAMEBUFFER_BINDING:
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES:
+ case GL_FENCE_STATUS_NV:
+ case GL_FENCE_CONDITION_NV:
+ case GL_TEXTURE_WIDTH_QCOM:
+ case GL_TEXTURE_HEIGHT_QCOM:
+ case GL_TEXTURE_DEPTH_QCOM:
+ case GL_TEXTURE_INTERNAL_FORMAT_QCOM:
+ case GL_TEXTURE_FORMAT_QCOM:
+ case GL_TEXTURE_TYPE_QCOM:
+ case GL_TEXTURE_IMAGE_VALID_QCOM:
+ case GL_TEXTURE_NUM_LEVELS_QCOM:
+ case GL_TEXTURE_TARGET_QCOM:
+ case GL_TEXTURE_OBJECT_VALID_QCOM:
+ case GL_BLEND_EQUATION_RGB_OES:
+ case GL_BLEND_EQUATION_ALPHA_OES:
+ case GL_BLEND_DST_RGB_OES:
+ case GL_BLEND_SRC_RGB_OES:
+ case GL_BLEND_DST_ALPHA_OES:
+ case GL_BLEND_SRC_ALPHA_OES:
+ case GL_MAX_LIGHTS:
+ case GL_SHADER_TYPE:
+ case GL_DELETE_STATUS:
+ case GL_COMPILE_STATUS:
+ case GL_INFO_LOG_LENGTH:
+ case GL_SHADER_SOURCE_LENGTH:
+ case GL_CURRENT_PROGRAM:
+ case GL_LINK_STATUS:
+ case GL_VALIDATE_STATUS:
+ case GL_ATTACHED_SHADERS:
+ case GL_ACTIVE_UNIFORMS:
+ case GL_ACTIVE_ATTRIBUTES:
+ case GL_SUBPIXEL_BITS:
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ case GL_SHADER_COMPILER:
+ case GL_MAX_VERTEX_ATTRIBS:
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ case GL_MAX_VARYING_VECTORS:
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ case GL_MAX_RENDERBUFFER_SIZE:
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ case GL_LINE_WIDTH:
+ s = 1;
+ break;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ case GL_DEPTH_RANGE:
+ case GL_MAX_VIEWPORT_DIMS:
+ case GL_SMOOTH_POINT_SIZE_RANGE:
+ case GL_SMOOTH_LINE_WIDTH_RANGE:
+ s= 2;
+ break;
+ case GL_SPOT_DIRECTION:
+ case GL_POINT_DISTANCE_ATTENUATION:
+ case GL_CURRENT_NORMAL:
+ s = 3;
+ break;
+ case GL_CURRENT_VERTEX_ATTRIB:
+ case GL_CURRENT_TEXTURE_COORDS:
+ case GL_CURRENT_COLOR:
+ case GL_FOG_COLOR:
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ case GL_EMISSION:
+ case GL_POSITION:
+ case GL_LIGHT_MODEL_AMBIENT:
+ case GL_TEXTURE_ENV_COLOR:
+ case GL_SCISSOR_BOX:
+ case GL_VIEWPORT:
+ case GL_TEXTURE_CROP_RECT_OES:
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_COLOR_WRITEMASK:
+ case GL_AMBIENT_AND_DIFFUSE:
+ case GL_BLEND_COLOR:
+ s = 4;
+ break;
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ s = 16;
+ break;
+ default:
+ ERR("glUtilsParamSize: unknow param 0x%08x\n", param);
+ s = 1; // assume 1
+ }
+ return s;
+}
+
+void glUtilsPackPointerData(unsigned char *dst, unsigned char *src,
+ int size, GLenum type, unsigned int stride,
+ unsigned int datalen)
+{
+ unsigned int vsize = size * glSizeof(type);
+ if (stride == 0) stride = vsize;
+
+ if (stride == vsize) {
+ memcpy(dst, src, datalen);
+ } else {
+ for (unsigned int i = 0; i < datalen; i += vsize) {
+ memcpy(dst, src, vsize);
+ dst += vsize;
+ src += stride;
+ }
+ }
+}
+
+void glUtilsWritePackPointerData(void* _stream, unsigned char *src,
+ int size, GLenum type, unsigned int stride,
+ unsigned int datalen)
+{
+ IOStream* stream = reinterpret_cast<IOStream*>(_stream);
+
+ unsigned int vsize = size * glSizeof(type);
+ if (stride == 0) stride = vsize;
+
+ if (stride == vsize) {
+ stream->writeFully(src, datalen);
+ } else {
+ for (unsigned int i = 0; i < datalen; i += vsize) {
+ stream->writeFully(src, (size_t)vsize);
+ src += stride;
+ }
+ }
+}
+
+int glUtilsPixelBitSize(GLenum format, GLenum type)
+{
+ int components = 0;
+ int componentsize = 0;
+ int pixelsize = 0;
+ switch(type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ componentsize = 8;
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_RGB565_OES:
+ case GL_RGB5_A1_OES:
+ case GL_RGBA4_OES:
+ pixelsize = 16;
+ break;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ case GL_FIXED:
+ case GL_UNSIGNED_INT_24_8_OES:
+ pixelsize = 32;
+ break;
+ default:
+ ERR("glUtilsPixelBitSize: unknown pixel type - assuming pixel data 0\n");
+ componentsize = 0;
+ }
+
+ if (pixelsize == 0) {
+ switch(format) {
+#if 0
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+#endif
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL_OES:
+ components = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ components = 2;
+ break;
+ case GL_RGB:
+#if 0
+ case GL_BGR:
+#endif
+ components = 3;
+ break;
+ case GL_RGBA:
+ case GL_BGRA_EXT:
+ components = 4;
+ break;
+ default:
+ ERR("glUtilsPixelBitSize: unknown pixel format...\n");
+ components = 0;
+ }
+ pixelsize = components * componentsize;
+ }
+
+ return pixelsize;
+}
+
+// pack a list of strings into one.
+void glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count)
+{
+ char *p = ptr;
+ *p = '\0';
+ for (int i = 0; i < count; i++) {
+ int l=0;
+ if (strings[i]!=NULL) {
+ 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;
+ }
+}
+
+// claculate the length of a list of strings
+int glUtilsCalcShaderSourceLen( char **strings, GLint *length, GLsizei count)
+{
+ int len = 0;
+ for (int i = 0; i < count; i++) {
+ int l;
+ if (length == NULL || length[i] < 0) {
+ l = strings[i]!=NULL ? strlen(strings[i]) : 0;
+ } else {
+ l = length[i];
+ }
+ len += l;
+ }
+ return len;
+
+}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/glUtils.h b/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
new file mode 100644
index 0000000..f8857f1
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
@@ -0,0 +1,95 @@
+/*
+* Copyright (C) 2011 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 __GL_UTILS_H__
+#define __GL_UTILS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef GL_API
+ #undef GL_API
+#endif
+#define GL_API
+
+#ifdef GL_APIENTRY
+ #undef GL_APIENTRY
+#endif
+
+#ifdef GL_APIENTRYP
+ #undef GL_APIENTRYP
+#endif
+#define GL_APIENTRYP
+
+#ifndef ANDROID
+#define GL_APIENTRY
+#endif
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ size_t glSizeof(GLenum type);
+ size_t glUtilsParamSize(GLenum param);
+ void glUtilsPackPointerData(unsigned char *dst, unsigned char *str,
+ int size, GLenum type, unsigned int stride,
+ unsigned int datalen);
+ void glUtilsWritePackPointerData(void* stream, unsigned char *src,
+ int size, GLenum type, unsigned int stride,
+ unsigned int datalen);
+ int glUtilsPixelBitSize(GLenum format, GLenum type);
+ void glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count);
+ int glUtilsCalcShaderSourceLen(char **strings, GLint *length, GLsizei count);
+#ifdef __cplusplus
+};
+#endif
+
+namespace GLUtils {
+
+ template <class T> void minmax(T *indices, int count, int *min, int *max) {
+ *min = -1;
+ *max = -1;
+ T *ptr = indices;
+ for (int i = 0; i < count; i++) {
+ if (*min == -1 || *ptr < *min) *min = *ptr;
+ if (*max == -1 || *ptr > *max) *max = *ptr;
+ ptr++;
+ }
+ }
+
+ template <class T> void shiftIndices(T *indices, int count, int offset) {
+ T *ptr = indices;
+ for (int i = 0; i < count; i++) {
+ *ptr += offset;
+ ptr++;
+ }
+ }
+
+
+ template <class T> void shiftIndices(T *src, T *dst, int count, int offset)
+ {
+ for (int i = 0; i < count; i++) {
+ *dst = *src + offset;
+ dst++;
+ src++;
+ }
+ }
+}; // namespace GLUtils
+#endif
diff --git a/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h b/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h
new file mode 100644
index 0000000..d7bdef8
--- /dev/null
+++ b/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h
@@ -0,0 +1,62 @@
+/*
+* Copyright (C) 2011 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 __GL_BASE_TYPES__H
+#define __GL_BASE_TYPES__H
+
+#include <KHR/khrplatform.h>
+
+#ifndef gl_APIENTRY
+#define gl_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#ifndef gl2_APIENTRY
+#define gl2_APIENTRY KHRONOS_APIENTRY
+#endif
+
+typedef void GLvoid;
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef char GLchar;
+typedef khronos_int8_t GLbyte;
+typedef short GLshort;
+typedef int GLint;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned int GLuint;
+typedef khronos_float_t GLfloat;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef khronos_int32_t GLclampx;
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t GLsizeiptr;
+typedef char *GLstr;
+/* JR XXX Treating this as an in handle - is this correct? */
+typedef void * GLeglImageOES;
+
+/* ErrorCode */
+#ifndef GL_INVALID_ENUM
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_OUT_OF_MEMORY 0x0505
+#endif
+
+#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/Android.mk b/emulator/opengl/shared/OpenglOsUtils/Android.mk
new file mode 100644
index 0000000..82391cd
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/Android.mk
@@ -0,0 +1,57 @@
+# This build script corresponds to a small library containing
+# OS-specific support functions for:
+# - thread-local storage
+# - dynamic library loading
+# - child process creation and wait (probably not needed in guest)
+#
+LOCAL_PATH := $(call my-dir)
+
+### Guest library ##############################################
+$(call emugl-begin-static-library,libOpenglOsUtils)
+
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ $(call emugl-export,LDLIBS,-ldl)
+
+ LOCAL_SRC_FILES := \
+ osProcessUnix.cpp \
+ osThreadUnix.cpp \
+ osDynLibrary.cpp
+
+$(call emugl-end-module)
+
+
+### Host library ##############################################
+
+host_common_SRC_FILES := osDynLibrary.cpp
+host_common_LDLIBS :=
+
+ifeq ($(HOST_OS),windows)
+ host_common_SRC_FILES += \
+ osProcessWin.cpp \
+ osThreadWin.cpp
+ host_common_LDLIBS += -lws2_32 -lpsapi
+else
+ host_common_SRC_FILES += \
+ osProcessUnix.cpp \
+ osThreadUnix.cpp
+ host_common_LDLIBS += -ldl
+endif
+
+ifeq ($(HOST_OS),linux)
+ host_common_LDLIBS += -lpthread -lrt
+endif
+
+### 32-bit host library ####
+$(call emugl-begin-host-static-library,libOpenglOsUtils)
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ LOCAL_SRC_FILES = $(host_common_SRC_FILES)
+ $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
+$(call emugl-end-module)
+
+### 64-bit host library ####
+$(call emugl-begin-host-static-library,lib64OpenglOsUtils)
+ $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+ LOCAL_SRC_FILES = $(host_common_SRC_FILES)
+ $(call emugl-export,LDLIBS,$(host_common_LDLIBS))
+ $(call emugl-export,CFLAGS,-m64)
+$(call emugl-end-module)
diff --git a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
new file mode 100644
index 0000000..e8e6ab7
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
@@ -0,0 +1,79 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osDynLibrary.h"
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+#include <stdio.h>
+
+namespace osUtils {
+
+dynLibrary *dynLibrary::open(const char *p_libName)
+{
+ dynLibrary *lib = new dynLibrary();
+ if (!lib) {
+ return NULL;
+ }
+
+#ifdef _WIN32
+ lib->m_lib = LoadLibrary(p_libName);
+#else // !WIN32
+ lib->m_lib = dlopen(p_libName, RTLD_NOW);
+#endif
+
+ if (lib->m_lib == NULL) {
+ printf("Failed to load %s\n", p_libName);
+#ifndef _WIN32
+ printf("error %s\n", dlerror()); //only on linux
+#endif
+ delete lib;
+ return NULL;
+ }
+
+ return lib;
+}
+
+dynLibrary::dynLibrary() :
+ m_lib(NULL)
+{
+}
+
+dynLibrary::~dynLibrary()
+{
+ if (NULL != m_lib) {
+#ifdef _WIN32
+ FreeLibrary(m_lib);
+#else // !WIN32
+ dlclose(m_lib);
+#endif
+ }
+}
+
+dynFuncPtr dynLibrary::findSymbol(const char *p_symName)
+{
+ if (NULL == m_lib) {
+ return NULL;
+ }
+
+#ifdef _WIN32
+ return (dynFuncPtr) GetProcAddress(m_lib, p_symName);
+#else // !WIN32
+ return (dynFuncPtr) dlsym(m_lib, p_symName);
+#endif
+}
+
+} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h
new file mode 100644
index 0000000..c83fbf3
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osDynLibrary.h
@@ -0,0 +1,71 @@
+/*
+* Copyright (C) 2011 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 _OSUTILS_DYN_LIBRARY_H
+#define _OSUTILS_DYN_LIBRARY_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace osUtils {
+
+typedef void (*dynFuncPtr)(void);
+
+class dynLibrary
+{
+public:
+ static dynLibrary *open(const char *p_libName);
+ ~dynLibrary();
+
+ dynFuncPtr findSymbol(const char *p_symName);
+
+private:
+ dynLibrary();
+
+private:
+#ifdef _WIN32
+ HMODULE m_lib;
+#else
+ void *m_lib;
+#endif
+};
+
+} // of namespace osUtils
+
+
+
+// Macro to compose emugl shared library name under various OS and bitness
+// eg.
+// on x86_64, EMUGL_LIBNAME("foo") --> "lib64foo.so"
+
+#ifdef _WIN32
+# define DLL_EXTENSION "" // _WIN32 LoadLibrary only accept name w/o .dll extension
+#elif defined(__APPLE__)
+# define DLL_EXTENSION ".dylib"
+#else
+# define DLL_EXTENSION ".so"
+#endif
+
+#if defined(__x86_64__)
+# define EMUGL_LIBNAME(name) "lib64" name DLL_EXTENSION
+#elif defined(__i386__)
+# define EMUGL_LIBNAME(name) "lib" name DLL_EXTENSION
+#else
+/* This header is included by target w/o using EMUGL_LIBNAME(). Don't #error, leave it undefined */
+#endif
+
+
+#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcess.h b/emulator/opengl/shared/OpenglOsUtils/osProcess.h
new file mode 100644
index 0000000..82b31b3
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osProcess.h
@@ -0,0 +1,62 @@
+/*
+* Copyright (C) 2011 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 _OSUTILS_PROCESS_H
+#define _OSUTILS_PROCESS_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace osUtils {
+
+class childProcess
+{
+public:
+ static childProcess *create(const char *p_cmdLine, const char *p_startdir);
+ ~childProcess();
+
+ int getPID()
+ {
+#ifdef _WIN32
+ return m_proc.dwProcessId;
+#else
+ return(m_pid);
+#endif
+ }
+
+ int tryWait(bool& isAlive);
+ bool wait(int *exitStatus);
+
+private:
+ childProcess() {};
+
+private:
+#ifdef _WIN32
+ PROCESS_INFORMATION m_proc;
+#else
+ int m_pid;
+#endif
+};
+
+int ProcessGetPID();
+int ProcessGetTID();
+bool ProcessGetName(char *p_outName, int p_outNameLen);
+int KillProcess(int pid, bool wait);
+bool isProcessRunning(int pid);
+
+} // of namespace osUtils
+
+#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp b/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
new file mode 100644
index 0000000..c97ff58
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
@@ -0,0 +1,210 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osProcess.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <poll.h>
+#include <pthread.h>
+#include <string.h>
+#include <pwd.h>
+#include <paths.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+
+namespace osUtils {
+
+//
+// buildArgList converts a command line into null terminated argument list.
+// to be used with execv or execvp.
+// each argument is seperated by space or tab, to specify multiple words
+// at the same argument place it inside single-quoted or double-quoted string.
+//
+static char **buildArgList(const char *command)
+{
+ char **argv = NULL;
+ int argvSize = 0;
+ int nArgs = 0;
+ char *tmpcmd = strdup(command);
+ char *t = tmpcmd;
+ char *strStart = NULL;
+ int i = 0;
+
+ #define ADD_ARG \
+ { \
+ nArgs++; \
+ if (!argv) { \
+ argvSize = 12; \
+ argv = (char **)malloc(argvSize * sizeof(char *)); \
+ } \
+ else if (nArgs > argvSize) { \
+ argvSize += 12; \
+ argv = (char **)realloc(argv, argvSize * sizeof(char *)); \
+ } \
+ argv[nArgs-1] = t; \
+ t = NULL; \
+ }
+
+ while( tmpcmd[i] != '\0' ) {
+ if (!strStart) {
+ if (tmpcmd[i] == '"' || tmpcmd[i] == '\'') {
+ strStart = &tmpcmd[i];
+ }
+ else if (tmpcmd[i] == ' ' || tmpcmd[i] == '\t') {
+ tmpcmd[i] = '\0';
+ if (t) ADD_ARG;
+ }
+ else if (!t) {
+ t = &tmpcmd[i];
+ }
+ }
+ else if (tmpcmd[i] == *strStart) {
+ t = strStart;
+ strStart = NULL;
+ }
+
+ i++;
+ }
+ if (t) {
+ ADD_ARG;
+ }
+ if (nArgs > 0) {
+ ADD_ARG; // for NULL terminating list
+ }
+
+ return argv;
+}
+
+static pid_t start_process(const char *command,const char *startDir)
+{
+ pid_t pid;
+
+ pid = fork();
+
+ if (pid < 0) {
+ return pid;
+ }
+ else if (pid == 0) {
+ //
+ // Close all opened file descriptors
+ //
+ for (int i=3; i<256; i++) {
+ close(i);
+ }
+
+ if (startDir) {
+ chdir(startDir);
+ }
+
+ char **argv = buildArgList(command);
+ if (!argv) {
+ return -1;
+ }
+ execvp(argv[0], argv);
+
+ perror("execl");
+ exit(-101);
+ }
+
+ return pid;
+}
+
+childProcess *
+childProcess::create(const char *p_cmdLine, const char *p_startdir)
+{
+ childProcess *child = new childProcess();
+ if (!child) {
+ return NULL;
+ }
+
+ child->m_pid = start_process(p_cmdLine, p_startdir);
+ if (child->m_pid < 0) {
+ delete child;
+ return NULL;
+ }
+
+ return child;
+}
+
+childProcess::~childProcess()
+{
+}
+
+bool
+childProcess::wait(int *exitStatus)
+{
+ int ret=0;
+ if (m_pid>0) {
+ pid_t pid = waitpid(m_pid,&ret,0);
+ if (pid != -1) {
+ m_pid=-1;
+ if (exitStatus) {
+ *exitStatus = ret;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+int
+childProcess::tryWait(bool &isAlive)
+{
+ int ret=0;
+ isAlive = false;
+ if (m_pid>0) {
+ pid_t pid = waitpid(m_pid,&ret,WNOHANG);
+ if (pid == 0) {
+ isAlive = true;
+ }
+ }
+
+ return ((char)WEXITSTATUS(ret));
+}
+
+int ProcessGetPID()
+{
+ return getpid();
+}
+
+int KillProcess(int pid, bool wait)
+{
+ if (pid<1) {
+ return false;
+ }
+
+ if (0!=kill(pid,SIGTERM)) {
+ return false;
+ }
+
+ if (wait) {
+ if (waitpid(pid,NULL,0)<0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool isProcessRunning(int pid)
+{
+ return (kill(pid,0) == 0);
+}
+
+} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp b/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp
new file mode 100644
index 0000000..6ff0fdf
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osProcessWin.cpp
@@ -0,0 +1,171 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osProcess.h"
+#include <windows.h>
+#include <string>
+#include <stdlib.h>
+#include <psapi.h>
+
+namespace osUtils {
+
+childProcess *
+childProcess::create(const char *p_cmdLine, const char *p_startdir)
+{
+ childProcess *child = new childProcess();
+ if (!child) {
+ return NULL;
+ }
+
+ STARTUPINFOA si;
+ ZeroMemory(&si, sizeof(si));
+
+ ZeroMemory(&child->m_proc, sizeof(child->m_proc));
+ BOOL ret = CreateProcessA(
+ NULL ,
+ (LPSTR)p_cmdLine,
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_DEFAULT_ERROR_MODE,
+ NULL,
+ (p_startdir != NULL ? p_startdir : ".\\"),
+ &si,
+ &child->m_proc);
+ if (ret == 0) {
+ delete child;
+ return NULL;
+ }
+
+ // close the thread handle we do not need it,
+ // keep the process handle for wait/trywait operations, will
+ // be closed on destruction
+ CloseHandle(child->m_proc.hThread);
+
+ return child;
+}
+
+childProcess::~childProcess()
+{
+ if (m_proc.hProcess) {
+ CloseHandle(m_proc.hProcess);
+ }
+}
+
+bool
+childProcess::wait(int *exitStatus)
+{
+DWORD _exitStatus;
+
+ if (WaitForSingleObject(m_proc.hProcess, INFINITE) == WAIT_FAILED) {
+ return false;
+ }
+
+ if (!GetExitCodeProcess(m_proc.hProcess, &_exitStatus))
+ {
+ return false;
+ }
+
+ if (exitStatus) {
+ *exitStatus = _exitStatus;
+ }
+
+ return true;
+}
+
+int
+childProcess::tryWait(bool& isAlive)
+{
+ DWORD status = WaitForSingleObject(m_proc.hProcess, 0);
+
+ if(status == WAIT_OBJECT_0)
+ {
+ // process has exited
+ isAlive = false;
+ GetExitCodeProcess(m_proc.hProcess, &status);
+ }
+ else if (status == WAIT_TIMEOUT)
+ {
+ isAlive = true;
+ status = 0;
+ }
+
+ return status;
+
+}
+
+int ProcessGetPID()
+{
+ return GetCurrentProcessId();
+}
+
+int ProcessGetTID()
+{
+ return GetCurrentThreadId();
+}
+
+bool ProcessGetName(char *p_outName, int p_outNameLen)
+{
+ return 0 != GetModuleFileNameEx( GetCurrentProcess(), NULL, p_outName, p_outNameLen);
+}
+
+int KillProcess(int pid, bool wait)
+{
+ DWORD exitStatus = 1;
+ HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+
+ if (NULL == hProc) {
+ return 0;
+ }
+
+ //
+ // Terminate the process
+ //
+ TerminateProcess(hProc, 0x55);
+
+ if (wait) {
+ //
+ // Wait for it to be terminated
+ //
+ if(WaitForSingleObject(hProc, INFINITE) == WAIT_FAILED) {
+ CloseHandle(hProc);
+ return 0;
+ }
+
+ if (!GetExitCodeProcess(hProc, &exitStatus)) {
+ CloseHandle(hProc);
+ return 0;
+ }
+ }
+
+ CloseHandle(hProc);
+
+ return exitStatus;
+}
+
+bool isProcessRunning(int pid)
+{
+ bool isRunning = false;
+
+ HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
+ if (NULL != process) {
+ DWORD ret = WaitForSingleObject(process, 0);
+ CloseHandle(process);
+ isRunning = (ret == WAIT_TIMEOUT);
+ }
+ return isRunning;
+}
+
+} // of namespace osUtils
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThread.h b/emulator/opengl/shared/OpenglOsUtils/osThread.h
new file mode 100644
index 0000000..970396d
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osThread.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (C) 2011 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 _OSUTILS_THREAD_H
+#define _OSUTILS_THREAD_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else // !WIN32
+#include <pthread.h>
+#endif
+
+namespace osUtils {
+
+class Thread
+{
+public:
+ Thread();
+ virtual ~Thread();
+
+ virtual int Main() = 0;
+
+ bool start();
+ bool wait(int *exitStatus);
+ bool trywait(int *exitStatus);
+
+private:
+#ifdef _WIN32
+ static DWORD WINAPI thread_main(void *p_arg);
+#else // !WIN32
+ static void* thread_main(void *p_arg);
+#endif
+
+private:
+#ifdef _WIN32
+ HANDLE m_thread;
+ DWORD m_threadId;
+#else // !WIN32
+ pthread_t m_thread;
+ int m_exitStatus;
+ pthread_mutex_t m_lock;
+#endif
+ bool m_isRunning;
+};
+
+} // of namespace osUtils
+
+#endif
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
new file mode 100644
index 0000000..d8879eb
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
@@ -0,0 +1,94 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osThread.h"
+
+namespace osUtils {
+
+Thread::Thread() :
+ m_thread((pthread_t)NULL),
+ m_exitStatus(0),
+ m_isRunning(false)
+{
+ pthread_mutex_init(&m_lock, NULL);
+}
+
+Thread::~Thread()
+{
+ pthread_mutex_destroy(&m_lock);
+}
+
+bool
+Thread::start()
+{
+ pthread_mutex_lock(&m_lock);
+ m_isRunning = true;
+ int ret = pthread_create(&m_thread, NULL, Thread::thread_main, this);
+ if(ret) {
+ m_isRunning = false;
+ }
+ pthread_mutex_unlock(&m_lock);
+ return m_isRunning;
+}
+
+bool
+Thread::wait(int *exitStatus)
+{
+ if (!m_isRunning) {
+ return false;
+ }
+
+ void *retval;
+ if (pthread_join(m_thread,&retval)) {
+ return false;
+ }
+
+ long long int ret=(long long int)retval;
+ if (exitStatus) {
+ *exitStatus = (int)ret;
+ }
+ return true;
+}
+
+bool
+Thread::trywait(int *exitStatus)
+{
+ bool ret = false;
+
+ pthread_mutex_lock(&m_lock);
+ if (!m_isRunning) {
+ *exitStatus = m_exitStatus;
+ ret = true;
+ }
+ pthread_mutex_unlock(&m_lock);
+ return ret;
+}
+
+void *
+Thread::thread_main(void *p_arg)
+{
+ Thread *self = (Thread *)p_arg;
+ int ret = self->Main();
+
+ pthread_mutex_lock(&self->m_lock);
+ self->m_isRunning = false;
+ self->m_exitStatus = ret;
+ pthread_mutex_unlock(&self->m_lock);
+
+ return (void*)ret;
+}
+
+} // of namespace osUtils
+
diff --git a/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
new file mode 100644
index 0000000..2d563f8
--- /dev/null
+++ b/emulator/opengl/shared/OpenglOsUtils/osThreadWin.cpp
@@ -0,0 +1,101 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osThread.h"
+
+namespace osUtils {
+
+Thread::Thread() :
+ m_thread(NULL),
+ m_threadId(0),
+ m_isRunning(false)
+{
+}
+
+Thread::~Thread()
+{
+ if(m_thread) {
+ CloseHandle(m_thread);
+ }
+}
+
+bool
+Thread::start()
+{
+ m_isRunning = true;
+ m_thread = CreateThread(NULL, 0, &Thread::thread_main, this, 0, &m_threadId);
+ if(!m_thread) {
+ m_isRunning = false;
+ }
+ return m_isRunning;
+}
+
+bool
+Thread::wait(int *exitStatus)
+{
+ if (!m_isRunning) {
+ return false;
+ }
+
+ if(WaitForSingleObject(m_thread, INFINITE) == WAIT_FAILED) {
+ return false;
+ }
+
+ DWORD retval;
+ if (!GetExitCodeThread(m_thread,&retval)) {
+ return false;
+ }
+
+ m_isRunning = 0;
+
+ if (exitStatus) {
+ *exitStatus = retval;
+ }
+ return true;
+}
+
+bool
+Thread::trywait(int *exitStatus)
+{
+ if (!m_isRunning) {
+ return false;
+ }
+
+ if(WaitForSingleObject(m_thread, 0) == WAIT_OBJECT_0) {
+
+ DWORD retval;
+ if (!GetExitCodeThread(m_thread,&retval)) {
+ return true;
+ }
+
+ if (exitStatus) {
+ *exitStatus = retval;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+DWORD WINAPI
+Thread::thread_main(void *p_arg)
+{
+ Thread *self = (Thread *)p_arg;
+ int ret = self->Main();
+ self->m_isRunning = false;
+ return ret;
+}
+
+} // of namespace osUtils