diff options
author | Josep Torra <n770galaxy@gmail.com> | 2014-03-26 16:46:55 +0100 |
---|---|---|
committer | Josep Torra <n770galaxy@gmail.com> | 2014-03-26 16:51:45 +0100 |
commit | c5339b1dd002a95320f41855d652195bd48aee02 (patch) | |
tree | ba1164f8daa3b5350d31742ecc3ae4a4c65d7d0a | |
parent | 11a0fccf59774c6d927b6b299e87fee99cbdabac (diff) |
Add egl mini library
Provides EGLDisplay, EGLMemory and EGLMemoryPool refcounted objects.
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | egl.c | 576 | ||||
-rw-r--r-- | egl.h | 81 | ||||
-rw-r--r-- | triangle.c | 44 |
4 files changed, 687 insertions, 20 deletions
@@ -1,4 +1,4 @@ -OBJS=triangle.o video.o ilclient.o ilcore.o +OBJS=triangle.o video.o ilclient.o ilcore.o egl.o BIN=rpi_test_egl CFLAGS+=-O0 -g3 @@ -8,8 +8,8 @@ LDFLAGS+=-L$(SDKSTAGE)/opt/vc/lib/ -lGLESv2 -lEGL -lopenmaxil -lbcm_host -lvcos INCLUDES+=-I$(SDKSTAGE)/opt/vc/include/ -I$(SDKSTAGE)/opt/vc/include/interface/vcos/pthreads -I$(SDKSTAGE)/opt/vc/include/interface/vmcs_host/linux -I./ -CFLAGS += $(shell pkg-config --cflags glib-2.0) -LDFLAGS += $(shell pkg-config --libs glib-2.0) +CFLAGS += $(shell pkg-config --cflags glib-2.0 gobject-2.0) +LDFLAGS += $(shell pkg-config --libs glib-2.0 gobject-2.0) all: $(BIN) $(LIB) @@ -0,0 +1,576 @@ +/* + * Derived from GStreamer 0.10 EGL Library in gst-omx + * Copyright (C) 2014 Fluendo S.A. + * @author: Josep Torra <josep@fluendo.com> + * * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#define EGL_EGLEXT_PROTOTYPES +#include "egl.h" + +#define DEBUG_MAGIC_CHECK 0 + +#if DEBUG_MAGIC_CHECK +#define EGLMEMORY_MAGIC 0x5fce5fce +#define EGLMEMORY_POOL_MAGIC 0x5fce9001 + +#define EGLMEMORY_POOL_MAGIC_ASSERT(pool) G_STMT_START { \ + g_assert (pool->magic == EGLMEMORY_POOL_MAGIC); \ +} G_STMT_END +#define EGLMEMORY_MAGIC_ASSERT(mem) G_STMT_START { \ + g_assert (mem->magic == EGLMEMORY_MAGIC); \ +} G_STMT_END +#else +#define EGLMEMORY_POOL_MAGIC_ASSERT(pool) G_STMT_START{ }G_STMT_END +#define EGLMEMORY_MAGIC_ASSERT(mem) G_STMT_START{ }G_STMT_END +#endif + +struct _EGLImageMemory +{ + volatile gint refcount; + +#if DEBUG_MAGIC_CHECK + guint32 magic; +#endif + + EGLClientBuffer client_buffer; + EGLImageKHR image; + + gpointer user_data; + GDestroyNotify destroy_data; + + EGLImageMemoryPool *pool; +}; + +#define EGL_IMAGE_MEMORY(mem) ((EGLImageMemory *)(mem)) + +struct _EGLImageMemoryPool +{ + volatile gint refcount; + +#if DEBUG_MAGIC_CHECK + guint32 magic; +#endif + + GMutex *lock; + GCond *cond; + + EGLDisplayWrapper *display; + EGLImageMemory *memory; + + gint size; + volatile gint unused; + volatile gint active; + + gpointer user_data; + DestroyNotifyEGLImageMemoryPool destroy_data; +}; + +#define EGL_IMAGE_MEMORY_POOL_LOCK(pool) G_STMT_START { \ + g_mutex_lock (pool->lock); \ +} G_STMT_END + +#define EGL_IMAGE_MEMORY_POOL_UNLOCK(pool) G_STMT_START { \ + g_mutex_unlock (pool->lock); \ +} G_STMT_END + +#define EGL_IMAGE_MEMORY_POOL_WAIT_RELEASED(pool) G_STMT_START { \ + g_cond_wait (pool->cond, pool->lock); \ +} G_STMT_END + +#define EGL_IMAGE_MEMORY_POOL_SIGNAL_UNUSED(pool) G_STMT_START { \ + g_cond_signal (pool->cond); \ +} G_STMT_END + +#define EGL_IMAGE_MEMORY_POOL_IS_FULL(pool) (g_atomic_int_get (&pool->unused) == 0) +#define EGL_IMAGE_MEMORY_POOL_IS_EMPTY(pool) (g_atomic_int_get (&pool->unused) == pool->size) + +#define EGL_IMAGE_MEMORY_POOL_SET_ACTIVE(pool,active) \ + g_atomic_int_set (&pool->active, active) +#define EGL_IMAGE_MEMORY_POOL_IS_ACTIVE(pool) (g_atomic_int_get (&pool->active) == TRUE) + +struct _EGLDisplayWrapper +{ + volatile gint refcount; + + EGLDisplay display; + + gpointer user_data; + GDestroyNotify destroy_data; +}; + +/** + * egl_image_memory_ref + * @mem: a #EGLImageMemory + * + * Increase the refcount of @mem. + * + */ +EGLImageMemory * +egl_image_memory_ref (EGLImageMemory * mem) +{ + g_return_val_if_fail (mem != NULL, NULL); + + EGLMEMORY_MAGIC_ASSERT (mem); + + g_atomic_int_inc (&mem->refcount); + + return mem; +} + +static void +egl_image_memory_free (EGLImageMemory * mem) +{ + EGLImageMemoryPool *pool = mem->pool; + + /* We grab the pool lock as we will make changes to number of unused + * memories. */ + EGL_IMAGE_MEMORY_POOL_LOCK (pool); + + /* We have one more unused memory */ + g_atomic_int_inc (&pool->unused); + + /* Wake up potential waiters */ + EGL_IMAGE_MEMORY_POOL_SIGNAL_UNUSED (pool); + + EGL_IMAGE_MEMORY_POOL_UNLOCK (pool); + + if (mem->destroy_data) { + mem->destroy_data (mem->user_data); + } + + /* Remove our ref to the pool. That could destroy the pool so it is + * important to do that when we released the lock */ + mem->pool = egl_image_memory_pool_unref (pool); +} + +/** + * egl_image_memory_unref: + * @mem: a #EGLImageMemory + * + * Unref @mem and when the refcount reaches 0 frees the resources + * and return NULL. + * + */ +EGLImageMemory * +egl_image_memory_unref (EGLImageMemory * mem) +{ + g_return_val_if_fail (mem != NULL, NULL); + + EGLMEMORY_MAGIC_ASSERT (mem); + + if (g_atomic_int_dec_and_test (&mem->refcount)) { + egl_image_memory_free (mem); + mem = NULL; + } + + return mem; +} + +/** + * egl_image_memory_get_image: + * @mem: a #EGLImageMemory + * + * Gives the #EGLImageKHR used by the #EGLImageMemory. + * + */ +EGLImageKHR +egl_image_memory_get_image (EGLImageMemory * mem) +{ + return mem->image; +} + +/** + * egl_image_memory_pool_new: + * @size: a number of memories managed by the pool + * @display: a #EGLDisplayWrapper display + * @user_data: user data passed to the callback + * @destroy_data: #DestroyNotifyEGLImageMemoryPool for user_data + * + * Create a new EGLImageMemoryPool instance with the provided images. + * + * Returns: a new #EGLImageMemoryPool + * + */ +EGLImageMemoryPool * +egl_image_memory_pool_new (gint size, EGLDisplayWrapper * display, + gpointer user_data, DestroyNotifyEGLImageMemoryPool destroy_data) +{ + EGLImageMemoryPool *pool; + + pool = g_new0 (EGLImageMemoryPool, 1); + + pool->refcount = 1; + pool->lock = g_mutex_new (); + pool->cond = g_cond_new (); + pool->display = egl_display_ref (display); + pool->memory = (EGLImageMemory *) g_new0 (EGLImageMemory, size); + pool->size = pool->unused = size; + pool->user_data = user_data; + pool->destroy_data = destroy_data; + +#if DEBUG_MAGIC_CHECK + { + gint i; + pool->magic = EGLMEMORY_POOL_MAGIC; + for (i = 0; i < size; i++) { + EGLImageMemory *mem = &pool->memory[i]; + mem->magic = EGLMEMORY_MAGIC; + } + } +#endif + + return pool; +} + +/** + * egl_image_memory_pool_ref: + * @pool: a #EGLImageMemoryPool + * + * Increase the refcount of @pool. + * + */ +EGLImageMemoryPool * +egl_image_memory_pool_ref (EGLImageMemoryPool * pool) +{ + g_return_val_if_fail (pool != NULL, NULL); + + EGLMEMORY_POOL_MAGIC_ASSERT (pool); + + g_atomic_int_inc (&pool->refcount); + + return pool; +} + +static void +egl_image_memory_pool_free (EGLImageMemoryPool * pool) +{ + if (g_atomic_int_get (&pool->unused) != pool->size) { + g_critical ("refcounting problem detected, some memory is still in use"); + } + + if (pool->destroy_data) { + pool->destroy_data (pool, pool->user_data); + } + + egl_display_unref (pool->display); + g_mutex_free (pool->lock); + g_cond_free (pool->cond); + + g_free (pool->memory); + g_free (pool); +} + +/** + * egl_image_memory_pool_unref: + * @pool: a #EGLImageMemoryPool + * + * Unref @pool and when the refcount reaches 0 frees the resources + * and return NULL. + * + */ +EGLImageMemoryPool * +egl_image_memory_pool_unref (EGLImageMemoryPool * pool) +{ + g_return_val_if_fail (pool != NULL, NULL); + + EGLMEMORY_POOL_MAGIC_ASSERT (pool); + + if (g_atomic_int_dec_and_test (&pool->refcount)) { + egl_image_memory_pool_free (pool); + pool = NULL; + } + return pool; +} + +/** + * egl_image_memory_pool_get_size: + * @pool: a #EGLImageMemoryPool + * + * Gives the number of memories that are managed by the pool. + * + */ +gint +egl_image_memory_pool_get_size (EGLImageMemoryPool * pool) +{ + g_return_val_if_fail (pool != NULL, 0); + + return pool->size; +} + +/** + * egl_image_memory_pool_set_resources: + * @pool: a #EGLImageMemoryPool + * @idx: memory index + * @client_buffer: an #EGLClientBuffer to store in the pool + * @image: an #EGLImageKHR to store in the pool. + * + * Stores @client_buffer and @image at @idx memory slot. + * + */ +gboolean +egl_image_memory_pool_set_resources (EGLImageMemoryPool * pool, gint idx, + EGLClientBuffer client_buffer, EGLImageKHR image) +{ + EGLImageMemory *mem; + + g_return_val_if_fail (pool != NULL, FALSE); + g_return_val_if_fail (idx >= 0 && idx < pool->size, FALSE); + + mem = &pool->memory[idx]; + mem->client_buffer = client_buffer; + mem->image = image; + + return TRUE; +} + +/** + * egl_image_memory_pool_get_resources: + * @pool: a #EGLImageMemoryPool + * @idx: memory index + * @client_buffer: (out) (allow-none): the #EGLClientBuffer at @idx + * @image: (out) (allow-none): the #EGLImageKHR at @idx + * + * Retrieves @client_buffer and @image at @idx memory slot. + * + */ +gboolean +egl_image_memory_pool_get_resources (EGLImageMemoryPool * pool, gint idx, + EGLClientBuffer * client_buffer, EGLImageKHR * image) +{ + EGLImageMemory *mem; + + g_return_val_if_fail (pool != NULL, FALSE); + g_return_val_if_fail (idx >= 0 && idx < pool->size, FALSE); + + mem = &pool->memory[idx]; + + if (client_buffer) + *client_buffer = mem->client_buffer; + + if (image) + *image = mem->image; + + return TRUE; +} + +/** + * egl_image_memory_pool_get_display: + * @pool: a #EGLImageMemoryPool + * + * Provides a reference to the #EGLDisplayWrapper used by the pool + */ +EGLDisplayWrapper * +egl_image_memory_pool_get_display (EGLImageMemoryPool * pool) +{ + g_return_val_if_fail (pool != NULL, NULL); + + EGLMEMORY_POOL_MAGIC_ASSERT (pool); + + g_return_val_if_fail (pool->display != NULL, NULL); + + return egl_display_ref (pool->display); +} + +/** + * egl_image_memory_pool_get_images: + * @pool: a #EGLImageMemoryPool + * + * Provides a #GList of EGL images + */ +GList * +egl_image_memory_pool_get_images (EGLImageMemoryPool * pool) +{ + gint i; + GList *images = NULL; + + g_return_val_if_fail (pool != NULL, NULL); + + for (i = 0; i < pool->size; i++) { + EGLImageMemory *mem = &pool->memory[i]; + images = g_list_append (images, mem->image); + } + + return images; +} + +/** + * egl_image_memory_pool_set_active: + * @pool: a #EGLImageMemoryPool + * @active: a #gboolean that indicates the pool is active + * + * Change @pool active state and unblocks any wait condition if needed. + * + */ +void +egl_image_memory_pool_set_active (EGLImageMemoryPool * pool, + gboolean active) +{ + g_return_if_fail (pool != NULL); + + EGLMEMORY_POOL_MAGIC_ASSERT (pool); + + EGL_IMAGE_MEMORY_POOL_SET_ACTIVE (pool, active); + + if (!active) { + EGL_IMAGE_MEMORY_POOL_SIGNAL_UNUSED (pool); + } +} + +/** + * egl_image_memory_pool_wait_released: + * @pool: a #EGLImageMemoryPool + * + * Waits until none of the memory is in use. + * + */ +void +egl_image_memory_pool_wait_released (EGLImageMemoryPool * pool) +{ + g_return_if_fail (pool != NULL); + + EGLMEMORY_POOL_MAGIC_ASSERT (pool); + + EGL_IMAGE_MEMORY_POOL_LOCK (pool); + while (!EGL_IMAGE_MEMORY_POOL_IS_EMPTY (pool)) { + EGL_IMAGE_MEMORY_POOL_WAIT_RELEASED (pool); + } + EGL_IMAGE_MEMORY_POOL_UNLOCK (pool); +} + +/** + * egl_image_memory_pool_acquire_memory: + * @pool: a #EGLImageMemoryPool + * @idx: ordinal that specifies a #EGLImageMemory in the pool + * @user_data: user data passed to the callback + * @destroy_data: #GDestroyNotify for user_data + * + * Provides an specified #EGLImageMemory. + * + */ +EGLImageMemory * +egl_image_memory_pool_acquire_memory (EGLImageMemoryPool * pool, + gint idx, gpointer user_data, GDestroyNotify destroy_data) +{ + EGLImageMemory *mem; + + g_return_val_if_fail (pool != NULL, NULL); + g_return_val_if_fail (idx >= 0 && idx < pool->size, NULL); + + EGL_IMAGE_MEMORY_POOL_LOCK (pool); + if (!EGL_IMAGE_MEMORY_POOL_IS_ACTIVE (pool)) { + EGL_IMAGE_MEMORY_POOL_UNLOCK (pool); + return NULL; + } + + mem = &pool->memory[idx]; + + g_atomic_int_add (&pool->unused, -1); + g_atomic_int_set (&mem->refcount, 1); + mem->pool = egl_image_memory_pool_ref (pool); + mem->user_data = user_data; + mem->destroy_data = destroy_data; + + EGL_IMAGE_MEMORY_POOL_UNLOCK (pool); + + return mem; +} + +G_DEFINE_BOXED_TYPE (EGLImageMemoryPool, egl_image_memory_pool, + (GBoxedCopyFunc) egl_image_memory_pool_ref, + (GBoxedFreeFunc) egl_image_memory_pool_unref); + +/** + * egl_display_new: + * @display: a #EGLDisplayWrapper display + * @user_data: user data passed to the callback + * @destroy_data: #GDestroyNotify for user_data + * + * Create a new #EGLDisplayWrapper that wraps and refcount @display. + * + * Returns: a new #EGLDisplayWrapper + * + */ +EGLDisplayWrapper * +egl_display_new (EGLDisplay display, gpointer user_data, + GDestroyNotify destroy_data) +{ + EGLDisplayWrapper *gdisplay; + + gdisplay = g_slice_new (EGLDisplayWrapper); + gdisplay->refcount = 1; + gdisplay->display = display; + gdisplay->user_data = user_data; + gdisplay->destroy_data = destroy_data; + + return gdisplay; +} + +/** + * egl_display_ref + * @display: a #EGLDisplayWrapper + * + * Increase the refcount of @display. + * + */ +EGLDisplayWrapper * +egl_display_ref (EGLDisplayWrapper * display) +{ + g_return_val_if_fail (display != NULL, NULL); + + g_atomic_int_inc (&display->refcount); + + return display; +} + +/** + * egl_display_unref: + * @display: a #EGLDisplayWrapper + * + * Decrease the refcount of @display and calls provided destroy function on + * last reference. + * + */ +void +egl_display_unref (EGLDisplayWrapper * display) +{ + g_return_if_fail (display != NULL); + + if (g_atomic_int_dec_and_test (&display->refcount)) { + if (display->destroy_data) { + display->destroy_data (display->user_data); + } + g_slice_free (EGLDisplayWrapper, display); + } +} + +/** + * egl_display_get + * @display: a #EGLDisplayWrapper + * + * Gives the #EGLDisplay wrapped. + * + */ +EGLDisplay +egl_display_get (EGLDisplayWrapper * display) +{ + g_return_val_if_fail (display != NULL, EGL_NO_DISPLAY); + + return display->display; +} + @@ -0,0 +1,81 @@ +/* + * Derived from GStreamer 0.10 EGL Library in gst-omx + * Copyright (C) 2014 Fluendo S.A. + * @author: Josep Torra <josep@fluendo.com> + * * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __MY_EGL_H__ +#define __MY_EGL_H__ + +#include <glib.h> +#include <glib-object.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +G_BEGIN_DECLS + +typedef struct _EGLImageMemory EGLImageMemory; +typedef struct _EGLImageMemoryPool EGLImageMemoryPool; +typedef struct _EGLDisplayWrapper EGLDisplayWrapper; +typedef void (*DestroyNotifyEGLImageMemoryPool) (EGLImageMemoryPool * + pool, gpointer user_data); + +/* EGLImageMemory handling */ +EGLImageMemory *egl_image_memory_ref (EGLImageMemory * mem); +EGLImageMemory *egl_image_memory_unref (EGLImageMemory * mem); +EGLImageKHR egl_image_memory_get_image (EGLImageMemory * mem); + +/* EGLImageMemoryPool handling */ +#define TYPE_EGL_IMAGE_MEMORY_POOL (egl_image_memory_pool_get_type()) +GType egl_image_memory_pool_get_type (void); + +EGLImageMemoryPool *egl_image_memory_pool_new (gint size, + EGLDisplayWrapper * display, gpointer user_data, + DestroyNotifyEGLImageMemoryPool destroy_data); +EGLImageMemoryPool *egl_image_memory_pool_ref (EGLImageMemoryPool * + pool); +EGLImageMemoryPool *egl_image_memory_pool_unref (EGLImageMemoryPool * + pool); +gint egl_image_memory_pool_get_size (EGLImageMemoryPool * pool); + +gboolean egl_image_memory_pool_set_resources (EGLImageMemoryPool * pool, + gint idx, EGLClientBuffer client_buffer, EGLImageKHR image); + +gboolean egl_image_memory_pool_get_resources (EGLImageMemoryPool * pool, + gint idx, EGLClientBuffer * client_buffer, EGLImageKHR * image); + +EGLDisplayWrapper *egl_image_memory_pool_get_display (EGLImageMemoryPool * + pool); +GList *egl_image_memory_pool_get_images (EGLImageMemoryPool * pool); +void egl_image_memory_pool_set_active (EGLImageMemoryPool * pool, + gboolean active); +void egl_image_memory_pool_wait_released (EGLImageMemoryPool * pool); +EGLImageMemory *egl_image_memory_pool_acquire_memory (EGLImageMemoryPool * + pool, gint idx, gpointer user_data, GDestroyNotify destroy_data); + +/* EGLDisplay wrapper with refcount, connection is closed after last ref is gone */ +EGLDisplayWrapper * egl_display_new (EGLDisplay display, gpointer user_data, + GDestroyNotify destroy_data); +EGLDisplayWrapper *egl_display_ref (EGLDisplayWrapper * display); +void egl_display_unref (EGLDisplayWrapper * display); +EGLDisplay egl_display_get (EGLDisplayWrapper * display); + +G_END_DECLS + +#endif /* __MY_EGL_H__ */ @@ -50,6 +50,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cube_texture_and_coords.h" #include "triangle.h" +#include "egl.h" #define PATH "./" @@ -71,18 +72,21 @@ typedef struct gboolean animate; /* OpenGL|ES objects */ - EGLDisplay display; + EGLDisplayWrapper *display; EGLSurface surface; EGLContext context; GLuint tex; + /* model rotation vector and direction */ GLfloat rot_angle_x_inc; GLfloat rot_angle_y_inc; GLfloat rot_angle_z_inc; + /* current model rotation angles */ GLfloat rot_angle_x; GLfloat rot_angle_y; GLfloat rot_angle_z; + /* current distance from camera */ GLfloat distance; GLfloat distance_inc; @@ -123,6 +127,7 @@ init_ogl (AppState * state) int32_t success = 0; EGLBoolean result; EGLint num_config; + EGLDisplay display; static EGL_DISPMANX_WINDOW_T nativewindow; @@ -145,24 +150,26 @@ init_ogl (AppState * state) EGLConfig config; /* get an EGL display connection */ - state->display = eglGetDisplay (EGL_DEFAULT_DISPLAY); - assert (state->display != EGL_NO_DISPLAY); + display = eglGetDisplay (EGL_DEFAULT_DISPLAY); + assert (display != EGL_NO_DISPLAY); + state->display = egl_display_new (display, display, + (GDestroyNotify) eglTerminate); /* initialize the EGL display connection */ - result = eglInitialize (state->display, NULL, NULL); + result = eglInitialize (display, NULL, NULL); assert (EGL_FALSE != result); /* get an appropriate EGL frame buffer configuration * this uses a BRCM extension that gets the closest match, rather * than standard which returns anything that matches. */ result = - eglSaneChooseConfigBRCM (state->display, attribute_list, &config, 1, + eglSaneChooseConfigBRCM (display, attribute_list, &config, 1, &num_config); assert (EGL_FALSE != result); /* create an EGL rendering context */ state->context = - eglCreateContext (state->display, config, EGL_NO_CONTEXT, NULL); + eglCreateContext (display, config, EGL_NO_CONTEXT, NULL); assert (state->context != EGL_NO_CONTEXT); /* Open display */ @@ -200,12 +207,12 @@ init_ogl (AppState * state) vc_dispmanx_update_submit_sync (dispman_update); state->surface = - eglCreateWindowSurface (state->display, config, &nativewindow, NULL); + eglCreateWindowSurface (display, config, &nativewindow, NULL); assert (state->surface != EGL_NO_SURFACE); /* connect the context to the surface */ result = - eglMakeCurrent (state->display, state->surface, state->surface, + eglMakeCurrent (display, state->surface, state->surface, state->context); assert (EGL_FALSE != result); @@ -388,6 +395,7 @@ inc_and_clip_distance (GLfloat distance, GLfloat distance_inc) static void redraw_scene (AppState * state) { + EGLDisplay display = egl_display_get (state->display); /* Start with a clear screen */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -413,7 +421,7 @@ redraw_scene (AppState * state) glRotatef (90.f, 0.f, 1.f, 0.f); /* bottom face normal along y axis */ glDrawArrays (GL_TRIANGLE_STRIP, 20, 4); - eglSwapBuffers (state->display, state->surface); + eglSwapBuffers (display, state->surface); } /*********************************************************** @@ -431,6 +439,7 @@ redraw_scene (AppState * state) static void init_textures (AppState * state) { + EGLDisplay display = egl_display_get (state->display); glGenTextures (1, &state->tex); glBindTexture (GL_TEXTURE_2D, state->tex); @@ -450,7 +459,7 @@ init_textures (AppState * state) /* Create EGL Image */ - state->ipc.eglImage = eglCreateImageKHR (state->display, + state->ipc.eglImage = eglCreateImageKHR (display, state->context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer) state->tex, 0); if (state->ipc.eglImage == EGL_NO_IMAGE_KHR) { @@ -474,22 +483,23 @@ static void close_ogl (void) { DISPMANX_UPDATE_HANDLE_T dispman_update; - + EGLDisplay display = egl_display_get (state->display); + if (state->ipc.eglImage != 0) { - if (!eglDestroyImageKHR (state->display, (EGLImageKHR) state->ipc.eglImage)) + if (!eglDestroyImageKHR (display, (EGLImageKHR) state->ipc.eglImage)) g_print ("eglDestroyImageKHR failed."); } /* clear screen */ glClear (GL_COLOR_BUFFER_BIT); - eglSwapBuffers (state->display, state->surface); + eglSwapBuffers (display, state->surface); /* Release OpenGL resources */ - eglMakeCurrent (state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, + eglMakeCurrent (display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroySurface (state->display, state->surface); - eglDestroyContext (state->display, state->context); - eglTerminate (state->display); + eglDestroySurface (display, state->surface); + eglDestroyContext (display, state->context); + egl_display_unref (state->display); dispman_update = vc_dispmanx_update_start (0); vc_dispmanx_element_remove (dispman_update, state->dispman_element); |