diff -r e70851cd9e5e -r a3f46bb01be2 holdingarea/libGLESv2/src/GLES2/context.c --- a/holdingarea/libGLESv2/src/GLES2/context.c Thu Sep 16 12:43:44 2010 +0100 +++ b/holdingarea/libGLESv2/src/GLES2/context.c Mon Sep 20 14:29:05 2010 +0100 @@ -1,559 +1,559 @@ -/* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Initial Contributors: - * Nokia Corporation - initial contribution. - * - * Contributors: - * - * Description: - * - */ - -#include "context.h" -#include "util.h" - -DGLContext* DGLContext_create(void* native_context) -{ - DGLContext* ctx = malloc(sizeof(DGLContext)); - if(ctx == NULL) - { - return NULL; - } - - ctx->native_context = native_context; - ctx->initialized = GL_FALSE; - - return ctx; -} - -GLboolean DGLContext_initialize(DGLContext* ctx) -{ - GLint temp; - - DGLES2_ASSERT(ctx != NULL); - DGLES2_ASSERT(!ctx->initialized); - - hglLoad(&ctx->hgl); - - ctx->buffers = NULL; - ctx->shaders = NULL; - ctx->programs = NULL; - ctx->textures = NULL; - ctx->renderbuffers = NULL; - - ctx->hgl.GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &temp); - ctx->max_vertex_attribs = temp; - - ctx->vertex_arrays = malloc(ctx->max_vertex_attribs * sizeof(DGLVertexArray)); - if(ctx->vertex_arrays == NULL) - { - return GL_FALSE; - } - - { - int max_texture_size; - ctx->hgl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - ctx->max_texture_level = dglLog2(max_texture_size); - } - - // Initialize state. - ctx->error = GL_NO_ERROR; - ctx->buffer_binding = 0; - ctx->framebuffer_binding = 0; - ctx->renderbuffer_binding = 0; - - DGLContext_bindTexture(ctx, GL_TEXTURE_2D, 0); - DGLContext_bindTexture(ctx, GL_TEXTURE_CUBE_MAP, 0); - - ctx->attrib_zero[0] = 0; - ctx->attrib_zero[1] = 0; - ctx->attrib_zero[2] = 0; - ctx->attrib_zero[3] = 1; - - // Initialize vertex arrays. - { - unsigned int i; - for(i = 0; i < ctx->max_vertex_attribs; i++) - { - DGLVertexArray* va = &ctx->vertex_arrays[i]; - - va->size = 4; - va->type = GL_FLOAT; - va->normalized = 0; - va->stride = 0; - va->ptr = NULL; - - va->enabled = 0; - va->floatptr = NULL; - va->buffer = NULL; - } - } - - ctx->initialized = GL_TRUE; - - return GL_TRUE; -} - -void DGLContext_destroy(DGLContext *ctx) -{ - DGLES2_ASSERT(ctx != NULL); - - if(ctx->vertex_arrays != NULL) - { - unsigned int i; - for(i = 0; i < ctx->max_vertex_attribs; i++) - { - if(ctx->vertex_arrays[i].floatptr != NULL) - { - free(ctx->vertex_arrays[i].floatptr); - ctx->vertex_arrays[i].floatptr = NULL; - } - } - free(ctx->vertex_arrays); - ctx->vertex_arrays = NULL; - } - - // Destroy buffers - { - DGLBuffer* buffer = ctx->buffers; - DGLBuffer* next; - while(buffer != NULL) - { - next = (DGLBuffer*)buffer->obj.next; - DGLBuffer_destroy(buffer); - buffer = next; - } - ctx->buffers = NULL; - } - - // Destroy shaders - { - DGLShader* shader = ctx->shaders; - DGLShader* next; - while(shader != NULL) - { - next = (DGLShader*)shader->obj.next; - DGLShader_destroy(shader); - shader = next; - } - ctx->shaders = NULL; - } - - // Destroy programs - { - DGLProgram* program = ctx->programs; - DGLProgram* next; - while(program != NULL) - { - next = (DGLProgram*)program->obj.next; - DGLProgram_destroy(program); - program = next; - } - ctx->programs = NULL; - } - - // Destroy textures - { - DGLTexture* texture = ctx->textures; - DGLTexture* next; - while(texture != NULL) - { - next = (DGLTexture*)texture->obj.next; - DGLTexture_destroy(texture); - texture = next; - } - ctx->textures = NULL; - } - - // Destroy renderbuffers - { - DGLRenderbuffer* buffer = ctx->renderbuffers; - DGLRenderbuffer* next; - while(buffer != NULL) - { - next = (DGLRenderbuffer*)buffer->obj.next; - DGLRenderbuffer_destroy(buffer); - buffer = next; - } - ctx->renderbuffers = NULL; - } - - free(ctx); -} - -void DGLContext_loadGL(DGLContext* ctx) -{ - DGLES2_ASSERT(ctx != NULL); - hglLoad(&ctx->hgl); -} - -void DGLContext_setError(DGLContext* ctx, GLenum error) -{ - DGLES2_ASSERT(ctx != NULL); - ctx->error = error; -} - -/* This function should be called before calling state-changing - host GL functions to clear the host GL error flag. After calling - the host GL functions, this function should be called again - to verify the success of the state change. Only then should - the wrapper state be modified to reflect the changes made - in the host state. */ -GLenum DGLContext_getHostError(DGLContext* ctx) -{ - DGLES2_ASSERT(ctx != NULL); - { - GLenum host_error = ctx->hgl.GetError(); - if(host_error != GL_NO_ERROR) - { - DGLContext_setError(ctx, host_error); - } - return host_error; - } -} - -GLboolean DGLContext_createBuffer(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - DGLES2_ASSERT(DGLContext_findBuffer(ctx, name) == NULL); - DGLES2_ASSERT(name != 0); - - { - DGLBuffer* buffer = DGLBuffer_create(name); - if(buffer == NULL) - { - return GL_FALSE; - } - DGLObject_insert((DGLObject**)&ctx->buffers, (DGLObject*)buffer); - } - - return GL_TRUE; -} - -void DGLContext_destroyBuffer(DGLContext *ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name == 0) - { - return; - } - - // Release buffer from the vertex arrays and context. - { - unsigned int i; - for(i = 0; i < ctx->max_vertex_attribs; i++) - { - DGLVertexArray* va = &ctx->vertex_arrays[i]; - if(va->buffer != NULL && va->buffer->obj.name == name) - { - va->buffer = NULL; - } - } - - if(ctx->buffer_binding == name) - { - ctx->buffer_binding = 0; - } - } - - { - DGLBuffer* removed = (DGLBuffer*)DGLObject_remove((DGLObject**)&ctx->buffers, name); - if(removed != NULL) - { - DGLBuffer_destroy(removed); - } - } -} - -DGLBuffer* DGLContext_findBuffer(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - return (DGLBuffer*)DGLObject_find((DGLObject*)ctx->buffers, name); -} - -GLboolean DGLContext_bindBuffer(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name != 0 && DGLContext_findBuffer(ctx, name) == NULL) - { - // A new buffer must be created. - if(!DGLContext_createBuffer(ctx, name)) - { - return GL_FALSE; - } - } - ctx->buffer_binding = name; - - return GL_TRUE; -} - -GLboolean DGLContext_createShader(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - DGLES2_ASSERT(DGLContext_findShader(ctx, name) == NULL); - DGLES2_ASSERT(name != 0); - - { - DGLShader* shader = DGLShader_create(name); - if(shader == NULL) - { - return GL_FALSE; - } - DGLObject_insert((DGLObject**)&ctx->shaders, (DGLObject*)shader); - } - - return GL_TRUE; -} - -void DGLContext_destroyShader(DGLContext *ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name == 0) - { - return; - } - - { - DGLShader* removed = (DGLShader*)DGLObject_remove((DGLObject**)&ctx->shaders, name); - if(removed != NULL) - { - DGLShader_destroy(removed); - } - } -} - -DGLShader* DGLContext_findShader(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - return (DGLShader*)DGLObject_find((DGLObject*)ctx->shaders, name); -} - -GLboolean DGLContext_setShaderSource(DGLContext* ctx, GLuint name, const char* source, int length) -{ - DGLES2_ASSERT(ctx != NULL); - { - DGLShader* shader = DGLContext_findShader(ctx, name); - DGLES2_ASSERT(shader != NULL); - - // Erase the previous source. - if(shader->source != NULL) - { - free(shader->source); - shader->source = NULL; - } - shader->length = 0; - - DGLES2_ASSERT(source != NULL); - DGLES2_ASSERT(length >= 0); - - shader->source = malloc(length + 1); - if(shader->source == NULL) - { - return GL_FALSE; - } - strncpy(shader->source, source, length); - shader->source[length] = 0; - shader->length = length; - - return GL_TRUE; - } -} - -GLboolean DGLContext_createProgram(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - DGLES2_ASSERT(DGLContext_findProgram(ctx, name) == NULL); - DGLES2_ASSERT(name != 0); - - { - DGLProgram* program = DGLProgram_create(name); - if(program == NULL) - { - return GL_FALSE; - } - DGLObject_insert((DGLObject**)&ctx->programs, (DGLObject*)program); - } - - return GL_TRUE; -} - -void DGLContext_destroyProgram(DGLContext *ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name == 0) - { - return; - } - - { - DGLProgram* removed = (DGLProgram*)DGLObject_remove((DGLObject**)&ctx->programs, name); - if(removed != NULL) - { - DGLProgram_destroy(removed); - } - } -} - -DGLProgram* DGLContext_findProgram(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - return (DGLProgram*)DGLObject_find((DGLObject*)ctx->programs, name); -} - -GLboolean DGLContext_createTexture(DGLContext* ctx, GLuint name, DGLTextureType type) -{ - DGLES2_ASSERT(ctx != NULL); - DGLES2_ASSERT(DGLContext_findTexture(ctx, name) == NULL); - - { - DGLTexture* texture = DGLTexture_create(name, type, ctx->max_texture_level + 1); - if(texture == NULL) - { - return GL_FALSE; - } - DGLObject_insert((DGLObject**)&ctx->textures, (DGLObject*)texture); - } - - return GL_TRUE; -} - -void DGLContext_destroyTexture(DGLContext *ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name == 0) - { - // The texture named zero cannot be destroyed. - return; - } - - // Unbind texture. - if(ctx->texture_binding_2d == name) - { - ctx->texture_binding_2d = 0; - } - if(ctx->texture_binding_cube_map == name) - { - ctx->texture_binding_cube_map = 0; - } - - { - DGLTexture* removed = (DGLTexture*)DGLObject_remove((DGLObject**)&ctx->textures, name); - if(removed != NULL) - { - DGLTexture_destroy(removed); - } - } -} - -DGLTexture* DGLContext_findTexture(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - return (DGLTexture*)DGLObject_find((DGLObject*)ctx->textures, name); -} - -GLboolean DGLContext_bindTexture(DGLContext* ctx, GLenum target, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(target == GL_TEXTURE_2D) - { - if(DGLContext_findTexture(ctx, name) == NULL) - { - // A new texture must be created. - if(!DGLContext_createTexture(ctx, name, DGLES2_TEXTURE_2D)) - { - return GL_FALSE; - } - } - ctx->texture_binding_2d = name; - } - else if(target == GL_TEXTURE_CUBE_MAP) - { - if(DGLContext_findTexture(ctx, name) == NULL) - { - // A new texture must be created. - if(!DGLContext_createTexture(ctx, name, DGLES2_TEXTURE_CUBE_MAP)) - { - return GL_FALSE; - } - } - ctx->texture_binding_cube_map = name; - } - else - { - DGLES2_ASSERT(GL_FALSE); - } - - return GL_TRUE; -} - -GLuint DGLContext_getTextureBinding(const DGLContext* ctx, GLenum target) -{ - DGLES2_ASSERT(ctx != NULL); - switch(target) - { - case GL_TEXTURE_2D: - return ctx->texture_binding_2d; - - case GL_TEXTURE_CUBE_MAP: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return ctx->texture_binding_cube_map; - - default: - DGLES2_ASSERT(GL_FALSE); - } - - // No reached. - return 0; -} - -DGLTexture* DGLContext_getTexture(DGLContext* ctx, GLenum target) -{ - DGLES2_ASSERT(ctx != NULL); - { - GLuint binding = DGLContext_getTextureBinding(ctx, target); - return DGLContext_findTexture(ctx, binding); - } -} - -DGLTextureLevel* DGLContext_getTextureLevel(DGLContext* ctx, GLenum target, GLint level) -{ - DGLES2_ASSERT(ctx != NULL); - { - DGLTexture* texture = DGLContext_getTexture(ctx, target); - DGLES2_ASSERT(texture != NULL); - - DGLES2_ASSERT(level < ctx->max_texture_level); - return DGLTexture_getLevel(texture, target, level); - } -} - -GLboolean DGLContext_specifyTextureFromEGLImage(DGLContext* ctx, GLeglImageOES image, GLenum target) -{ - DGLES2_ASSERT(ctx != NULL); - { - DGLTexture* texture; +/* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Initial Contributors: + * Nokia Corporation - initial contribution. + * + * Contributors: + * + * Description: + * + */ + +#include "context.h" +#include "util.h" + +DGLContext* DGLContext_create(void* native_context) +{ + DGLContext* ctx = malloc(sizeof(DGLContext)); + if(ctx == NULL) + { + return NULL; + } + + ctx->native_context = native_context; + ctx->initialized = GL_FALSE; + + return ctx; +} + +GLboolean DGLContext_initialize(DGLContext* ctx) +{ + GLint temp; + + DGLES2_ASSERT(ctx != NULL); + DGLES2_ASSERT(!ctx->initialized); + + hglLoad(&ctx->hgl); + + ctx->buffers = NULL; + ctx->shaders = NULL; + ctx->programs = NULL; + ctx->textures = NULL; + ctx->renderbuffers = NULL; + + ctx->hgl.GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &temp); + ctx->max_vertex_attribs = temp; + + ctx->vertex_arrays = malloc(ctx->max_vertex_attribs * sizeof(DGLVertexArray)); + if(ctx->vertex_arrays == NULL) + { + return GL_FALSE; + } + + { + int max_texture_size; + ctx->hgl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + ctx->max_texture_level = dglLog2(max_texture_size); + } + + // Initialize state. + ctx->error = GL_NO_ERROR; + ctx->buffer_binding = 0; + ctx->framebuffer_binding = 0; + ctx->renderbuffer_binding = 0; + + DGLContext_bindTexture(ctx, GL_TEXTURE_2D, 0); + DGLContext_bindTexture(ctx, GL_TEXTURE_CUBE_MAP, 0); + + ctx->attrib_zero[0] = 0; + ctx->attrib_zero[1] = 0; + ctx->attrib_zero[2] = 0; + ctx->attrib_zero[3] = 1; + + // Initialize vertex arrays. + { + unsigned int i; + for(i = 0; i < ctx->max_vertex_attribs; i++) + { + DGLVertexArray* va = &ctx->vertex_arrays[i]; + + va->size = 4; + va->type = GL_FLOAT; + va->normalized = 0; + va->stride = 0; + va->ptr = NULL; + + va->enabled = 0; + va->floatptr = NULL; + va->buffer = NULL; + } + } + + ctx->initialized = GL_TRUE; + + return GL_TRUE; +} + +void DGLContext_destroy(DGLContext *ctx) +{ + DGLES2_ASSERT(ctx != NULL); + + if(ctx->vertex_arrays != NULL) + { + unsigned int i; + for(i = 0; i < ctx->max_vertex_attribs; i++) + { + if(ctx->vertex_arrays[i].floatptr != NULL) + { + free(ctx->vertex_arrays[i].floatptr); + ctx->vertex_arrays[i].floatptr = NULL; + } + } + free(ctx->vertex_arrays); + ctx->vertex_arrays = NULL; + } + + // Destroy buffers + { + DGLBuffer* buffer = ctx->buffers; + DGLBuffer* next; + while(buffer != NULL) + { + next = (DGLBuffer*)buffer->obj.next; + DGLBuffer_destroy(buffer); + buffer = next; + } + ctx->buffers = NULL; + } + + // Destroy shaders + { + DGLShader* shader = ctx->shaders; + DGLShader* next; + while(shader != NULL) + { + next = (DGLShader*)shader->obj.next; + DGLShader_destroy(shader); + shader = next; + } + ctx->shaders = NULL; + } + + // Destroy programs + { + DGLProgram* program = ctx->programs; + DGLProgram* next; + while(program != NULL) + { + next = (DGLProgram*)program->obj.next; + DGLProgram_destroy(program); + program = next; + } + ctx->programs = NULL; + } + + // Destroy textures + { + DGLTexture* texture = ctx->textures; + DGLTexture* next; + while(texture != NULL) + { + next = (DGLTexture*)texture->obj.next; + DGLTexture_destroy(texture); + texture = next; + } + ctx->textures = NULL; + } + + // Destroy renderbuffers + { + DGLRenderbuffer* buffer = ctx->renderbuffers; + DGLRenderbuffer* next; + while(buffer != NULL) + { + next = (DGLRenderbuffer*)buffer->obj.next; + DGLRenderbuffer_destroy(buffer); + buffer = next; + } + ctx->renderbuffers = NULL; + } + + free(ctx); +} + +void DGLContext_loadGL(DGLContext* ctx) +{ + DGLES2_ASSERT(ctx != NULL); + hglLoad(&ctx->hgl); +} + +void DGLContext_setError(DGLContext* ctx, GLenum error) +{ + DGLES2_ASSERT(ctx != NULL); + ctx->error = error; +} + +/* This function should be called before calling state-changing + host GL functions to clear the host GL error flag. After calling + the host GL functions, this function should be called again + to verify the success of the state change. Only then should + the wrapper state be modified to reflect the changes made + in the host state. */ +GLenum DGLContext_getHostError(DGLContext* ctx) +{ + DGLES2_ASSERT(ctx != NULL); + { + GLenum host_error = ctx->hgl.GetError(); + if(host_error != GL_NO_ERROR) + { + DGLContext_setError(ctx, host_error); + } + return host_error; + } +} + +GLboolean DGLContext_createBuffer(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + DGLES2_ASSERT(DGLContext_findBuffer(ctx, name) == NULL); + DGLES2_ASSERT(name != 0); + + { + DGLBuffer* buffer = DGLBuffer_create(name); + if(buffer == NULL) + { + return GL_FALSE; + } + DGLObject_insert((DGLObject**)&ctx->buffers, (DGLObject*)buffer); + } + + return GL_TRUE; +} + +void DGLContext_destroyBuffer(DGLContext *ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name == 0) + { + return; + } + + // Release buffer from the vertex arrays and context. + { + unsigned int i; + for(i = 0; i < ctx->max_vertex_attribs; i++) + { + DGLVertexArray* va = &ctx->vertex_arrays[i]; + if(va->buffer != NULL && va->buffer->obj.name == name) + { + va->buffer = NULL; + } + } + + if(ctx->buffer_binding == name) + { + ctx->buffer_binding = 0; + } + } + + { + DGLBuffer* removed = (DGLBuffer*)DGLObject_remove((DGLObject**)&ctx->buffers, name); + if(removed != NULL) + { + DGLBuffer_destroy(removed); + } + } +} + +DGLBuffer* DGLContext_findBuffer(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + return (DGLBuffer*)DGLObject_find((DGLObject*)ctx->buffers, name); +} + +GLboolean DGLContext_bindBuffer(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name != 0 && DGLContext_findBuffer(ctx, name) == NULL) + { + // A new buffer must be created. + if(!DGLContext_createBuffer(ctx, name)) + { + return GL_FALSE; + } + } + ctx->buffer_binding = name; + + return GL_TRUE; +} + +GLboolean DGLContext_createShader(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + DGLES2_ASSERT(DGLContext_findShader(ctx, name) == NULL); + DGLES2_ASSERT(name != 0); + + { + DGLShader* shader = DGLShader_create(name); + if(shader == NULL) + { + return GL_FALSE; + } + DGLObject_insert((DGLObject**)&ctx->shaders, (DGLObject*)shader); + } + + return GL_TRUE; +} + +void DGLContext_destroyShader(DGLContext *ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name == 0) + { + return; + } + + { + DGLShader* removed = (DGLShader*)DGLObject_remove((DGLObject**)&ctx->shaders, name); + if(removed != NULL) + { + DGLShader_destroy(removed); + } + } +} + +DGLShader* DGLContext_findShader(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + return (DGLShader*)DGLObject_find((DGLObject*)ctx->shaders, name); +} + +GLboolean DGLContext_setShaderSource(DGLContext* ctx, GLuint name, const char* source, int length) +{ + DGLES2_ASSERT(ctx != NULL); + { + DGLShader* shader = DGLContext_findShader(ctx, name); + DGLES2_ASSERT(shader != NULL); + + // Erase the previous source. + if(shader->source != NULL) + { + free(shader->source); + shader->source = NULL; + } + shader->length = 0; + + DGLES2_ASSERT(source != NULL); + DGLES2_ASSERT(length >= 0); + + shader->source = malloc(length + 1); + if(shader->source == NULL) + { + return GL_FALSE; + } + strncpy(shader->source, source, length); + shader->source[length] = 0; + shader->length = length; + + return GL_TRUE; + } +} + +GLboolean DGLContext_createProgram(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + DGLES2_ASSERT(DGLContext_findProgram(ctx, name) == NULL); + DGLES2_ASSERT(name != 0); + + { + DGLProgram* program = DGLProgram_create(name); + if(program == NULL) + { + return GL_FALSE; + } + DGLObject_insert((DGLObject**)&ctx->programs, (DGLObject*)program); + } + + return GL_TRUE; +} + +void DGLContext_destroyProgram(DGLContext *ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name == 0) + { + return; + } + + { + DGLProgram* removed = (DGLProgram*)DGLObject_remove((DGLObject**)&ctx->programs, name); + if(removed != NULL) + { + DGLProgram_destroy(removed); + } + } +} + +DGLProgram* DGLContext_findProgram(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + return (DGLProgram*)DGLObject_find((DGLObject*)ctx->programs, name); +} + +GLboolean DGLContext_createTexture(DGLContext* ctx, GLuint name, DGLTextureType type) +{ + DGLES2_ASSERT(ctx != NULL); + DGLES2_ASSERT(DGLContext_findTexture(ctx, name) == NULL); + + { + DGLTexture* texture = DGLTexture_create(name, type, ctx->max_texture_level + 1); + if(texture == NULL) + { + return GL_FALSE; + } + DGLObject_insert((DGLObject**)&ctx->textures, (DGLObject*)texture); + } + + return GL_TRUE; +} + +void DGLContext_destroyTexture(DGLContext *ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name == 0) + { + // The texture named zero cannot be destroyed. + return; + } + + // Unbind texture. + if(ctx->texture_binding_2d == name) + { + ctx->texture_binding_2d = 0; + } + if(ctx->texture_binding_cube_map == name) + { + ctx->texture_binding_cube_map = 0; + } + + { + DGLTexture* removed = (DGLTexture*)DGLObject_remove((DGLObject**)&ctx->textures, name); + if(removed != NULL) + { + DGLTexture_destroy(removed); + } + } +} + +DGLTexture* DGLContext_findTexture(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + return (DGLTexture*)DGLObject_find((DGLObject*)ctx->textures, name); +} + +GLboolean DGLContext_bindTexture(DGLContext* ctx, GLenum target, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(target == GL_TEXTURE_2D) + { + if(DGLContext_findTexture(ctx, name) == NULL) + { + // A new texture must be created. + if(!DGLContext_createTexture(ctx, name, DGLES2_TEXTURE_2D)) + { + return GL_FALSE; + } + } + ctx->texture_binding_2d = name; + } + else if(target == GL_TEXTURE_CUBE_MAP) + { + if(DGLContext_findTexture(ctx, name) == NULL) + { + // A new texture must be created. + if(!DGLContext_createTexture(ctx, name, DGLES2_TEXTURE_CUBE_MAP)) + { + return GL_FALSE; + } + } + ctx->texture_binding_cube_map = name; + } + else + { + DGLES2_ASSERT(GL_FALSE); + } + + return GL_TRUE; +} + +GLuint DGLContext_getTextureBinding(const DGLContext* ctx, GLenum target) +{ + DGLES2_ASSERT(ctx != NULL); + switch(target) + { + case GL_TEXTURE_2D: + return ctx->texture_binding_2d; + + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return ctx->texture_binding_cube_map; + + default: + DGLES2_ASSERT(GL_FALSE); + } + + // No reached. + return 0; +} + +DGLTexture* DGLContext_getTexture(DGLContext* ctx, GLenum target) +{ + DGLES2_ASSERT(ctx != NULL); + { + GLuint binding = DGLContext_getTextureBinding(ctx, target); + return DGLContext_findTexture(ctx, binding); + } +} + +DGLTextureLevel* DGLContext_getTextureLevel(DGLContext* ctx, GLenum target, GLint level) +{ + DGLES2_ASSERT(ctx != NULL); + { + DGLTexture* texture = DGLContext_getTexture(ctx, target); + DGLES2_ASSERT(texture != NULL); + + DGLES2_ASSERT(level < ctx->max_texture_level); + return DGLTexture_getLevel(texture, target, level); + } +} + +GLboolean DGLContext_specifyTextureFromEGLImage(DGLContext* ctx, GLeglImageOES image, GLenum target) +{ + DGLES2_ASSERT(ctx != NULL); + { + DGLTexture* texture; GLenum internal_format; GLsizei width, height; GLsizei stride; @@ -564,7 +564,7 @@ DGLContext_getHostError(ctx); - texture = DGLContext_getTexture(ctx, target); + texture = DGLContext_getTexture(ctx, target); DGLES2_ASSERT(texture != NULL); deglGetImageInfo(image, &internal_format, &width, &height, &stride, &data_format, &data_type); @@ -579,100 +579,100 @@ DGLTexture_setEGLImage(texture, target, image); deglRegisterImageTarget(image, target, texture->obj.name); return GL_TRUE; - } - else - { - return GL_FALSE; - } - } -} - -GLboolean DGLContext_createRenderbuffer(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - DGLES2_ASSERT(DGLContext_findRenderbuffer(ctx, name) == NULL); - DGLES2_ASSERT(name != 0); - - { - DGLRenderbuffer* buffer = DGLRenderbuffer_create(name); - if(buffer == NULL) - { - return GL_FALSE; - } - DGLObject_insert((DGLObject**)&ctx->renderbuffers, (DGLObject*)buffer); - } - - return GL_TRUE; -} - -void DGLContext_destroyRenderbuffer(DGLContext *ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name == 0) - { - return; - } - - { - DGLRenderbuffer* removed = (DGLRenderbuffer*)DGLObject_remove((DGLObject**)&ctx->renderbuffers, name); - if(removed != NULL) - { - DGLRenderbuffer_destroy(removed); - } - } -} - -DGLRenderbuffer* DGLContext_getColorRenderbuffer(DGLContext* ctx) -{ - DGLES2_ASSERT(ctx != NULL); - - if(ctx->framebuffer_binding == 0) - { - return NULL; - } - - { - GLint type; - GLint name; - DGLRenderbuffer* buffer; - - ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); - - if(type != GL_RENDERBUFFER) - { - return NULL; - } - - ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name); - buffer = DGLContext_findRenderbuffer(ctx, name); - DGLES2_ASSERT(buffer != NULL); - return buffer; - } -} - -DGLRenderbuffer* DGLContext_findRenderbuffer(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - return (DGLRenderbuffer*)DGLObject_find((DGLObject*)ctx->renderbuffers, name); -} - -GLboolean DGLContext_bindRenderbuffer(DGLContext* ctx, GLuint name) -{ - DGLES2_ASSERT(ctx != NULL); - if(name != 0 && DGLContext_findRenderbuffer(ctx, name) == NULL) - { - // A new renderbuffer must be created. - if(!DGLContext_createRenderbuffer(ctx, name)) - { - return GL_FALSE; - } - } - ctx->renderbuffer_binding = name; - - return GL_TRUE; -} - -GLboolean DGLContext_specifyRenderbufferFromEGLImage(DGLContext* ctx, GLeglImageOES image) + } + else + { + return GL_FALSE; + } + } +} + +GLboolean DGLContext_createRenderbuffer(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + DGLES2_ASSERT(DGLContext_findRenderbuffer(ctx, name) == NULL); + DGLES2_ASSERT(name != 0); + + { + DGLRenderbuffer* buffer = DGLRenderbuffer_create(name); + if(buffer == NULL) + { + return GL_FALSE; + } + DGLObject_insert((DGLObject**)&ctx->renderbuffers, (DGLObject*)buffer); + } + + return GL_TRUE; +} + +void DGLContext_destroyRenderbuffer(DGLContext *ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name == 0) + { + return; + } + + { + DGLRenderbuffer* removed = (DGLRenderbuffer*)DGLObject_remove((DGLObject**)&ctx->renderbuffers, name); + if(removed != NULL) + { + DGLRenderbuffer_destroy(removed); + } + } +} + +DGLRenderbuffer* DGLContext_getColorRenderbuffer(DGLContext* ctx) +{ + DGLES2_ASSERT(ctx != NULL); + + if(ctx->framebuffer_binding == 0) + { + return NULL; + } + + { + GLint type; + GLint name; + DGLRenderbuffer* buffer; + + ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); + + if(type != GL_RENDERBUFFER) + { + return NULL; + } + + ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name); + buffer = DGLContext_findRenderbuffer(ctx, name); + DGLES2_ASSERT(buffer != NULL); + return buffer; + } +} + +DGLRenderbuffer* DGLContext_findRenderbuffer(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + return (DGLRenderbuffer*)DGLObject_find((DGLObject*)ctx->renderbuffers, name); +} + +GLboolean DGLContext_bindRenderbuffer(DGLContext* ctx, GLuint name) +{ + DGLES2_ASSERT(ctx != NULL); + if(name != 0 && DGLContext_findRenderbuffer(ctx, name) == NULL) + { + // A new renderbuffer must be created. + if(!DGLContext_createRenderbuffer(ctx, name)) + { + return GL_FALSE; + } + } + ctx->renderbuffer_binding = name; + + return GL_TRUE; +} + +GLboolean DGLContext_specifyRenderbufferFromEGLImage(DGLContext* ctx, GLeglImageOES image) { GLenum imageFormat; GLenum storageFormat; @@ -762,17 +762,17 @@ DGLES2_ASSERT(ctx != NULL); if(ctx->framebuffer_binding != 0) - { - GLenum type; - GLuint name; - - ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - - if(type == GL_RENDERBUFFER) - { - DGLRenderbuffer* buffer; - ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - buffer = DGLContext_findRenderbuffer(ctx, name); + { + GLenum type; + GLuint name; + + ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(type == GL_RENDERBUFFER) + { + DGLRenderbuffer* buffer; + ctx->hgl.GetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); + buffer = DGLContext_findRenderbuffer(ctx, name); if(buffer != NULL && buffer->egl_image != NULL) { deglUpdateImageSiblings(buffer->egl_image, GL_RENDERBUFFER, buffer->obj.name);