emulator: opengl: Back-port GLES emulation from the master tree.

The modules here are only built when BUILD_EMULATOR_OPENGL is defined to true
in your environment or your BoardConfig.mk (see tools/emulator/opengl/Android.mk)

Change-Id: I5f32c35b4452fb5a7b4d5f9fc5870ec1da6032e6
This commit is contained in:
David 'Digit' Turner
2011-09-16 17:59:01 +02:00
parent dfd5d02cec
commit 4e6af749d5
257 changed files with 44173 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
# 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
### 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 := $(commonSources)
ifeq ($(HOST_OS),windows)
LOCAL_SRC_FILES += Win32PipeStream.cpp
else
LOCAL_SRC_FILES += UnixStream.cpp
endif
$(call emugl-export,STATIC_LIBRARIES,libcutils)
$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
$(call emugl-end-module)

View File

@@ -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(...) LOGE(__VA_ARGS__)
# ifdef EMUGL_DEBUG
# define DBG(...) LOGD(__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

View File

@@ -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 _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

View File

@@ -0,0 +1,232 @@
/*
* 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>
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;
}
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;
}

View File

@@ -0,0 +1,363 @@
/*
* 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;
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; }
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); }
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

View File

@@ -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

View File

@@ -0,0 +1,18 @@
#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__

View File

@@ -0,0 +1,314 @@
#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;
}
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;
}
/***** GLSharedGroup ****/
GLSharedGroup::GLSharedGroup() :
m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
m_shaders(android::List<GLuint>())
{
}
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::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type)
{
android::AutoMutex _lock(m_lock);
ProgramData* pData = m_programs.valueFor(program);
if (pData)
{
pData->setIndexInfo(index,base,size,type);
}
}
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;
}
void GLSharedGroup::addShaderData(GLuint shader)
{
android::AutoMutex _lock(m_lock);
m_shaders.push_front(shader);
}
bool GLSharedGroup::isShader(GLuint shader)
{
android::AutoMutex _lock(m_lock);
android::List<GLuint>::iterator iter;
iter = m_shaders.begin();
while (iter!=m_shaders.end())
{
if (*iter==shader)
return true;
iter++;
}
return false;
}
void GLSharedGroup::deleteShaderData(GLuint shader)
{
android::AutoMutex _lock(m_lock);
android::List<GLuint>::iterator iter;
iter = m_shaders.begin();
while (iter!=m_shaders.end())
{
if (*iter==shader)
{
m_shaders.erase(iter);
return;
}
iter++;
}
}

View File

@@ -0,0 +1,111 @@
/*
* 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/threads.h>
#include <utils/List.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;
} IndexInfo;
GLuint m_numIndexes;
IndexInfo* m_Indexes;
bool m_initialized;
bool m_locShiftWAR;
public:
ProgramData();
void initProgramData(GLuint numIndexes);
bool isInitialized();
virtual ~ProgramData();
void setIndexInfo(GLuint index, GLint base, GLint size, GLenum type);
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);
};
class GLSharedGroup {
private:
android::DefaultKeyedVector<GLuint, BufferData*> m_buffers;
android::DefaultKeyedVector<GLuint, ProgramData*> m_programs;
android::List<GLuint> m_shaders;
mutable android::Mutex m_lock;
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 deleteProgramData(GLuint program);
void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type);
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);
void addShaderData(GLuint shader);
bool isShader(GLuint shader);
void deleteShaderData(GLuint shader);
};
typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr;
#endif //_GL_SHARED_GROUP_H_

View File

@@ -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)

View File

@@ -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

View File

@@ -0,0 +1,163 @@
/*
* 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 (%d) failed\n", __FUNCTION__, allocSize);
free(m_buf);
m_buf = NULL;
m_bufsize = 0;
}
}
return m_buf;
};
int SocketStream::commitBuffer(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 *)(m_buf) + (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;
}

View File

@@ -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);
protected:
int m_sock;
size_t m_bufsize;
unsigned char *m_buf;
SocketStream(int sock, size_t bufSize);
int writeFully(const void *buf, size_t len);
};
#endif /* __SOCKET_STREAM_H */

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,450 @@
/*
* 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"
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_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;
}
}
}
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;
}

View File

@@ -0,0 +1,92 @@
/*
* 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);
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

View File

@@ -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