aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/shared/OpenglCodecCommon
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-04-16 12:49:39 -0700
committerJesse Hall <jessehall@google.com>2012-04-16 15:54:18 -0700
commitce6c3389061fb9fcdefc94fab2044a8e11600b52 (patch)
treefedd1a11cbd21ec14bf00be83b8712054f8c5506 /emulator/opengl/shared/OpenglCodecCommon
parentad0111a77b0f0908cc945dc6e8e8949b75cb8886 (diff)
downloadsdk-ce6c3389061fb9fcdefc94fab2044a8e11600b52.zip
sdk-ce6c3389061fb9fcdefc94fab2044a8e11600b52.tar.gz
sdk-ce6c3389061fb9fcdefc94fab2044a8e11600b52.tar.bz2
Move emulator GLES from development.git to sdk.git
The emulator GLES support has two interfaces: a host shared library interface used by QEMU, and a protocol between the platform and the host. The host library interface is not versioned; QEMU and the GLES renderer must match. The protocol on the other hand must be backwards compatible: a new GLES renderer must support an older platform image. Thus for branching purposes it makes more sense to put the GLES renderer in sdk.git, which is branched along with qemu.git for SDK releases. Platform images will be built against the protocol version in the platform branch of sdk.git. Change-Id: I2c3bce627ecfd0a4b3e688d1839fe10755a21e58
Diffstat (limited to 'emulator/opengl/shared/OpenglCodecCommon')
-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
25 files changed, 3428 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