static void* _gfx_gl_binder_init( size_t num, size_t size) { size_t unitSize = sizeof(GFX_Unit) + size; /* Allocate */ void* data = calloc(num, unitSize); if(!data) { /* Out of memory error */ gfx_errors_push( GFX_ERROR_OUT_OF_MEMORY, "Internal binder could not be allocated." ); return NULL; } void* bindings = data; /* Iterate and set to empty */ while(num--) { GFX_Unit* unit = (GFX_Unit*)bindings; unit->counter = GFX_BINDER_COUNTER_EMPTY; /* Next unit */ bindings = GFX_PTR_ADD_BYTES(bindings, unitSize); } return data; }
static void APIENTRY _gfx_gl_error_callback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { GFXErrorCode code; switch(type) { /* Ignore group and marker calls */ case GL_DEBUG_TYPE_MARKER : case GL_DEBUG_TYPE_PUSH_GROUP : case GL_DEBUG_TYPE_POP_GROUP : return; /* Unknown errors */ case GL_DEBUG_TYPE_ERROR : case GL_DEBUG_TYPE_OTHER : code = GFX_ERROR_UNKNOWN; break; /* Known errors */ default : code = type; break; } /* Push the error */ gfx_errors_push(code, message); }
GFXMesh* gfx_mesh_create(void) { /* Allocate mesh */ GFX_Mesh* mesh = malloc(sizeof(GFX_Mesh)); if(!mesh) { /* Out of memory error */ gfx_errors_push( GFX_ERROR_OUT_OF_MEMORY, "Mesh could not be allocated." ); return NULL; } /* Initialize */ _gfx_lod_map_init( (GFX_LodMap*)mesh, 0, sizeof(GFX_SourceData), sizeof(GFX_SourceData) ); gfx_vector_init(&mesh->layouts, sizeof(GFXVertexLayout*)); gfx_vector_init(&mesh->buckets, 1); gfx_vector_init(&mesh->buffers, sizeof(GFXSharedBuffer)); return (GFXMesh*)mesh; }
GFXThreadPool* gfx_thread_pool_create( GFXThreadPoolInit init, GFXThreadPoolTerminate terminate, int suspend) { /* Create a new thread pool */ GFX_Pool* pool = malloc(sizeof(GFX_Pool)); if(!pool) { /* Out of memory error */ gfx_errors_push( GFX_ERROR_OUT_OF_MEMORY, "Thread pool could not be allocated." ); return NULL; } /* Create mutex */ if(_gfx_platform_mutex_init(&pool->mutex)) { /* Create condition variable */ if(_gfx_platform_cond_init(&pool->assign)) { if(_gfx_platform_cond_init(&pool->flush)) { /* Initialize */ pool->status = suspend ? GFX_INT_POOL_SUSPENDED : GFX_INT_POOL_RESUMED; pool->pool.size = 0; pool->pool.init = init; pool->pool.terminate = terminate; gfx_vector_init(&pool->tasks, sizeof(GFX_Task)); pool->threads = NULL; pool->deads = NULL; return (GFXThreadPool*)pool; } _gfx_platform_cond_clear(&pool->assign); } _gfx_platform_mutex_clear(&pool->mutex); } /* Nevermind */ free(pool); return NULL; }
static int _gfx_x11_load_extensions( int* major, int* minor) { int num = XDefaultScreen(_gfx_x11.display); /* Check XRandR version */ if( !XRRQueryVersion(_gfx_x11.display, major, minor) || *major < 1 || (*major == 1 && *minor < 2)) { gfx_errors_push(GFX_ERROR_INCOMPATIBLE_CONTEXT, "RandR 1.2 is not supported."); return 0; } /* Check all vital extensions */ if( !_gfx_x11_is_extension_supported(num, "GLX_ARB_get_proc_address") || !_gfx_x11_is_extension_supported(num, "GLX_ARB_create_context") || !_gfx_x11_is_extension_supported(num, "GLX_ARB_create_context_profile")) { gfx_errors_push(GFX_ERROR_INCOMPATIBLE_CONTEXT, "Vital GLX extensions are missing."); return 0; } /* Load all functions */ _gfx_x11.extensions.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); _gfx_x11.extensions.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT"); _gfx_x11.extensions.EXT_swap_control_tear = _gfx_x11_is_extension_supported(num, "GLX_EXT_swap_control_tear") ? 1 : 0; /* Check non-vital extensions */ if(!_gfx_x11_is_extension_supported(num, "GLX_EXT_swap_control")) _gfx_x11.extensions.SwapIntervalEXT = NULL; return 1; }
void _gfx_renderer_poll_errors(void) { GFX_CONT_INIT(); /* Loop over all errors */ GLenum err = GFX_REND_GET.GetError(); while(err != GL_NO_ERROR) { gfx_errors_push(err, "An OpenGL error occurred."); err = GFX_REND_GET.GetError(); } }
int _gfx_mesh_add_bucket( GFXMesh* mesh, GFXBucket* bucket) { /* See if it already exists */ GFX_Mesh* internal = (GFX_Mesh*)mesh; size_t size = _gfx_mesh_bucket_size(mesh, UINT_MAX); GFX_Bucket* buck = _gfx_mesh_find_bucket(internal, bucket, size); if(buck == internal->buckets.end) { /* Insert bucket */ buck = gfx_vector_insert_range( &internal->buckets, size, NULL, internal->buckets.end ); if(buck == internal->buckets.end) return 0; /* Initialize bucket, reference and source IDs */ memset(buck, 0, size); buck->bucket = bucket; buck->ref = 1; } else { /* Increase reference counter */ if(!(buck->ref + 1)) { /* Overflow error */ gfx_errors_push( GFX_ERROR_OVERFLOW, "Overflow occurred during Mesh bucket referencing." ); return 0; } ++buck->ref; } return 1; }
GFXLodMap* gfx_lod_map_create( GFXLodFlags flags, size_t dataSize, size_t compSize) { /* Allocate new map */ GFX_LodMap* map = malloc(sizeof(GFX_LodMap)); if(map) _gfx_lod_map_init(map, flags, dataSize, compSize); /* Out of memory error */ else gfx_errors_push( GFX_ERROR_OUT_OF_MEMORY, "Lod Map could not be allocated." ); return (GFXLodMap*)map; }
GFXSampler* _gfx_sampler_create( const GFXSampler* values) { GFX_CONT_INIT(NULL); /* Allocate new sampler */ GFX_Sampler* samp = calloc(1, sizeof(GFX_Sampler)); if(!samp) { /* Out of memory error */ gfx_errors_push( GFX_ERROR_OUT_OF_MEMORY, "Sampler could not be allocated." ); return NULL; } if(GFX_REND_GET.intExt[GFX_INT_EXT_SAMPLER_OBJECTS]) { /* Register as object */ samp->id = _gfx_render_object_register( &GFX_CONT_GET.objects, samp, &_gfx_sampler_obj_funcs ); if(!samp->id.id) { free(samp); return NULL; } /* Allocate OGL resources */ GFX_REND_GET.CreateSamplers(1, &samp->handle); } /* Initialize */ samp->references = 1; _gfx_sampler_set((GFXSampler*)samp, values); return (GFXSampler*)samp; }
int _gfx_sampler_reference( GFXSampler* sampler) { GFX_Sampler* internal = (GFX_Sampler*)sampler; if(!(internal->references + 1)) { /* Overflow error */ gfx_errors_push( GFX_ERROR_OVERFLOW, "Overflow occurred during Sampler referencing." ); return 0; } ++internal->references; return 1; }
static int _gfx_x11_error_handler( Display* display, XErrorEvent* evt) { if(_gfx_x11.errors) { char* text = malloc(GFX_X11_ERROR_LENGTH); XGetErrorText(display, evt->error_code, text, GFX_X11_ERROR_LENGTH); /* Make sure it's null terminated */ text[GFX_X11_ERROR_LENGTH - 1] = 0; gfx_errors_push(GFX_ERROR_PLATFORM_ERROR, text); free(text); } return 0; }
unsigned char gfx_thread_pool_expand( GFXThreadPool* pool, unsigned char size, void* arg) { GFX_Pool* internal = (GFX_Pool*)pool; /* Check for overflow */ if(USHRT_MAX - size < pool->size) { gfx_errors_push( GFX_ERROR_OVERFLOW, "Overflow occurred during thread pool expansion." ); return 0; } /* Allocate new node */ if(!size) return 0; GFX_ThreadList* node = (GFX_ThreadList*)gfx_list_create( sizeof(GFX_ThreadList) + sizeof(GFX_PlatformThread) * size ); if(!node) return 0; node->alive = 1; node->pool = internal; node->arg = arg; /* Initialize all threads */ unsigned char s; for(s = 0; s < size; ++s) { if(!_gfx_platform_thread_init( _gfx_thread_list_get(node, s), _gfx_thread_addr, node, 1)) { break; } } node->size = s; pool->size += s; /* Fail if none managed to initialize */ if(!s) { gfx_list_free((GFXList*)node); return 0; } /* Add thread list */ if(internal->threads) gfx_list_splice_before( (GFXList*)node, (GFXList*)internal->threads ); internal->threads = node; return s; }