Add _cogl_egl_texture_2d_new_from_image API

This adds an internal texture_2d constructor that can wrap an EGLImage
as a CoglTexture2D. The plan is to utilize this for texture-from-pixmap
support with EGL as well as creating textures from wayland buffers.
This commit is contained in:
Robert Bragg 2011-05-24 22:34:10 +01:00
parent c9f1541de0
commit 60b25615fd
16 changed files with 214 additions and 11 deletions

View File

@ -335,23 +335,28 @@ cogl_sources_c += \
endif
if SUPPORT_EGL_PLATFORM_POWERVR_X11
cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c
$(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-egl-private.h
endif
if SUPPORT_EGL_PLATFORM_POWERVR_NULL
cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c
$(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-egl-private.h
endif
if SUPPORT_EGL_PLATFORM_GDL
cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c
$(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-egl-private.h
endif
if SUPPORT_EGL_PLATFORM_WAYLAND
cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c
$(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-egl-private.h
endif
if SUPPORT_EGL_PLATFORM_ANDROID
cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c
$(srcdir)/winsys/cogl-winsys-egl.c \
$(srcdir)/winsys/cogl-winsys-egl-private.h
endif
EXTRA_DIST += stb_image.c

View File

@ -65,6 +65,7 @@ struct _CoglContext
/* Features cache */
CoglFeatureFlags feature_flags;
CoglPrivateFeatureFlags private_feature_flags;
CoglHandle default_pipeline;
CoglHandle default_layer_0;

View File

@ -141,6 +141,7 @@ cogl_context_new (CoglDisplay *display,
/* Init default values */
context->feature_flags = 0;
context->private_feature_flags = 0;
context->texture_types = NULL;
context->buffer_types = NULL;

View File

@ -41,6 +41,9 @@ G_BEGIN_DECLS
#define NativeWindowType EGLNativeWindowType
#endif
#ifndef GL_OES_EGL_image
#define GLeglImageOES void *
#endif
G_END_DECLS
#endif

View File

@ -126,6 +126,11 @@ typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
COGL_DRIVER_ERROR_INVALID_VERSION
} CoglDriverError;
typedef enum
{
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0
} CoglPrivateFeatureFlags;
gboolean
_cogl_check_extension (const char *name, const char *ext);

View File

@ -40,13 +40,11 @@
#include "cogl-display-private.h"
#include "cogl-winsys-private.h"
#include "cogl-winsys-stub-private.h"
#include "cogl-winsys-egl-private.h"
#ifdef COGL_HAS_GLX_SUPPORT
extern const CoglWinsysVtable *_cogl_winsys_glx_get_vtable (void);
#endif
#ifdef COGL_HAS_EGL_SUPPORT
extern const CoglWinsysVtable *_cogl_winsys_egl_get_vtable (void);
#endif
#ifdef COGL_HAS_WGL_SUPPORT
extern const CoglWinsysVtable *_cogl_winsys_wgl_get_vtable (void);
#endif

View File

@ -61,6 +61,19 @@ _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
CoglPixelFormat internal_format,
GError **error);
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
/* NB: The reason we require the width, height and format to be passed
* even though they may seem redundant is because GLES 1/2 don't
* provide a way to query these properties. */
CoglTexture2D *
_cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
EGLImageKHR image,
GError **error);
#endif
/*
* _cogl_texture_2d_externally_modified:
* @handle: A handle to a 2D texture

View File

@ -39,6 +39,7 @@
#include "cogl-journal-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-winsys-egl-private.h"
#include <string.h>
#include <math.h>
@ -493,6 +494,53 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
return _cogl_texture_2d_handle_new (tex_2d);
}
#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
/* NB: The reason we require the width, height and format to be passed
* even though they may seem redundant is because GLES 1/2 don't
* provide a way to query these properties. */
CoglTexture2D *
_cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
EGLImageKHR image,
GError **error)
{
CoglTexture2D *tex_2d;
GLenum gl_error;
g_return_val_if_fail (_cogl_context_get_winsys (ctx) ==
_cogl_winsys_egl_get_vtable (),
NULL);
g_return_val_if_fail (ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
NULL);
tex_2d = _cogl_texture_2d_create_base (width, height, COGL_TEXTURE_NONE,
format);
_cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture,
FALSE);
while ((gl_error = glGetError ()) != GL_NO_ERROR)
;
ctx->drv.pf_glEGLImageTargetTexture2D (GL_TEXTURE_2D, image);
if (glGetError () != GL_NO_ERROR)
{
g_set_error (error,
COGL_TEXTURE_ERROR,
COGL_TEXTURE_ERROR_BAD_PARAMETER,
"Could not create a CoglTexture2D from a given EGLImage");
return NULL;
}
return _cogl_texture_2d_handle_new (tex_2d);
}
#endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
void
_cogl_texture_2d_externally_modified (CoglHandle handle)
{

View File

@ -66,7 +66,8 @@ G_BEGIN_DECLS
*/
typedef enum {
COGL_TEXTURE_ERROR_SIZE,
COGL_TEXTURE_ERROR_FORMAT
COGL_TEXTURE_ERROR_FORMAT,
COGL_TEXTURE_ERROR_BAD_PARAMETER
} CoglTextureError;
GQuark cogl_texture_error_quark (void);

View File

@ -421,3 +421,15 @@ COGL_FEATURE_BEGIN (point_sprites, 2, 0,
COGL_FEATURE_POINT_SPRITE,
0)
COGL_FEATURE_END ()
COGL_FEATURE_BEGIN (EGL_image, 255, 255,
"OES\0",
"EGL_image\0",
0,
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)
COGL_FEATURE_FUNCTION (void, glEGLImageTargetTexture2D,
(GLenum target,
GLeglImageOES image))
COGL_FEATURE_FUNCTION (void, glEGLImageTargetRenderbufferStorage,
(GLenum target,
GLeglImageOES image))
COGL_FEATURE_END ()

View File

@ -155,6 +155,7 @@ static const CoglFeatureData cogl_feature_data[] =
void
_cogl_gl_update_features (CoglContext *context)
{
CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0;
const char *gl_extensions;
int max_clip_planes = 0;
@ -212,8 +213,12 @@ _cogl_gl_update_features (CoglContext *context)
gl_major, gl_minor,
gl_extensions,
context))
flags |= cogl_feature_data[i].feature_flags;
{
private_flags |= cogl_feature_data[i].feature_flags_private;
flags |= cogl_feature_data[i].feature_flags;
}
/* Cache features */
context->private_feature_flags |= private_flags;
context->feature_flags |= flags;
}

View File

@ -139,3 +139,15 @@ COGL_FEATURE_FUNCTION (void *, glMapBuffer,
COGL_FEATURE_FUNCTION (GLboolean, glUnmapBuffer,
(GLenum target))
COGL_FEATURE_END ()
COGL_FEATURE_BEGIN (EGL_image, 255, 255,
"OES\0",
"EGL_image\0",
0,
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)
COGL_FEATURE_FUNCTION (void, glEGLImageTargetTexture2D,
(GLenum target,
eglImageOES image))
COGL_FEATURE_FUNCTION (void, glEGLImageTargetRenderbufferStorage,
(GLenum target,
eglImageOES image))
COGL_FEATURE_END ()

View File

@ -77,6 +77,7 @@ static const CoglFeatureData cogl_feature_data[] =
void
_cogl_gl_update_features (CoglContext *context)
{
CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0;
const char *gl_extensions;
#ifndef HAVE_COGL_GLES2
@ -129,8 +130,12 @@ _cogl_gl_update_features (CoglContext *context)
0, 0,
gl_extensions,
context))
flags |= cogl_feature_data[i].feature_flags;
{
private_flags |= cogl_feature_data[i].feature_flags_private;
flags |= cogl_feature_data[i].feature_flags;
}
/* Cache features */
context->private_feature_flags |= private_flags;
context->feature_flags |= flags;
}

View File

@ -51,3 +51,20 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion,
EGLint numRects,
const EGLint *rects))
COGL_WINSYS_FEATURE_END ()
/* XXX: These macros can't handle falling back to looking for
* EGL_KHR_image if EGL_KHR_image_base and EGL_KHR_image_pixmap aren't
* found... */
COGL_WINSYS_FEATURE_BEGIN (image_base,
"KHR\0",
"image_base\0",
0)
COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglCreateImage,
(EGLDisplay dpy,
EGLContext ctx,
EGLenum target,
EGLClientBuffer buffer,
const EGLint *attrib_list))
COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroyImage,
(EGLDisplay dpy,
EGLImageKHR image))
COGL_WINSYS_FEATURE_END ()

View File

@ -0,0 +1,46 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_WINSYS_EGL_PRIVATE_H
#define __COGL_WINSYS_EGL_PRIVATE_H
#include "cogl-defines.h"
#include "cogl-winsys-private.h"
#include "cogl-context.h"
const CoglWinsysVtable *
_cogl_winsys_egl_get_vtable (void);
#ifdef EGL_KHR_image_base
EGLImageKHR
_cogl_egl_create_image (CoglContext *ctx,
EGLenum target,
EGLClientBuffer buffer,
const EGLint *attribs);
void
_cogl_egl_destroy_image (CoglContext *ctx,
EGLImageKHR image);
#endif
#endif /* __COGL_WINSYS_EGL_PRIVATE_H */

View File

@ -1638,3 +1638,34 @@ cogl_wayland_onscreen_get_surface (CoglOnscreen *onscreen)
}
#endif /* COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT */
#ifdef EGL_KHR_image_base
EGLImageKHR
_cogl_egl_create_image (CoglContext *ctx,
EGLenum target,
EGLClientBuffer buffer,
const EGLint *attribs)
{
CoglDisplayEGL *egl_display = ctx->display->winsys;
CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
g_return_val_if_fail (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR);
return egl_renderer->pf_eglCreateImage (egl_renderer->edpy,
egl_display->egl_context,
target,
buffer,
attribs);
}
void
_cogl_egl_destroy_image (CoglContext *ctx,
EGLImageKHR image)
{
CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
g_return_if_fail (egl_renderer->pf_eglDestroyImage);
egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image);
}
#endif