2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h" /* Also includes international specific stuff */
|
2009-10-09 05:10:27 -07:00
|
|
|
#include "evas_engine.h"
|
2015-09-30 15:12:13 -07:00
|
|
|
#include "../gl_common/evas_gl_define.h"
|
2016-01-04 23:41:14 -08:00
|
|
|
#include "../software_generic/evas_native_common.h"
|
2009-10-09 05:10:27 -07:00
|
|
|
|
2011-10-15 02:31:04 -07:00
|
|
|
#ifdef HAVE_DLSYM
|
|
|
|
# include <dlfcn.h> /* dlopen,dlclose,etc */
|
|
|
|
#else
|
|
|
|
# error gl_x11 should not get compiled if dlsym is not found on the system!
|
|
|
|
#endif
|
|
|
|
|
2013-10-29 03:06:33 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
#include "evas_cs2_private.h"
|
|
|
|
#endif
|
|
|
|
|
2011-05-01 19:14:00 -07:00
|
|
|
#define EVAS_GL_NO_GL_H_CHECK 1
|
|
|
|
#include "Evas_GL.h"
|
2010-01-21 00:44:11 -08:00
|
|
|
|
2013-04-11 05:23:07 -07:00
|
|
|
#define EVAS_GL_UPDATE_TILE_SIZE 16
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
typedef struct _Render_Engine Render_Engine;
|
2010-08-02 23:09:53 -07:00
|
|
|
|
|
|
|
struct _Render_Engine
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
Render_Engine_GL_Generic generic;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
};
|
|
|
|
|
2014-07-04 04:51:32 -07:00
|
|
|
const char *debug_dir;
|
|
|
|
int swap_buffer_debug_mode = -1;
|
|
|
|
int swap_buffer_debug = 0;
|
|
|
|
int partial_render_debug = -1;
|
|
|
|
int extn_have_buffer_age = 1;
|
|
|
|
|
2010-08-02 23:09:53 -07:00
|
|
|
static int initted = 0;
|
|
|
|
static int gl_wins = 0;
|
2013-12-11 01:26:45 -08:00
|
|
|
#ifdef GL_GLES
|
2014-01-06 20:13:01 -08:00
|
|
|
static int extn_have_y_inverted = 1;
|
2013-12-11 01:26:45 -08:00
|
|
|
#endif
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
typedef void (*_eng_fn) (void);
|
|
|
|
typedef _eng_fn (*glsym_func_eng_fn) ();
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
typedef void (*glsym_func_void) ();
|
|
|
|
typedef void *(*glsym_func_void_ptr) ();
|
|
|
|
typedef int (*glsym_func_int) ();
|
|
|
|
typedef unsigned int (*glsym_func_uint) ();
|
2011-12-17 21:03:24 -08:00
|
|
|
typedef const char *(*glsym_func_const_char_ptr) ();
|
2010-08-02 23:09:53 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_unref = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_free = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_disable = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_enable = NULL;
|
|
|
|
Evas_GL_Common_Image_New_From_Data glsym_evas_gl_common_image_new_from_data = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
|
|
|
|
Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
|
|
|
|
Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
|
|
|
|
EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
|
2015-03-16 19:40:04 -07:00
|
|
|
EVGL_Native_Surface_Call glsym_evgl_native_surface_buffer_get = NULL;
|
2015-04-20 18:54:02 -07:00
|
|
|
EVGL_Native_Surface_Yinvert_Call glsym_evgl_native_surface_yinvert_get = NULL;
|
2015-04-30 00:04:47 -07:00
|
|
|
EVGL_Current_Native_Context_Get_Call glsym_evgl_current_native_context_get = NULL;
|
2014-07-25 11:05:37 -07:00
|
|
|
Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
|
2014-07-11 06:16:03 -07:00
|
|
|
|
|
|
|
Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done = NULL;
|
|
|
|
Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL;
|
|
|
|
Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump = NULL;
|
|
|
|
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
|
|
|
|
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL;
|
|
|
|
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL;
|
|
|
|
|
2015-11-05 21:53:33 -08:00
|
|
|
glsym_func_void glsym_evas_gl_common_shaders_flush = NULL;
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_func_void glsym_evas_gl_common_error_set = NULL;
|
|
|
|
glsym_func_int glsym_evas_gl_common_error_get = NULL;
|
|
|
|
glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL;
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2010-01-28 21:32:51 -08:00
|
|
|
|
2016-10-18 22:05:31 -07:00
|
|
|
#if !defined(EGL_KHR_cl_event2) && !defined(EGL_VERSION_1_5)
|
|
|
|
typedef intptr_t EGLAttribKHR;
|
|
|
|
#endif
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
_eng_fn (*glsym_eglGetProcAddress) (const char *a) = NULL;
|
2016-10-18 21:39:02 -07:00
|
|
|
EGLImageKHR (*glsym_eglCreateImage) (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const EGLAttribKHR *e) = NULL;
|
2016-10-18 21:32:55 -07:00
|
|
|
EGLImageKHR (*glsym_eglCreateImageKHR) (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, EGLint *e) = NULL;
|
2011-12-17 21:03:24 -08:00
|
|
|
void (*glsym_eglDestroyImage) (EGLDisplay a, void *b) = NULL;
|
|
|
|
void (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
|
2014-07-06 11:19:28 -07:00
|
|
|
unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
|
2015-07-29 14:12:35 -07:00
|
|
|
unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
|
2015-11-04 11:10:06 -08:00
|
|
|
unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, /*struct wl_resource */void *b, EGLint c, EGLint *d) = NULL;
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2013-04-09 16:36:33 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
typedef XID (*glsym_func_xid) ();
|
|
|
|
|
|
|
|
_eng_fn (*glsym_glXGetProcAddress) (const char *a) = NULL;
|
|
|
|
void (*glsym_glXBindTexImage) (Display *a, GLXDrawable b, int c, int *d) = NULL;
|
|
|
|
void (*glsym_glXReleaseTexImage) (Display *a, GLXDrawable b, int c) = NULL;
|
|
|
|
int (*glsym_glXGetVideoSync) (unsigned int *a) = NULL;
|
|
|
|
int (*glsym_glXWaitVideoSync) (int a, int b, unsigned int *c) = NULL;
|
|
|
|
XID (*glsym_glXCreatePixmap) (Display *a, void *b, Pixmap c, const int *d) = NULL;
|
|
|
|
void (*glsym_glXDestroyPixmap) (Display *a, XID b) = NULL;
|
2016-08-15 23:19:21 -07:00
|
|
|
int (*glsym_glXQueryDrawable) (Display *a, XID b, int c, unsigned int *d) = NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
int (*glsym_glXSwapIntervalSGI) (int a) = NULL;
|
|
|
|
void (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c) = NULL;
|
2013-04-09 17:40:37 -07:00
|
|
|
void (*glsym_glXReleaseBuffersMESA) (Display *a, XID b) = NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
static inline Outbuf *
|
|
|
|
eng_get_ob(Render_Engine *re)
|
|
|
|
{
|
|
|
|
return re->generic.software.ob;
|
|
|
|
}
|
2013-05-20 02:09:50 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
//----------------------------------------------------------//
|
|
|
|
// NEW_EVAS_GL Engine Functions
|
|
|
|
static void *
|
|
|
|
evgl_eng_display_get(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, NULL); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
2013-05-20 02:09:50 -07:00
|
|
|
return NULL;
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2014-07-11 06:16:03 -07:00
|
|
|
if (eng_get_ob(re))
|
|
|
|
return (void*)eng_get_ob(re)->egl_disp;
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2014-07-11 06:16:03 -07:00
|
|
|
if (eng_get_ob(re)->info)
|
|
|
|
return (void*)eng_get_ob(re)->info->info.display;
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
2012-09-24 00:41:27 -07:00
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
|
|
|
evgl_eng_evas_surface_get(void *data)
|
2010-01-21 00:44:11 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, NULL); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
2013-05-20 02:09:50 -07:00
|
|
|
return NULL;
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2014-07-11 06:16:03 -07:00
|
|
|
if (eng_get_ob(re))
|
|
|
|
return (void*)eng_get_ob(re)->egl_surface[0];
|
2012-09-24 00:41:27 -07:00
|
|
|
#else
|
2014-07-11 06:16:03 -07:00
|
|
|
if (eng_get_ob(re))
|
|
|
|
return (void*)eng_get_ob(re)->win;
|
2012-09-24 00:41:27 -07:00
|
|
|
#endif
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2015-11-06 00:50:22 -08:00
|
|
|
#ifdef GL_GLES
|
|
|
|
static EGLDisplay main_dpy = EGL_NO_DISPLAY;
|
|
|
|
static EGLSurface main_draw = EGL_NO_SURFACE;
|
|
|
|
static EGLSurface main_read = EGL_NO_SURFACE;
|
|
|
|
static EGLContext main_ctx = EGL_NO_CONTEXT;
|
|
|
|
|
|
|
|
EGLContext
|
|
|
|
evas_eglGetCurrentContext(void)
|
|
|
|
{
|
|
|
|
if (eina_main_loop_is())
|
|
|
|
return main_ctx;
|
|
|
|
else
|
|
|
|
return eglGetCurrentContext();
|
|
|
|
}
|
|
|
|
|
|
|
|
EGLSurface
|
|
|
|
evas_eglGetCurrentSurface(EGLint readdraw)
|
|
|
|
{
|
|
|
|
if (eina_main_loop_is())
|
|
|
|
return (readdraw == EGL_READ) ? main_read : main_draw;
|
|
|
|
else
|
|
|
|
return eglGetCurrentSurface(readdraw);
|
|
|
|
}
|
|
|
|
|
|
|
|
EGLDisplay
|
|
|
|
evas_eglGetCurrentDisplay(void)
|
|
|
|
{
|
|
|
|
if (eina_main_loop_is())
|
|
|
|
return main_dpy;
|
|
|
|
else
|
|
|
|
return eglGetCurrentDisplay();
|
|
|
|
}
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
evas_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
|
|
|
|
{
|
|
|
|
if (eina_main_loop_is())
|
|
|
|
{
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
if ((dpy == main_dpy) && (draw == main_draw) &&
|
|
|
|
(read == main_read) && (ctx == main_ctx))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
ret = eglMakeCurrent(dpy, draw, read, ctx);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
main_dpy = dpy;
|
|
|
|
main_draw = draw;
|
|
|
|
main_read = read;
|
|
|
|
main_ctx = ctx;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return eglMakeCurrent(dpy, draw, read, ctx);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
|
|
|
evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
int ret = 0;
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, 0); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
EGLContext ctx = (EGLContext)context;
|
|
|
|
EGLSurface sfc = (EGLSurface)surface;
|
2014-07-11 06:16:03 -07:00
|
|
|
EGLDisplay dpy = eng_get_ob(re)->egl_disp; //eglGetCurrentDisplay();
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
if ((!context) && (!surface))
|
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
ret = evas_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
2014-09-01 03:16:21 -07:00
|
|
|
int err = eglGetError();
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("evas_eglMakeCurrent() failed! Error Code=%#x", err);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2013-04-09 17:40:37 -07:00
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2014-09-01 20:52:52 -07:00
|
|
|
// FIXME: Check (eglGetCurrentDisplay() != dpy) ?
|
2015-11-06 00:50:22 -08:00
|
|
|
if ((evas_eglGetCurrentContext() != ctx) ||
|
|
|
|
(evas_eglGetCurrentSurface(EGL_READ) != sfc) ||
|
|
|
|
(evas_eglGetCurrentSurface(EGL_DRAW) != sfc) )
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
//!!!! Does it need to be flushed with it's set to NULL above??
|
|
|
|
// Flush remainder of what's in Evas' pipeline
|
|
|
|
if (flush) eng_window_use(NULL);
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
// Do a make current
|
2015-11-06 00:50:22 -08:00
|
|
|
ret = evas_eglMakeCurrent(dpy, sfc, sfc, ctx);
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
2014-09-01 03:16:21 -07:00
|
|
|
int err = eglGetError();
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("evas_eglMakeCurrent() failed! Error Code=%#x", err);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return 1;
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2012-09-24 00:41:27 -07:00
|
|
|
GLXContext ctx = (GLXContext)context;
|
|
|
|
Window sfc = (Window)surface;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
if ((!context) && (!surface))
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
ret = __glXMakeContextCurrent(eng_get_ob(re)->info->info.display, 0, NULL);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
2014-11-01 19:36:21 -07:00
|
|
|
ERR("glXMakeContextCurrent() failed!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if ((glXGetCurrentContext() != ctx))
|
|
|
|
{
|
|
|
|
//!!!! Does it need to be flushed with it's set to NULL above??
|
|
|
|
// Flush remainder of what's in Evas' pipeline
|
|
|
|
if (flush) eng_window_use(NULL);
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
// Do a make current
|
2014-10-25 04:04:52 -07:00
|
|
|
if ((sfc == eng_get_ob(re)->win) ||
|
|
|
|
(sfc == eng_get_ob(re)->glxwin))
|
|
|
|
ret = __glXMakeContextCurrent(eng_get_ob(re)->info->info.display,
|
|
|
|
eng_get_ob(re)->glxwin, ctx);
|
|
|
|
else
|
|
|
|
ret = __glXMakeContextCurrent(eng_get_ob(re)->info->info.display,
|
|
|
|
sfc, ctx);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
2014-11-01 19:36:21 -07:00
|
|
|
ERR("glXMakeContextCurrent() failed. Ret: %d! Context: %p Surface: %p",
|
|
|
|
ret, (void *)ctx, (void *)sfc);
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
|
|
|
evgl_eng_native_window_create(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, NULL); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
XSetWindowAttributes attr;
|
|
|
|
Window win;
|
|
|
|
|
|
|
|
attr.backing_store = NotUseful;
|
|
|
|
attr.override_redirect = True;
|
|
|
|
attr.border_pixel = 0;
|
|
|
|
attr.background_pixmap = None;
|
|
|
|
attr.bit_gravity = NorthWestGravity;
|
|
|
|
attr.win_gravity = NorthWestGravity;
|
|
|
|
attr.save_under = False;
|
|
|
|
attr.do_not_propagate_mask = NoEventMask;
|
2015-11-03 01:13:59 -08:00
|
|
|
attr.event_mask = 0;
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
win = XCreateWindow(eng_get_ob(re)->info->info.display,
|
2014-10-25 04:04:52 -07:00
|
|
|
eng_get_ob(re)->win,
|
|
|
|
-20, -20, 2, 2, 0,
|
2015-11-03 01:13:59 -08:00
|
|
|
CopyFromParent, InputOutput, CopyFromParent,
|
2012-09-24 00:41:27 -07:00
|
|
|
CWBackingStore | CWOverrideRedirect |
|
|
|
|
CWBorderPixel | CWBackPixmap |
|
|
|
|
CWSaveUnder | CWDontPropagate |
|
|
|
|
CWEventMask | CWBitGravity |
|
|
|
|
CWWinGravity, &attr);
|
|
|
|
if (!win)
|
|
|
|
{
|
|
|
|
ERR("Creating native X window failed.");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
2012-09-24 00:41:27 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
Adding MSAA (Multisample Anti-Aliased) Surface Option to Evas GL.
Currently, this feature is only supported in EGL/GLESv2 environment
with GL_IMG_multisampled_render_to_texture extension supported.
_____________________
from: (sanghee park) sh15.park@samsung.com
Dear all,
I compose this mail to ask reviewal this patch about multisampling on the evasgl.
I want to make multisampling capacity to enhance rendering quality of the evasgl.
But if MSAA is applied always, this have possibility lowering rendering performance,
I separated user's input level to high, mid, low, none.
If you want to test this patch, try to examine rendering qulity on EGL circumstance with multisampling level.
Plaese review it, and any suggestion will be appreciated.
Best Regards,
SangHee
SVN revision: 70992
2012-05-14 01:52:56 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return (void*)win;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
|
|
|
evgl_eng_native_window_destroy(void *data, void *native_window)
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, 0); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
2012-06-27 01:19:25 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
2012-06-27 01:19:25 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!native_window)
|
2012-06-27 01:19:25 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Inavlid native surface.");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_NATIVE_WINDOW);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
2012-06-27 01:19:25 -07:00
|
|
|
}
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
XDestroyWindow(eng_get_ob(re)->info->info.display, (Window)native_window);
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
native_window = NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return 1;
|
|
|
|
}
|
2012-06-27 01:19:25 -07:00
|
|
|
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
// Theoretically, we wouldn't need this functoin if the surfaceless context
|
2015-11-03 01:13:59 -08:00
|
|
|
// is supported. But, until then...
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
2014-08-14 04:18:56 -07:00
|
|
|
evgl_eng_window_surface_create(void *data, void *native_window EINA_UNUSED)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, NULL); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return NULL;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
EGLSurface surface = EGL_NO_SURFACE;
|
|
|
|
|
|
|
|
// Create resource surface for EGL
|
2014-07-11 06:16:03 -07:00
|
|
|
surface = eglCreateWindowSurface(eng_get_ob(re)->egl_disp,
|
|
|
|
eng_get_ob(re)->egl_config,
|
2012-09-24 00:41:27 -07:00
|
|
|
(EGLNativeWindowType)native_window,
|
|
|
|
NULL);
|
|
|
|
if (!surface)
|
|
|
|
{
|
|
|
|
ERR("Creating window surface failed. Error: %#x.", eglGetError());
|
2014-10-25 04:04:52 -07:00
|
|
|
abort();
|
2012-09-24 00:41:27 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2006-02-27 20:07:49 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return (void*)surface;
|
|
|
|
#else
|
|
|
|
/*
|
|
|
|
// We don't need to create new one for GLX
|
|
|
|
Window surface;
|
2011-11-10 00:59:09 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
surface = eng_get_ob(re)->win;
|
2010-01-21 00:44:11 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return (void *)surface;
|
|
|
|
*/
|
2014-08-15 20:40:42 -07:00
|
|
|
return (void *)native_window;
|
2012-09-24 00:41:27 -07:00
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2010-08-26 02:40:48 -07:00
|
|
|
static int
|
2012-09-24 00:41:27 -07:00
|
|
|
evgl_eng_window_surface_destroy(void *data, void *surface)
|
2010-08-26 02:40:48 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, 0); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
2010-08-26 02:40:48 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
2010-08-26 02:40:48 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
if (!surface)
|
|
|
|
{
|
|
|
|
ERR("Invalid surface.");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface);
|
2012-09-24 00:41:27 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return 1;
|
2012-11-13 06:07:39 -08:00
|
|
|
if (surface) return 0;
|
2010-08-26 02:40:48 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
2014-09-22 03:15:37 -07:00
|
|
|
evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version)
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, NULL); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2014-09-22 03:15:37 -07:00
|
|
|
if ((version < EVAS_GL_GLES_1_X) || (version > EVAS_GL_GLES_3_X))
|
|
|
|
{
|
|
|
|
ERR("Invalid context version number %d", version);
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2015-03-04 22:36:35 -08:00
|
|
|
if ((version == EVAS_GL_GLES_3_X) &&
|
|
|
|
((!eng_get_ob(re)->gl_context) || (eng_get_ob(re)->gl_context->gles_version != EVAS_GL_GLES_3_X)))
|
|
|
|
{
|
|
|
|
ERR("GLES 3 version not supported!");
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_ATTRIBUTE);
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
EGLContext context = EGL_NO_CONTEXT;
|
2012-05-15 06:13:05 -07:00
|
|
|
int context_attrs[3];
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2015-03-05 02:21:24 -08:00
|
|
|
if (eng_get_ob(re)->gles3 && (version >= EVAS_GL_GLES_2_X))
|
|
|
|
version = 3;
|
|
|
|
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
2014-09-22 03:15:37 -07:00
|
|
|
context_attrs[1] = version;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
context_attrs[2] = EGL_NONE;
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
// Share context already assumes that it's sharing with evas' context
|
|
|
|
if (share_ctx)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
context = eglCreateContext(eng_get_ob(re)->egl_disp,
|
|
|
|
eng_get_ob(re)->egl_config,
|
2012-09-24 00:41:27 -07:00
|
|
|
(EGLContext)share_ctx,
|
|
|
|
context_attrs);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-03-04 22:36:35 -08:00
|
|
|
else if ((version == EVAS_GL_GLES_1_X) || (version == EVAS_GL_GLES_3_X))
|
2014-09-22 03:15:37 -07:00
|
|
|
{
|
|
|
|
context = eglCreateContext(eng_get_ob(re)->egl_disp,
|
|
|
|
eng_get_ob(re)->egl_config,
|
|
|
|
NULL,
|
|
|
|
context_attrs);
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
else
|
2012-05-02 19:33:18 -07:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
context = eglCreateContext(eng_get_ob(re)->egl_disp,
|
|
|
|
eng_get_ob(re)->egl_config,
|
|
|
|
eng_get_ob(re)->egl_context[0], // Evas' GL Context
|
2012-05-15 06:13:05 -07:00
|
|
|
context_attrs);
|
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!context)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-09-01 03:16:21 -07:00
|
|
|
int err = eglGetError();
|
|
|
|
ERR("Engine Context Creations Failed. Error: %#x.", err);
|
2014-09-22 03:15:37 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return (void*)context;
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2012-09-24 00:41:27 -07:00
|
|
|
GLXContext context = NULL;
|
|
|
|
|
|
|
|
// Share context already assumes that it's sharing with evas' context
|
|
|
|
if (share_ctx)
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
context = glXCreateContext(eng_get_ob(re)->info->info.display,
|
|
|
|
eng_get_ob(re)->visualinfo,
|
2012-09-24 00:41:27 -07:00
|
|
|
(GLXContext)share_ctx,
|
2012-05-15 06:13:05 -07:00
|
|
|
1);
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
|
|
|
else
|
2011-11-10 00:59:09 -08:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
context = glXCreateContext(eng_get_ob(re)->info->info.display,
|
|
|
|
eng_get_ob(re)->visualinfo,
|
|
|
|
eng_get_ob(re)->context, // Evas' GL Context
|
2012-09-24 00:41:27 -07:00
|
|
|
1);
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!context)
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Internal Resource Context Creations Failed.");
|
2014-09-01 20:52:52 -07:00
|
|
|
if(!(eng_get_ob(re)->info->info.display)) glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
|
|
|
if(!(eng_get_ob(re)->win)) glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_NATIVE_WINDOW);
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return (void*)context;
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
|
|
|
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-09-24 00:41:27 -07:00
|
|
|
evgl_eng_context_destroy(void *data, void *context)
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, 0); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if ((!re) || (!context))
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Invalid Render Input Data. Engine: %p, Context: %p", data, context);
|
2014-09-01 20:52:52 -07:00
|
|
|
if (!re) glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
|
|
|
if (!context) glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_CONTEXT);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
#ifdef GL_GLES
|
2014-07-11 06:16:03 -07:00
|
|
|
eglDestroyContext(eng_get_ob(re)->egl_disp, (EGLContext)context);
|
2012-09-24 00:41:27 -07:00
|
|
|
#else
|
2014-07-11 06:16:03 -07:00
|
|
|
glXDestroyContext(eng_get_ob(re)->info->info.display, (GLXContext)context);
|
2012-07-23 20:57:27 -07:00
|
|
|
#endif
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
evgl_eng_string_get(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, NULL); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
2012-06-27 01:19:25 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return NULL;
|
2012-06-27 01:19:25 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#ifdef GL_GLES
|
2014-07-11 06:16:03 -07:00
|
|
|
return eglQueryString(eng_get_ob(re)->egl_disp, EGL_EXTENSIONS);
|
2012-09-24 00:41:27 -07:00
|
|
|
#else
|
2014-07-11 06:16:03 -07:00
|
|
|
return glXQueryExtensionsString(eng_get_ob(re)->info->info.display,
|
|
|
|
eng_get_ob(re)->info->info.screen);
|
2012-09-24 00:41:27 -07:00
|
|
|
#endif
|
From: "Sung W. Park" <sungwoo@gmail.com>
Subject: Re: [E-devel] [E-Devel][Review][Patch] Evas GL Extensions + a
bug fix
Here's an initial attempt at the GL extensions issue for Evas GL.
I have been in discussion with a few EFL developers regarding how we should
provide extensions. Essentially, there are two ways to go about doing this.
1. provide evas_gl_proc_address_get() function as it is done in other
glue layers
2. provide all the extension functions in the EVAS_GL_API struct.
#1 approach is how it's done in other glue layers and the driver implementor can
provide new extensions easily. It is however pretty annoying to get the
function prototypes right and use the function pointers and etc.
#2 approach provides all the extension functions in the struct so it's
definitely easier to use. Adding new extensions can be a pain as people may
have to wait for new version releases.
For now, we thought it was OK to just throw them in the struct as in
#2 and try it out. So, I've implemented this approach. As for the extensions,
I've basically included all the extensions in gl2ext.h as EvasGL currently
provides all the GLES 2.0 functions. In order to display the right
information, I had to override glGetString() with GL_EXTENSIONS as parameter to properly
display the supported extensions.
Also, I've added a few EGL extensions that have been
modified for EvasGL use. For example, eglCreateImage/eglDestroyImage has been
defined as folllows.
EvasGLImage (*evasglCreateImage) (int target, void* buffer, int*
attrib_list); void
(*evasglDestroyImage)
(EvasGLImage image);
const char *evas_gl_string_query() function was added to return a string of
supported EvasGL extensions. So essentially, a user can search this string to see
if the desired extension is supported. if it is, he can use the functions. He can
always check if the function pointers are NULL as well.
Take a look at the pach and let me know what you think.
______________
While I was adding the extension code, I've added a few fixes/ changes
to the EvasGL.
1. glDeletBuffers bug
- When I wad destroying evasgl context, I was deleting the context FBO with
glDeleteBuffers instead of glDeleteFramebuffers. This code in effect was
deleting BOs in other contexts and we had some funky behaviors as a
result. The
bug has been fixed.
2. make_current
- I've made some changes to the make current code and also added a resource
context to the engine data. the resource context is used for creating surface
texture/ fbos when surface/ context is created. Before, i was using evas'
context but thought it'd be a good idea to use a separate context.
SVN revision: 64139
2011-10-18 01:13:23 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
|
|
|
evgl_eng_proc_address_get(const char *name)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
|
|
|
|
return dlsym(RTLD_DEFAULT, name);
|
|
|
|
#else
|
|
|
|
if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
|
|
|
|
return dlsym(RTLD_DEFAULT, name);
|
|
|
|
#endif
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2012-08-01 18:15:38 -07:00
|
|
|
static int
|
2012-09-24 00:41:27 -07:00
|
|
|
evgl_eng_rotation_angle_get(void *data)
|
2012-08-01 18:15:38 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* EVGLINIT(re, 0); */
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
2012-08-01 18:15:38 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Invalid Render Engine Data!");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
2012-08-01 18:15:38 -07:00
|
|
|
}
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
if ((eng_get_ob(re)) && (eng_get_ob(re)->gl_context))
|
2014-09-03 19:41:27 -07:00
|
|
|
return eng_get_ob(re)->gl_context->rot;
|
2012-09-24 00:41:27 -07:00
|
|
|
else
|
2012-08-01 18:15:38 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Unable to retrieve rotation angle.");
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_CONTEXT);
|
2012-08-01 18:15:38 -07:00
|
|
|
return 0;
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
|
|
|
|
2014-09-19 01:32:26 -07:00
|
|
|
static void *
|
|
|
|
evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
|
|
|
|
const int *attrib_list)
|
|
|
|
{
|
2014-09-19 01:44:56 -07:00
|
|
|
Render_Engine_GL_Generic *re = data;
|
2014-09-19 01:32:26 -07:00
|
|
|
|
|
|
|
// TODO: Add support for surfaceless pbuffers (EGL_NO_TEXTURE)
|
|
|
|
// TODO: Add support for EGL_MIPMAP_TEXTURE??? (GLX doesn't support them)
|
|
|
|
|
2014-10-06 05:26:11 -07:00
|
|
|
if (attrib_list)
|
|
|
|
WRN("This PBuffer implementation does not support extra attributes yet");
|
|
|
|
|
2014-09-19 01:32:26 -07:00
|
|
|
#ifdef GL_GLES
|
2014-11-13 18:22:59 -08:00
|
|
|
Evas_Engine_GL_Context *evasglctx;
|
2014-09-19 01:32:26 -07:00
|
|
|
int config_attrs[20];
|
|
|
|
int surface_attrs[20];
|
|
|
|
EGLSurface egl_sfc;
|
|
|
|
EGLConfig egl_cfg;
|
|
|
|
int num_config, i = 0;
|
2014-09-19 01:44:56 -07:00
|
|
|
EGLDisplay disp;
|
|
|
|
EGLContext ctx;
|
2014-09-19 01:32:26 -07:00
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
disp = re->window_egl_display_get(re->software.ob);
|
2014-11-13 18:22:59 -08:00
|
|
|
evasglctx = re->window_gl_context_get(re->software.ob);
|
|
|
|
ctx = evasglctx->eglctxt;
|
2014-09-19 01:44:56 -07:00
|
|
|
|
2014-09-19 01:32:26 -07:00
|
|
|
#if 0
|
|
|
|
// Choose framebuffer configuration
|
|
|
|
// DISABLED FOR NOW
|
|
|
|
if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_RED_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = EGL_GREEN_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = EGL_BLUE_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
|
|
|
|
if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
//config_attrs[i++] = EGL_BIND_TO_TEXTURE_RGBA;
|
|
|
|
//config_attrs[i++] = EGL_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//config_attrs[i++] = EGL_BIND_TO_TEXTURE_RGB;
|
|
|
|
//config_attrs[i++] = EGL_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sfc->depth_fmt || sfc->depth_stencil_fmt)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sfc->stencil_fmt || sfc->depth_stencil_fmt)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
config_attrs[i++] = EGL_RENDERABLE_TYPE;
|
2015-03-05 02:21:24 -08:00
|
|
|
if (eng_get_ob(re)->gles3)
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
|
|
|
|
else
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
|
2014-09-19 01:32:26 -07:00
|
|
|
config_attrs[i++] = EGL_SURFACE_TYPE;
|
|
|
|
config_attrs[i++] = EGL_PBUFFER_BIT;
|
|
|
|
config_attrs[i++] = EGL_NONE;
|
|
|
|
#else
|
2015-11-06 00:50:22 -08:00
|
|
|
// It looks like evas_eglMakeCurrent might fail if we use a different config from
|
2014-09-19 01:32:26 -07:00
|
|
|
// the actual display surface. This is weird.
|
|
|
|
i = 0;
|
|
|
|
config_attrs[i++] = EGL_CONFIG_ID;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = EGL_NONE;
|
2014-09-19 01:44:56 -07:00
|
|
|
eglQueryContext(disp, ctx, EGL_CONFIG_ID, &config_attrs[1]);
|
2014-09-19 01:32:26 -07:00
|
|
|
#endif
|
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
if (!eglChooseConfig(disp, config_attrs, &egl_cfg, 1, &num_config)
|
2014-09-19 01:32:26 -07:00
|
|
|
|| (num_config < 1))
|
|
|
|
{
|
|
|
|
int err = eglGetError();
|
2014-09-19 01:44:56 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
2014-09-19 01:32:26 -07:00
|
|
|
ERR("eglChooseConfig failed with error %x", err);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now, choose the config for the PBuffer
|
|
|
|
i = 0;
|
|
|
|
surface_attrs[i++] = EGL_WIDTH;
|
|
|
|
surface_attrs[i++] = sfc->w;
|
|
|
|
surface_attrs[i++] = EGL_HEIGHT;
|
|
|
|
surface_attrs[i++] = sfc->h;
|
|
|
|
#if 0
|
|
|
|
// Adding these parameters will trigger EGL_BAD_ATTRIBUTE because
|
|
|
|
// the config also requires EGL_BIND_TO_TEXTURE_RGB[A]. But some drivers
|
|
|
|
// don't support those configs (eg. nvidia)
|
|
|
|
surface_attrs[i++] = EGL_TEXTURE_FORMAT;
|
|
|
|
if (sfc->pbuffer.color_fmt == EVAS_GL_RGB_888)
|
|
|
|
surface_attrs[i++] = EGL_TEXTURE_RGB;
|
|
|
|
else
|
|
|
|
surface_attrs[i++] = EGL_TEXTURE_RGBA;
|
|
|
|
surface_attrs[i++] = EGL_TEXTURE_TARGET;
|
|
|
|
surface_attrs[i++] = EGL_TEXTURE_2D;
|
|
|
|
surface_attrs[i++] = EGL_MIPMAP_TEXTURE;
|
|
|
|
surface_attrs[i++] = EINA_TRUE;
|
|
|
|
#endif
|
|
|
|
surface_attrs[i++] = EGL_NONE;
|
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
egl_sfc = eglCreatePbufferSurface(disp, egl_cfg, surface_attrs);
|
2014-09-19 01:32:26 -07:00
|
|
|
if (!egl_sfc)
|
|
|
|
{
|
|
|
|
int err = eglGetError();
|
2014-09-19 01:44:56 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
2014-09-19 01:32:26 -07:00
|
|
|
ERR("eglCreatePbufferSurface failed with error %x", err);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return egl_sfc;
|
|
|
|
#else
|
2015-11-17 00:18:57 -08:00
|
|
|
Evas_Engine_GL_Context *evasglctx;
|
2014-10-06 05:26:11 -07:00
|
|
|
GLXPbuffer pbuf;
|
|
|
|
GLXFBConfig *cfgs;
|
|
|
|
int config_attrs[20];
|
|
|
|
int surface_attrs[20];
|
|
|
|
int ncfg = 0, i;
|
|
|
|
|
2015-11-17 00:18:57 -08:00
|
|
|
evasglctx = re->window_gl_context_get(re->software.ob);
|
2014-10-06 05:26:11 -07:00
|
|
|
|
|
|
|
#ifndef GLX_VISUAL_ID
|
|
|
|
# define GLX_VISUAL_ID 0x800b
|
2014-09-19 01:32:26 -07:00
|
|
|
#endif
|
2014-10-06 05:26:11 -07:00
|
|
|
|
|
|
|
i = 0;
|
2015-11-17 00:18:57 -08:00
|
|
|
#if 0
|
|
|
|
// DISABLED BECAUSE BadMatch HAPPENS
|
2014-10-06 05:26:11 -07:00
|
|
|
if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_BUFFER_SIZE;
|
|
|
|
if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = 32;
|
|
|
|
//config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
|
|
|
|
//config_attrs[i++] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
config_attrs[i++] = 24;
|
|
|
|
//config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT;
|
|
|
|
//config_attrs[i++] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sfc->depth_fmt)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = 24; // FIXME: This should depend on the requested bits
|
|
|
|
}
|
|
|
|
if (sfc->stencil_fmt)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = 8; // FIXME: This should depend on the requested bits
|
|
|
|
}
|
|
|
|
//config_attrs[i++] = GLX_VISUAL_ID;
|
|
|
|
//config_attrs[i++] = XVisualIDFromVisual(vis);
|
2015-11-17 00:18:57 -08:00
|
|
|
#else
|
|
|
|
config_attrs[i++] = GLX_FBCONFIG_ID;
|
|
|
|
if (sfc->pbuffer.color_fmt == EVAS_GL_RGB_888)
|
|
|
|
config_attrs[i++] = evasglctx->glxcfg_rgb;
|
|
|
|
else
|
|
|
|
config_attrs[i++] = evasglctx->glxcfg_rgba;
|
|
|
|
#endif
|
2014-10-06 05:26:11 -07:00
|
|
|
config_attrs[i++] = 0;
|
|
|
|
|
|
|
|
cfgs = glXChooseFBConfig(re->software.ob->disp, re->software.ob->screen,
|
|
|
|
config_attrs, &ncfg);
|
|
|
|
if (!cfgs || !ncfg)
|
|
|
|
{
|
|
|
|
ERR("GLX failed to find a valid config for the pbuffer");
|
|
|
|
if (cfgs) XFree(cfgs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
surface_attrs[i++] = GLX_LARGEST_PBUFFER;
|
|
|
|
surface_attrs[i++] = 0;
|
|
|
|
surface_attrs[i++] = GLX_PBUFFER_WIDTH;
|
|
|
|
surface_attrs[i++] = sfc->w;
|
|
|
|
surface_attrs[i++] = GLX_PBUFFER_HEIGHT;
|
|
|
|
surface_attrs[i++] = sfc->h;
|
|
|
|
surface_attrs[i++] = 0;
|
|
|
|
pbuf = glXCreatePbuffer(re->software.ob->disp, cfgs[0], surface_attrs);
|
2015-10-29 22:53:36 -07:00
|
|
|
XFree(cfgs);
|
2014-10-06 05:26:11 -07:00
|
|
|
|
|
|
|
if (!pbuf)
|
|
|
|
{
|
|
|
|
ERR("GLX failed to create a pbuffer");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (void*)(intptr_t)pbuf;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evgl_eng_pbuffer_surface_destroy(void *data, void *surface)
|
|
|
|
{
|
|
|
|
/* EVGLINIT(re, 0); */
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
glsym_evas_gl_common_error_set(NULL, EVAS_GL_NOT_INITIALIZED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!surface)
|
|
|
|
{
|
|
|
|
ERR("Invalid surface.");
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
Render_Engine *re = data;
|
|
|
|
|
|
|
|
eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface);
|
|
|
|
#else
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
GLXPbuffer pbuf = (GLXPbuffer)(intptr_t) surface;
|
|
|
|
|
|
|
|
glXDestroyPbuffer(re->software.ob->disp, pbuf);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 1;
|
2014-09-19 01:32:26 -07:00
|
|
|
}
|
|
|
|
|
2014-09-22 23:33:16 -07:00
|
|
|
// This function should create a surface that can be used for offscreen rendering
|
2015-03-09 01:17:19 -07:00
|
|
|
// and still be bindable to a texture in Evas main GL context.
|
2014-09-22 23:33:16 -07:00
|
|
|
// For now, this will create an X pixmap... Ideally it should be able to create
|
|
|
|
// a bindable pbuffer surface or just an FBO if that is supported and it can
|
|
|
|
// be shared with Evas.
|
2014-11-26 05:42:08 -08:00
|
|
|
// FIXME: Avoid passing evgl_engine around like that.
|
2014-09-22 23:33:16 -07:00
|
|
|
static void *
|
2015-03-09 01:17:19 -07:00
|
|
|
evgl_eng_indirect_surface_create(EVGL_Engine *evgl EINA_UNUSED, void *data,
|
2014-11-26 05:42:08 -08:00
|
|
|
EVGL_Surface *evgl_sfc,
|
2014-09-22 23:33:16 -07:00
|
|
|
Evas_GL_Config *cfg, int w, int h)
|
|
|
|
{
|
2014-11-26 05:42:08 -08:00
|
|
|
Render_Engine *re = data;
|
2014-11-28 19:07:33 -08:00
|
|
|
#ifdef GL_GLES
|
2014-11-26 05:42:08 -08:00
|
|
|
Eina_Bool alpha = EINA_FALSE;
|
2014-11-28 19:07:33 -08:00
|
|
|
#endif
|
2014-11-26 05:42:08 -08:00
|
|
|
int colordepth;
|
2014-09-22 23:33:16 -07:00
|
|
|
Pixmap px;
|
|
|
|
|
|
|
|
if (!re || !evgl_sfc || !cfg)
|
|
|
|
{
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-20 18:54:02 -07:00
|
|
|
if ((w < 1) || (h < 1))
|
2014-09-22 23:33:16 -07:00
|
|
|
{
|
|
|
|
ERR("Inconsistent parameters, not creating any surface!");
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-11-26 05:42:08 -08:00
|
|
|
/* Choose appropriate pixmap depth */
|
|
|
|
if (cfg->color_format == EVAS_GL_RGBA_8888)
|
|
|
|
{
|
2014-11-28 19:07:33 -08:00
|
|
|
#ifdef GL_GLES
|
2014-11-26 05:42:08 -08:00
|
|
|
alpha = EINA_TRUE;
|
2014-11-28 19:07:33 -08:00
|
|
|
#endif
|
2014-11-26 05:42:08 -08:00
|
|
|
colordepth = 32;
|
|
|
|
}
|
|
|
|
else if (cfg->color_format == EVAS_GL_RGB_888)
|
|
|
|
colordepth = 24;
|
|
|
|
else // this could also be XDefaultDepth but this case shouldn't happen
|
|
|
|
colordepth = 24;
|
|
|
|
|
|
|
|
px = XCreatePixmap(eng_get_ob(re)->disp, eng_get_ob(re)->win, w, h, colordepth);
|
2014-09-22 23:33:16 -07:00
|
|
|
if (!px)
|
|
|
|
{
|
|
|
|
ERR("Failed to create XPixmap!");
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_ALLOC);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
EGLSurface egl_sfc;
|
2014-11-26 05:42:08 -08:00
|
|
|
EGLConfig egl_cfg;
|
2014-12-22 05:08:24 -08:00
|
|
|
int i, num = 0, best = -1;
|
2014-11-26 05:42:08 -08:00
|
|
|
EGLConfig configs[200];
|
|
|
|
int config_attrs[40];
|
|
|
|
Eina_Bool found = EINA_FALSE;
|
|
|
|
int msaa = 0, depth = 0, stencil = 0;
|
|
|
|
Visual *visual = NULL;
|
2014-12-22 05:08:24 -08:00
|
|
|
Eina_Bool retried = EINA_FALSE;
|
2015-06-02 22:57:37 -07:00
|
|
|
EGLint val = 0;
|
2014-11-26 05:42:08 -08:00
|
|
|
|
|
|
|
/* Now we need to iterate over all EGL configurations to check the compatible
|
|
|
|
* ones and finally check their visual ID. */
|
|
|
|
|
2014-12-19 00:36:14 -08:00
|
|
|
if ((cfg->depth_bits > EVAS_GL_DEPTH_NONE) &&
|
|
|
|
(cfg->depth_bits <= EVAS_GL_DEPTH_BIT_32))
|
|
|
|
depth = 8 * ((int) cfg->depth_bits);
|
|
|
|
|
|
|
|
if ((cfg->stencil_bits > EVAS_GL_STENCIL_NONE) &&
|
|
|
|
(cfg->stencil_bits <= EVAS_GL_STENCIL_BIT_16))
|
|
|
|
stencil = 1 << ((int) cfg->stencil_bits - 1);
|
|
|
|
|
|
|
|
if ((cfg->multisample_bits > EVAS_GL_MULTISAMPLE_NONE) &&
|
|
|
|
(cfg->multisample_bits <= EVAS_GL_MULTISAMPLE_HIGH))
|
|
|
|
msaa = evgl->caps.msaa_samples[(int) cfg->multisample_bits - 1];
|
|
|
|
|
2014-12-22 05:08:24 -08:00
|
|
|
try_again:
|
2014-11-26 05:42:08 -08:00
|
|
|
i = 0;
|
|
|
|
config_attrs[i++] = EGL_SURFACE_TYPE;
|
|
|
|
config_attrs[i++] = EGL_PIXMAP_BIT;
|
|
|
|
config_attrs[i++] = EGL_RENDERABLE_TYPE;
|
2015-03-09 01:17:19 -07:00
|
|
|
if (cfg->gles_version == EVAS_GL_GLES_3_X)
|
2015-03-04 22:36:35 -08:00
|
|
|
config_attrs[i++] = EGL_OPENGL_ES3_BIT;
|
2015-04-20 18:54:02 -07:00
|
|
|
else if (cfg->gles_version == EVAS_GL_GLES_2_X)
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
|
2015-03-04 22:36:35 -08:00
|
|
|
else
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES_BIT;
|
2014-12-19 00:36:14 -08:00
|
|
|
if (alpha)
|
2014-11-26 05:42:08 -08:00
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = 1; // should it be 8?
|
|
|
|
DBG("Requesting RGBA pixmap");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
}
|
2014-12-19 00:36:14 -08:00
|
|
|
if (depth)
|
2014-11-26 05:42:08 -08:00
|
|
|
{
|
|
|
|
depth = 8 * ((int) cfg->depth_bits);
|
|
|
|
config_attrs[i++] = EGL_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = depth;
|
|
|
|
DBG("Requesting depth buffer size %d", depth);
|
|
|
|
}
|
2014-12-19 00:36:14 -08:00
|
|
|
if (stencil)
|
2014-11-26 05:42:08 -08:00
|
|
|
{
|
|
|
|
stencil = 1 << ((int) cfg->stencil_bits - 1);
|
|
|
|
config_attrs[i++] = EGL_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = stencil;
|
|
|
|
DBG("Requesting stencil buffer size %d", stencil);
|
|
|
|
}
|
2014-12-19 00:36:14 -08:00
|
|
|
if (msaa)
|
2014-11-26 05:42:08 -08:00
|
|
|
{
|
|
|
|
msaa = evgl->caps.msaa_samples[(int) cfg->multisample_bits - 1];
|
|
|
|
config_attrs[i++] = EGL_SAMPLE_BUFFERS;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = EGL_SAMPLES;
|
|
|
|
config_attrs[i++] = msaa;
|
|
|
|
DBG("Requesting MSAA buffer with %d samples", msaa);
|
|
|
|
}
|
|
|
|
config_attrs[i++] = EGL_NONE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
|
2015-02-24 03:54:55 -08:00
|
|
|
if (!eglChooseConfig(eng_get_ob(re)->egl_disp, config_attrs, configs, 200, &num) || !num)
|
2014-11-26 05:42:08 -08:00
|
|
|
{
|
|
|
|
int err = eglGetError();
|
|
|
|
ERR("eglChooseConfig() can't find any configs, error: %x", err);
|
|
|
|
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
|
|
|
XFreePixmap(eng_get_ob(re)->disp, px);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-12-19 00:36:14 -08:00
|
|
|
DBG("Found %d potential configurations", num);
|
2014-11-26 05:42:08 -08:00
|
|
|
for (i = 0; (i < num) && !found; i++)
|
|
|
|
{
|
|
|
|
VisualID visid = 0;
|
|
|
|
XVisualInfo *xvi, vi_in;
|
|
|
|
XRenderPictFormat *fmt;
|
|
|
|
int nvi = 0, j;
|
|
|
|
|
|
|
|
if (!eglGetConfigAttrib(eng_get_ob(re)->egl_disp, configs[i],
|
|
|
|
EGL_NATIVE_VISUAL_ID, &val))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Find matching visuals. Only alpha & depth are really valid here.
|
|
|
|
visid = val;
|
|
|
|
vi_in.screen = eng_get_ob(re)->screen;
|
|
|
|
vi_in.visualid = visid;
|
|
|
|
xvi = XGetVisualInfo(eng_get_ob(re)->disp,
|
|
|
|
VisualScreenMask | VisualIDMask,
|
|
|
|
&vi_in, &nvi);
|
|
|
|
if (xvi)
|
|
|
|
{
|
|
|
|
for (j = 0; (j < nvi) && !found; j++)
|
|
|
|
{
|
|
|
|
if (xvi[j].depth >= colordepth)
|
|
|
|
{
|
2014-12-22 05:08:24 -08:00
|
|
|
if (best < 0) best = i;
|
2014-11-26 05:42:08 -08:00
|
|
|
if (alpha)
|
|
|
|
{
|
|
|
|
fmt = XRenderFindVisualFormat(eng_get_ob(re)->disp, xvi[j].visual);
|
|
|
|
if (fmt && (fmt->direct.alphaMask))
|
|
|
|
found = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else found = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
egl_cfg = configs[i];
|
|
|
|
visual = xvi[j].visual;
|
|
|
|
XFree(xvi);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
XFree(xvi);
|
|
|
|
}
|
|
|
|
}
|
2014-09-22 23:33:16 -07:00
|
|
|
|
2014-11-26 05:42:08 -08:00
|
|
|
if (!found)
|
|
|
|
{
|
2014-12-22 05:08:24 -08:00
|
|
|
if (num && (best >= 0))
|
|
|
|
{
|
|
|
|
ERR("No matching config found. Trying with EGL config #%d", best);
|
|
|
|
egl_cfg = configs[best];
|
|
|
|
}
|
|
|
|
else if (msaa && !retried)
|
|
|
|
{
|
|
|
|
ERR("Trying again without MSAA.");
|
|
|
|
msaa = 0;
|
|
|
|
retried = EINA_TRUE;
|
|
|
|
goto try_again;
|
|
|
|
}
|
2014-11-26 05:42:08 -08:00
|
|
|
else
|
2014-12-22 05:08:24 -08:00
|
|
|
{
|
|
|
|
// This config will probably not work, but we try anyways.
|
|
|
|
// NOTE: Maybe it would be safer to just return NULL here, leaving
|
|
|
|
// the app responsible for changing its config.
|
|
|
|
ERR("XGetVisualInfo failed. Trying with the window's EGL config.");
|
|
|
|
egl_cfg = eng_get_ob(re)->egl_config;
|
|
|
|
}
|
2014-11-26 05:42:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
egl_sfc = eglCreatePixmapSurface(eng_get_ob(re)->egl_disp, egl_cfg, px, NULL);
|
2014-09-22 23:33:16 -07:00
|
|
|
if (!egl_sfc)
|
|
|
|
{
|
|
|
|
int err = eglGetError();
|
|
|
|
ERR("eglCreatePixmapSurface failed with error: %x", err);
|
|
|
|
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
|
|
|
XFreePixmap(eng_get_ob(re)->disp, px);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-20 18:54:02 -07:00
|
|
|
if (extn_have_y_inverted &&
|
|
|
|
eglGetConfigAttrib(eng_get_ob(re)->egl_disp, egl_cfg,
|
|
|
|
EGL_Y_INVERTED_NOK, &val))
|
|
|
|
evgl_sfc->yinvert = val;
|
|
|
|
else
|
|
|
|
evgl_sfc->yinvert = 1;
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
evgl_sfc->indirect = EINA_TRUE;
|
|
|
|
evgl_sfc->indirect_sfc = egl_sfc;
|
|
|
|
evgl_sfc->indirect_sfc_native = (void *)(intptr_t) px;
|
|
|
|
evgl_sfc->indirect_sfc_visual = visual;
|
|
|
|
evgl_sfc->indirect_sfc_config = egl_cfg;
|
|
|
|
DBG("Successfully created indirect surface: Pixmap %lu EGLSurface %p", px, egl_sfc);
|
2014-09-22 23:33:16 -07:00
|
|
|
return evgl_sfc;
|
|
|
|
|
|
|
|
#else
|
2014-11-26 05:42:08 -08:00
|
|
|
// TODO/FIXME: do the same as with EGL above...
|
2015-03-09 01:17:19 -07:00
|
|
|
ERR("GLX support is not fully implemented for indirect surface");
|
2014-11-26 05:42:08 -08:00
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
evgl_sfc->indirect = EINA_TRUE;
|
|
|
|
evgl_sfc->indirect_sfc_native = (void *)(intptr_t) px;
|
|
|
|
evgl_sfc->indirect_sfc = (void *)(intptr_t) px;
|
|
|
|
evgl_sfc->indirect_sfc_visual = eng_get_ob(re)->info->info.visual; // FIXME: Check this!
|
2014-10-06 05:26:11 -07:00
|
|
|
return evgl_sfc;
|
2014-09-22 23:33:16 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
// This function should destroy the indirect surface as well as the X pixmap
|
2014-09-22 23:33:16 -07:00
|
|
|
static int
|
2015-03-09 01:17:19 -07:00
|
|
|
evgl_eng_indirect_surface_destroy(void *data, EVGL_Surface *evgl_sfc)
|
2014-09-22 23:33:16 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
2015-03-09 01:17:19 -07:00
|
|
|
if ((!evgl_sfc) || (!evgl_sfc->indirect_sfc))
|
2014-09-22 23:33:16 -07:00
|
|
|
{
|
2015-03-09 01:17:19 -07:00
|
|
|
ERR("Invalid surface");
|
2014-09-22 23:33:16 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)evgl_sfc->indirect_sfc);
|
2014-09-22 23:33:16 -07:00
|
|
|
#endif
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
if (!evgl_sfc->indirect_sfc_native)
|
2014-09-22 23:33:16 -07:00
|
|
|
{
|
2015-03-09 01:17:19 -07:00
|
|
|
ERR("Inconsistent parameters, not freeing XPixmap for indirect surface!");
|
2014-09-22 23:33:16 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
XFreePixmap(eng_get_ob(re)->disp, (Pixmap)evgl_sfc->indirect_sfc_native);
|
2014-09-22 23:33:16 -07:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-24 03:54:55 -08:00
|
|
|
static void *
|
2015-03-04 22:36:35 -08:00
|
|
|
evgl_eng_gles_context_create(void *data,
|
2015-02-24 03:54:55 -08:00
|
|
|
EVGL_Context *share_ctx, EVGL_Surface *sfc)
|
|
|
|
{
|
|
|
|
Render_Engine *re = data;
|
|
|
|
if (!re) return NULL;
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
EGLContext context = EGL_NO_CONTEXT;
|
|
|
|
int context_attrs[3];
|
|
|
|
EGLConfig config;
|
|
|
|
|
2015-03-04 22:36:35 -08:00
|
|
|
if (!share_ctx)
|
|
|
|
{
|
|
|
|
ERR("Share context not set, Unable to retrieve GLES version");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-24 03:54:55 -08:00
|
|
|
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
2015-03-04 22:36:35 -08:00
|
|
|
context_attrs[1] = share_ctx->version;
|
2015-02-24 03:54:55 -08:00
|
|
|
context_attrs[2] = EGL_NONE;
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
if (!sfc || !sfc->indirect_sfc_config)
|
2015-02-24 03:54:55 -08:00
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("Surface is not set! Creating context anyways but evas_eglMakeCurrent "
|
2015-02-24 03:54:55 -08:00
|
|
|
"might very well fail with EGL_BAD_MATCH (0x3009)");
|
|
|
|
config = eng_get_ob(re)->egl_config;
|
|
|
|
}
|
2015-03-09 01:17:19 -07:00
|
|
|
else config = sfc->indirect_sfc_config;
|
2015-02-24 03:54:55 -08:00
|
|
|
|
|
|
|
context = eglCreateContext(eng_get_ob(re)->egl_disp, config,
|
2015-04-20 18:54:02 -07:00
|
|
|
share_ctx->context,
|
2015-02-24 03:54:55 -08:00
|
|
|
context_attrs);
|
|
|
|
if (!context)
|
|
|
|
{
|
|
|
|
int err = eglGetError();
|
|
|
|
ERR("eglCreateContext failed with error 0x%x", err);
|
|
|
|
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-03-09 01:17:19 -07:00
|
|
|
DBG("Successfully created context for indirect rendering.");
|
2015-02-24 03:54:55 -08:00
|
|
|
return context;
|
|
|
|
#else
|
2015-03-09 01:17:19 -07:00
|
|
|
CRI("Support for indirect rendering contexts is not implemented for GLX");
|
2015-02-24 03:54:55 -08:00
|
|
|
(void) share_ctx; (void) sfc;
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-05-11 20:03:29 -07:00
|
|
|
static void
|
|
|
|
evgl_eng_native_win_surface_config_get(void *data, int *win_depth,
|
|
|
|
int *win_stencil, int *win_msaa)
|
2015-03-15 21:57:09 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = data;
|
2015-05-11 20:03:29 -07:00
|
|
|
if (!re) return;
|
2015-03-15 21:57:09 -07:00
|
|
|
|
2015-05-11 20:03:29 -07:00
|
|
|
if (win_depth)
|
|
|
|
*win_depth = eng_get_ob(re)->detected.depth_buffer_size;
|
|
|
|
if (win_stencil)
|
|
|
|
*win_stencil = eng_get_ob(re)->detected.stencil_buffer_size;
|
|
|
|
if (win_msaa)
|
|
|
|
*win_msaa = eng_get_ob(re)->detected.msaa;
|
|
|
|
|
|
|
|
DBG("Window config(depth %d, stencil %d, msaa %d)",
|
2015-03-15 21:57:09 -07:00
|
|
|
eng_get_ob(re)->detected.depth_buffer_size,
|
|
|
|
eng_get_ob(re)->detected.stencil_buffer_size,
|
|
|
|
eng_get_ob(re)->detected.msaa);
|
|
|
|
}
|
2015-02-24 03:54:55 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
static const EVGL_Interface evgl_funcs =
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
evgl_eng_display_get,
|
|
|
|
evgl_eng_evas_surface_get,
|
|
|
|
evgl_eng_native_window_create,
|
|
|
|
evgl_eng_native_window_destroy,
|
|
|
|
evgl_eng_window_surface_create,
|
|
|
|
evgl_eng_window_surface_destroy,
|
|
|
|
evgl_eng_context_create,
|
|
|
|
evgl_eng_context_destroy,
|
|
|
|
evgl_eng_make_current,
|
|
|
|
evgl_eng_proc_address_get,
|
|
|
|
evgl_eng_string_get,
|
2014-09-19 01:32:26 -07:00
|
|
|
evgl_eng_rotation_angle_get,
|
2014-09-22 23:33:16 -07:00
|
|
|
evgl_eng_pbuffer_surface_create,
|
2014-10-06 05:26:11 -07:00
|
|
|
evgl_eng_pbuffer_surface_destroy,
|
2015-03-09 01:17:19 -07:00
|
|
|
evgl_eng_indirect_surface_create,
|
|
|
|
evgl_eng_indirect_surface_destroy,
|
|
|
|
evgl_eng_gles_context_create,
|
2015-05-11 20:03:29 -07:00
|
|
|
evgl_eng_native_win_surface_config_get,
|
2012-09-24 00:41:27 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------//
|
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
static inline int
|
|
|
|
_has_ext(const char *exts, const char *ext)
|
|
|
|
{
|
|
|
|
if (!exts || !ext) return EINA_FALSE;
|
|
|
|
return strstr(exts, ext) != NULL;
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
static void
|
2012-11-21 23:58:06 -08:00
|
|
|
gl_symbols(void)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
static int done = 0;
|
|
|
|
|
|
|
|
if (done) return;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
#define LINK2GENERIC(sym) \
|
2015-11-05 21:53:33 -08:00
|
|
|
glsym_##sym = dlsym(RTLD_DEFAULT, #sym); \
|
|
|
|
if (!glsym_##sym) ERR("Could not find function '%s'", #sym);
|
2014-07-11 06:16:03 -07:00
|
|
|
|
|
|
|
// Get function pointer to evas_gl_common that is now provided through the link of GL_Generic.
|
|
|
|
LINK2GENERIC(evas_gl_common_image_all_unload);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_ref);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_unref);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_new_from_data);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_native_disable);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_free);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_native_enable);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_new);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_flush);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_free);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_use);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_newframe);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_done);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_resize);
|
|
|
|
LINK2GENERIC(evas_gl_common_buffer_dump);
|
|
|
|
LINK2GENERIC(evas_gl_preload_render_lock);
|
|
|
|
LINK2GENERIC(evas_gl_preload_render_unlock);
|
|
|
|
LINK2GENERIC(evas_gl_preload_render_relax);
|
|
|
|
LINK2GENERIC(evas_gl_preload_init);
|
|
|
|
LINK2GENERIC(evas_gl_preload_shutdown);
|
|
|
|
LINK2GENERIC(evgl_engine_shutdown);
|
2015-03-16 19:40:04 -07:00
|
|
|
LINK2GENERIC(evgl_native_surface_buffer_get);
|
2015-04-20 18:54:02 -07:00
|
|
|
LINK2GENERIC(evgl_native_surface_yinvert_get);
|
2015-04-30 00:04:47 -07:00
|
|
|
LINK2GENERIC(evgl_current_native_context_get);
|
2014-07-25 11:05:37 -07:00
|
|
|
LINK2GENERIC(evas_gl_symbols);
|
2014-09-01 20:52:52 -07:00
|
|
|
LINK2GENERIC(evas_gl_common_error_get);
|
|
|
|
LINK2GENERIC(evas_gl_common_error_set);
|
|
|
|
LINK2GENERIC(evas_gl_common_current_context_get);
|
2015-11-05 21:53:33 -08:00
|
|
|
LINK2GENERIC(evas_gl_common_shaders_flush);
|
2014-07-11 06:16:03 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
#define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym);
|
2012-09-24 00:41:27 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
|
2012-09-24 00:41:27 -07:00
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
|
2016-08-03 19:49:33 -07:00
|
|
|
|
2015-03-23 17:17:37 -07:00
|
|
|
#else
|
|
|
|
|
|
|
|
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
|
2016-08-03 19:49:33 -07:00
|
|
|
|
2015-03-23 17:17:37 -07:00
|
|
|
#endif
|
2016-08-03 19:49:33 -07:00
|
|
|
#undef FINDSYM
|
2015-03-23 17:17:37 -07:00
|
|
|
|
|
|
|
done = 1;
|
|
|
|
}
|
|
|
|
|
2016-10-14 14:03:47 -07:00
|
|
|
#ifdef GL_GLES
|
2016-10-18 21:39:02 -07:00
|
|
|
static EGLImageKHR
|
|
|
|
_eflCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttribKHR *attrib_list)
|
2016-10-14 14:03:47 -07:00
|
|
|
{
|
|
|
|
if (glsym_eglCreateImage)
|
|
|
|
return glsym_eglCreateImage(dpy, ctx, target, buffer, attrib_list);
|
|
|
|
if (glsym_eglCreateImageKHR)
|
|
|
|
{
|
|
|
|
int count, i;
|
|
|
|
EGLint *ints = NULL;
|
|
|
|
|
|
|
|
if (attrib_list)
|
|
|
|
{
|
|
|
|
for (count = 0; attrib_list[count] != EGL_NONE; count += 2);
|
|
|
|
count++;
|
|
|
|
ints = alloca(count * sizeof(EGLint));
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
ints[i] = attrib_list[i];
|
|
|
|
}
|
|
|
|
return glsym_eglCreateImageKHR(dpy, ctx, target, buffer, ints);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-03-23 17:17:37 -07:00
|
|
|
void
|
2016-08-03 19:49:33 -07:00
|
|
|
eng_gl_symbols(Outbuf *ob)
|
2015-03-23 17:17:37 -07:00
|
|
|
{
|
|
|
|
static int done = 0;
|
2016-08-03 19:49:33 -07:00
|
|
|
const char *exts;
|
2015-03-23 17:17:37 -07:00
|
|
|
|
|
|
|
if (done) return;
|
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
/* GetProcAddress() may not return NULL, even if the extension is not
|
|
|
|
* supported. Nvidia drivers since version 360 never return NULL, thus
|
|
|
|
* we need to always match the function name with their full extension
|
|
|
|
* name. Other drivers tend to return NULL for glX/egl prefixed names, but
|
|
|
|
* this could change in the future.
|
|
|
|
*
|
|
|
|
* -- jpeg, 2016/08/04
|
|
|
|
*/
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
#define FINDSYM(dst, sym, ext, typ) do { \
|
|
|
|
if (!dst) { \
|
|
|
|
if (_has_ext(exts, ext) && glsym_eglGetProcAddress) \
|
|
|
|
dst = (typ) glsym_eglGetProcAddress(sym); \
|
|
|
|
if (!dst) \
|
|
|
|
dst = (typ) dlsym(RTLD_DEFAULT, sym); \
|
|
|
|
}} while (0)
|
|
|
|
|
|
|
|
// Find GL extensions
|
2014-07-25 11:05:37 -07:00
|
|
|
glsym_evas_gl_symbols((void*)glsym_eglGetProcAddress);
|
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// Find EGL extensions
|
|
|
|
exts = eglQueryString(ob->egl_disp, EGL_EXTENSIONS);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImage", NULL, glsym_func_void_ptr);
|
2016-10-14 14:03:47 -07:00
|
|
|
FINDSYM(glsym_eglCreateImageKHR, "eglCreateImageKHR", "EGL_KHR_image_base", glsym_func_void_ptr);
|
|
|
|
FINDSYM(glsym_eglCreateImageKHR, "eglCreateImageKHR", "EGL_KHR_image", glsym_func_void_ptr);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", NULL, glsym_func_void);
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", "EGL_KHR_image_base", glsym_func_void);
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", "EGL_KHR_image", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", NULL, glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", "EGL_EXT_swap_buffers_with_damage", glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageKHR", "EGL_KHR_swap_buffers_with_damage", glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL", "EGL_INTEL_swap_buffers_with_damage", glsym_func_uint);
|
2013-03-11 23:26:32 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_eglSetDamageRegionKHR, "eglSetDamageRegionKHR", "EGL_KHR_partial_update", glsym_func_uint);
|
2013-03-11 23:26:32 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL", "EGL_WL_bind_wayland_display", glsym_func_uint);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// This is a GL extension
|
|
|
|
exts = (const char *) glGetString(GL_EXTENSIONS);
|
|
|
|
FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image_external", glsym_func_void);
|
2014-07-25 11:05:37 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
#else
|
2016-08-03 00:32:39 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
#define FINDSYM(dst, sym, ext, typ) do { \
|
|
|
|
if (!dst) { \
|
|
|
|
if (_has_ext(exts, ext) && glsym_glXGetProcAddress) \
|
|
|
|
dst = (typ) glsym_glXGetProcAddress(sym); \
|
|
|
|
if (!dst) \
|
|
|
|
dst = (typ) dlsym(RTLD_DEFAULT, sym); \
|
|
|
|
}} while (0)
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// Find GL extensions
|
|
|
|
glsym_evas_gl_symbols((void*)glsym_glXGetProcAddress);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// Find GLX extensions
|
|
|
|
exts = glXQueryExtensionsString((Display *) ob->disp, ob->screen);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", NULL, glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", "GLX_EXT_texture_from_pixmap", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", "GLX_ARB_render_texture", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", NULL, glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", "GLX_EXT_texture_from_pixmap", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", "GLX_ARB_render_texture", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", "GLX_SGI_video_sync", glsym_func_int);
|
|
|
|
FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", "GLX_SGI_video_sync", glsym_func_int);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// GLX 1.3
|
|
|
|
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", NULL, glsym_func_xid);
|
|
|
|
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", NULL, glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", NULL, glsym_func_int);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// swap interval: MESA and SGI take (interval)
|
|
|
|
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", "GLX_MESA_swap_control", glsym_func_int);
|
|
|
|
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", "GLX_SGI_swap_control", glsym_func_int);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
// swap interval: EXT takes (dpy, drawable, interval)
|
|
|
|
FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", "GLX_EXT_swap_control", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
FINDSYM(glsym_glXReleaseBuffersMESA, "glXReleaseBuffersMESA", "GLX_MESA_release_buffers", glsym_func_void);
|
2013-04-09 17:40:37 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#endif
|
2016-08-03 19:49:33 -07:00
|
|
|
#undef FINDSYM
|
2012-11-21 23:58:06 -08:00
|
|
|
|
|
|
|
done = 1;
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
|
|
|
|
2013-03-11 23:26:32 -07:00
|
|
|
static void
|
|
|
|
gl_extn_veto(Render_Engine *re)
|
|
|
|
{
|
|
|
|
const char *str = NULL;
|
|
|
|
#ifdef GL_GLES
|
2014-07-11 06:16:03 -07:00
|
|
|
str = eglQueryString(eng_get_ob(re)->egl_disp, EGL_EXTENSIONS);
|
2013-03-11 23:26:32 -07:00
|
|
|
if (str)
|
|
|
|
{
|
2015-03-23 17:30:59 -07:00
|
|
|
const char *s;
|
2013-03-11 23:26:32 -07:00
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
printf("EGL EXTN:\n%s\n", str);
|
2015-03-23 17:30:59 -07:00
|
|
|
// Disable Partial Rendering
|
|
|
|
if ((s = getenv("EVAS_GL_PARTIAL_DISABLE")) && atoi(s))
|
|
|
|
{
|
|
|
|
extn_have_buffer_age = 0;
|
|
|
|
glsym_eglSwapBuffersWithDamage = NULL;
|
2015-07-29 14:12:35 -07:00
|
|
|
glsym_eglSetDamageRegionKHR = NULL;
|
2015-03-23 17:30:59 -07:00
|
|
|
}
|
2013-04-09 16:36:33 -07:00
|
|
|
if (!strstr(str, "EGL_EXT_buffer_age"))
|
|
|
|
{
|
2015-07-29 14:12:35 -07:00
|
|
|
if (!strstr(str, "EGL_KHR_partial_update"))
|
|
|
|
extn_have_buffer_age = 0;
|
|
|
|
}
|
|
|
|
if (!strstr(str, "EGL_KHR_partial_update"))
|
|
|
|
{
|
|
|
|
glsym_eglSetDamageRegionKHR = NULL;
|
2013-04-09 16:36:33 -07:00
|
|
|
}
|
2014-01-06 20:13:01 -08:00
|
|
|
if (!strstr(str, "EGL_NOK_texture_from_pixmap"))
|
2015-10-13 23:17:06 -07:00
|
|
|
{
|
2014-01-06 20:13:01 -08:00
|
|
|
extn_have_y_inverted = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const GLubyte *vendor, *renderer;
|
|
|
|
|
|
|
|
vendor = glGetString(GL_VENDOR);
|
|
|
|
renderer = glGetString(GL_RENDERER);
|
|
|
|
// XXX: workaround mesa bug!
|
|
|
|
// looking for mesa and intel build which is known to
|
|
|
|
// advertise the EGL_NOK_texture_from_pixmap extension
|
|
|
|
// but not set it correctly. guessing vendor/renderer
|
|
|
|
// strings will be like the following:
|
|
|
|
// OpenGL vendor string: Intel Open Source Technology Center
|
|
|
|
// OpenGL renderer string: Mesa DRI Intel(R) Sandybridge Desktop
|
2014-03-19 03:48:46 -07:00
|
|
|
if (((vendor) && (strstr((const char *)vendor, "Intel"))) &&
|
|
|
|
((renderer) && (strstr((const char *)renderer, "Mesa"))) &&
|
|
|
|
((renderer) && (strstr((const char *)renderer, "Intel")))
|
2014-01-06 20:13:01 -08:00
|
|
|
)
|
|
|
|
extn_have_y_inverted = 0;
|
2013-11-28 01:18:16 -08:00
|
|
|
}
|
2014-04-05 06:21:13 -07:00
|
|
|
if (!strstr(str, "EGL_EXT_swap_buffers_with_damage"))
|
|
|
|
{
|
|
|
|
glsym_eglSwapBuffersWithDamage = NULL;
|
|
|
|
}
|
2015-11-11 00:06:44 -08:00
|
|
|
if (strstr(str, "EGL_TIZEN_image_native_surface"))
|
|
|
|
{
|
|
|
|
eng_get_ob(re)->gl_context->shared->info.egl_tbm_ext = 1;
|
|
|
|
}
|
2013-04-09 17:40:37 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
printf("NO EGL EXTN!\n");
|
|
|
|
extn_have_buffer_age = 0;
|
2013-03-11 23:26:32 -07:00
|
|
|
}
|
|
|
|
#else
|
2014-07-11 06:16:03 -07:00
|
|
|
str = glXQueryExtensionsString(eng_get_ob(re)->info->info.display,
|
|
|
|
eng_get_ob(re)->info->info.screen);
|
2013-03-11 23:26:32 -07:00
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
printf("GLX EXTN:\n%s\n", str);
|
|
|
|
if (!strstr(str, "_texture_from_pixmap"))
|
|
|
|
{
|
|
|
|
glsym_glXBindTexImage = NULL;
|
|
|
|
glsym_glXReleaseTexImage = NULL;
|
|
|
|
}
|
2014-07-30 00:16:45 -07:00
|
|
|
if (!strstr(str, "GLX_SGI_video_sync"))
|
2013-03-11 23:26:32 -07:00
|
|
|
{
|
|
|
|
glsym_glXGetVideoSync = NULL;
|
|
|
|
glsym_glXWaitVideoSync = NULL;
|
|
|
|
}
|
2013-04-09 16:36:33 -07:00
|
|
|
if (!strstr(str, "GLX_EXT_buffer_age"))
|
|
|
|
{
|
|
|
|
extn_have_buffer_age = 0;
|
|
|
|
}
|
2013-04-09 17:40:37 -07:00
|
|
|
if (!strstr(str, "GLX_EXT_swap_control"))
|
|
|
|
{
|
|
|
|
glsym_glXSwapIntervalEXT = NULL;
|
|
|
|
}
|
|
|
|
if (!strstr(str, "GLX_SGI_swap_control"))
|
|
|
|
{
|
|
|
|
glsym_glXSwapIntervalSGI = NULL;
|
|
|
|
}
|
|
|
|
if (!strstr(str, "GLX_MESA_release_buffers"))
|
|
|
|
{
|
|
|
|
glsym_glXReleaseBuffersMESA = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
printf("NO GLX EXTN!\n");
|
|
|
|
glsym_glXBindTexImage = NULL;
|
|
|
|
glsym_glXReleaseTexImage = NULL;
|
|
|
|
glsym_glXGetVideoSync = NULL;
|
|
|
|
glsym_glXWaitVideoSync = NULL;
|
|
|
|
extn_have_buffer_age = 0;
|
|
|
|
glsym_glXSwapIntervalEXT = NULL;
|
|
|
|
glsym_glXSwapIntervalSGI = NULL;
|
|
|
|
glsym_glXReleaseBuffersMESA = NULL;
|
2013-03-11 23:26:32 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
int _evas_engine_GL_X11_log_dom = -1;
|
|
|
|
/* function tables - filled in later (func and parent func) */
|
|
|
|
static Evas_Func func, pfunc;
|
|
|
|
|
|
|
|
static void *
|
2012-11-10 03:07:35 -08:00
|
|
|
eng_info(Evas *eo_e EINA_UNUSED)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_Info_GL_X11 *info;
|
|
|
|
|
|
|
|
info = calloc(1, sizeof(Evas_Engine_Info_GL_X11));
|
|
|
|
info->magic.magic = rand();
|
|
|
|
info->func.best_visual_get = eng_best_visual_get;
|
|
|
|
info->func.best_colormap_get = eng_best_colormap_get;
|
|
|
|
info->func.best_depth_get = eng_best_depth_get;
|
|
|
|
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_info_free(Evas *eo_e EINA_UNUSED, void *info)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_Info_GL_X11 *in;
|
|
|
|
// dont free! why bother? its not worth it
|
|
|
|
// eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
|
|
|
|
in = (Evas_Engine_Info_GL_X11 *)info;
|
|
|
|
free(in);
|
|
|
|
}
|
|
|
|
|
2015-11-05 21:53:33 -08:00
|
|
|
static void
|
2015-11-06 00:06:17 -08:00
|
|
|
eng_outbuf_idle_flush(Outbuf *ob)
|
2015-11-05 21:53:33 -08:00
|
|
|
{
|
|
|
|
if (glsym_evas_gl_common_shaders_flush)
|
2015-11-06 00:06:17 -08:00
|
|
|
glsym_evas_gl_common_shaders_flush(ob->gl_context->shared);
|
2015-11-05 21:53:33 -08:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void
|
|
|
|
_re_winfree(Render_Engine *re)
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
if (!eng_get_ob(re)->surf) return;
|
|
|
|
glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
|
|
|
|
eng_window_unsurf(eng_get_ob(re));
|
2013-05-20 02:09:50 -07:00
|
|
|
}
|
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
static void *
|
|
|
|
eng_setup(void *in, unsigned int w, unsigned int h)
|
|
|
|
{
|
|
|
|
Evas_Engine_Info_GL_X11 *info = in;
|
|
|
|
Render_Engine *re = NULL;
|
|
|
|
Outbuf *ob = NULL;
|
|
|
|
Render_Engine_Merge_Mode merge_mode = MERGE_SMART;
|
|
|
|
Render_Engine_Swap_Mode swap_mode;
|
|
|
|
const char *s;
|
|
|
|
|
2016-12-08 15:04:11 -08:00
|
|
|
swap_mode = evas_render_engine_gl_swap_mode_get(info->swap_mode);
|
2016-12-02 15:30:02 -08:00
|
|
|
|
2014-07-04 04:51:32 -07:00
|
|
|
// Set this env var to dump files every frame
|
|
|
|
// Or set the global var in gdb to 1|0 to turn it on and off
|
|
|
|
if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS"))
|
|
|
|
swap_buffer_debug = 1;
|
|
|
|
|
|
|
|
if (swap_buffer_debug_mode == -1)
|
|
|
|
{
|
|
|
|
if (
|
|
|
|
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
|
|
|
|
(getuid() == geteuid()) &&
|
|
|
|
#endif
|
|
|
|
((debug_dir = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR"))))
|
|
|
|
{
|
|
|
|
int stat;
|
|
|
|
// Create a directory with 0775 permission
|
|
|
|
stat = mkdir(debug_dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
|
|
|
|
if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
swap_buffer_debug_mode = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
if (!initted)
|
2006-12-09 00:52:08 -08:00
|
|
|
{
|
2016-12-02 15:30:02 -08:00
|
|
|
glsym_evas_gl_preload_init();
|
|
|
|
}
|
2014-07-11 06:16:03 -07:00
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2016-12-02 15:30:02 -08:00
|
|
|
int eb, evb;
|
2014-07-04 04:51:32 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
|
|
|
|
#endif
|
|
|
|
re = calloc(1, sizeof(Render_Engine));
|
|
|
|
if (!re) return NULL;
|
|
|
|
|
|
|
|
ob = eng_window_new(info,
|
|
|
|
info->info.display,
|
|
|
|
info->info.drawable,
|
|
|
|
info->info.screen,
|
|
|
|
info->info.visual,
|
|
|
|
info->info.colormap,
|
|
|
|
info->info.depth,
|
|
|
|
w, h,
|
|
|
|
info->indirect,
|
|
|
|
info->info.destination_alpha,
|
|
|
|
info->info.rotation,
|
|
|
|
swap_mode,
|
|
|
|
info->depth_bits,
|
|
|
|
info->stencil_bits,
|
|
|
|
info->msaa_bits);
|
|
|
|
if (!ob) goto on_error;
|
|
|
|
|
|
|
|
if (!evas_render_engine_gl_generic_init(&re->generic, ob,
|
|
|
|
eng_outbuf_swap_mode,
|
|
|
|
eng_outbuf_get_rot,
|
|
|
|
eng_outbuf_reconfigure,
|
|
|
|
eng_outbuf_region_first_rect,
|
2016-10-20 12:13:49 -07:00
|
|
|
#ifdef GL_GLES
|
2016-12-02 15:30:02 -08:00
|
|
|
eng_outbuf_damage_region_set,
|
2016-10-20 12:13:49 -07:00
|
|
|
#else
|
2016-12-02 15:30:02 -08:00
|
|
|
NULL,
|
|
|
|
#endif
|
|
|
|
eng_outbuf_new_region_for_update,
|
|
|
|
eng_outbuf_push_updated_region,
|
|
|
|
eng_outbuf_push_free_region_for_update,
|
|
|
|
eng_outbuf_idle_flush,
|
|
|
|
eng_outbuf_flush,
|
|
|
|
NULL,
|
|
|
|
eng_window_free,
|
|
|
|
eng_window_use,
|
|
|
|
eng_outbuf_gl_context_get,
|
|
|
|
eng_outbuf_egl_display_get,
|
|
|
|
eng_gl_context_new,
|
|
|
|
eng_gl_context_use,
|
|
|
|
&evgl_funcs,
|
|
|
|
w, h))
|
|
|
|
goto on_error;
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
gl_wins++;
|
2014-07-04 04:51:32 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
if ((s = getenv("EVAS_GL_PARTIAL_MERGE")))
|
|
|
|
{
|
|
|
|
if ((!strcmp(s, "bounding")) ||
|
|
|
|
(!strcmp(s, "b")))
|
|
|
|
merge_mode = MERGE_BOUNDING;
|
|
|
|
else if ((!strcmp(s, "full")) ||
|
|
|
|
(!strcmp(s, "f")))
|
|
|
|
merge_mode = MERGE_FULL;
|
|
|
|
else if ((!strcmp(s, "smart")) ||
|
|
|
|
(!strcmp(s, "s")))
|
|
|
|
merge_mode = MERGE_SMART;
|
|
|
|
}
|
2014-07-04 04:51:32 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
evas_render_engine_software_generic_merge_mode_set(&re->generic.software, merge_mode);
|
2014-07-11 06:16:03 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
if (!initted)
|
2006-03-08 00:02:34 -08:00
|
|
|
{
|
2016-12-02 15:30:02 -08:00
|
|
|
gl_extn_veto(re);
|
|
|
|
// evgl_engine_init(re, &evgl_funcs);
|
|
|
|
initted = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (re->generic.software.tb)
|
|
|
|
evas_render_engine_software_generic_tile_strict_set
|
|
|
|
(&re->generic.software, EINA_TRUE);
|
|
|
|
|
|
|
|
eng_window_use(eng_get_ob(re));
|
|
|
|
|
|
|
|
return re;
|
|
|
|
|
|
|
|
on_error:
|
|
|
|
if (ob) eng_window_free(ob);
|
|
|
|
free(re);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_update(void *data, void *in, unsigned int w, unsigned int h)
|
|
|
|
{
|
|
|
|
Evas_Engine_Info_GL_X11 *info = in;
|
|
|
|
Render_Engine *re = data;
|
|
|
|
Render_Engine_Swap_Mode swap_mode;
|
|
|
|
|
2016-12-08 15:04:11 -08:00
|
|
|
swap_mode = evas_render_engine_gl_swap_mode_get(info->swap_mode);
|
2016-12-02 15:30:02 -08:00
|
|
|
|
|
|
|
if (eng_get_ob(re) && _re_wincheck(eng_get_ob(re)))
|
|
|
|
{
|
|
|
|
if ((info->info.display != eng_get_ob(re)->disp) ||
|
|
|
|
(info->info.drawable != eng_get_ob(re)->win) ||
|
|
|
|
(info->info.screen != eng_get_ob(re)->screen) ||
|
|
|
|
(info->info.visual != eng_get_ob(re)->visual) ||
|
|
|
|
(info->info.colormap != eng_get_ob(re)->colormap) ||
|
|
|
|
(info->info.depth != eng_get_ob(re)->depth) ||
|
|
|
|
(info->depth_bits != eng_get_ob(re)->depth_bits) ||
|
|
|
|
(info->stencil_bits != eng_get_ob(re)->stencil_bits) ||
|
|
|
|
(info->msaa_bits != eng_get_ob(re)->msaa_bits) ||
|
|
|
|
(info->info.destination_alpha != eng_get_ob(re)->alpha))
|
2010-01-25 06:02:14 -08:00
|
|
|
{
|
2016-12-02 15:30:02 -08:00
|
|
|
Outbuf *ob, *ob_old;
|
2014-07-04 04:51:32 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
ob_old = re->generic.software.ob;
|
|
|
|
re->generic.software.ob = NULL;
|
|
|
|
gl_wins--;
|
|
|
|
|
|
|
|
ob = eng_window_new(info,
|
|
|
|
info->info.display,
|
|
|
|
info->info.drawable,
|
|
|
|
info->info.screen,
|
|
|
|
info->info.visual,
|
|
|
|
info->info.colormap,
|
|
|
|
info->info.depth,
|
|
|
|
w, h,
|
|
|
|
info->indirect,
|
|
|
|
info->info.destination_alpha,
|
|
|
|
info->info.rotation,
|
|
|
|
swap_mode,
|
|
|
|
info->depth_bits,
|
|
|
|
info->stencil_bits,
|
|
|
|
info->msaa_bits);
|
|
|
|
if (!ob)
|
2010-08-26 02:40:48 -07:00
|
|
|
{
|
2016-12-02 15:30:02 -08:00
|
|
|
if (ob_old) eng_window_free(ob_old);
|
|
|
|
return 0;
|
2010-07-28 01:11:30 -07:00
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2016-12-02 15:30:02 -08:00
|
|
|
eng_window_use(ob);
|
|
|
|
if (ob_old) eng_window_free(ob_old);
|
|
|
|
evas_render_engine_software_generic_update(&re->generic.software, ob,
|
|
|
|
w, h);
|
|
|
|
gl_wins++;
|
|
|
|
}
|
|
|
|
else if ((eng_get_ob(re)->w != w) ||
|
|
|
|
(eng_get_ob(re)->h != h) ||
|
|
|
|
(eng_get_ob(re)->info->info.rotation != eng_get_ob(re)->rot))
|
2010-05-17 21:22:33 -07:00
|
|
|
{
|
2016-12-02 15:30:02 -08:00
|
|
|
eng_outbuf_reconfigure(eng_get_ob(re), w, h, eng_get_ob(re)->info->info.rotation, 0);
|
|
|
|
if (re->generic.software.tb)
|
|
|
|
evas_common_tilebuf_free(re->generic.software.tb);
|
|
|
|
re->generic.software.tb = evas_common_tilebuf_new(w, h);
|
|
|
|
if (re->generic.software.tb)
|
|
|
|
evas_common_tilebuf_set_tile_size(re->generic.software.tb,
|
|
|
|
TILESIZE, TILESIZE);
|
2010-05-17 21:22:33 -07:00
|
|
|
}
|
2010-05-17 20:49:59 -07:00
|
|
|
}
|
2014-07-04 04:51:32 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
eng_window_use(eng_get_ob(re));
|
2012-06-27 01:19:25 -07:00
|
|
|
|
2009-03-24 02:05:32 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_output_free(void *data)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-05-17 20:49:59 -07:00
|
|
|
if (re)
|
|
|
|
{
|
2014-07-04 04:51:32 -07:00
|
|
|
#ifndef GL_GLES
|
2014-07-11 06:16:03 -07:00
|
|
|
Display *disp = eng_get_ob(re)->disp;
|
|
|
|
Window win = eng_get_ob(re)->win;
|
2014-07-04 04:51:32 -07:00
|
|
|
#endif
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
|
2013-06-23 19:41:32 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
#if 0
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
// Destroy the resource surface
|
|
|
|
// Only required for EGL case
|
|
|
|
if (re->surface)
|
2014-07-11 06:16:03 -07:00
|
|
|
eglDestroySurface(eng_get_ob(re)->egl_disp, re->surface);
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
// Destroy the resource context
|
|
|
|
_destroy_internal_context(re, context);
|
|
|
|
#endif
|
2013-07-30 03:45:40 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
if (gl_wins == 1) glsym_evgl_engine_shutdown(re);
|
2014-07-04 04:51:32 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
evas_render_engine_software_generic_clean(&re->generic.software);
|
2014-07-04 04:51:32 -07:00
|
|
|
|
|
|
|
#ifndef GL_GLES
|
|
|
|
if (glsym_glXReleaseBuffersMESA)
|
|
|
|
glsym_glXReleaseBuffersMESA(disp, win);
|
2013-04-09 17:40:37 -07:00
|
|
|
#endif
|
2014-07-04 04:51:32 -07:00
|
|
|
gl_wins--;
|
2013-05-02 03:06:10 -07:00
|
|
|
|
2010-05-17 20:49:59 -07:00
|
|
|
free(re);
|
|
|
|
}
|
2010-05-17 21:22:33 -07:00
|
|
|
if ((initted == 1) && (gl_wins == 0))
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_preload_shutdown();
|
2010-05-17 21:22:33 -07:00
|
|
|
initted = 0;
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2007-03-03 08:05:15 -08:00
|
|
|
/* vsync games - not for now though */
|
2010-01-29 09:14:50 -08:00
|
|
|
#define VSYNC_TO_SCREEN 1
|
2007-03-03 08:05:15 -08:00
|
|
|
|
2014-07-04 04:51:32 -07:00
|
|
|
Eina_Bool
|
2013-06-23 19:41:32 -07:00
|
|
|
eng_preload_make_current(void *data, void *doit)
|
|
|
|
{
|
2014-07-04 04:51:32 -07:00
|
|
|
Outbuf *ob = data;
|
2013-06-23 19:41:32 -07:00
|
|
|
|
|
|
|
if (doit)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
2015-11-06 00:50:22 -08:00
|
|
|
if (!evas_eglMakeCurrent(ob->egl_disp, ob->egl_surface[0], ob->egl_surface[0], ob->egl_context[0]))
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
#else
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(ob->info->info.display, ob->glxwin, ob->context))
|
2013-06-23 19:41:32 -07:00
|
|
|
{
|
2014-11-01 19:36:21 -07:00
|
|
|
ERR("glXMakeContextCurrent(%p, %p, %p) failed",
|
|
|
|
ob->info->info.display, (void *)ob->win, (void *)ob->context);
|
2015-02-11 04:45:50 -08:00
|
|
|
GLERRV("__glXMakeContextCurrent");
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
2015-11-06 00:50:22 -08:00
|
|
|
if (!evas_eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
#else
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(ob->info->info.display, 0, NULL))
|
2013-06-23 19:41:32 -07:00
|
|
|
{
|
2014-11-01 19:36:21 -07:00
|
|
|
ERR("glXMakeContextCurrent(%p, None, NULL) failed",
|
|
|
|
ob->info->info.display);
|
2015-02-11 04:45:50 -08:00
|
|
|
GLERRV("__glXMakeContextCurrent");
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
static Eina_Bool
|
2016-12-15 17:40:55 -08:00
|
|
|
eng_canvas_alpha_get(void *data)
|
2014-07-11 06:16:03 -07:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
return re->generic.software.ob->alpha;
|
|
|
|
}
|
|
|
|
|
2010-04-12 01:23:53 -07:00
|
|
|
static void
|
|
|
|
eng_output_dump(void *data)
|
|
|
|
{
|
2016-04-12 01:30:48 -07:00
|
|
|
Render_Engine *re = data;
|
2010-04-12 01:23:53 -07:00
|
|
|
|
2016-04-12 01:30:48 -07:00
|
|
|
eng_window_use(eng_get_ob(re));
|
2010-04-12 01:23:53 -07:00
|
|
|
evas_common_image_image_all_unload();
|
|
|
|
evas_common_font_font_all_unload();
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
|
2010-08-26 02:40:48 -07:00
|
|
|
_re_winfree(re);
|
2007-06-16 19:56:59 -07:00
|
|
|
}
|
|
|
|
|
2014-09-01 04:15:33 -07:00
|
|
|
static void *
|
|
|
|
eng_gl_current_context_get(void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
EVGL_Context *ctx;
|
2015-04-30 00:04:47 -07:00
|
|
|
EVGLNative_Context context;
|
2014-09-01 04:15:33 -07:00
|
|
|
|
2014-09-01 20:52:52 -07:00
|
|
|
ctx = glsym_evas_gl_common_current_context_get();
|
2014-09-01 04:15:33 -07:00
|
|
|
if (!ctx)
|
|
|
|
return NULL;
|
|
|
|
|
2015-04-30 00:04:47 -07:00
|
|
|
context = glsym_evgl_current_native_context_get(ctx);
|
|
|
|
|
2014-09-01 04:15:33 -07:00
|
|
|
#ifdef GL_GLES
|
2015-11-06 00:50:22 -08:00
|
|
|
if (evas_eglGetCurrentContext() == context)
|
2014-09-01 04:15:33 -07:00
|
|
|
return ctx;
|
|
|
|
#else
|
2015-04-30 00:04:47 -07:00
|
|
|
if (glXGetCurrentContext() == context)
|
2014-09-01 04:15:33 -07:00
|
|
|
return ctx;
|
|
|
|
#endif
|
2015-04-30 00:04:47 -07:00
|
|
|
|
|
|
|
return NULL;
|
2014-09-01 04:15:33 -07:00
|
|
|
}
|
|
|
|
|
2014-09-01 03:16:21 -07:00
|
|
|
static int
|
2014-09-01 20:52:52 -07:00
|
|
|
eng_gl_error_get(void *data)
|
2014-09-01 03:16:21 -07:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2014-09-01 20:52:52 -07:00
|
|
|
if ((err = glsym_evas_gl_common_error_get(data)) != EVAS_GL_SUCCESS)
|
2014-09-01 03:16:21 -07:00
|
|
|
goto end;
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
err = eglGetError() - EGL_SUCCESS;
|
|
|
|
#else
|
|
|
|
Render_Engine *re = data;
|
|
|
|
|
|
|
|
if (!eng_get_ob(re)->win)
|
|
|
|
err = EVAS_GL_BAD_DISPLAY;
|
|
|
|
else if (!eng_get_ob(re)->info)
|
|
|
|
err = EVAS_GL_BAD_SURFACE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
end:
|
2014-09-01 20:52:52 -07:00
|
|
|
glsym_evas_gl_common_error_set(data, EVAS_GL_SUCCESS);
|
2014-09-01 03:16:21 -07:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
//
|
2010-01-23 21:11:54 -08:00
|
|
|
// FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
|
|
|
|
// (i am sure this is the reason) not to mention seemingly superfluous. but
|
|
|
|
// i need to enable it for it to work on fglrx at least. havent tried nvidia.
|
2011-06-17 00:47:28 -07:00
|
|
|
//
|
2010-01-23 21:11:54 -08:00
|
|
|
// why is this the case? does anyone know? has anyone tried it on other gfx
|
|
|
|
// drivers?
|
2011-06-17 00:47:28 -07:00
|
|
|
//
|
2010-01-30 18:50:01 -08:00
|
|
|
//#define GLX_TEX_PIXMAP_RECREATE 1
|
2010-01-23 21:11:54 -08:00
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
static void
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_bind_cb(void *image)
|
2010-01-21 00:44:11 -08:00
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Native *n = im->native.data;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.x11.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
2016-08-17 01:50:18 -07:00
|
|
|
if (n->ns_data.x11.multiple_buffer)
|
|
|
|
{
|
|
|
|
EGLint err;
|
2016-10-14 14:03:47 -07:00
|
|
|
if (!glsym_eglDestroyImage ||
|
|
|
|
(!glsym_eglCreateImage && !glsym_eglCreateImageKHR))
|
2016-08-17 01:50:18 -07:00
|
|
|
{
|
|
|
|
ERR("Try eglDestroyImage()/eglCreateImage() on EGL with no support");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
glsym_eglDestroyImage(im->native.disp, n->ns_data.x11.surface);
|
|
|
|
if ((err = eglGetError()) != EGL_SUCCESS)
|
|
|
|
{
|
|
|
|
ERR("eglDestroyImage() failed.");
|
|
|
|
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2016-10-14 14:03:47 -07:00
|
|
|
n->ns_data.x11.surface = _eflCreateImage(im->native.disp,
|
|
|
|
EGL_NO_CONTEXT,
|
|
|
|
EGL_NATIVE_PIXMAP_KHR,
|
|
|
|
(void *)n->ns_data.x11.pixmap,
|
|
|
|
NULL);
|
2016-08-17 01:50:18 -07:00
|
|
|
if (!n->ns_data.x11.surface)
|
|
|
|
ERR("eglCreateImage() for Pixmap 0x%#lx failed: %#x", n->ns_data.x11.pixmap, eglGetError());
|
|
|
|
|
|
|
|
}
|
2015-10-04 23:28:53 -07:00
|
|
|
if (glsym_glEGLImageTargetTexture2DOES)
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
glsym_glEGLImageTargetTexture2DOES(im->native.target, n->ns_data.x11.surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
GLERRV("glsym_glEGLImageTargetTexture2DOES");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
2015-10-04 23:28:53 -07:00
|
|
|
|
|
|
|
if (glsym_glXBindTexImage)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_glXBindTexImage(im->native.disp, (XID)n->ns_data.x11.surface,
|
2015-10-04 23:28:53 -07:00
|
|
|
GLX_FRONT_LEFT_EXT, NULL);
|
|
|
|
GLERRV("glsym_glXBindTexImage");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXBindTexImage on GLX with no support");
|
2012-05-15 06:13:05 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
2015-11-11 20:56:17 -08:00
|
|
|
glBindTexture(im->native.target, n->ns.data.opengl.texture_id);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.tbm.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
|
|
|
if (glsym_glEGLImageTargetTexture2DOES)
|
2015-01-18 19:28:32 -08:00
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
glsym_glEGLImageTargetTexture2DOES(im->native.target, n->ns_data.tbm.surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
GLERRV("glsym_glEGLImageTargetTexture2DOES");
|
2015-01-18 19:28:32 -08:00
|
|
|
}
|
2015-10-04 23:28:53 -07:00
|
|
|
else
|
|
|
|
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
|
|
|
}
|
2015-03-09 01:25:20 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.evasgl.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
Eina_Bool is_egl_image = EINA_FALSE;
|
2016-02-17 00:48:26 -08:00
|
|
|
void *surface = NULL;
|
2016-01-04 23:41:14 -08:00
|
|
|
|
|
|
|
if (glsym_evgl_native_surface_buffer_get)
|
|
|
|
surface = glsym_evgl_native_surface_buffer_get(n->ns_data.evasgl.surface, &is_egl_image);
|
2015-10-04 23:28:53 -07:00
|
|
|
if (is_egl_image)
|
|
|
|
{
|
2015-04-29 06:56:52 -07:00
|
|
|
#ifdef GL_GLES
|
2015-10-04 23:28:53 -07:00
|
|
|
if (glsym_glEGLImageTargetTexture2DOES)
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
glsym_glEGLImageTargetTexture2DOES(im->native.target, surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
GLERRV("glsym_glEGLImageTargetTexture2DOES");
|
|
|
|
}
|
|
|
|
else
|
2015-04-29 06:56:52 -07:00
|
|
|
#endif
|
2015-10-04 23:28:53 -07:00
|
|
|
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr_t)surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
}
|
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
}
|
2015-11-04 11:10:06 -08:00
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.wl_surface.surface)
|
2015-11-04 11:10:06 -08:00
|
|
|
{
|
|
|
|
if (glsym_glEGLImageTargetTexture2DOES)
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->ns_data.wl_surface.surface);
|
2015-11-11 17:03:10 -08:00
|
|
|
GLERRV("glsym_glEGLImageTargetTexture2DOES");
|
2015-11-04 11:10:06 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
2010-01-21 00:44:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_unbind_cb(void *image)
|
2010-01-21 00:44:11 -08:00
|
|
|
{
|
2015-11-03 01:13:59 -08:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Native *n = im->native.data;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2015-11-03 01:13:59 -08:00
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2015-11-03 01:13:59 -08:00
|
|
|
// nothing
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
2015-11-03 01:13:59 -08:00
|
|
|
|
|
|
|
if (glsym_glXReleaseTexImage)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_glXReleaseTexImage(im->native.disp, (XID)(n->ns_data.x11.surface),
|
2015-11-03 01:13:59 -08:00
|
|
|
GLX_FRONT_LEFT_EXT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXReleaseTexImage on GLX with no support");
|
2012-05-15 06:13:05 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
2015-11-03 01:13:59 -08:00
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
2015-11-11 20:56:17 -08:00
|
|
|
glBindTexture(im->native.target, 0);
|
2015-11-03 01:13:59 -08:00
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
|
|
|
// nothing
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
2015-03-16 19:40:04 -07:00
|
|
|
#ifdef GL_GLES
|
2015-11-03 01:13:59 -08:00
|
|
|
// nothing
|
2015-03-16 19:40:04 -07:00
|
|
|
#else
|
2015-11-03 01:13:59 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2015-03-16 19:40:04 -07:00
|
|
|
#endif
|
2015-11-03 01:13:59 -08:00
|
|
|
}
|
2010-01-21 00:44:11 -08:00
|
|
|
}
|
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
static void
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_free_cb(void *image)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Native *n = im->native.data;
|
|
|
|
uint32_t pmid, texid;
|
2015-11-04 11:10:06 -08:00
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
|
|
|
void *wlid;
|
|
|
|
# endif
|
|
|
|
#endif
|
2010-12-05 23:09:51 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
pmid = n->ns_data.x11.pixmap;
|
2016-03-17 02:20:49 -07:00
|
|
|
eina_hash_del(im->native.shared->native_pm_hash, &pmid, im);
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.x11.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
if (glsym_eglDestroyImage)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_eglDestroyImage(im->native.disp,
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.x11.surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
if ((err = eglGetError()) != EGL_SUCCESS)
|
|
|
|
{
|
|
|
|
ERR("eglDestroyImage() failed.");
|
|
|
|
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2014-09-01 03:16:21 -07:00
|
|
|
ERR("Try eglDestroyImage on EGL with no support");
|
2015-10-04 23:28:53 -07:00
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.x11.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
|
|
|
if (im->native.loose)
|
|
|
|
{
|
|
|
|
if (glsym_glXReleaseTexImage)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_glXReleaseTexImage(im->native.disp, (XID)n->ns_data.x11.surface,
|
2015-10-04 23:28:53 -07:00
|
|
|
GLX_FRONT_LEFT_EXT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXReleaseTexImage on GLX with no support");
|
|
|
|
}
|
|
|
|
if (glsym_glXDestroyPixmap)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_glXDestroyPixmap(im->native.disp, (XID)n->ns_data.x11.surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
GLERRV("glsym_glXDestroyPixmap");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXDestroyPixmap on GLX with no support");
|
2016-01-05 01:46:21 -08:00
|
|
|
n->ns_data.x11.surface = 0;
|
2015-10-04 23:28:53 -07:00
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
texid = n->ns.data.opengl.texture_id;
|
2016-03-17 02:20:49 -07:00
|
|
|
eina_hash_del(im->native.shared->native_tex_hash, &texid, im);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
eina_hash_del(im->native.shared->native_tbm_hash, &n->ns_data.tbm.buffer, im);
|
2015-01-18 19:28:32 -08:00
|
|
|
#ifdef GL_GLES
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.tbm.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
if (glsym_eglDestroyImage)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_eglDestroyImage(im->native.disp,
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.tbm.surface);
|
2015-10-04 23:28:53 -07:00
|
|
|
if ((err = eglGetError()) != EGL_SUCCESS)
|
|
|
|
{
|
|
|
|
ERR("eglDestroyImage() failed.");
|
|
|
|
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2015-01-18 19:28:32 -08:00
|
|
|
ERR("Try eglDestroyImage on EGL with no support");
|
2015-10-04 23:28:53 -07:00
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
#endif
|
|
|
|
}
|
2015-03-09 01:25:20 -07:00
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
eina_hash_del(im->native.shared->native_evasgl_hash, &n->ns.data.evasgl.surface, im);
|
2015-03-09 01:25:20 -07:00
|
|
|
}
|
2015-11-04 11:10:06 -08:00
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
2016-01-04 23:41:14 -08:00
|
|
|
wlid = (void*)n->ns_data.wl_surface.wl_buf;
|
2016-03-17 02:20:49 -07:00
|
|
|
eina_hash_del(im->native.shared->native_wl_hash, &wlid, image);
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.wl_surface.surface)
|
2015-11-04 11:10:06 -08:00
|
|
|
{
|
|
|
|
if (glsym_eglDestroyImage)
|
|
|
|
{
|
2016-03-17 02:20:49 -07:00
|
|
|
glsym_eglDestroyImage(im->native.disp, n->ns_data.wl_surface.surface);
|
2015-11-04 11:10:06 -08:00
|
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
|
|
ERR("eglDestroyImage() failed.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try eglDestroyImage on EGL with no support");
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
im->native.data = NULL;
|
|
|
|
im->native.func.bind = NULL;
|
|
|
|
im->native.func.unbind = NULL;
|
|
|
|
im->native.func.free = NULL;
|
|
|
|
free(n);
|
2010-01-21 00:44:11 -08:00
|
|
|
}
|
|
|
|
|
2015-04-20 18:54:02 -07:00
|
|
|
static int
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_yinvert_cb(void *image)
|
2015-04-20 18:54:02 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Native *n = im->native.data;
|
|
|
|
int yinvert = 0, val;
|
|
|
|
|
|
|
|
// Yinvert callback should only be used for EVAS_NATIVE_SURFACE_EVASGL type now,
|
|
|
|
// as yinvert value is not changed for other types.
|
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
|
|
|
#if GL_GLES
|
|
|
|
if (extn_have_y_inverted &&
|
2016-03-17 02:20:49 -07:00
|
|
|
eglGetConfigAttrib(im->native.disp, n->ns_data.x11.config,
|
2015-04-20 18:54:02 -07:00
|
|
|
EGL_Y_INVERTED_NOK, &val))
|
|
|
|
yinvert = val;
|
|
|
|
#else
|
2016-03-17 02:20:49 -07:00
|
|
|
glXGetFBConfigAttrib(im->native.disp, n->ns_data.x11.config,
|
2015-04-20 18:54:02 -07:00
|
|
|
GLX_Y_INVERTED_EXT, &val);
|
2015-10-14 02:08:29 -07:00
|
|
|
if (val) yinvert = 1;
|
2015-04-20 18:54:02 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
yinvert = 0;
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
|
|
|
yinvert = 1;
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
2016-01-04 23:41:14 -08:00
|
|
|
yinvert = glsym_evgl_native_surface_yinvert_get(n->ns_data.evasgl.surface);
|
2015-04-20 18:54:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return yinvert;
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:18:34 -08:00
|
|
|
static int
|
|
|
|
eng_image_native_init(void *data EINA_UNUSED, Evas_Native_Surface_Type type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
case EVAS_NATIVE_SURFACE_TBM:
|
|
|
|
return _evas_native_tbm_init();
|
|
|
|
#endif
|
|
|
|
case EVAS_NATIVE_SURFACE_X11:
|
|
|
|
case EVAS_NATIVE_SURFACE_OPENGL:
|
|
|
|
case EVAS_NATIVE_SURFACE_EVASGL:
|
|
|
|
return 1;
|
|
|
|
#if defined(GL_GLES) && defined(HAVE_WAYLAND)
|
|
|
|
case EVAS_NATIVE_SURFACE_WL:
|
|
|
|
return (glsym_eglQueryWaylandBufferWL != NULL) ? 1 : 0;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
ERR("Native surface type %d not supported!", type);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_native_shutdown(void *data EINA_UNUSED, Evas_Native_Surface_Type type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
case EVAS_NATIVE_SURFACE_TBM:
|
|
|
|
_evas_native_tbm_shutdown();
|
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
case EVAS_NATIVE_SURFACE_X11:
|
|
|
|
case EVAS_NATIVE_SURFACE_OPENGL:
|
|
|
|
case EVAS_NATIVE_SURFACE_EVASGL:
|
|
|
|
#if defined(GL_GLES) && defined(HAVE_WAYLAND)
|
|
|
|
case EVAS_NATIVE_SURFACE_WL:
|
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
ERR("Native surface type %d not supported!", type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-02 23:09:53 -07:00
|
|
|
static void *
|
2010-01-21 00:44:11 -08:00
|
|
|
eng_image_native_set(void *data, void *image, void *native)
|
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
2016-08-07 23:15:54 -07:00
|
|
|
const Evas_Native_Surface *ns = native;
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_GL_Image *im = image, *im2 = NULL;
|
|
|
|
Visual *vis = NULL;
|
|
|
|
Pixmap pm = 0;
|
|
|
|
Native *n = NULL;
|
|
|
|
uint32_t pmid, texid;
|
|
|
|
unsigned int tex = 0;
|
|
|
|
unsigned int fbo = 0;
|
2015-01-18 19:28:32 -08:00
|
|
|
void *buffer = NULL;
|
2015-11-04 11:10:06 -08:00
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
|
|
|
void *wlid, *wl_buf = NULL;
|
|
|
|
# endif
|
|
|
|
#endif
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
if (!im)
|
|
|
|
{
|
2012-09-20 02:16:57 -07:00
|
|
|
if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
im = glsym_evas_gl_common_image_new_from_data(eng_get_ob(re)->gl_context,
|
2012-05-15 06:13:05 -07:00
|
|
|
ns->data.opengl.w,
|
|
|
|
ns->data.opengl.h,
|
|
|
|
NULL, 1,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
|
|
}
|
|
|
|
else
|
2012-09-20 02:16:57 -07:00
|
|
|
return NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
|
|
|
if (ns)
|
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
|
|
|
vis = ns->data.x11.visual;
|
|
|
|
pm = ns->data.x11.pixmap;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens = im->native.data;
|
|
|
|
if ((ens->data.x11.visual == vis) &&
|
|
|
|
(ens->data.x11.pixmap == pm))
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
tex = ns->data.opengl.texture_id;
|
|
|
|
fbo = ns->data.opengl.framebuffer_id;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens = im->native.data;
|
|
|
|
if ((ens->data.opengl.texture_id == tex) &&
|
|
|
|
(ens->data.opengl.framebuffer_id == fbo))
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
|
|
|
buffer = ns->data.tbm.buffer;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens = im->native.data;
|
|
|
|
if (ens->data.tbm.buffer == buffer)
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
|
|
|
buffer = ns->data.evasgl.surface;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens = im->native.data;
|
|
|
|
if (ens->data.evasgl.surface == buffer)
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
2015-11-04 11:10:06 -08:00
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
|
|
|
wl_buf = ns->data.wl.legacy_buffer;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens;
|
|
|
|
|
|
|
|
ens = im->native.data;
|
|
|
|
if (ens->data.wl.legacy_buffer == wl_buf)
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
}
|
|
|
|
if ((!ns) && (!im->native.data)) return im;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
eng_window_use(eng_get_ob(re));
|
2011-12-17 21:03:24 -08:00
|
|
|
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
if (im->native.func.free)
|
2016-03-30 23:55:15 -07:00
|
|
|
im->native.func.free(im);
|
2015-10-04 23:28:53 -07:00
|
|
|
glsym_evas_gl_common_image_native_disable(im);
|
2011-12-17 21:03:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!ns) return im;
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
pmid = pm;
|
|
|
|
im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_pm_hash, &pmid);
|
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
n = im2->native.data;
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
glsym_evas_gl_common_image_ref(im2);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
2011-12-17 21:03:24 -08:00
|
|
|
{
|
|
|
|
texid = tex;
|
2014-07-11 06:16:03 -07:00
|
|
|
im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_tex_hash, &texid);
|
2011-12-17 21:03:24 -08:00
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
n = im2->native.data;
|
|
|
|
if (n)
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_image_ref(im2);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
2011-12-17 21:03:24 -08:00
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
|
|
|
im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_tbm_hash, &buffer);
|
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
n = im2->native.data;
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
glsym_evas_gl_common_image_ref(im2);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
return im2;
|
|
|
|
}
|
2015-10-04 23:28:53 -07:00
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
}
|
2015-03-09 01:25:20 -07:00
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
|
|
|
im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer);
|
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
n = im2->native.data;
|
|
|
|
if (n)
|
2015-10-04 23:28:53 -07:00
|
|
|
{
|
|
|
|
glsym_evas_gl_common_image_ref(im2);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
}
|
2015-03-09 01:25:20 -07:00
|
|
|
}
|
2015-11-04 11:10:06 -08:00
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
|
|
|
wlid = wl_buf;
|
|
|
|
im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_wl_hash, &wlid);
|
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
if((n = im2->native.data))
|
|
|
|
{
|
|
|
|
glsym_evas_gl_common_image_ref(im2);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
2014-07-11 06:16:03 -07:00
|
|
|
im2 = glsym_evas_gl_common_image_new_from_data(eng_get_ob(re)->gl_context,
|
2015-10-04 23:28:53 -07:00
|
|
|
im->w, im->h, NULL, im->alpha,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_image_free(im);
|
2012-05-15 06:13:05 -07:00
|
|
|
im = im2;
|
2012-08-07 23:25:59 -07:00
|
|
|
if (!im) return NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2015-10-04 23:28:53 -07:00
|
|
|
if (native)
|
|
|
|
{
|
2016-10-14 14:03:47 -07:00
|
|
|
if (!glsym_eglCreateImage && !glsym_eglCreateImageKHR)
|
2016-08-02 19:29:14 -07:00
|
|
|
{
|
|
|
|
ERR("Try eglCreateImage on EGL with no support");
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-10-04 23:28:53 -07:00
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
EGLConfig egl_config;
|
|
|
|
int config_attrs[20];
|
|
|
|
int num_config, i = 0;
|
|
|
|
int yinvert = 1;
|
|
|
|
|
|
|
|
// assume 32bit pixmap! :)
|
|
|
|
config_attrs[i++] = EGL_RED_SIZE;
|
|
|
|
config_attrs[i++] = 8;
|
|
|
|
config_attrs[i++] = EGL_GREEN_SIZE;
|
|
|
|
config_attrs[i++] = 8;
|
|
|
|
config_attrs[i++] = EGL_BLUE_SIZE;
|
|
|
|
config_attrs[i++] = 8;
|
|
|
|
config_attrs[i++] = EGL_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = 8;
|
|
|
|
config_attrs[i++] = EGL_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = EGL_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = EGL_RENDERABLE_TYPE;
|
|
|
|
if (eng_get_ob(re)->gles3)
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
|
|
|
|
else
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
|
|
|
|
config_attrs[i++] = EGL_SURFACE_TYPE;
|
|
|
|
config_attrs[i++] = EGL_PIXMAP_BIT;
|
|
|
|
config_attrs[i++] = EGL_NONE;
|
|
|
|
|
|
|
|
if (!eglChooseConfig(eng_get_ob(re)->egl_disp, config_attrs,
|
|
|
|
&egl_config, 1, &num_config))
|
|
|
|
{
|
|
|
|
int err = eglGetError();
|
2016-08-02 19:29:14 -07:00
|
|
|
ERR("eglChooseConfig() failed for pixmap %#lx, "
|
|
|
|
"num_config = %i with error %d", pm, num_config, err);
|
2015-10-04 23:28:53 -07:00
|
|
|
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
2016-08-02 19:29:14 -07:00
|
|
|
free(n);
|
|
|
|
return NULL;
|
2015-10-04 23:28:53 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
if (extn_have_y_inverted &&
|
|
|
|
eglGetConfigAttrib(eng_get_ob(re)->egl_disp, egl_config,
|
|
|
|
EGL_Y_INVERTED_NOK, &val))
|
|
|
|
yinvert = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.x11.pixmap = pm;
|
|
|
|
n->ns_data.x11.visual = vis;
|
2016-10-14 14:03:47 -07:00
|
|
|
n->ns_data.x11.surface = _eflCreateImage(eng_get_ob(re)->egl_disp,
|
|
|
|
EGL_NO_CONTEXT,
|
|
|
|
EGL_NATIVE_PIXMAP_KHR,
|
|
|
|
(void *)pm, NULL);
|
2016-08-17 01:50:18 -07:00
|
|
|
|
|
|
|
if ((ns->version < 4) ||
|
|
|
|
((ns->version == 4) && !(ns->data.x11.multiple_buffer == 1)))
|
|
|
|
n->ns_data.x11.multiple_buffer = 0;
|
|
|
|
else
|
|
|
|
n->ns_data.x11.multiple_buffer = 1;
|
|
|
|
|
2016-01-04 23:41:14 -08:00
|
|
|
if (!n->ns_data.x11.surface)
|
2016-08-02 19:29:14 -07:00
|
|
|
{
|
|
|
|
ERR("eglCreateImage() for Pixmap %#lx failed: %#x", pm, eglGetError());
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.x11.config = (void *)egl_config;
|
2015-10-04 23:28:53 -07:00
|
|
|
im->native.yinvert = yinvert;
|
|
|
|
im->native.loose = 0;
|
2016-03-17 02:20:49 -07:00
|
|
|
im->native.disp = eng_get_ob(re)->egl_disp;
|
|
|
|
im->native.shared = eng_get_ob(re)->gl_context->shared;
|
2015-10-04 23:28:53 -07:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
2016-08-02 19:29:14 -07:00
|
|
|
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_pm_hash, &pmid, im);
|
2015-10-04 23:28:53 -07:00
|
|
|
glsym_evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
2012-08-07 23:25:59 -07:00
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
int dummy;
|
|
|
|
unsigned int w, h, depth = 32, border;
|
|
|
|
Window wdummy;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2012-08-07 23:25:59 -07:00
|
|
|
// fixme: round trip :(
|
2014-07-11 06:16:03 -07:00
|
|
|
XGetGeometry(eng_get_ob(re)->disp, pm, &wdummy, &dummy, &dummy,
|
2012-08-07 23:25:59 -07:00
|
|
|
&w, &h, &border, &depth);
|
|
|
|
if (depth <= 32)
|
|
|
|
{
|
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
2012-11-13 06:07:39 -08:00
|
|
|
int pixmap_att[20], i;
|
|
|
|
int config_attrs[40], num = 0;
|
|
|
|
int tex_format = 0, tex_target = 0, yinvert = 0, mipmap = 0;
|
2012-12-13 02:26:02 -08:00
|
|
|
unsigned int target = 0;
|
2012-11-13 06:07:39 -08:00
|
|
|
GLXFBConfig *configs;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2012-11-13 06:07:39 -08:00
|
|
|
i = 0;
|
|
|
|
config_attrs[i++] = GLX_BUFFER_SIZE;
|
|
|
|
config_attrs[i++] = depth;
|
|
|
|
if (depth == 32)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
}
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2012-11-13 06:07:39 -08:00
|
|
|
#ifndef GLX_VISUAL_ID
|
|
|
|
# define GLX_VISUAL_ID 0x800b
|
|
|
|
#endif
|
|
|
|
config_attrs[i++] = GLX_VISUAL_ID;
|
|
|
|
config_attrs[i++] = XVisualIDFromVisual(vis);
|
|
|
|
#ifndef GLX_SAMPLE_BUFFERS
|
|
|
|
# define GLX_SAMPLE_BUFFERS 0x186a0
|
|
|
|
#endif
|
|
|
|
config_attrs[i++] = GLX_SAMPLE_BUFFERS;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = GLX_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = GLX_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = GLX_AUX_BUFFERS;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = GLX_STEREO;
|
|
|
|
config_attrs[i++] = 0;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2012-11-13 06:07:39 -08:00
|
|
|
config_attrs[i++] = 0;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
configs = glXChooseFBConfig(eng_get_ob(re)->disp,
|
|
|
|
eng_get_ob(re)->screen,
|
2012-11-13 06:07:39 -08:00
|
|
|
config_attrs,
|
|
|
|
&num);
|
|
|
|
if (configs)
|
|
|
|
{
|
2013-04-18 04:29:55 -07:00
|
|
|
int j = 0, val = 0, found = 0;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2013-04-18 04:29:55 -07:00
|
|
|
try_again:
|
2013-04-18 01:16:41 -07:00
|
|
|
for (j = 0; j < num; j++)
|
2012-11-13 06:07:39 -08:00
|
|
|
{
|
2013-04-18 04:29:55 -07:00
|
|
|
if (found == 0)
|
|
|
|
{
|
2013-11-08 17:40:17 -08:00
|
|
|
XVisualInfo *vi;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
vi = glXGetVisualFromFBConfig(eng_get_ob(re)->disp, configs[j]);
|
2013-11-08 17:40:17 -08:00
|
|
|
if (!vi) continue;
|
2013-11-08 17:42:49 -08:00
|
|
|
if (vi->depth != (int)depth) continue;
|
2013-11-08 17:40:17 -08:00
|
|
|
XFree(vi);
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 04:29:55 -07:00
|
|
|
GLX_BUFFER_SIZE, &val);
|
2013-04-18 04:42:06 -07:00
|
|
|
if (val != (int) depth) continue;
|
2013-04-18 04:29:55 -07:00
|
|
|
}
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_DRAWABLE_TYPE, &val);
|
|
|
|
if (!(val & GLX_PIXMAP_BIT)) continue;
|
|
|
|
tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_ALPHA_SIZE, &val);
|
|
|
|
if ((depth == 32) && (!val)) continue;
|
|
|
|
if (val > 0)
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
|
|
|
|
if (val) tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
|
|
|
|
if (val) tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
|
|
|
}
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_Y_INVERTED_EXT, &val);
|
2015-10-14 02:08:29 -07:00
|
|
|
if (val) yinvert = 1;
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_BIND_TO_TEXTURE_TARGETS_EXT,
|
|
|
|
&val);
|
|
|
|
tex_target = val;
|
2014-07-11 06:16:03 -07:00
|
|
|
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
|
|
|
|
mipmap = val;
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.x11.config = configs[j];
|
2013-04-18 04:29:55 -07:00
|
|
|
found = 1;
|
2013-04-18 01:16:41 -07:00
|
|
|
break;
|
2012-11-13 06:07:39 -08:00
|
|
|
}
|
2013-04-18 04:29:55 -07:00
|
|
|
if (found == 0)
|
|
|
|
{
|
|
|
|
found = -1;
|
|
|
|
goto try_again;
|
|
|
|
}
|
2012-11-13 06:07:39 -08:00
|
|
|
XFree(configs);
|
|
|
|
}
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_pm_hash, &pmid, im);
|
2012-11-13 06:07:39 -08:00
|
|
|
if ((tex_target & GLX_TEXTURE_2D_BIT_EXT))
|
2012-08-07 23:25:59 -07:00
|
|
|
target = GLX_TEXTURE_2D_EXT;
|
2014-02-13 02:35:17 -08:00
|
|
|
else if ((tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
|
2012-08-07 23:25:59 -07:00
|
|
|
{
|
|
|
|
ERR("rect!!! (not handled)");
|
|
|
|
target = GLX_TEXTURE_RECTANGLE_EXT;
|
|
|
|
}
|
|
|
|
if (!target)
|
|
|
|
{
|
|
|
|
ERR("broken tex-from-pixmap");
|
2012-11-13 06:07:39 -08:00
|
|
|
if (!(tex_target & GLX_TEXTURE_2D_BIT_EXT))
|
2012-08-07 23:25:59 -07:00
|
|
|
target = GLX_TEXTURE_RECTANGLE_EXT;
|
2012-11-13 06:07:39 -08:00
|
|
|
else if (!(tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
|
2012-08-07 23:25:59 -07:00
|
|
|
target = GLX_TEXTURE_2D_EXT;
|
|
|
|
}
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2012-11-13 06:07:39 -08:00
|
|
|
i = 0;
|
2012-08-07 23:25:59 -07:00
|
|
|
pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
|
2012-11-13 06:07:39 -08:00
|
|
|
pixmap_att[i++] = tex_format;
|
2012-08-07 23:25:59 -07:00
|
|
|
pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
|
2012-11-13 06:07:39 -08:00
|
|
|
pixmap_att[i++] = mipmap;
|
2012-08-07 23:25:59 -07:00
|
|
|
if (target)
|
|
|
|
{
|
|
|
|
pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
|
|
|
|
pixmap_att[i++] = target;
|
|
|
|
}
|
|
|
|
pixmap_att[i++] = 0;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2012-08-07 23:25:59 -07:00
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
2016-01-05 01:46:21 -08:00
|
|
|
n->ns_data.x11.pixmap = pm;
|
|
|
|
n->ns_data.x11.visual = vis;
|
2012-08-07 23:25:59 -07:00
|
|
|
if (glsym_glXCreatePixmap)
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.x11.surface = (void *)glsym_glXCreatePixmap(eng_get_ob(re)->disp,
|
2016-01-05 01:46:21 -08:00
|
|
|
n->ns_data.x11.config,
|
|
|
|
n->ns_data.x11.pixmap,
|
2015-04-20 18:54:02 -07:00
|
|
|
pixmap_att);
|
2012-08-07 23:25:59 -07:00
|
|
|
else
|
|
|
|
ERR("Try glXCreatePixmap on GLX with no support");
|
2016-01-04 23:41:14 -08:00
|
|
|
if (n->ns_data.x11.surface)
|
2012-08-07 23:25:59 -07:00
|
|
|
{
|
2012-11-12 06:45:07 -08:00
|
|
|
// printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
|
2015-04-20 18:54:02 -07:00
|
|
|
// n, pm, w, h, depth, n->surface);
|
2012-08-07 23:25:59 -07:00
|
|
|
if (!target)
|
|
|
|
{
|
|
|
|
ERR("no target :(");
|
|
|
|
if (glsym_glXQueryDrawable)
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_glXQueryDrawable(eng_get_ob(re)->disp,
|
2016-01-05 01:46:21 -08:00
|
|
|
n->ns_data.x11.pixmap,
|
2012-08-07 23:25:59 -07:00
|
|
|
GLX_TEXTURE_TARGET_EXT,
|
|
|
|
&target);
|
|
|
|
}
|
|
|
|
if (target == GLX_TEXTURE_2D_EXT)
|
|
|
|
{
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
2012-11-13 06:07:39 -08:00
|
|
|
im->native.mipmap = mipmap;
|
2012-08-07 23:25:59 -07:00
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
# ifdef GL_TEXTURE_RECTANGLE_ARB
|
2012-08-07 23:25:59 -07:00
|
|
|
else if (target == GLX_TEXTURE_RECTANGLE_EXT)
|
|
|
|
{
|
|
|
|
im->native.target = GL_TEXTURE_RECTANGLE_ARB;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
# endif
|
2012-08-07 23:25:59 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
ERR("still unknown target");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("GLX Pixmap create fail");
|
2012-11-13 06:07:39 -08:00
|
|
|
im->native.yinvert = yinvert;
|
2014-07-11 06:16:03 -07:00
|
|
|
im->native.loose = eng_get_ob(re)->detected.loose_binding;
|
2016-03-17 02:20:49 -07:00
|
|
|
im->native.disp = eng_get_ob(re)->disp;
|
|
|
|
im->native.shared = eng_get_ob(re)->gl_context->shared;
|
2012-08-07 23:25:59 -07:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
2015-11-03 01:13:59 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_image_native_enable(im);
|
2012-08-07 23:25:59 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
2011-12-17 21:03:24 -08:00
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
|
|
|
|
|
|
|
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_tex_hash, &texid, im);
|
2012-05-15 05:03:01 -07:00
|
|
|
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.opengl.surface = 0;
|
2015-10-04 23:28:53 -07:00
|
|
|
|
|
|
|
im->native.yinvert = 0;
|
|
|
|
im->native.loose = 0;
|
2016-03-17 02:20:49 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
im->native.disp = eng_get_ob(re)->egl_disp;
|
|
|
|
#else
|
|
|
|
im->native.disp = eng_get_ob(re)->disp;
|
|
|
|
#endif
|
|
|
|
im->native.shared = eng_get_ob(re)->gl_context->shared;
|
2015-10-04 23:28:53 -07:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
|
|
|
|
// FIXME: need to implement mapping sub texture regions
|
|
|
|
// x, y, w, h for possible texture atlasing
|
|
|
|
|
|
|
|
glsym_evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
if (native)
|
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_tbm_hash, &buffer, im);
|
|
|
|
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.tbm.buffer = buffer;
|
2016-10-14 14:03:47 -07:00
|
|
|
if (glsym_eglCreateImage || glsym_eglCreateImageKHR)
|
|
|
|
n->ns_data.tbm.surface = _eflCreateImage(eng_get_ob(re)->egl_disp,
|
|
|
|
EGL_NO_CONTEXT,
|
|
|
|
EGL_NATIVE_SURFACE_TIZEN,
|
|
|
|
(void *)buffer,
|
|
|
|
NULL);
|
2015-10-04 23:28:53 -07:00
|
|
|
else
|
|
|
|
ERR("Try eglCreateImage on EGL with no support");
|
2016-01-04 23:41:14 -08:00
|
|
|
if (!n->ns_data.tbm.surface)
|
2015-10-04 23:28:53 -07:00
|
|
|
ERR("eglCreateImage() for %p failed", buffer);
|
|
|
|
im->native.yinvert = 1;
|
|
|
|
im->native.loose = 0;
|
2016-03-17 02:20:49 -07:00
|
|
|
im->native.disp = eng_get_ob(re)->egl_disp;
|
|
|
|
im->native.shared = eng_get_ob(re)->gl_context->shared;
|
2015-10-04 23:28:53 -07:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_EXTERNAL_OES;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
glsym_evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
2015-01-18 19:28:32 -08:00
|
|
|
}
|
|
|
|
#endif
|
2015-03-09 01:25:20 -07:00
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
|
|
|
|
{
|
2015-10-04 23:28:53 -07:00
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
|
|
|
|
|
|
|
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer, im);
|
|
|
|
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.evasgl.surface = ns->data.evasgl.surface;
|
2015-03-09 01:25:20 -07:00
|
|
|
|
2015-10-04 23:28:53 -07:00
|
|
|
im->native.yinvert = 0;
|
|
|
|
im->native.loose = 0;
|
2016-03-17 02:20:49 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
im->native.disp = eng_get_ob(re)->egl_disp;
|
|
|
|
#else
|
|
|
|
im->native.disp = eng_get_ob(re)->disp;
|
|
|
|
#endif
|
|
|
|
im->native.shared = eng_get_ob(re)->gl_context->shared;
|
2015-10-04 23:28:53 -07:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.func.yinvert = _native_yinvert_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
|
|
|
|
// FIXME: need to implement mapping sub texture regions
|
|
|
|
// x, y, w, h for possible texture atlasing
|
|
|
|
|
|
|
|
glsym_evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-11-04 11:10:06 -08:00
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifdef HAVE_WAYLAND
|
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
if ((n = calloc(1, sizeof(Native))))
|
|
|
|
{
|
2016-10-18 21:39:02 -07:00
|
|
|
EGLAttribKHR attribs[3];
|
2015-11-04 11:10:06 -08:00
|
|
|
int format, yinvert = 1;
|
|
|
|
|
|
|
|
glsym_eglQueryWaylandBufferWL(eng_get_ob(re)->egl_disp, wl_buf,
|
|
|
|
EGL_TEXTURE_FORMAT, &format);
|
|
|
|
if ((format != EGL_TEXTURE_RGB) &&
|
|
|
|
(format != EGL_TEXTURE_RGBA))
|
|
|
|
{
|
|
|
|
ERR("eglQueryWaylandBufferWL() %d format is not supported ", format);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-11-14 18:20:04 -08:00
|
|
|
# ifndef EGL_WAYLAND_PLANE_WL
|
|
|
|
# define EGL_WAYLAND_PLANE_WL 0x31D6
|
|
|
|
# endif
|
|
|
|
# ifndef EGL_WAYLAND_BUFFER_WL
|
|
|
|
# define EGL_WAYLAND_BUFFER_WL 0x31D5
|
|
|
|
# endif
|
2015-11-04 11:10:06 -08:00
|
|
|
attribs[0] = EGL_WAYLAND_PLANE_WL;
|
|
|
|
attribs[1] = 0; //if plane is 1 then 0, if plane is 2 then 1
|
|
|
|
attribs[2] = EGL_NONE;
|
|
|
|
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
|
|
|
if (glsym_eglQueryWaylandBufferWL(eng_get_ob(re)->egl_disp, wl_buf,
|
|
|
|
EGL_WAYLAND_Y_INVERTED_WL,
|
|
|
|
&yinvert) == EGL_FALSE)
|
|
|
|
yinvert = 1;
|
|
|
|
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_wl_hash,
|
|
|
|
&wlid, im);
|
|
|
|
|
2016-01-04 23:41:14 -08:00
|
|
|
n->ns_data.wl_surface.wl_buf = wl_buf;
|
2016-10-14 14:03:47 -07:00
|
|
|
if (glsym_eglCreateImage || glsym_eglCreateImageKHR)
|
|
|
|
n->ns_data.wl_surface.surface = _eflCreateImage(eng_get_ob(re)->egl_disp,
|
|
|
|
NULL,
|
|
|
|
EGL_WAYLAND_BUFFER_WL,
|
|
|
|
wl_buf, attribs);
|
2015-11-04 11:10:06 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("Try eglCreateImage on EGL with no support");
|
|
|
|
eina_hash_del(eng_get_ob(re)->gl_context->shared->native_wl_hash,
|
|
|
|
&wlid, im);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-01-04 23:41:14 -08:00
|
|
|
if (!n->ns_data.wl_surface.surface)
|
2015-11-04 11:10:06 -08:00
|
|
|
{
|
|
|
|
ERR("eglCreatePixmapSurface() for %p failed", wl_buf);
|
|
|
|
eina_hash_del(eng_get_ob(re)->gl_context->shared->native_wl_hash,
|
|
|
|
&wlid, im);
|
|
|
|
glsym_evas_gl_common_image_free(im);
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//XXX: workaround for mesa-10.2.8
|
|
|
|
// mesa's eglQueryWaylandBufferWL() with EGL_WAYLAND_Y_INVERTED_WL works incorrect.
|
|
|
|
//im->native.yinvert = yinvert;
|
|
|
|
im->native.yinvert = 1;
|
|
|
|
im->native.loose = 0;
|
2016-03-17 02:20:49 -07:00
|
|
|
im->native.disp = eng_get_ob(re)->egl_disp;
|
|
|
|
im->native.shared = eng_get_ob(re)->gl_context->shared;
|
2015-11-04 11:10:06 -08:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
|
|
|
|
glsym_evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
2010-08-02 23:09:53 -07:00
|
|
|
return im;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
static int
|
|
|
|
module_open(Evas_Module *em)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
static Eina_Bool xrm_inited = EINA_FALSE;
|
2015-03-19 01:52:53 -07:00
|
|
|
const char *platform_env = NULL;
|
2014-07-11 06:16:03 -07:00
|
|
|
if (!xrm_inited)
|
2011-08-29 13:56:48 -07:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
xrm_inited = EINA_TRUE;
|
|
|
|
XrmInitialize();
|
2011-08-29 13:56:48 -07:00
|
|
|
}
|
2014-07-11 06:16:03 -07:00
|
|
|
if (!em) return 0;
|
|
|
|
/* get whatever engine module we inherit from */
|
|
|
|
if (!_evas_module_engine_inherit(&pfunc, "gl_generic")) return 0;
|
|
|
|
if (_evas_engine_GL_X11_log_dom < 0)
|
|
|
|
_evas_engine_GL_X11_log_dom = eina_log_domain_register
|
|
|
|
("evas-gl_x11", EVAS_DEFAULT_LOG_COLOR);
|
|
|
|
if (_evas_engine_GL_X11_log_dom < 0)
|
2003-09-04 00:40:34 -07:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
EINA_LOG_ERR("Can not create a module log domain.");
|
|
|
|
return 0;
|
2003-09-04 00:40:34 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
if (partial_render_debug == -1)
|
2010-01-21 01:42:26 -08:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1;
|
|
|
|
else partial_render_debug = 0;
|
2010-01-21 01:42:26 -08:00
|
|
|
}
|
2015-09-24 22:38:21 -07:00
|
|
|
// partial_render_debug = 1;
|
2011-08-16 00:06:36 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
/* store it for later use */
|
|
|
|
func = pfunc;
|
|
|
|
/* now to override methods */
|
|
|
|
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
|
|
|
|
ORD(info);
|
|
|
|
ORD(info_free);
|
|
|
|
ORD(setup);
|
2016-12-02 15:30:02 -08:00
|
|
|
ORD(update);
|
2014-07-11 06:16:03 -07:00
|
|
|
ORD(canvas_alpha_get);
|
|
|
|
ORD(output_free);
|
|
|
|
ORD(output_dump);
|
2011-08-16 00:06:36 -07:00
|
|
|
|
2016-03-08 23:18:34 -08:00
|
|
|
ORD(image_native_init);
|
|
|
|
ORD(image_native_shutdown);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(image_native_set);
|
2013-12-26 23:56:30 -08:00
|
|
|
|
2014-09-01 03:16:21 -07:00
|
|
|
ORD(gl_error_get);
|
|
|
|
// gl_current_surface_get is in gl generic
|
|
|
|
ORD(gl_current_context_get);
|
|
|
|
|
2015-03-19 01:52:53 -07:00
|
|
|
if (!(platform_env = getenv("EGL_PLATFORM")))
|
|
|
|
setenv("EGL_PLATFORM", "x11", 0);
|
|
|
|
|
2014-07-25 11:05:37 -07:00
|
|
|
gl_symbols();
|
|
|
|
|
2015-03-19 01:52:53 -07:00
|
|
|
if (!platform_env)
|
|
|
|
unsetenv("EGL_PLATFORM");
|
|
|
|
|
2006-12-09 00:52:08 -08:00
|
|
|
/* now advertise out own api */
|
|
|
|
em->functions = (void *)(&func);
|
2006-01-14 04:13:38 -08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
module_close(Evas_Module *em EINA_UNUSED)
|
2006-01-14 04:13:38 -08:00
|
|
|
{
|
2016-11-11 16:32:59 -08:00
|
|
|
if (_evas_engine_GL_X11_log_dom >= 0)
|
|
|
|
{
|
|
|
|
eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
|
|
|
|
_evas_engine_GL_X11_log_dom = -1;
|
|
|
|
}
|
2006-01-14 04:13:38 -08:00
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static Evas_Module_Api evas_modapi =
|
2006-01-14 04:13:38 -08:00
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
EVAS_MODULE_API_VERSION,
|
|
|
|
"gl_x11",
|
|
|
|
"none",
|
|
|
|
{
|
|
|
|
module_open,
|
|
|
|
module_close
|
|
|
|
}
|
2006-01-14 04:13:38 -08:00
|
|
|
};
|
2009-06-16 06:01:36 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
|
2009-06-16 06:01:36 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
#ifndef EVAS_STATIC_BUILD_GL_XLIB
|
|
|
|
EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
|
2009-06-16 06:01:36 -07:00
|
|
|
#endif
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
|