blob: cec0340303f3fe706db7d24c44bf193d21970de2 [file] [log] [blame]
#define _SIZE_T_DEFINED_
typedef unsigned int size_t;
#include <stdio.h>
#include <stdlib.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <utils/threads.h>
#include <pthread.h>
#include <cutils/log.h>
#include <assert.h>
#ifdef __arm__
#ifndef __location__
#define __HIERALLOC_STRING_0__(s) #s
#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
#endif
#undef assert
#define assert(EXPR) { do { if (!(EXPR)) {LOGD("\n*\n*\n*\n* assert fail: '"#EXPR"' at "__location__"\n*\n*\n*\n*"); exit(EXIT_FAILURE); } } while (false); }
//#define printf LOGD
#else // #ifdef __arm__
//#define LOGD printf
#endif // #ifdef __arm__
#include <pixelflinger2/pixelflinger2_format.h>
#include <pixelflinger2/pixelflinger2.h>
#include <map>
typedef uint8_t GGLubyte; // ub
#define ggl_likely(x) __builtin_expect(!!(x), 1)
#define ggl_unlikely(x) __builtin_expect(!!(x), 0)
#undef NELEM
#define NELEM(x) (sizeof(x)/sizeof(*(x)))
template<typename T>
inline T max(T a, T b)
{
return a<b ? b : a;
}
template<typename T>
inline T min(T a, T b)
{
return a<b ? a : b;
}
struct egl_context_t {
enum {
IS_CURRENT = 0x00010000,
NEVER_CURRENT = 0x00020000
};
uint32_t flags;
EGLDisplay dpy;
EGLConfig config;
EGLSurface read;
EGLSurface draw;
unsigned frame;
clock_t lastSwapTime;
float accumulateSeconds;
static inline egl_context_t* context(EGLContext ctx);
};
struct GLES2Context;
#ifdef HAVE_ANDROID_OS
#include <bionic_tls.h>
// We have a dedicated TLS slot in bionic
inline void setGlThreadSpecific(GLES2Context *value)
{
((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
}
inline GLES2Context* getGlThreadSpecific()
{
return (GLES2Context *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
}
#else
extern pthread_key_t gGLKey;
inline void setGlThreadSpecific(GLES2Context *value)
{
pthread_setspecific(gGLKey, value);
}
inline GLES2Context* getGlThreadSpecific()
{
return static_cast<GLES2Context*>(pthread_getspecific(gGLKey));
}
#endif
struct VBO {
unsigned size;
GLenum usage;
void * data;
};
struct GLES2Context {
GGLContext rasterizer;
egl_context_t egl;
GGLInterface * iface; // shortcut to &rasterizer.interface
struct VertexState {
struct VertAttribPointer {
unsigned size; // number of values per vertex
GLenum type; // data type
unsigned stride; // bytes
const void * ptr;
bool normalized :
1;
bool enabled :
1;
} attribs [GGL_MAXVERTEXATTRIBS];
VBO * vbo, * indices;
std::map<GLuint, VBO *> vbos;
GLuint free;
Vector4 defaultAttribs [GGL_MAXVERTEXATTRIBS];
} vert;
struct TextureState {
GGLTexture * tmus[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS];
int sampler2tmu[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; // sampler2tmu[sampler] is index of tmu, -1 means not used
unsigned active;
std::map<GLuint, GGLTexture *> textures;
GLuint free; // first possible free name
GGLTexture * tex2D, * texCube; // default textures
unsigned unpack;
void UpdateSampler(GGLInterface * iface, unsigned tmu);
} tex;
GLES2Context();
void InitializeTextures();
void InitializeVertices();
~GLES2Context();
void UninitializeTextures();
void UninitializeVertices();
static inline GLES2Context* get() {
return getGlThreadSpecific();
}
};
inline egl_context_t* egl_context_t::context(EGLContext ctx)
{
GLES2Context* const gl = static_cast<GLES2Context*>(ctx);
return static_cast<egl_context_t*>(&gl->egl);
}
#define GLES2_GET_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
/*puts(__FUNCTION__);*/
#define GLES2_GET_CONST_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
/*puts(__FUNCTION__);*/