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__);*/ |