| David Li | aa1f54d | 2011-03-01 16:54:04 -0800 | [diff] [blame] | 1 | #define _SIZE_T_DEFINED_ | 
|  | 2 | typedef unsigned int size_t; | 
|  | 3 |  | 
|  | 4 | #include <stdio.h> | 
|  | 5 | #include <stdlib.h> | 
|  | 6 |  | 
|  | 7 | #include <EGL/egl.h> | 
|  | 8 | #include <EGL/eglext.h> | 
|  | 9 | #include <GLES/gl.h> | 
|  | 10 | #include <GLES/glext.h> | 
|  | 11 |  | 
|  | 12 | #include <utils/threads.h> | 
|  | 13 | #include <pthread.h> | 
|  | 14 |  | 
|  | 15 | #include <cutils/log.h> | 
|  | 16 |  | 
|  | 17 | #include <assert.h> | 
|  | 18 |  | 
|  | 19 | #ifdef __arm__ | 
|  | 20 | #ifndef __location__ | 
|  | 21 | #define __HIERALLOC_STRING_0__(s)   #s | 
|  | 22 | #define __HIERALLOC_STRING_1__(s)   __HIERALLOC_STRING_0__(s) | 
|  | 23 | #define __HIERALLOC_STRING_2__      __HIERALLOC_STRING_1__(__LINE__) | 
|  | 24 | #define __location__                __FILE__ ":" __HIERALLOC_STRING_2__ | 
|  | 25 | #endif | 
|  | 26 | #undef assert | 
|  | 27 | #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); } | 
|  | 28 | //#define printf LOGD | 
|  | 29 | #else // #ifdef __arm__ | 
|  | 30 | //#define LOGD printf | 
|  | 31 | #endif // #ifdef __arm__ | 
|  | 32 |  | 
|  | 33 |  | 
|  | 34 | #include <pixelflinger2/pixelflinger2_format.h> | 
|  | 35 | #include <pixelflinger2/pixelflinger2.h> | 
|  | 36 |  | 
|  | 37 | #include <map> | 
|  | 38 |  | 
|  | 39 | typedef uint8_t                 GGLubyte;               // ub | 
|  | 40 |  | 
|  | 41 | #define ggl_likely(x)   __builtin_expect(!!(x), 1) | 
|  | 42 | #define ggl_unlikely(x) __builtin_expect(!!(x), 0) | 
|  | 43 |  | 
|  | 44 | #undef NELEM | 
|  | 45 | #define NELEM(x) (sizeof(x)/sizeof(*(x))) | 
|  | 46 |  | 
|  | 47 | template<typename T> | 
|  | 48 | inline T max(T a, T b) | 
|  | 49 | { | 
|  | 50 | return a<b ? b : a; | 
|  | 51 | } | 
|  | 52 |  | 
|  | 53 | template<typename T> | 
|  | 54 | inline T min(T a, T b) | 
|  | 55 | { | 
|  | 56 | return a<b ? a : b; | 
|  | 57 | } | 
|  | 58 |  | 
|  | 59 | struct egl_context_t { | 
|  | 60 | enum { | 
|  | 61 | IS_CURRENT      =   0x00010000, | 
|  | 62 | NEVER_CURRENT   =   0x00020000 | 
|  | 63 | }; | 
|  | 64 | uint32_t            flags; | 
|  | 65 | EGLDisplay          dpy; | 
|  | 66 | EGLConfig           config; | 
|  | 67 | EGLSurface          read; | 
|  | 68 | EGLSurface          draw; | 
|  | 69 |  | 
|  | 70 | unsigned frame; | 
|  | 71 | clock_t lastSwapTime; | 
|  | 72 | float accumulateSeconds; | 
|  | 73 |  | 
|  | 74 | static inline egl_context_t* context(EGLContext ctx); | 
|  | 75 | }; | 
|  | 76 |  | 
|  | 77 | struct GLES2Context; | 
|  | 78 |  | 
|  | 79 | #ifdef HAVE_ANDROID_OS | 
|  | 80 | #include <bionic_tls.h> | 
|  | 81 | // We have a dedicated TLS slot in bionic | 
|  | 82 | inline void setGlThreadSpecific(GLES2Context *value) | 
|  | 83 | { | 
|  | 84 | ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value; | 
|  | 85 | } | 
|  | 86 | inline GLES2Context* getGlThreadSpecific() | 
|  | 87 | { | 
|  | 88 | return (GLES2Context *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]); | 
|  | 89 | } | 
|  | 90 | #else | 
|  | 91 | extern pthread_key_t gGLKey; | 
|  | 92 | inline void setGlThreadSpecific(GLES2Context *value) | 
|  | 93 | { | 
|  | 94 | pthread_setspecific(gGLKey, value); | 
|  | 95 | } | 
|  | 96 | inline GLES2Context* getGlThreadSpecific() | 
|  | 97 | { | 
|  | 98 | return static_cast<GLES2Context*>(pthread_getspecific(gGLKey)); | 
|  | 99 | } | 
|  | 100 | #endif | 
|  | 101 |  | 
|  | 102 | struct VBO { | 
|  | 103 | unsigned size; | 
|  | 104 | GLenum usage; | 
|  | 105 | void * data; | 
|  | 106 | }; | 
|  | 107 |  | 
|  | 108 | struct GLES2Context { | 
|  | 109 | GGLContext rasterizer; | 
|  | 110 | egl_context_t egl; | 
|  | 111 | GGLInterface * iface; // shortcut to &rasterizer.interface | 
|  | 112 |  | 
|  | 113 | struct VertexState { | 
|  | 114 | struct VertAttribPointer { | 
|  | 115 | unsigned size; // number of values per vertex | 
|  | 116 | GLenum type;  // data type | 
|  | 117 | unsigned stride; // bytes | 
|  | 118 | const void * ptr; | 
|  | 119 | bool normalized : | 
|  | 120 | 1; | 
|  | 121 | bool enabled : | 
|  | 122 | 1; | 
|  | 123 | } attribs [GGL_MAXVERTEXATTRIBS]; | 
|  | 124 |  | 
|  | 125 | VBO * vbo, * indices; | 
|  | 126 | std::map<GLuint, VBO *> vbos; | 
|  | 127 | GLuint free; | 
|  | 128 |  | 
|  | 129 | Vector4 defaultAttribs [GGL_MAXVERTEXATTRIBS]; | 
|  | 130 | } vert; | 
|  | 131 |  | 
|  | 132 | struct TextureState { | 
|  | 133 | GGLTexture * tmus[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; | 
|  | 134 | int sampler2tmu[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; // sampler2tmu[sampler] is index of tmu, -1 means not used | 
|  | 135 | unsigned active; | 
|  | 136 | std::map<GLuint, GGLTexture *> textures; | 
|  | 137 | GLuint free; // first possible free name | 
|  | 138 | GGLTexture * tex2D, * texCube; // default textures | 
|  | 139 | unsigned unpack; | 
|  | 140 |  | 
|  | 141 | void UpdateSampler(GGLInterface * iface, unsigned tmu); | 
|  | 142 | } tex; | 
|  | 143 |  | 
|  | 144 | GLES2Context(); | 
|  | 145 | void InitializeTextures(); | 
|  | 146 | void InitializeVertices(); | 
|  | 147 |  | 
|  | 148 | ~GLES2Context(); | 
|  | 149 | void UninitializeTextures(); | 
|  | 150 | void UninitializeVertices(); | 
|  | 151 |  | 
|  | 152 | static inline GLES2Context* get() { | 
|  | 153 | return getGlThreadSpecific(); | 
|  | 154 | } | 
|  | 155 | }; | 
|  | 156 |  | 
|  | 157 | inline egl_context_t* egl_context_t::context(EGLContext ctx) | 
|  | 158 | { | 
|  | 159 | GLES2Context* const gl = static_cast<GLES2Context*>(ctx); | 
|  | 160 | return static_cast<egl_context_t*>(&gl->egl); | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | #define GLES2_GET_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \ | 
|  | 164 | /*puts(__FUNCTION__);*/ | 
|  | 165 | #define GLES2_GET_CONST_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \ | 
|  | 166 | /*puts(__FUNCTION__);*/ |