/* * Copyright (C) 2006 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 ANDROID_OPENGLES_CONTEXT_H #define ANDROID_OPENGLES_CONTEXT_H #include #include #include #include #ifdef HAVE_ANDROID_OS #include #endif #include #include #include #include namespace android { const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10 #ifdef GL_OES_compressed_ETC1_RGB8_texture + 1 #endif ; class EGLTextureObject; class EGLSurfaceManager; class EGLBufferObjectManager; namespace gl { struct ogles_context_t; struct matrixx_t; struct transform_t; struct buffer_t; ogles_context_t* getGlContext(); template static inline void swap(T& a, T& b) { T t(a); a = b; b = t; } template inline T max(T a, T b) { return a inline T max(T a, T b, T c) { return max(a, max(b, c)); } template inline T min(T a, T b) { return a inline T min(T a, T b, T c) { return min(a, min(b, c)); } template inline T min(T a, T b, T c, T d) { return min(min(a,b), min(c,d)); } // ---------------------------------------------------------------------------- // vertices // ---------------------------------------------------------------------------- struct vec3_t { union { struct { GLfixed x, y, z; }; struct { GLfixed r, g, b; }; struct { GLfixed S, T, R; }; GLfixed v[3]; }; }; struct vec4_t { union { struct { GLfixed x, y, z, w; }; struct { GLfixed r, g, b, a; }; struct { GLfixed S, T, R, Q; }; GLfixed v[4]; }; }; struct vertex_t { enum { // these constant matter for our clipping CLIP_L = 0x0001, // clipping flags CLIP_R = 0x0002, CLIP_B = 0x0004, CLIP_T = 0x0008, CLIP_N = 0x0010, CLIP_F = 0x0020, EYE = 0x0040, RESERVED = 0x0080, USER_CLIP_0 = 0x0100, // user clipping flags USER_CLIP_1 = 0x0200, USER_CLIP_2 = 0x0400, USER_CLIP_3 = 0x0800, USER_CLIP_4 = 0x1000, USER_CLIP_5 = 0x2000, LIT = 0x4000, // lighting has been applied TT = 0x8000, // texture coords transformed FRUSTUM_CLIP_ALL= 0x003F, USER_CLIP_ALL = 0x3F00, CLIP_ALL = 0x3F3F, }; // the fields below are arranged to minimize d-cache usage // we group together, by cache-line, the fields most likely to be used union { vec4_t obj; vec4_t eye; }; vec4_t clip; uint32_t flags; size_t index; // cache tag, and vertex index GLfixed fog; uint8_t locked; uint8_t mru; uint8_t reserved[2]; vec4_t window; vec4_t color; vec4_t texture[GGL_TEXTURE_UNIT_COUNT]; #ifdef __LP64__ uint32_t reserved1[2]; #else uint32_t reserved1[4]; #endif inline void clear() { flags = index = locked = mru = 0; } }; struct point_size_t { GGLcoord size; GLboolean smooth; }; struct line_width_t { GGLcoord width; GLboolean smooth; }; struct polygon_offset_t { GLfixed factor; GLfixed units; GLboolean enable; }; // ---------------------------------------------------------------------------- // arrays // ---------------------------------------------------------------------------- struct array_t { typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*); fetcher_t fetch; GLvoid const* physical_pointer; GLint size; GLsizei stride; GLvoid const* pointer; buffer_t const* bo; uint16_t type; GLboolean enable; GLboolean pad; GLsizei bounds; void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei); inline void resolve(); inline const GLubyte* element(GLint i) const { return (const GLubyte*)physical_pointer + i * stride; } }; struct array_machine_t { array_t vertex; array_t normal; array_t color; array_t texture[GGL_TEXTURE_UNIT_COUNT]; uint8_t activeTexture; uint8_t tmu; uint16_t cull; uint32_t flags; GLenum indicesType; buffer_t const* array_buffer; buffer_t const* element_array_buffer; void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei); void (*compileElement)(ogles_context_t*, vertex_t*, GLint); void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*); void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*); void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*); void (*perspective)(ogles_context_t*c, vertex_t* v); void (*clipVertex)(ogles_context_t* c, vertex_t* nv, GGLfixed t, const vertex_t* s, const vertex_t* p); void (*clipEye)(ogles_context_t* c, vertex_t* nv, GGLfixed t, const vertex_t* s, const vertex_t* p); }; struct vertex_cache_t { enum { // must be at least 4 // 3 vertice for triangles // or 2 + 2 for indexed triangles w/ cache contention VERTEX_BUFFER_SIZE = 8, // must be a power of two and at least 3 VERTEX_CACHE_SIZE = 64, // 8 KB INDEX_BITS = 16, INDEX_MASK = ((1LU<(__get_tls()[TLS_SLOT_OPENGL]); } #else extern pthread_key_t gGLKey; inline void setGlThreadSpecific(ogles_context_t *value) { pthread_setspecific(gGLKey, value); } inline ogles_context_t* getGlThreadSpecific() { return static_cast(pthread_getspecific(gGLKey)); } #endif struct prims_t { typedef ogles_context_t* GL; void (*renderPoint)(GL, vertex_t*); void (*renderLine)(GL, vertex_t*, vertex_t*); void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*); }; struct ogles_context_t { context_t rasterizer; array_machine_t arrays __attribute__((aligned(32))); texture_state_t textures; transform_state_t transforms; vertex_cache_t vc; prims_t prims; culling_t cull; lighting_t lighting; user_clip_planes_t clipPlanes; compute_iterators_t lerp; __attribute__((aligned(32))); vertex_t current; vec4_t currentColorClamped; vec3_t currentNormal; viewport_t viewport; point_size_t point; line_width_t line; polygon_offset_t polygonOffset; fog_t fog; uint32_t perspective : 1; uint32_t transformTextures : 1; EGLSurfaceManager* surfaceManager; EGLBufferObjectManager* bufferObjectManager; GLenum error; static inline ogles_context_t* get() { return getGlThreadSpecific(); } }; }; // namespace gl }; // namespace android using namespace android::gl; #endif // ANDROID_OPENGLES_CONTEXT_H