aa1f54d78f
Somewhat functional, refer to README for details. Need to enable Android.mk to build. It builds libGLES_android.so, which needs to replace the one in system/lib/egl built by libagl. Change-Id: Iec3aaa8f3963a4185d81955cd24019eb0c4a5850 Signed-off-by: David Li <davidxli@google.com>
167 lines
4.0 KiB
C++
167 lines
4.0 KiB
C++
#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__);*/
|