static void GLES2_DestroyRenderer(SDL_Renderer *renderer) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_ProgramCacheEntry *entry; GLES2_ProgramCacheEntry *next; /* Deallocate everything */ if (rdata) { GLES2_ActivateRenderer(renderer); entry = rdata->program_cache.head; while (entry) { glDeleteShader(entry->vertex_shader->id); glDeleteShader(entry->fragment_shader->id); SDL_free(entry->vertex_shader); SDL_free(entry->fragment_shader); glDeleteProgram(entry->id); next = entry->next; SDL_free(entry); entry = next; } if (rdata->context) { SDL_GL_DeleteContext(rdata->context); } if (rdata->shader_formats) { SDL_free(rdata->shader_formats); } SDL_free(rdata); } SDL_free(renderer); }
static void GLES2_DestroyRenderer(SDL_Renderer *renderer) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; /* Deallocate everything */ if (rdata) { GLES2_ActivateRenderer(renderer); { GLES2_ShaderCacheEntry *entry; GLES2_ShaderCacheEntry *next; entry = rdata->shader_cache.head; while (entry) { rdata->glDeleteShader(entry->id); next = entry->next; SDL_free(entry); entry = next; } } { GLES2_ProgramCacheEntry *entry; GLES2_ProgramCacheEntry *next; entry = rdata->program_cache.head; while (entry) { rdata->glDeleteProgram(entry->id); next = entry->next; SDL_free(entry); entry = next; } } if (rdata->context) { while (rdata->framebuffers) { GLES2_FBOList *nextnode = rdata->framebuffers->next; rdata->glDeleteFramebuffers(1, &rdata->framebuffers->FBO); SDL_free(rdata->framebuffers); rdata->framebuffers = nextnode; } SDL_GL_DeleteContext(rdata->context); } if (rdata->shader_formats) { SDL_free(rdata->shader_formats); } SDL_free(rdata); } SDL_free(renderer); }
static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; GLES2_ActivateRenderer(renderer); /* Destroy the texture */ if (tdata) { glDeleteTextures(1, &tdata->texture); SDL_free(tdata->pixel_data); SDL_free(tdata); texture->driverdata = NULL; } }
static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch) { GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; Uint8 *blob = NULL; Uint8 *src; int srcPitch; int y; GLES2_ActivateRenderer(renderer); /* Bail out if we're supposed to update an empty rectangle */ if (rect->w <= 0 || rect->h <= 0) return 0; /* Reformat the texture data into a tightly packed array */ srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format); src = (Uint8 *)pixels; if (pitch != srcPitch) { blob = (Uint8 *)SDL_malloc(srcPitch * rect->h); if (!blob) { SDL_OutOfMemory(); return -1; } src = blob; for (y = 0; y < rect->h; ++y) { SDL_memcpy(src, pixels, srcPitch); src += srcPitch; pixels = (Uint8 *)pixels + pitch; } src = blob; } /* Create a texture subimage with the supplied data */ glGetError(); glActiveTexture(GL_TEXTURE0); glBindTexture(tdata->texture_type, tdata->texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D(tdata->texture_type, 0, rect->x, rect->y, rect->w, rect->h, tdata->pixel_format, tdata->pixel_type, src); if (blob) { SDL_free(blob); } if (glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to update texture"); return -1; } return 0; }
static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_TextureData *tdata; GLenum format; GLenum type; GLenum scaleMode; GLES2_ActivateRenderer(renderer); /* Determine the corresponding GLES texture format params */ switch (texture->format) { case SDL_PIXELFORMAT_ABGR8888: format = GL_RGBA; type = GL_UNSIGNED_BYTE; break; default: SDL_SetError("Texture format not supported"); return -1; } /* Allocate a texture struct */ tdata = (GLES2_TextureData *)SDL_calloc(1, sizeof(GLES2_TextureData)); if (!tdata) { SDL_OutOfMemory(); return -1; } tdata->texture = 0; tdata->texture_type = GL_TEXTURE_2D; tdata->pixel_format = format; tdata->pixel_type = type; scaleMode = GetScaleQuality(); /* Allocate a blob for image data */ if (texture->access == SDL_TEXTUREACCESS_STREAMING) { tdata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); tdata->pixel_data = SDL_calloc(1, tdata->pitch * texture->h); if (!tdata->pixel_data) { SDL_OutOfMemory(); SDL_free(tdata); return -1; } } /* Allocate the texture */ glGetError(); glGenTextures(1, &tdata->texture); glActiveTexture(GL_TEXTURE0); glBindTexture(tdata->texture_type, tdata->texture); glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); if (glGetError() != GL_NO_ERROR) { SDL_SetError("Texture creation failed"); glDeleteTextures(1, &tdata->texture); SDL_free(tdata); return -1; } texture->driverdata = tdata; return 0; }