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"
|
2012-09-24 00:41:27 -07:00
|
|
|
#include "evas_gl_core_private.h"
|
2009-10-09 05:10:27 -07:00
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
//#define TIMDBG 1
|
|
|
|
#ifdef TIMDBG
|
|
|
|
# include <sys/time.h>
|
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
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
|
|
|
|
|
2013-04-10 02:39:56 -07:00
|
|
|
enum {
|
|
|
|
MERGE_BOUNDING,
|
|
|
|
MERGE_FULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static int partial_render_debug = -1;
|
|
|
|
static int partial_rect_union_mode = -1;
|
2013-07-22 02:52:32 -07:00
|
|
|
static int swap_buffer_debug_mode = -1;
|
|
|
|
static int swap_buffer_debug = 0;
|
2013-04-10 02:39:56 -07:00
|
|
|
|
2012-09-25 20:49:33 -07:00
|
|
|
enum {
|
|
|
|
MODE_FULL,
|
|
|
|
MODE_COPY,
|
|
|
|
MODE_DOUBLE,
|
2014-02-08 06:04:04 -08:00
|
|
|
MODE_TRIPLE,
|
|
|
|
MODE_QUADRUPLE
|
2012-09-25 20:49:33 -07:00
|
|
|
};
|
|
|
|
|
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
|
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
Tilebuf_Rect *rects;
|
2014-02-08 06:04:04 -08:00
|
|
|
Tilebuf_Rect *rects_prev[4];
|
2013-07-08 18:42:01 -07:00
|
|
|
Eina_Inlist *cur_rect;
|
2012-09-25 20:49:33 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_GL_X11_Window *win;
|
|
|
|
Evas_Engine_Info_GL_X11 *info;
|
|
|
|
Evas *evas;
|
2013-07-08 18:42:01 -07:00
|
|
|
Tilebuf *tb;
|
2012-05-15 06:13:05 -07:00
|
|
|
int end;
|
2012-09-25 20:49:33 -07:00
|
|
|
int mode;
|
|
|
|
int w, h;
|
|
|
|
int vsync;
|
2012-09-27 19:30:09 -07:00
|
|
|
int lost_back;
|
2013-03-21 19:34:38 -07:00
|
|
|
int prev_age;
|
2013-07-22 02:52:32 -07:00
|
|
|
int frame_cnt;
|
2013-05-20 02:09:50 -07:00
|
|
|
Eina_Bool evgl_initted : 1;
|
2013-06-17 01:53:33 -07:00
|
|
|
|
|
|
|
struct {
|
|
|
|
Evas_Object_Image_Pixels_Get_Cb get_pixels;
|
|
|
|
void *get_pixels_data;
|
|
|
|
Evas_Object *obj;
|
|
|
|
} func;
|
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
|
|
|
};
|
|
|
|
|
2010-08-02 23:09:53 -07:00
|
|
|
static int initted = 0;
|
|
|
|
static int gl_wins = 0;
|
2013-04-09 16:36:33 -07:00
|
|
|
static int extn_have_buffer_age = 1;
|
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
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
static Eina_Bool eng_preload_make_current(void *data, void *doit);
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2010-01-28 21:32:51 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
#ifndef EGL_NATIVE_PIXMAP_KHR
|
|
|
|
# define EGL_NATIVE_PIXMAP_KHR 0x30b0
|
|
|
|
#endif
|
2013-03-11 04:40:56 -07:00
|
|
|
#ifndef EGL_BUFFER_AGE_EXT
|
2013-04-09 16:36:33 -07:00
|
|
|
# define EGL_BUFFER_AGE_EXT 0x313d
|
2013-03-11 04:40:56 -07:00
|
|
|
#endif
|
2013-11-28 01:18:16 -08:00
|
|
|
#ifndef EGL_Y_INVERTED_NOK
|
|
|
|
# define EGL_Y_INVERTED_NOK 0x307F
|
|
|
|
#endif
|
2013-04-09 16:36:33 -07:00
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
_eng_fn (*glsym_eglGetProcAddress) (const char *a) = NULL;
|
|
|
|
void *(*glsym_eglCreateImage) (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e) = NULL;
|
|
|
|
void (*glsym_eglDestroyImage) (EGLDisplay a, void *b) = NULL;
|
|
|
|
void (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
|
2013-04-12 01:34:13 -07:00
|
|
|
void *(*glsym_eglMapImageSEC) (void *a, void *b, int c, int d) = NULL;
|
|
|
|
unsigned int (*glsym_eglUnmapImageSEC) (void *a, void *b, int c) = NULL;
|
2013-06-14 04:30:17 -07:00
|
|
|
unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = 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
|
|
|
|
|
|
|
#ifndef GLX_BACK_BUFFER_AGE_EXT
|
|
|
|
# define GLX_BACK_BUFFER_AGE_EXT 0x20f4
|
|
|
|
#endif
|
|
|
|
|
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;
|
|
|
|
void (*glsym_glXQueryDrawable) (Display *a, XID b, int c, unsigned int *d) = NULL;
|
|
|
|
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
|
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
#ifdef TIMDBG
|
|
|
|
static double
|
|
|
|
gettime(void)
|
|
|
|
{
|
|
|
|
struct timeval timev;
|
|
|
|
|
|
|
|
gettimeofday(&timev, NULL);
|
|
|
|
return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
measure(int end, const char *name)
|
|
|
|
{
|
|
|
|
FILE *fs;
|
|
|
|
static unsigned long user = 0, kern = 0, user2 = 0, kern2 = 0;
|
|
|
|
static double t = 0.0, t2 = 0.0;
|
|
|
|
unsigned long u = 0, k = 0;
|
|
|
|
|
|
|
|
fs = fopen("/proc/self/stat", "rb");
|
|
|
|
if (fs) {
|
|
|
|
fscanf(fs, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s "
|
|
|
|
"%lu %lu %*s", &u, &k);
|
|
|
|
fclose(fs);
|
|
|
|
}
|
|
|
|
if (end)
|
|
|
|
{
|
|
|
|
long hz;
|
|
|
|
|
|
|
|
t2 = gettime();
|
|
|
|
user2 = u;
|
|
|
|
kern2 = k;
|
|
|
|
hz = sysconf(_SC_CLK_TCK);
|
|
|
|
fprintf(stderr, "(%8lu %8lu) k=%4lu u=%4lu == tot=%4lu@%4li in=%3.5f < %s\n",
|
|
|
|
user, kern, kern2 - kern, user2 - user,
|
|
|
|
(kern2 - kern) + (user2 - user), hz, t2 - t, name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
user = u;
|
|
|
|
kern = k;
|
|
|
|
t = gettime();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
static int evgl_init(Render_Engine *re);
|
|
|
|
|
|
|
|
#define EVGLINIT(_re, _ret) if (!evgl_init(_re)) return _ret
|
|
|
|
|
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
|
|
|
|
2013-05-20 02:09:50 -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
|
2012-09-24 00:41:27 -07:00
|
|
|
if (re->win)
|
|
|
|
return (void*)re->win->egl_disp;
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2012-09-24 00:41:27 -07:00
|
|
|
if (re->info)
|
|
|
|
return (void*)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
|
|
|
|
2013-05-20 02:09:50 -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
|
2012-09-24 00:41:27 -07:00
|
|
|
if (re->win)
|
|
|
|
return (void*)re->win->egl_surface[0];
|
|
|
|
#else
|
|
|
|
if (re->win)
|
|
|
|
return (void*)re->win->win;
|
|
|
|
#endif
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
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
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(re, 0);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
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;
|
|
|
|
EGLDisplay dpy = re->win->egl_disp; //eglGetCurrentDisplay();
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
if ((!context) && (!surface))
|
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ret = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2013-04-09 17:40:37 -07:00
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if ((eglGetCurrentContext() != ctx) ||
|
|
|
|
(eglGetCurrentSurface(EGL_READ) != sfc) ||
|
|
|
|
(eglGetCurrentSurface(EGL_DRAW) != sfc) )
|
|
|
|
{
|
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
|
|
|
|
ret = eglMakeCurrent(dpy, sfc, sfc, ctx);
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
|
|
|
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
|
|
|
{
|
2013-05-02 03:06:10 -07:00
|
|
|
ret = glXMakeCurrent(re->info->info.display, None, NULL);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
ERR("glXMakeCurrent() failed!");
|
|
|
|
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
|
|
|
|
ret = glXMakeCurrent(re->info->info.display, sfc, ctx);
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
ERR("glXMakeCurrent() failed. Ret: %d! Context: %p Surface: %p", ret, (void*)ctx, (void*)sfc);
|
|
|
|
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
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(re, NULL);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
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;
|
|
|
|
attr.event_mask = 0;
|
|
|
|
|
|
|
|
win = XCreateWindow(re->info->info.display,
|
|
|
|
DefaultRootWindow(re->info->info.display),
|
|
|
|
0, 0, 2, 2, 0,
|
|
|
|
CopyFromParent, InputOutput, CopyFromParent,
|
|
|
|
CWBackingStore | CWOverrideRedirect |
|
|
|
|
CWBorderPixel | CWBackPixmap |
|
|
|
|
CWSaveUnder | CWDontPropagate |
|
|
|
|
CWEventMask | CWBitGravity |
|
|
|
|
CWWinGravity, &attr);
|
|
|
|
if (!win)
|
|
|
|
{
|
|
|
|
ERR("Creating native X window failed.");
|
|
|
|
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
|
|
|
|
2013-05-20 02:09:50 -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!");
|
|
|
|
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.");
|
|
|
|
return 0;
|
2012-06-27 01:19:25 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
XDestroyWindow(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
|
|
|
|
// is supported. But, until then...
|
|
|
|
static void *
|
|
|
|
evgl_eng_window_surface_create(void *data, void *native_window)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(re, NULL);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
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
|
|
|
|
surface = eglCreateWindowSurface(re->win->egl_disp,
|
|
|
|
re->win->egl_config,
|
|
|
|
(EGLNativeWindowType)native_window,
|
|
|
|
NULL);
|
|
|
|
if (!surface)
|
|
|
|
{
|
|
|
|
ERR("Creating window surface failed. Error: %#x.", eglGetError());
|
|
|
|
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
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
surface = re->win->win;
|
2010-01-21 00:44:11 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
return (void *)surface;
|
|
|
|
*/
|
|
|
|
return (void*)native_window;
|
|
|
|
#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;
|
|
|
|
|
2013-05-20 02:09:50 -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!");
|
|
|
|
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.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
eglDestroySurface(re->win->egl_disp, (EGLSurface)surface);
|
|
|
|
#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 *
|
|
|
|
evgl_eng_context_create(void *data, void *share_ctx)
|
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;
|
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(re, NULL);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
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-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
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
|
|
|
|
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;
|
|
|
|
context_attrs[1] = 2;
|
|
|
|
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
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
context = eglCreateContext(re->win->egl_disp,
|
|
|
|
re->win->egl_config,
|
|
|
|
(EGLContext)share_ctx,
|
|
|
|
context_attrs);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
else
|
2012-05-02 19:33:18 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
context = eglCreateContext(re->win->egl_disp,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->win->egl_config,
|
|
|
|
re->win->egl_context[0], // Evas' GL Context
|
|
|
|
context_attrs);
|
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!context)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Engine Context Creations Failed. Error: %#x.", eglGetError());
|
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)
|
|
|
|
{
|
|
|
|
context = glXCreateContext(re->info->info.display,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->win->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
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
context = glXCreateContext(re->info->info.display,
|
|
|
|
re->win->visualinfo,
|
|
|
|
re->win->context, // Evas' GL Context
|
|
|
|
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.");
|
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;
|
|
|
|
|
2013-05-20 02:09:50 -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);
|
|
|
|
return 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
eglDestroyContext(re->win->egl_disp, (EGLContext)context);
|
|
|
|
#else
|
|
|
|
glXDestroyContext(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
|
|
|
|
2013-05-20 02:09:50 -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!");
|
|
|
|
return NULL;
|
2012-06-27 01:19:25 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#ifdef GL_GLES
|
2013-06-03 23:35:15 -07:00
|
|
|
return eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
|
2012-09-24 00:41:27 -07:00
|
|
|
#else
|
|
|
|
return glXQueryExtensionsString(re->info->info.display,
|
|
|
|
re->info->info.screen);
|
|
|
|
#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;
|
|
|
|
|
2013-05-20 02:09:50 -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!");
|
|
|
|
return 0;
|
2012-08-01 18:15:38 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if ((re->win) && (re->win->gl_context))
|
|
|
|
return re->win->gl_context->rot;
|
|
|
|
else
|
2012-08-01 18:15:38 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("Unable to retrieve rotation angle.");
|
2012-08-01 18:15:38 -07:00
|
|
|
return 0;
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static EVGL_Interface evgl_funcs =
|
|
|
|
{
|
|
|
|
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,
|
|
|
|
evgl_eng_rotation_angle_get
|
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------//
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
#define FINDSYM(dst, sym, typ) \
|
2013-03-08 02:35:36 -08:00
|
|
|
if (glsym_eglGetProcAddress) { \
|
|
|
|
if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
|
|
|
|
} else { \
|
|
|
|
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
|
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);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
|
2012-09-24 00:41:27 -07:00
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
|
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
|
|
|
|
|
|
|
|
FINDSYM(glsym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr);
|
|
|
|
FINDSYM(glsym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint);
|
|
|
|
|
2013-06-14 04:30:17 -07:00
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL", glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", glsym_func_uint);
|
2013-03-11 23:26:32 -07:00
|
|
|
|
|
|
|
|
2012-08-01 18:15:38 -07:00
|
|
|
#else
|
2012-09-24 00:41:27 -07:00
|
|
|
#define FINDSYM(dst, sym, typ) \
|
2013-03-08 02:35:36 -08:00
|
|
|
if (glsym_glXGetProcAddress) { \
|
|
|
|
if (!dst) dst = (typ)glsym_glXGetProcAddress(sym); \
|
|
|
|
} else { \
|
|
|
|
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
|
|
|
|
|
|
|
|
FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
|
|
|
|
|
|
|
|
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
|
|
|
|
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void);
|
|
|
|
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void);
|
2013-03-13 03:37:04 -07:00
|
|
|
FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", glsym_func_void);
|
2012-09-24 00:41:27 -07:00
|
|
|
|
|
|
|
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
|
|
|
|
FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
|
|
|
|
|
|
|
|
FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
|
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
FINDSYM(glsym_glXReleaseBuffersMESA, "glXReleaseBuffersMESA", glsym_func_void);
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
#endif
|
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
|
2013-06-03 23:35:15 -07:00
|
|
|
str = eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
|
2013-03-11 23:26:32 -07:00
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
printf("EGL EXTN:\n%s\n", str);
|
2013-04-09 16:36:33 -07:00
|
|
|
if (!strstr(str, "EGL_EXT_buffer_age"))
|
|
|
|
{
|
|
|
|
extn_have_buffer_age = 0;
|
|
|
|
}
|
2014-01-06 20:13:01 -08:00
|
|
|
if (!strstr(str, "EGL_NOK_texture_from_pixmap"))
|
2013-11-28 01:18:16 -08: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;
|
|
|
|
}
|
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
|
2013-06-03 23:35:15 -07:00
|
|
|
str = glXQueryExtensionsString(re->info->info.display,
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
if (!strstr(str, "_video_sync"))
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_re_wincheck(Render_Engine *re)
|
|
|
|
{
|
|
|
|
if (re->win->surf) return 1;
|
|
|
|
eng_window_resurf(re->win);
|
2012-09-27 19:30:09 -07:00
|
|
|
re->lost_back = 1;
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!re->win->surf)
|
2012-08-01 18:15:38 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
ERR("GL engine can't re-create window surface!");
|
2012-08-01 18:15:38 -07:00
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_re_winfree(Render_Engine *re)
|
|
|
|
{
|
|
|
|
if (!re->win->surf) return;
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_gl_preload_render_relax(eng_preload_make_current, re);
|
2012-09-24 00:41:27 -07:00
|
|
|
eng_window_unsurf(re->win);
|
2012-08-01 18:15:38 -07:00
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
static int
|
|
|
|
evgl_init(Render_Engine *re)
|
|
|
|
{
|
|
|
|
if (re->evgl_initted) return 1;
|
|
|
|
if (!evgl_engine_init(re, &evgl_funcs)) return 0;
|
|
|
|
re->evgl_initted = EINA_TRUE;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-03-24 02:05:32 -07:00
|
|
|
static int
|
2012-10-08 18:58:41 -07:00
|
|
|
eng_setup(Evas *eo_e, void *in)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2013-05-02 00:47:16 -07:00
|
|
|
Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
|
2002-11-08 00:02:15 -08:00
|
|
|
Render_Engine *re;
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_Engine_Info_GL_X11 *info;
|
2012-09-25 20:49:33 -07:00
|
|
|
const char *s;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
info = (Evas_Engine_Info_GL_X11 *)in;
|
2002-11-08 00:02:15 -08:00
|
|
|
if (!e->engine.data.output)
|
2006-12-09 00:52:08 -08:00
|
|
|
{
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
int eb, evb;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
|
|
|
|
#endif
|
2011-11-10 00:59:09 -08:00
|
|
|
re = calloc(1, sizeof(Render_Engine));
|
|
|
|
if (!re) return 0;
|
2010-01-24 03:01:20 -08:00
|
|
|
re->info = info;
|
2012-10-16 04:45:35 -07:00
|
|
|
re->evas = (Evas *)e;
|
2010-08-26 02:40:48 -07:00
|
|
|
re->w = e->output.w;
|
|
|
|
re->h = e->output.h;
|
2011-11-10 00:59:09 -08:00
|
|
|
re->win = eng_window_new(re->info->info.display,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->info->info.drawable,
|
2010-08-26 02:40:48 -07:00
|
|
|
re->info->info.screen,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->info->info.visual,
|
|
|
|
re->info->info.colormap,
|
2011-11-10 00:59:09 -08:00
|
|
|
re->info->info.depth,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->w,
|
|
|
|
re->h,
|
|
|
|
re->info->indirect,
|
2010-08-26 02:40:48 -07:00
|
|
|
re->info->info.destination_alpha,
|
|
|
|
re->info->info.rotation);
|
2011-11-10 00:59:09 -08:00
|
|
|
if (!re->win)
|
|
|
|
{
|
|
|
|
free(re);
|
|
|
|
return 0;
|
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-08-21 04:37:02 -07:00
|
|
|
e->engine.data.output = re;
|
2010-05-17 21:22:33 -07:00
|
|
|
gl_wins++;
|
2012-09-24 00:41:27 -07:00
|
|
|
|
2010-05-17 21:22:33 -07:00
|
|
|
if (!initted)
|
|
|
|
{
|
2012-11-21 23:58:06 -08:00
|
|
|
gl_symbols();
|
|
|
|
|
2010-05-17 21:22:33 -07:00
|
|
|
evas_common_cpu_init();
|
|
|
|
evas_common_blend_init();
|
|
|
|
evas_common_image_init();
|
|
|
|
evas_common_convert_init();
|
|
|
|
evas_common_scale_init();
|
|
|
|
evas_common_rectangle_init();
|
|
|
|
evas_common_polygon_init();
|
|
|
|
evas_common_line_init();
|
|
|
|
evas_common_font_init();
|
|
|
|
evas_common_draw_init();
|
|
|
|
evas_common_tilebuf_init();
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_gl_preload_init();
|
2013-03-11 23:26:32 -07:00
|
|
|
gl_extn_veto(re);
|
2013-05-20 02:09:50 -07:00
|
|
|
// evgl_engine_init(re, &evgl_funcs);
|
2010-05-17 21:22:33 -07:00
|
|
|
initted = 1;
|
|
|
|
}
|
2006-12-09 00:52:08 -08:00
|
|
|
}
|
2006-03-08 00:02:34 -08:00
|
|
|
else
|
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
re = e->engine.data.output;
|
2010-08-26 02:40:48 -07:00
|
|
|
if (_re_wincheck(re))
|
2010-01-25 06:02:14 -08:00
|
|
|
{
|
2010-08-26 02:40:48 -07:00
|
|
|
if ((re->info->info.display != re->win->disp) ||
|
2012-05-15 06:13:05 -07:00
|
|
|
(re->info->info.drawable != re->win->win) ||
|
2010-08-26 02:40:48 -07:00
|
|
|
(re->info->info.screen != re->win->screen) ||
|
2012-05-15 06:13:05 -07:00
|
|
|
(re->info->info.visual != re->win->visual) ||
|
|
|
|
(re->info->info.colormap != re->win->colormap) ||
|
2010-08-26 02:40:48 -07:00
|
|
|
(re->info->info.depth != re->win->depth) ||
|
2013-12-26 02:19:15 -08:00
|
|
|
(re->info->info.destination_alpha != re->win->alpha))
|
2010-07-28 01:11:30 -07:00
|
|
|
{
|
2010-08-26 02:40:48 -07:00
|
|
|
int inc = 0;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 02:40:48 -07:00
|
|
|
if (re->win)
|
|
|
|
{
|
|
|
|
re->win->gl_context->references++;
|
|
|
|
eng_window_free(re->win);
|
|
|
|
inc = 1;
|
|
|
|
gl_wins--;
|
|
|
|
}
|
|
|
|
re->w = e->output.w;
|
|
|
|
re->h = e->output.h;
|
|
|
|
re->win = eng_window_new(re->info->info.display,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->info->info.drawable,
|
2010-08-26 02:40:48 -07:00
|
|
|
re->info->info.screen,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->info->info.visual,
|
|
|
|
re->info->info.colormap,
|
2010-08-26 02:40:48 -07:00
|
|
|
re->info->info.depth,
|
2012-05-15 06:13:05 -07:00
|
|
|
re->w,
|
|
|
|
re->h,
|
2010-08-26 02:40:48 -07:00
|
|
|
re->info->indirect,
|
|
|
|
re->info->info.destination_alpha,
|
|
|
|
re->info->info.rotation);
|
2011-04-06 03:11:01 -07:00
|
|
|
eng_window_use(re->win);
|
2010-08-26 02:40:48 -07:00
|
|
|
if (re->win) gl_wins++;
|
|
|
|
if ((re->win) && (inc))
|
|
|
|
re->win->gl_context->references--;
|
|
|
|
}
|
|
|
|
else if ((re->win->w != e->output.w) ||
|
2013-12-26 02:19:15 -08:00
|
|
|
(re->win->h != e->output.h) ||
|
|
|
|
(re->info->info.rotation != re->win->rot))
|
2010-08-26 02:40:48 -07:00
|
|
|
{
|
|
|
|
re->w = e->output.w;
|
|
|
|
re->h = e->output.h;
|
|
|
|
re->win->w = e->output.w;
|
|
|
|
re->win->h = e->output.h;
|
2013-12-26 02:19:15 -08:00
|
|
|
re->win->rot = re->info->info.rotation;
|
2010-08-26 02:40:48 -07:00
|
|
|
eng_window_use(re->win);
|
2012-05-15 06:13:05 -07:00
|
|
|
evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
|
2010-07-28 01:11:30 -07:00
|
|
|
}
|
2010-01-25 06:02:14 -08:00
|
|
|
}
|
2006-03-08 00:02:34 -08:00
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
if ((s = getenv("EVAS_GL_SWAP_MODE")))
|
|
|
|
{
|
|
|
|
if ((!strcasecmp(s, "full")) ||
|
|
|
|
(!strcasecmp(s, "f")))
|
|
|
|
re->mode = MODE_FULL;
|
|
|
|
else if ((!strcasecmp(s, "copy")) ||
|
|
|
|
(!strcasecmp(s, "c")))
|
|
|
|
re->mode = MODE_COPY;
|
|
|
|
else if ((!strcasecmp(s, "double")) ||
|
|
|
|
(!strcasecmp(s, "d")) ||
|
|
|
|
(!strcasecmp(s, "2")))
|
|
|
|
re->mode = MODE_DOUBLE;
|
|
|
|
else if ((!strcasecmp(s, "triple")) ||
|
|
|
|
(!strcasecmp(s, "t")) ||
|
|
|
|
(!strcasecmp(s, "3")))
|
|
|
|
re->mode = MODE_TRIPLE;
|
2014-02-08 06:04:04 -08:00
|
|
|
else if ((!strcasecmp(s, "quadruple")) ||
|
|
|
|
(!strcasecmp(s, "q")) ||
|
|
|
|
(!strcasecmp(s, "4")))
|
|
|
|
re->mode = MODE_QUADRUPLE;
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// in most gl implementations - egl and glx here that we care about the TEND
|
|
|
|
// to either swap or copy backbuffer and front buffer, but strictly that is
|
|
|
|
// not true. technically backbuffer content is totally undefined after a swap
|
|
|
|
// and thus you MUST re-render all of it, thus MODE_FULL
|
2012-09-26 06:23:29 -07:00
|
|
|
re->mode = MODE_FULL;
|
2012-09-25 20:49:33 -07:00
|
|
|
// BUT... reality is that lmost every implementation copies or swaps so
|
|
|
|
// triple buffer mode can be used as it is a superset of double buffer and
|
|
|
|
// copy (though using those explicitly is more efficient). so let's play with
|
|
|
|
// triple buffer mdoe as a default and see.
|
2012-09-26 06:23:29 -07:00
|
|
|
// re->mode = MODE_TRIPLE;
|
2012-09-26 23:56:41 -07:00
|
|
|
// XXX: note - the above seems to break on some older intel chipsets and
|
2012-09-26 06:23:29 -07:00
|
|
|
// drivers. it seems we CANT depend on backbuffer staying around. bugger!
|
2012-09-26 23:56:41 -07:00
|
|
|
switch (info->swap_mode)
|
|
|
|
{
|
|
|
|
case EVAS_ENGINE_GL_X11_SWAP_MODE_FULL:
|
|
|
|
re->mode = MODE_FULL;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_X11_SWAP_MODE_COPY:
|
|
|
|
re->mode = MODE_COPY;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE:
|
|
|
|
re->mode = MODE_DOUBLE;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE:
|
|
|
|
re->mode = MODE_TRIPLE;
|
|
|
|
break;
|
2014-02-08 06:04:04 -08:00
|
|
|
case EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE:
|
|
|
|
re->mode = MODE_QUADRUPLE;
|
|
|
|
break;
|
2012-09-26 23:56:41 -07:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
2010-05-17 20:49:59 -07:00
|
|
|
if (!re->win)
|
|
|
|
{
|
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-05-17 20:49:59 -07:00
|
|
|
if (!e->engine.data.output)
|
|
|
|
{
|
2010-05-17 21:22:33 -07:00
|
|
|
if (re->win)
|
|
|
|
{
|
|
|
|
eng_window_free(re->win);
|
|
|
|
gl_wins--;
|
|
|
|
}
|
2010-05-17 20:49:59 -07:00
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
2013-08-28 22:58:09 -07:00
|
|
|
if (re->tb) evas_common_tilebuf_free(re->tb);
|
2013-07-08 18:42:01 -07:00
|
|
|
re->tb = evas_common_tilebuf_new(re->win->w, re->win->h);
|
|
|
|
if (!re->tb)
|
2011-10-21 01:58:00 -07:00
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
if (re->win)
|
2011-10-21 01:58:00 -07:00
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
eng_window_free(re->win);
|
|
|
|
gl_wins--;
|
2011-10-21 01:58:00 -07:00
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
free(re);
|
|
|
|
return 0;
|
2011-10-21 01:58:00 -07:00
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE);
|
|
|
|
evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE);
|
2011-11-10 00:59:09 -08:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
if (!e->engine.data.context)
|
2012-05-15 06:13:05 -07:00
|
|
|
e->engine.data.context =
|
|
|
|
e->engine.func->context_new(e->engine.data.output);
|
2009-10-13 02:40:39 -07:00
|
|
|
eng_window_use(re->win);
|
2011-04-04 03:23:12 -07:00
|
|
|
|
2010-10-25 00:22:43 -07:00
|
|
|
re->vsync = 0;
|
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)
|
|
|
|
{
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_gl_preload_render_relax(eng_preload_make_current, re);
|
|
|
|
|
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)
|
|
|
|
eglDestroySurface(re->win->egl_disp, re->surface);
|
|
|
|
#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
|
2010-05-17 21:22:33 -07:00
|
|
|
if (re->win)
|
|
|
|
{
|
2013-07-30 03:45:40 -07:00
|
|
|
if (gl_wins == 1) evgl_engine_shutdown(re);
|
|
|
|
|
2013-04-09 17:40:37 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
eng_window_free(re->win);
|
|
|
|
#else
|
|
|
|
Display *disp = re->win->disp;
|
|
|
|
Window win = re->win->win;
|
2010-05-17 21:22:33 -07:00
|
|
|
eng_window_free(re->win);
|
2013-04-09 17:40:37 -07:00
|
|
|
if (glsym_glXReleaseBuffersMESA)
|
|
|
|
glsym_glXReleaseBuffersMESA(disp, win);
|
|
|
|
#endif
|
2010-05-17 21:22:33 -07:00
|
|
|
gl_wins--;
|
|
|
|
}
|
2013-04-09 17:40:37 -07:00
|
|
|
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_free(re->tb);
|
|
|
|
if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
|
|
|
|
if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
|
|
|
|
if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
|
|
|
|
if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
|
2014-02-08 06:04:04 -08:00
|
|
|
if (re->rects_prev[3]) evas_common_tilebuf_free_render_rects(re->rects_prev[3]);
|
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))
|
|
|
|
{
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_gl_preload_shutdown();
|
2010-05-17 21:22:33 -07:00
|
|
|
evas_common_image_shutdown();
|
|
|
|
evas_common_font_shutdown();
|
|
|
|
initted = 0;
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_output_resize(void *data, int w, int h)
|
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;
|
2003-09-04 00:40:34 -07:00
|
|
|
re->win->w = w;
|
|
|
|
re->win->h = h;
|
2009-10-13 02:40:39 -07:00
|
|
|
eng_window_use(re->win);
|
2010-05-08 22:15:20 -07:00
|
|
|
evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot);
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_free(re->tb);
|
|
|
|
re->tb = evas_common_tilebuf_new(w, h);
|
|
|
|
if (re->tb)
|
2013-04-11 05:23:07 -07:00
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE);
|
|
|
|
evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE);
|
2013-04-11 05:23:07 -07:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-10-21 01:58:00 -07:00
|
|
|
eng_output_tile_size_set(void *data, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-10-21 01:58:00 -07:00
|
|
|
Render_Engine *re;
|
2011-11-10 00:59:09 -08:00
|
|
|
|
2011-10-21 01:58:00 -07:00
|
|
|
re = (Render_Engine *)data;
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_set_tile_size(re->tb, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
|
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-08-24 23:30:52 -07:00
|
|
|
eng_window_use(re->win);
|
2010-05-08 22:15:20 -07:00
|
|
|
evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-12-05 16:44:25 -08:00
|
|
|
eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-10-21 01:58:00 -07:00
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_output_redraws_clear(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;
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_clear(re->tb);
|
2011-12-17 21:03:24 -08:00
|
|
|
// INF("GL: finish update cycle!");
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2013-07-08 18:42:01 -07:00
|
|
|
static Tilebuf_Rect *
|
2014-02-08 06:04:04 -08:00
|
|
|
_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4)
|
2012-09-25 20:49:33 -07:00
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
Tilebuf_Rect *r, *rects;
|
|
|
|
Evas_Point p1, p2;
|
2012-11-19 05:10:07 -08:00
|
|
|
|
2013-07-08 18:42:01 -07:00
|
|
|
if (r1)
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
|
|
|
|
{
|
|
|
|
evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r2)
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
|
|
|
|
{
|
|
|
|
evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r3)
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
|
|
|
|
{
|
|
|
|
evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
|
|
|
|
}
|
|
|
|
}
|
2014-02-08 06:04:04 -08:00
|
|
|
if (r4)
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(r4), r)
|
|
|
|
{
|
|
|
|
evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
|
|
|
|
}
|
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
rects = evas_common_tilebuf_get_render_rects(tb);
|
|
|
|
|
2013-04-10 02:39:56 -07:00
|
|
|
if (partial_rect_union_mode == -1)
|
|
|
|
{
|
|
|
|
const char *s = getenv("EVAS_GL_PARTIAL_MERGE");
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
if ((!strcmp(s, "bounding")) ||
|
|
|
|
(!strcmp(s, "b")))
|
|
|
|
partial_rect_union_mode = MERGE_BOUNDING;
|
|
|
|
else if ((!strcmp(s, "full")) ||
|
|
|
|
(!strcmp(s, "f")))
|
|
|
|
partial_rect_union_mode = MERGE_FULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
partial_rect_union_mode = MERGE_BOUNDING;
|
|
|
|
}
|
|
|
|
if (partial_rect_union_mode == MERGE_BOUNDING)
|
|
|
|
{
|
2012-09-25 20:49:33 -07:00
|
|
|
// bounding box -> make a bounding box single region update of all regions.
|
|
|
|
// yes we could try and be smart and figure out size of regions, how far
|
|
|
|
// apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
|
|
|
|
// between multiple update regions to render and total pixels to render.
|
2013-07-08 18:42:01 -07:00
|
|
|
if (rects)
|
2012-09-25 20:49:33 -07:00
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
p1.x = rects->x; p1.y = rects->y;
|
|
|
|
p2.x = rects->x + rects->w; p2.y = rects->y + rects->h;
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
|
2013-04-10 02:39:56 -07:00
|
|
|
{
|
|
|
|
if (r->x < p1.x) p1.x = r->x;
|
|
|
|
if (r->y < p1.y) p1.y = r->y;
|
|
|
|
if ((r->x + r->w) > p2.x) p2.x = r->x + r->w;
|
|
|
|
if ((r->y + r->h) > p2.y) p2.y = r->y + r->h;
|
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_free_render_rects(rects);
|
|
|
|
rects = calloc(1, sizeof(Tilebuf_Rect));
|
|
|
|
if (rects)
|
|
|
|
{
|
|
|
|
rects->x = p1.x;
|
|
|
|
rects->y = p1.y;
|
|
|
|
rects->w = p2.x - p1.x;
|
|
|
|
rects->h = p2.y - p1.y;
|
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_clear(tb);
|
|
|
|
return rects;
|
2012-09-25 20:49:33 -07: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
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
static Eina_Bool
|
|
|
|
eng_preload_make_current(void *data, void *doit)
|
|
|
|
{
|
|
|
|
Render_Engine *re = data;
|
|
|
|
|
|
|
|
if (doit)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
if (!eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]))
|
|
|
|
return EINA_FALSE;
|
|
|
|
#else
|
|
|
|
if (!glXMakeCurrent(re->info->info.display, re->win->win, re->win->context))
|
|
|
|
{
|
|
|
|
ERR("glXMakeCurrent(%p, 0x%x, %p) failed", re->info->info.display, (unsigned int)re->win->win, (void *)re->win->context);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
if (!eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
|
|
|
|
return EINA_FALSE;
|
|
|
|
#else
|
|
|
|
if (!glXMakeCurrent(re->info->info.display, None, NULL))
|
|
|
|
{
|
|
|
|
ERR("glXMakeCurrent(%p, None, NULL) failed", re->info->info.display);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
static void *
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2013-07-08 18:42:01 -07:00
|
|
|
Tilebuf_Rect *rect;
|
2012-09-25 20:49:33 -07:00
|
|
|
Eina_Bool first_rect = EINA_FALSE;
|
|
|
|
|
2013-07-08 18:42:01 -07:00
|
|
|
#define CLEAR_PREV_RECTS(x) \
|
|
|
|
do { \
|
|
|
|
if (re->rects_prev[x]) \
|
|
|
|
evas_common_tilebuf_free_render_rects(re->rects_prev[x]); \
|
|
|
|
re->rects_prev[x] = NULL; \
|
|
|
|
} while (0)
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2003-09-04 00:40:34 -07:00
|
|
|
/* get the upate rect surface - return engine data as dummy */
|
2012-09-25 20:49:33 -07:00
|
|
|
if (re->end)
|
2011-10-21 01:58:00 -07:00
|
|
|
{
|
2012-09-25 20:49:33 -07:00
|
|
|
re->end = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!re->rects)
|
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
re->rects = evas_common_tilebuf_get_render_rects(re->tb);
|
2012-09-25 20:49:33 -07:00
|
|
|
if (re->rects)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2013-04-09 16:36:33 -07:00
|
|
|
if (re->info->swap_mode == EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO)
|
2013-03-11 04:40:56 -07:00
|
|
|
{
|
2013-04-10 17:21:42 -07:00
|
|
|
if (extn_have_buffer_age)
|
|
|
|
{
|
2013-04-09 16:36:33 -07:00
|
|
|
#ifdef GL_GLES
|
2013-04-10 17:21:42 -07:00
|
|
|
EGLint age = 0;
|
2013-04-09 16:36:33 -07:00
|
|
|
|
2013-04-10 17:21:42 -07:00
|
|
|
if (!eglQuerySurface(re->win->egl_disp,
|
|
|
|
re->win->egl_surface[0],
|
|
|
|
EGL_BUFFER_AGE_EXT, &age))
|
|
|
|
age = 0;
|
2013-04-09 16:36:33 -07:00
|
|
|
#else
|
2013-04-10 17:21:42 -07:00
|
|
|
unsigned int age = 0;
|
2013-04-09 16:36:33 -07:00
|
|
|
|
2013-04-10 17:21:42 -07:00
|
|
|
if (glsym_glXQueryDrawable)
|
|
|
|
{
|
|
|
|
if (re->win->glxwin)
|
|
|
|
glsym_glXQueryDrawable(re->win->disp,
|
|
|
|
re->win->glxwin,
|
|
|
|
GLX_BACK_BUFFER_AGE_EXT,
|
|
|
|
&age);
|
|
|
|
else
|
|
|
|
glsym_glXQueryDrawable(re->win->disp,
|
|
|
|
re->win->win,
|
|
|
|
GLX_BACK_BUFFER_AGE_EXT,
|
|
|
|
&age);
|
|
|
|
}
|
2013-04-09 16:36:33 -07:00
|
|
|
#endif
|
|
|
|
if (age == 1) re->mode = MODE_COPY;
|
|
|
|
else if (age == 2) re->mode = MODE_DOUBLE;
|
|
|
|
else if (age == 3) re->mode = MODE_TRIPLE;
|
2014-02-08 06:04:04 -08:00
|
|
|
else if (age == 4) re->mode = MODE_QUADRUPLE;
|
2013-04-09 16:36:33 -07:00
|
|
|
else re->mode = MODE_FULL;
|
2013-04-09 17:40:37 -07:00
|
|
|
if ((int)age != re->prev_age) re->mode = MODE_FULL;
|
2013-04-09 16:36:33 -07:00
|
|
|
re->prev_age = age;
|
|
|
|
}
|
2013-03-11 04:40:56 -07:00
|
|
|
}
|
2013-05-29 05:37:13 -07:00
|
|
|
if ((re->lost_back) || (re->mode == MODE_FULL))
|
2012-09-27 19:30:09 -07:00
|
|
|
{
|
|
|
|
/* if we lost our backbuffer since the last frame redraw all */
|
|
|
|
re->lost_back = 0;
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->win->w, re->win->h);
|
|
|
|
evas_common_tilebuf_free_render_rects(re->rects);
|
|
|
|
re->rects = evas_common_tilebuf_get_render_rects(re->tb);
|
2012-09-27 19:30:09 -07:00
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
/* ensure we get rid of previous rect lists we dont need if mode
|
|
|
|
* changed/is appropriate */
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_clear(re->tb);
|
2014-02-08 06:04:04 -08:00
|
|
|
CLEAR_PREV_RECTS(3);
|
|
|
|
re->rects_prev[3] = re->rects_prev[2];
|
2013-07-08 18:42:01 -07:00
|
|
|
re->rects_prev[2] = re->rects_prev[1];
|
|
|
|
re->rects_prev[1] = re->rects_prev[0];
|
|
|
|
re->rects_prev[0] = re->rects;
|
|
|
|
re->rects = NULL;
|
2012-09-25 20:49:33 -07:00
|
|
|
switch (re->mode)
|
|
|
|
{
|
|
|
|
case MODE_FULL:
|
|
|
|
case MODE_COPY: // no prev rects needed
|
2014-02-08 06:04:04 -08:00
|
|
|
re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL, NULL);
|
2013-07-08 18:42:01 -07:00
|
|
|
break;
|
2012-09-25 20:49:33 -07:00
|
|
|
case MODE_DOUBLE: // double mode - only 1 level of prev rect
|
2014-02-08 06:04:04 -08:00
|
|
|
re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL);
|
|
|
|
break;
|
|
|
|
case MODE_TRIPLE: // triple mode - 2 levels of prev rect
|
|
|
|
re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL);
|
2013-07-08 18:42:01 -07:00
|
|
|
break;
|
2014-02-08 06:04:04 -08:00
|
|
|
case MODE_QUADRUPLE: // keep all
|
|
|
|
re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]);
|
2013-07-08 18:42:01 -07:00
|
|
|
break;
|
2012-09-25 20:49:33 -07:00
|
|
|
default:
|
2013-07-08 18:42:01 -07:00
|
|
|
break;
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
|
|
|
first_rect = EINA_TRUE;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_clear(re->tb);
|
|
|
|
re->cur_rect = EINA_INLIST_GET(re->rects);
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
if (!re->cur_rect) return NULL;
|
|
|
|
rect = (Tilebuf_Rect *)re->cur_rect;
|
2012-09-25 20:49:33 -07:00
|
|
|
if (re->rects)
|
|
|
|
{
|
2014-02-14 09:33:47 -08:00
|
|
|
re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
|
|
|
|
|
2012-09-25 20:49:33 -07:00
|
|
|
switch (re->mode)
|
|
|
|
{
|
|
|
|
case MODE_COPY:
|
|
|
|
case MODE_DOUBLE:
|
|
|
|
case MODE_TRIPLE:
|
2014-02-08 06:04:04 -08:00
|
|
|
case MODE_QUADRUPLE:
|
2013-07-08 18:42:01 -07:00
|
|
|
rect = (Tilebuf_Rect *)re->cur_rect;
|
|
|
|
*x = rect->x;
|
|
|
|
*y = rect->y;
|
|
|
|
*w = rect->w;
|
|
|
|
*h = rect->h;
|
|
|
|
*cx = rect->x;
|
|
|
|
*cy = rect->y;
|
|
|
|
*cw = rect->w;
|
|
|
|
*ch = rect->h;
|
|
|
|
re->cur_rect = re->cur_rect->next;
|
|
|
|
re->win->gl_context->master_clip.enabled = EINA_TRUE;
|
|
|
|
re->win->gl_context->master_clip.x = rect->x;
|
|
|
|
re->win->gl_context->master_clip.y = rect->y;
|
|
|
|
re->win->gl_context->master_clip.w = rect->w;
|
|
|
|
re->win->gl_context->master_clip.h = rect->h;
|
|
|
|
break;
|
2012-09-25 20:49:33 -07:00
|
|
|
case MODE_FULL:
|
2013-07-08 18:42:01 -07:00
|
|
|
re->cur_rect = NULL;
|
|
|
|
if (x) *x = 0;
|
|
|
|
if (y) *y = 0;
|
|
|
|
if (w) *w = re->win->w;
|
|
|
|
if (h) *h = re->win->h;
|
|
|
|
if (cx) *cx = 0;
|
|
|
|
if (cy) *cy = 0;
|
|
|
|
if (cw) *cw = re->win->w;
|
|
|
|
if (ch) *ch = re->win->h;
|
|
|
|
re->win->gl_context->master_clip.enabled = EINA_FALSE;
|
|
|
|
break;
|
2012-09-25 20:49:33 -07:00
|
|
|
default:
|
2013-07-08 18:42:01 -07:00
|
|
|
break;
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
|
|
|
if (first_rect)
|
|
|
|
{
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_gl_preload_render_lock(eng_preload_make_current, re);
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-09-25 20:49:33 -07:00
|
|
|
// dont need to for egl - eng_window_use() can check for other ctxt's
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2012-09-25 20:49:33 -07:00
|
|
|
eng_window_use(NULL);
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
2012-09-25 20:49:33 -07:00
|
|
|
eng_window_use(re->win);
|
|
|
|
if (!_re_wincheck(re)) return NULL;
|
|
|
|
|
|
|
|
evas_gl_common_context_flush(re->win->gl_context);
|
|
|
|
evas_gl_common_context_newframe(re->win->gl_context);
|
2013-04-10 02:39:56 -07:00
|
|
|
if (partial_render_debug == -1)
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1;
|
|
|
|
else partial_render_debug = 0;
|
|
|
|
}
|
|
|
|
if (partial_render_debug == 1)
|
|
|
|
{
|
|
|
|
glClearColor(0.2, 0.5, 1.0, 1.0);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
}
|
2013-07-08 18:42:01 -07:00
|
|
|
if (!re->cur_rect)
|
|
|
|
{
|
|
|
|
re->end = 1;
|
|
|
|
}
|
2011-10-21 01:58:00 -07:00
|
|
|
return re->win->gl_context->def_surface;
|
|
|
|
}
|
|
|
|
return NULL;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2010-10-25 00:22:43 -07:00
|
|
|
static int safe_native = -1;
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
static void
|
2012-12-19 08:15:58 -08:00
|
|
|
eng_output_redraws_next_update_push(void *data, void *surface EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Evas_Render_Mode render_mode)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-12-19 08:15:58 -08:00
|
|
|
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2003-09-04 00:40:34 -07:00
|
|
|
/* put back update surface.. in this case just unflag redraw */
|
2010-08-26 02:40:48 -07:00
|
|
|
if (!_re_wincheck(re)) return;
|
2007-03-04 09:06:13 -08:00
|
|
|
re->win->draw.drew = 1;
|
2009-10-09 05:10:27 -07:00
|
|
|
evas_gl_common_context_flush(re->win->gl_context);
|
2010-10-22 01:17:37 -07:00
|
|
|
if (safe_native == -1)
|
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
const char *s = getenv("EVAS_GL_SAFE_NATIVE");
|
2010-10-22 01:17:37 -07:00
|
|
|
safe_native = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
if (s) safe_native = atoi(s);
|
2010-10-24 18:57:48 -07:00
|
|
|
else
|
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
s = (const char *)glGetString(GL_RENDERER);
|
2010-10-24 18:57:48 -07:00
|
|
|
if (s)
|
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
if (strstr(s, "PowerVR SGX 540") ||
|
|
|
|
strstr(s, "Mali-400 MP"))
|
2011-12-17 21:03:24 -08:00
|
|
|
safe_native = 1;
|
2010-10-24 18:57:48 -07:00
|
|
|
}
|
|
|
|
}
|
2010-10-22 01:17:37 -07:00
|
|
|
}
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2010-02-06 00:38:26 -08:00
|
|
|
// this is needed to make sure all previous rendering is flushed to
|
|
|
|
// buffers/surfaces
|
2010-10-22 01:17:37 -07:00
|
|
|
// previous rendering should be done and swapped
|
2013-05-17 18:04:37 -07:00
|
|
|
//xx if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE);
|
2011-12-17 21:03:24 -08:00
|
|
|
// if (eglGetError() != EGL_SUCCESS)
|
|
|
|
// {
|
|
|
|
// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n");
|
|
|
|
// }
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
// previous rendering should be done and swapped
|
2013-05-17 18:04:37 -07:00
|
|
|
//xx if (!safe_native) glXWaitX();
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-19 08:15:58 -08:00
|
|
|
eng_output_flush(void *data, Evas_Render_Mode render_mode)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2013-07-22 02:52:32 -07:00
|
|
|
static char *dname = NULL;
|
|
|
|
|
2013-06-26 06:32:21 -07:00
|
|
|
re = (Render_Engine *)data;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
|
2012-12-19 08:15:58 -08:00
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
if (!_re_wincheck(re)) goto end;
|
|
|
|
if (!re->win->draw.drew) goto end;
|
2012-09-25 20:49:33 -07:00
|
|
|
|
2007-03-04 09:06:13 -08:00
|
|
|
re->win->draw.drew = 0;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2013-06-11 02:12:07 -07:00
|
|
|
evas_gl_common_context_done(re->win->gl_context);
|
2013-07-22 02:52:32 -07:00
|
|
|
|
|
|
|
// Save contents of the framebuffer to a file
|
|
|
|
if (swap_buffer_debug_mode == -1)
|
|
|
|
{
|
2014-01-08 05:06:41 -08:00
|
|
|
if (
|
|
|
|
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
|
|
|
|
(getuid() == geteuid()) &&
|
|
|
|
#endif
|
2014-01-08 02:46:23 -08:00
|
|
|
((dname = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR"))))
|
2013-07-22 02:52:32 -07:00
|
|
|
{
|
|
|
|
int stat;
|
|
|
|
// Create a directory with 0775 permission
|
|
|
|
stat = mkdir(dname, 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (swap_buffer_debug_mode == 1)
|
|
|
|
{
|
|
|
|
// 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)
|
|
|
|
{
|
|
|
|
char fname[100];
|
|
|
|
int ret = 0;
|
2013-12-11 01:25:29 -08:00
|
|
|
snprintf(fname, sizeof(fname), "%p", (void*)re->win);
|
2013-07-22 02:52:32 -07:00
|
|
|
|
|
|
|
ret = evas_gl_common_buffer_dump(re->win->gl_context,
|
|
|
|
(const char*)dname,
|
|
|
|
(const char*)fname,
|
2014-02-14 09:33:47 -08:00
|
|
|
re->frame_cnt,
|
2014-03-17 22:48:44 -07:00
|
|
|
NULL);
|
2013-07-22 02:52:32 -07:00
|
|
|
if (!ret) swap_buffer_debug_mode = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2010-10-25 00:22:43 -07:00
|
|
|
if (!re->vsync)
|
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1);
|
|
|
|
else eglSwapInterval(re->win->egl_disp, 0);
|
2010-10-25 00:22:43 -07:00
|
|
|
re->vsync = 1;
|
|
|
|
}
|
2011-05-11 02:14:59 -07:00
|
|
|
if (re->info->callback.pre_swap)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
re->info->callback.pre_swap(re->info->callback.data, re->evas);
|
|
|
|
}
|
2013-06-24 01:27:14 -07:00
|
|
|
if ((glsym_eglSwapBuffersWithDamage) && (re->mode != MODE_FULL))
|
2013-03-11 04:40:56 -07:00
|
|
|
{
|
2013-06-05 02:07:29 -07:00
|
|
|
EGLint num = 0, *rects = NULL, i = 0;
|
2013-07-08 18:42:01 -07:00
|
|
|
Tilebuf_Rect *r;
|
2013-03-11 04:40:56 -07:00
|
|
|
|
|
|
|
// if partial swaps can be done use re->rects
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(re->rects), r) num++;
|
2013-06-05 02:07:29 -07:00
|
|
|
if (num > 0)
|
2013-03-11 04:40:56 -07:00
|
|
|
{
|
2013-06-05 02:07:29 -07:00
|
|
|
rects = alloca(sizeof(EGLint) * 4 * num);
|
2013-03-11 04:40:56 -07:00
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(re->rects), r)
|
|
|
|
{
|
2013-05-05 21:16:13 -07:00
|
|
|
int gw, gh;
|
|
|
|
|
|
|
|
gw = re->win->gl_context->w;
|
|
|
|
gh = re->win->gl_context->h;
|
|
|
|
switch (re->win->rot)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
rects[i + 0] = r->x;
|
2014-02-14 09:33:47 -08:00
|
|
|
rects[i + 1] = gh - (r->y + r->h);
|
2013-05-05 21:16:13 -07:00
|
|
|
rects[i + 2] = r->w;
|
|
|
|
rects[i + 3] = r->h;
|
|
|
|
break;
|
|
|
|
case 90:
|
|
|
|
rects[i + 0] = r->y;
|
2014-02-14 09:33:47 -08:00
|
|
|
rects[i + 1] = r->x;
|
2013-05-05 21:16:13 -07:00
|
|
|
rects[i + 2] = r->h;
|
|
|
|
rects[i + 3] = r->w;
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
rects[i + 0] = gw - (r->x + r->w);
|
2014-02-14 09:33:47 -08:00
|
|
|
rects[i + 1] = r->y;
|
2013-05-05 21:16:13 -07:00
|
|
|
rects[i + 2] = r->w;
|
|
|
|
rects[i + 3] = r->h;
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
rects[i + 0] = gh - (r->y + r->h);
|
2014-02-14 09:33:47 -08:00
|
|
|
rects[i + 1] = gw - (r->x + r->w);
|
2013-05-05 21:16:13 -07:00
|
|
|
rects[i + 2] = r->h;
|
|
|
|
rects[i + 3] = r->w;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rects[i + 0] = r->x;
|
2014-02-14 09:33:47 -08:00
|
|
|
rects[i + 1] = gh - (r->y + r->h);
|
2013-05-05 21:16:13 -07:00
|
|
|
rects[i + 2] = r->w;
|
|
|
|
rects[i + 3] = r->h;
|
|
|
|
break;
|
|
|
|
}
|
2013-03-11 04:40:56 -07:00
|
|
|
i += 4;
|
|
|
|
}
|
2013-06-24 01:27:14 -07:00
|
|
|
glsym_eglSwapBuffersWithDamage(re->win->egl_disp,
|
|
|
|
re->win->egl_surface[0],
|
|
|
|
rects, num);
|
2013-03-11 04:40:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-06-17 01:53:33 -07:00
|
|
|
eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
|
2013-07-22 02:52:32 -07:00
|
|
|
|
2013-05-17 18:04:37 -07:00
|
|
|
//xx if (!safe_native) eglWaitGL();
|
2011-05-11 02:14:59 -07:00
|
|
|
if (re->info->callback.post_swap)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
re->info->callback.post_swap(re->info->callback.data, re->evas);
|
|
|
|
}
|
|
|
|
// if (eglGetError() != EGL_SUCCESS)
|
|
|
|
// {
|
|
|
|
// printf("Error: eglSwapBuffers() fail.\n");
|
|
|
|
// }
|
|
|
|
#else
|
|
|
|
#ifdef VSYNC_TO_SCREEN
|
2012-09-25 20:49:33 -07:00
|
|
|
if (re->info->vsync)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
if (glsym_glXSwapIntervalEXT)
|
|
|
|
{
|
|
|
|
if (!re->vsync)
|
|
|
|
{
|
|
|
|
if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1);
|
|
|
|
else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0);
|
|
|
|
re->vsync = 1;
|
|
|
|
}
|
|
|
|
}
|
2013-04-09 17:40:37 -07:00
|
|
|
else if (glsym_glXSwapIntervalSGI)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
if (!re->vsync)
|
|
|
|
{
|
|
|
|
if (re->info->vsync) glsym_glXSwapIntervalSGI(1);
|
|
|
|
else glsym_glXSwapIntervalSGI(0);
|
|
|
|
re->vsync = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync))
|
|
|
|
{
|
|
|
|
unsigned int rc;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
glsym_glXGetVideoSync(&rc);
|
|
|
|
glsym_glXWaitVideoSync(1, 0, &rc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
#endif
|
2012-05-15 06:13:05 -07:00
|
|
|
if (re->info->callback.pre_swap)
|
|
|
|
{
|
|
|
|
re->info->callback.pre_swap(re->info->callback.data, re->evas);
|
|
|
|
}
|
2012-09-25 20:49:33 -07:00
|
|
|
// XXX: if partial swaps can be done use re->rects
|
2013-04-09 17:40:37 -07:00
|
|
|
// measure(0, "swap");
|
2012-09-25 20:49:33 -07:00
|
|
|
glXSwapBuffers(re->win->disp, re->win->win);
|
2013-04-09 17:40:37 -07:00
|
|
|
// measure(1, "swap");
|
2012-05-15 06:13:05 -07:00
|
|
|
if (re->info->callback.post_swap)
|
|
|
|
{
|
|
|
|
re->info->callback.post_swap(re->info->callback.data, re->evas);
|
|
|
|
}
|
|
|
|
#endif
|
2012-09-25 20:49:33 -07:00
|
|
|
// clear out rects after swap as we may use them during swap
|
|
|
|
if (re->rects)
|
|
|
|
{
|
2013-07-08 18:42:01 -07:00
|
|
|
evas_common_tilebuf_free_render_rects(re->rects);
|
2012-09-25 20:49:33 -07:00
|
|
|
re->rects = NULL;
|
|
|
|
}
|
2013-06-23 19:41:32 -07:00
|
|
|
|
2013-07-22 02:52:32 -07:00
|
|
|
re->frame_cnt++;
|
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
end:
|
|
|
|
evas_gl_preload_render_unlock(eng_preload_make_current, re);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2007-06-16 19:56:59 -07:00
|
|
|
static void
|
|
|
|
eng_output_idle_flush(void *data)
|
|
|
|
{
|
2010-04-12 01:23:53 -07:00
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
2012-10-08 18:58:41 -07:00
|
|
|
(void) re;
|
2010-04-12 01:23:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_output_dump(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
evas_common_image_image_all_unload();
|
|
|
|
evas_common_font_font_all_unload();
|
|
|
|
evas_gl_common_image_all_unload(re->win->gl_context);
|
2010-08-26 02:40:48 -07:00
|
|
|
_re_winfree(re);
|
2007-06-16 19:56:59 -07:00
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_context_cutout_add(void *data EINA_UNUSED, void *context, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
|
|
|
//
|
|
|
|
// re = (Render_Engine *)data;
|
|
|
|
// re->win->gl_context->dc = context;
|
2009-02-20 19:13:49 -08:00
|
|
|
evas_common_draw_context_add_cutout(context, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_context_cutout_clear(void *data EINA_UNUSED, void *context)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
|
|
|
//
|
|
|
|
// re = (Render_Engine *)data;
|
|
|
|
// re->win->gl_context->dc = context;
|
2009-02-20 19:13:49 -08:00
|
|
|
evas_common_draw_context_clear_cutouts(context);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-18 08:28:55 -08:00
|
|
|
eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
|
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;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2009-11-12 23:22:31 -08:00
|
|
|
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
|
2006-09-30 03:18:37 -07:00
|
|
|
re->win->gl_context->dc = context;
|
|
|
|
evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-18 08:28:55 -08:00
|
|
|
eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2x, int p2y, Eina_Bool do_async EINA_UNUSED)
|
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;
|
2009-10-09 05:10:27 -07:00
|
|
|
eng_window_use(re->win);
|
2009-11-12 23:22:31 -08:00
|
|
|
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
|
2006-09-30 03:18:37 -07:00
|
|
|
re->win->gl_context->dc = context;
|
2012-11-19 05:10:07 -08:00
|
|
|
evas_gl_common_line_draw(re->win->gl_context, p1x, p1y, p2x, p2y);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_polygon_point_add(void *data, void *context EINA_UNUSED, void *polygon, int x, int y)
|
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;
|
2012-10-08 18:58:41 -07:00
|
|
|
(void) re;
|
2009-12-26 16:40:25 -08:00
|
|
|
return evas_gl_common_poly_point_add(polygon, x, y);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_polygon_points_clear(void *data, void *context EINA_UNUSED, void *polygon)
|
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;
|
2012-10-08 18:58:41 -07:00
|
|
|
(void) re;
|
2009-12-26 16:40:25 -08:00
|
|
|
return evas_gl_common_poly_points_clear(polygon);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-18 08:28:55 -08:00
|
|
|
eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *polygon, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
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;
|
2009-10-09 05:10:27 -07:00
|
|
|
eng_window_use(re->win);
|
2009-11-12 23:22:31 -08:00
|
|
|
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
|
2006-09-30 03:18:37 -07:00
|
|
|
re->win->gl_context->dc = context;
|
2010-03-16 06:23:37 -07:00
|
|
|
evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_alpha_get(void *data EINA_UNUSED, void *image)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
2006-12-17 07:48:52 -08:00
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
// re = (Render_Engine *)data;
|
2006-12-17 08:46:30 -08:00
|
|
|
if (!image) return 1;
|
2006-12-17 07:48:52 -08:00
|
|
|
im = image;
|
2010-01-21 04:43:53 -08:00
|
|
|
return im->alpha;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
2014-04-08 01:19:38 -07:00
|
|
|
static Evas_Colorspace
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_colorspace_get(void *data EINA_UNUSED, void *image)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
2006-12-17 07:48:52 -08:00
|
|
|
Evas_GL_Image *im;
|
2009-02-21 00:19:58 -08:00
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
// re = (Render_Engine *)data;
|
2006-12-17 08:46:30 -08:00
|
|
|
if (!image) return EVAS_COLORSPACE_ARGB8888;
|
2006-12-17 07:48:52 -08:00
|
|
|
im = image;
|
|
|
|
return im->cs.space;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_alpha_set(void *data, void *image, int has_alpha)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image) return NULL;
|
2006-12-17 07:48:52 -08:00
|
|
|
im = image;
|
2010-08-18 22:18:17 -07:00
|
|
|
if (im->alpha == has_alpha) return image;
|
2010-01-21 01:42:26 -08:00
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
im->alpha = has_alpha;
|
|
|
|
return image;
|
|
|
|
}
|
2010-01-21 04:43:53 -08:00
|
|
|
eng_window_use(re->win);
|
2010-08-18 22:18:17 -07:00
|
|
|
if ((im->tex) && (im->tex->pt->dyn.img))
|
|
|
|
{
|
|
|
|
im->alpha = has_alpha;
|
|
|
|
im->tex->alpha = im->alpha;
|
|
|
|
return image;
|
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
/* FIXME: can move to gl_common */
|
|
|
|
if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
|
2008-06-03 02:09:39 -07:00
|
|
|
if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image;
|
|
|
|
else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image;
|
2006-12-17 07:48:52 -08:00
|
|
|
if (im->references > 1)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im_new;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2012-09-06 22:57:22 -07:00
|
|
|
if (!im->im->image.data)
|
2013-10-29 03:06:33 -07:00
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
|
|
|
evas_cache2_image_load_data(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
|
|
|
}
|
2013-10-16 01:20:14 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
2010-08-25 02:29:56 -07:00
|
|
|
im_new = evas_gl_common_image_new_from_copied_data
|
2012-05-15 06:13:05 -07:00
|
|
|
(im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
|
|
|
|
im->im->image.data,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!im_new) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im_new;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
else
|
2011-12-17 21:03:24 -08:00
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
2010-02-21 07:49:44 -08:00
|
|
|
return evas_gl_common_image_alpha_set(im, has_alpha ? 1 : 0);
|
2011-12-17 21:03:24 -08:00
|
|
|
// im->im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
|
|
|
|
// return image;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
2008-11-04 01:19:35 -08:00
|
|
|
static void *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_border_set(void *data EINA_UNUSED, void *image, int l EINA_UNUSED, int r EINA_UNUSED, int t EINA_UNUSED, int b EINA_UNUSED)
|
2008-11-04 01:19:35 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
|
|
|
//
|
|
|
|
// re = (Render_Engine *)data;
|
2008-11-04 01:19:35 -08:00
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_border_get(void *data EINA_UNUSED, void *image EINA_UNUSED, int *l EINA_UNUSED, int *r EINA_UNUSED, int *t EINA_UNUSED, int *b EINA_UNUSED)
|
2008-11-04 01:19:35 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
|
|
|
//
|
|
|
|
// re = (Render_Engine *)data;
|
2008-11-04 01:19:35 -08:00
|
|
|
}
|
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
static char *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_comment_get(void *data EINA_UNUSED, void *image, char *key EINA_UNUSED)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
2006-12-17 07:48:52 -08:00
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
// re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image) return NULL;
|
2006-12-17 07:48:52 -08:00
|
|
|
im = image;
|
2010-01-21 04:43:53 -08:00
|
|
|
if (!im->im) return NULL;
|
2006-12-17 07:48:52 -08:00
|
|
|
return im->im->info.comment;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_format_get(void *data EINA_UNUSED, void *image)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
// Render_Engine *re;
|
2006-12-17 07:48:52 -08:00
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
// re = (Render_Engine *)data;
|
2006-12-17 07:48:52 -08:00
|
|
|
im = image;
|
2012-10-08 18:58:41 -07:00
|
|
|
(void) im;
|
2006-12-17 07:48:52 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-04-08 01:19:38 -07:00
|
|
|
eng_image_colorspace_set(void *data, void *image, Evas_Colorspace cspace)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
Evas_GL_Image *im;
|
2009-02-21 00:19:58 -08:00
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image) return;
|
2006-12-17 07:48:52 -08:00
|
|
|
im = image;
|
2010-01-21 01:42:26 -08:00
|
|
|
if (im->native.data) return;
|
2006-12-17 07:48:52 -08:00
|
|
|
/* FIXME: can move to gl_common */
|
|
|
|
if (im->cs.space == cspace) return;
|
2009-10-09 05:10:27 -07:00
|
|
|
eng_window_use(re->win);
|
2013-10-16 01:20:14 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_colorspace(&im->im->cache_entry, cspace);
|
2006-12-17 07:48:52 -08:00
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2011-11-10 00:59:09 -08:00
|
|
|
if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
im->cs.data = NULL;
|
|
|
|
im->cs.no_free = 0;
|
|
|
|
}
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
2011-08-23 08:13:40 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
2011-08-29 13:56:48 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
2013-06-13 23:51:18 -07:00
|
|
|
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
2011-11-10 00:59:09 -08:00
|
|
|
im->tex = NULL;
|
|
|
|
if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
if (im->im->cache_entry.h > 0)
|
|
|
|
im->cs.data =
|
|
|
|
calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
|
|
|
else
|
|
|
|
im->cs.data = NULL;
|
|
|
|
im->cs.no_free = 0;
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
default:
|
2011-11-10 00:59:09 -08:00
|
|
|
abort();
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
im->cs.space = cspace;
|
|
|
|
}
|
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
//
|
|
|
|
typedef struct _Native Native;
|
|
|
|
|
|
|
|
struct _Native
|
|
|
|
{
|
|
|
|
Evas_Native_Surface ns;
|
2012-05-15 06:13:05 -07:00
|
|
|
Pixmap pixmap;
|
|
|
|
Visual *visual;
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
void *egl_surface;
|
|
|
|
#else
|
|
|
|
void *fbc;
|
|
|
|
XID glx_pixmap;
|
|
|
|
#endif
|
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
|
2012-05-15 06:13:05 -07:00
|
|
|
_native_bind_cb(void *data, 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
|
2011-12-17 21:03:24 -08:00
|
|
|
if (n->egl_surface)
|
|
|
|
{
|
|
|
|
if (glsym_glEGLImageTargetTexture2DOES)
|
|
|
|
{
|
|
|
|
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
|
|
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
|
|
ERR("glEGLImageTargetTexture2DOES() failed.");
|
|
|
|
}
|
|
|
|
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
|
|
|
|
Render_Engine *re = data;
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (glsym_glXBindTexImage)
|
|
|
|
{
|
|
|
|
glsym_glXBindTexImage(re->win->disp, n->glx_pixmap,
|
|
|
|
GLX_FRONT_LEFT_EXT, NULL);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXBindTexImage on GLX with no support");
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
data = NULL;
|
2010-01-21 00:44:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-05-15 06:13:05 -07:00
|
|
|
_native_unbind_cb(void *data, 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
|
2012-05-15 06:13:05 -07:00
|
|
|
// nothing
|
|
|
|
#else
|
|
|
|
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
|
|
|
Render_Engine *re = data;
|
2011-12-17 21:03:24 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (glsym_glXReleaseTexImage)
|
|
|
|
{
|
|
|
|
glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
|
|
|
|
GLX_FRONT_LEFT_EXT);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXReleaseTexImage on GLX with no support");
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
2011-12-17 21:03:24 -08:00
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
return;
|
|
|
|
data = NULL;
|
2010-01-21 00:44:11 -08:00
|
|
|
}
|
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
static void
|
2010-01-21 00:44:11 -08:00
|
|
|
_native_free_cb(void *data, void *image)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
Render_Engine *re = data;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Native *n = im->native.data;
|
|
|
|
uint32_t pmid, texid;
|
2010-12-05 23:09:51 -08:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
|
|
|
pmid = n->pixmap;
|
|
|
|
eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
if (n->egl_surface)
|
|
|
|
{
|
|
|
|
if (glsym_eglDestroyImage)
|
|
|
|
{
|
|
|
|
glsym_eglDestroyImage(re->win->egl_disp,
|
|
|
|
n->egl_surface);
|
|
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
|
|
ERR("eglDestroyImage() failed.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try eglDestroyImage on EGL with no support");
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
|
|
|
if (n->glx_pixmap)
|
|
|
|
{
|
|
|
|
if (im->native.loose)
|
|
|
|
{
|
|
|
|
if (glsym_glXReleaseTexImage)
|
|
|
|
{
|
|
|
|
glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
|
|
|
|
GLX_FRONT_LEFT_EXT);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXReleaseTexImage on GLX with no support");
|
|
|
|
}
|
|
|
|
if (glsym_glXDestroyPixmap)
|
|
|
|
{
|
|
|
|
glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glXDestroyPixmap on GLX with no support");
|
|
|
|
n->glx_pixmap = 0;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
texid = n->ns.data.opengl.texture_id;
|
|
|
|
eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
|
|
|
|
}
|
|
|
|
im->native.data = NULL;
|
|
|
|
im->native.func.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
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
Evas_Native_Surface *ns = native;
|
|
|
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
im = evas_gl_common_image_new_from_data(re->win->gl_context,
|
|
|
|
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)
|
|
|
|
{
|
2012-05-15 06:13:05 -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)
|
2011-12-17 21:03:24 -08:00
|
|
|
{
|
|
|
|
tex = ns->data.opengl.texture_id;
|
|
|
|
fbo = ns->data.opengl.framebuffer_id;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_Native_Surface *ens = im->native.data;
|
|
|
|
if ((ens->data.opengl.texture_id == tex) &&
|
|
|
|
(ens->data.opengl.framebuffer_id == fbo))
|
|
|
|
return im;
|
2011-12-17 21:03:24 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((!ns) && (!im->native.data)) return im;
|
|
|
|
|
|
|
|
eng_window_use(re->win);
|
|
|
|
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
if (im->native.func.free)
|
|
|
|
im->native.func.free(im->native.func.data, im);
|
|
|
|
evas_gl_common_image_native_disable(im);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ns) return im;
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_X11)
|
|
|
|
{
|
|
|
|
pmid = pm;
|
|
|
|
im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
|
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
n = im2->native.data;
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
evas_gl_common_image_ref(im2);
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
2011-12-17 21:03:24 -08:00
|
|
|
{
|
|
|
|
texid = tex;
|
|
|
|
im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
|
|
|
|
if (im2 == im) return im;
|
|
|
|
if (im2)
|
|
|
|
{
|
|
|
|
n = im2->native.data;
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
evas_gl_common_image_ref(im2);
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
|
|
|
|
im->w, im->h, NULL, im->alpha,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
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
|
2012-05-15 06:13:05 -07:00
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
EGLConfig egl_config;
|
|
|
|
int config_attrs[20];
|
|
|
|
int num_config, i = 0;
|
2013-11-28 01:18:16 -08:00
|
|
|
int yinvert = 1;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
|
|
|
|
|
2012-08-07 23:25:59 -07:00
|
|
|
// assume 32bit pixmap! :)
|
2012-05-15 06:13:05 -07:00
|
|
|
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;
|
|
|
|
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(re->win->egl_disp, config_attrs,
|
|
|
|
&egl_config, 1, &num_config))
|
|
|
|
ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config);
|
2013-11-28 01:18:16 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
if (extn_have_y_inverted &&
|
|
|
|
eglGetConfigAttrib(re->win->egl_disp, egl_config,
|
|
|
|
EGL_Y_INVERTED_NOK, &val))
|
|
|
|
yinvert = val;
|
|
|
|
}
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
|
|
|
n->pixmap = pm;
|
|
|
|
n->visual = vis;
|
|
|
|
if (glsym_eglCreateImage)
|
|
|
|
n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
|
|
|
|
EGL_NO_CONTEXT,
|
|
|
|
EGL_NATIVE_PIXMAP_KHR,
|
|
|
|
(void *)pm,
|
|
|
|
NULL);
|
|
|
|
else
|
|
|
|
ERR("Try eglCreateImage on EGL with no support");
|
|
|
|
if (!n->egl_surface)
|
|
|
|
ERR("eglCreatePixmapSurface() for 0x%x failed", (unsigned int)pm);
|
2013-11-28 01:18:16 -08:00
|
|
|
im->native.yinvert = yinvert;
|
2012-05-15 06:13:05 -07:00
|
|
|
im->native.loose = 0;
|
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.data = re;
|
|
|
|
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;
|
|
|
|
evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#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;
|
|
|
|
|
|
|
|
// fixme: round trip :(
|
|
|
|
XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
|
|
|
|
&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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
|
|
|
|
configs = glXChooseFBConfig(re->win->disp,
|
|
|
|
re->win->screen,
|
|
|
|
config_attrs,
|
|
|
|
&num);
|
|
|
|
if (configs)
|
|
|
|
{
|
2013-04-18 04:29:55 -07:00
|
|
|
int j = 0, val = 0, found = 0;
|
2012-11-13 06:07:39 -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;
|
|
|
|
|
|
|
|
vi = glXGetVisualFromFBConfig(re->win->disp, configs[j]);
|
|
|
|
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);
|
2013-04-19 17:13:38 -07:00
|
|
|
|
2013-04-18 04:29:55 -07:00
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
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
|
|
|
}
|
2013-04-18 01:16:41 -07:00
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
GLX_DRAWABLE_TYPE, &val);
|
|
|
|
if (!(val & GLX_PIXMAP_BIT)) continue;
|
|
|
|
tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
GLX_ALPHA_SIZE, &val);
|
|
|
|
if ((depth == 32) && (!val)) continue;
|
|
|
|
if (val > 0)
|
|
|
|
{
|
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
|
|
|
|
if (val) tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
|
|
|
|
if (val) tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
|
|
|
}
|
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
GLX_Y_INVERTED_EXT, &val);
|
|
|
|
yinvert = val;
|
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
|
|
|
GLX_BIND_TO_TEXTURE_TARGETS_EXT,
|
|
|
|
&val);
|
|
|
|
tex_target = val;
|
2012-11-13 06:07:39 -08:00
|
|
|
glXGetFBConfigAttrib(re->win->disp, configs[j],
|
2013-04-18 01:16:41 -07:00
|
|
|
GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
|
|
|
|
mipmap = val;
|
|
|
|
n->fbc = 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);
|
|
|
|
}
|
2012-08-07 23:25:59 -07:00
|
|
|
|
|
|
|
eina_hash_add(re->win->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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
|
|
|
n->pixmap = pm;
|
|
|
|
n->visual = vis;
|
|
|
|
if (glsym_glXCreatePixmap)
|
|
|
|
n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp,
|
|
|
|
n->fbc,
|
|
|
|
n->pixmap,
|
|
|
|
pixmap_att);
|
|
|
|
else
|
|
|
|
ERR("Try glXCreatePixmap on GLX with no support");
|
|
|
|
if (n->glx_pixmap)
|
|
|
|
{
|
2012-11-12 06:45:07 -08:00
|
|
|
// printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
|
2012-08-07 23:25:59 -07:00
|
|
|
// n, pm, w, h, depth, n->glx_pixmap);
|
|
|
|
if (!target)
|
|
|
|
{
|
|
|
|
ERR("no target :(");
|
|
|
|
if (glsym_glXQueryDrawable)
|
|
|
|
glsym_glXQueryDrawable(re->win->disp,
|
|
|
|
n->pixmap,
|
|
|
|
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;
|
2012-08-07 23:25:59 -07:00
|
|
|
im->native.loose = re->win->detected.loose_binding;
|
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.data = re;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
|
|
|
|
evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
{
|
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
n = calloc(1, sizeof(Native));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
|
|
|
|
|
|
|
eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
|
|
|
|
|
|
|
|
n->pixmap = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
n->visual = 0;
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2011-12-17 21:03:24 -08:00
|
|
|
n->egl_surface = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
n->fbc = 0;
|
|
|
|
n->glx_pixmap = 0;
|
|
|
|
#endif
|
2011-04-04 03:23:12 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
im->native.yinvert = 0;
|
|
|
|
im->native.loose = 0;
|
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.data = re;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
2011-12-17 21:03:24 -08:00
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
2012-05-15 06:13:05 -07:00
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
// FIXME: need to implement mapping sub texture regions
|
|
|
|
// x, y, w, h for possible texture atlasing
|
2011-04-04 03:23:12 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
evas_gl_common_image_native_enable(im);
|
2011-12-17 21:03:24 -08:00
|
|
|
}
|
|
|
|
}
|
2012-05-15 05:03:01 -07:00
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2010-08-02 23:09:53 -07:00
|
|
|
return im;
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_native_get(void *data EINA_UNUSED, void *image)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
Evas_GL_Image *im = image;
|
2010-01-21 00:44:11 -08:00
|
|
|
Native *n;
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!im) return NULL;
|
|
|
|
n = im->native.data;
|
|
|
|
if (!n) return NULL;
|
2010-01-21 00:44:11 -08:00
|
|
|
return &(n->ns);
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
|
|
|
|
2011-04-18 22:47:56 -07:00
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
//
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
static void *
|
2007-03-04 08:19:32 -08:00
|
|
|
eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2009-12-22 15:11:57 -08:00
|
|
|
return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2013-05-07 23:37:37 -07:00
|
|
|
static void *
|
|
|
|
eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
eng_window_use(re->win);
|
|
|
|
return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error);
|
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
static void *
|
2014-04-08 01:19:38 -07:00
|
|
|
eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
|
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;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2006-12-17 07:48:52 -08:00
|
|
|
return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2014-04-08 01:19:38 -07:00
|
|
|
eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
|
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;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2006-12-17 07:48:52 -08:00
|
|
|
return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_image_free(void *data, void *image)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image) return;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2003-09-04 00:40:34 -07:00
|
|
|
evas_gl_common_image_free(image);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_size_get(void *data EINA_UNUSED, void *image, int *w, int *h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image)
|
|
|
|
{
|
2011-11-10 00:59:09 -08:00
|
|
|
*w = 0;
|
|
|
|
*h = 0;
|
|
|
|
return;
|
2006-12-19 06:12:40 -08:00
|
|
|
}
|
2010-01-21 01:42:26 -08:00
|
|
|
if (w) *w = ((Evas_GL_Image *)image)->w;
|
|
|
|
if (h) *h = ((Evas_GL_Image *)image)->h;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_image_size_set(void *data, void *image, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2010-01-21 01:42:26 -08:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_GL_Image *im_old;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2010-01-21 01:42:26 -08:00
|
|
|
if (!im) return NULL;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
im->w = w;
|
|
|
|
im->h = h;
|
|
|
|
return image;
|
|
|
|
}
|
2006-12-19 06:12:40 -08:00
|
|
|
eng_window_use(re->win);
|
2010-08-18 20:30:47 -07:00
|
|
|
if ((im->tex) && (im->tex->pt->dyn.img))
|
|
|
|
{
|
2013-06-13 23:51:18 -07:00
|
|
|
evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
2010-08-18 20:30:47 -07:00
|
|
|
im->tex = NULL;
|
2010-10-07 22:11:32 -07:00
|
|
|
im->w = w;
|
|
|
|
im->h = h;
|
2010-08-18 20:30:47 -07:00
|
|
|
im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
|
|
|
|
return image;
|
|
|
|
}
|
2003-09-04 00:40:34 -07:00
|
|
|
im_old = image;
|
2011-08-29 13:56:48 -07:00
|
|
|
|
|
|
|
switch (eng_image_colorspace_get(data, image))
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
2012-05-15 06:13:05 -07:00
|
|
|
w &= ~0x1;
|
|
|
|
break;
|
2014-04-08 01:19:38 -07:00
|
|
|
default: break;
|
2011-08-29 13:56:48 -07:00
|
|
|
}
|
|
|
|
|
2013-10-16 01:20:14 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im_old);
|
2012-10-23 01:55:22 -07:00
|
|
|
if ((im_old->im) &&
|
2010-09-18 16:16:25 -07:00
|
|
|
((int)im_old->im->cache_entry.w == w) &&
|
|
|
|
((int)im_old->im->cache_entry.h == h))
|
2011-12-17 21:03:24 -08:00
|
|
|
return image;
|
2003-09-04 00:40:34 -07:00
|
|
|
if (im_old)
|
|
|
|
{
|
2011-11-10 00:59:09 -08:00
|
|
|
im = evas_gl_common_image_new(re->win->gl_context, w, h,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
2009-10-09 05:10:27 -07:00
|
|
|
evas_gl_common_image_free(im_old);
|
2003-09-04 00:40:34 -07:00
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
else
|
2012-05-15 06:13:05 -07:00
|
|
|
im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
|
2003-09-04 00:40:34 -07:00
|
|
|
return im;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2009-12-19 22:23:13 -08:00
|
|
|
eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2010-01-21 01:42:26 -08:00
|
|
|
Evas_GL_Image *im = image;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image) return NULL;
|
2010-01-21 01:42:26 -08:00
|
|
|
if (im->native.data) return image;
|
2010-01-21 04:43:53 -08:00
|
|
|
eng_window_use(re->win);
|
2009-12-19 22:23:13 -08:00
|
|
|
evas_gl_common_image_dirty(image, x, y, w, h);
|
2003-09-04 00:40:34 -07:00
|
|
|
return image;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2011-05-19 04:19:22 -07:00
|
|
|
eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2003-09-04 00:40:34 -07:00
|
|
|
Evas_GL_Image *im;
|
2011-05-19 04:19:22 -07:00
|
|
|
int error;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image)
|
|
|
|
{
|
2011-11-10 00:59:09 -08:00
|
|
|
*image_data = NULL;
|
2011-05-19 04:19:22 -07:00
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
2011-11-10 00:59:09 -08:00
|
|
|
return NULL;
|
2006-12-19 06:12:40 -08:00
|
|
|
}
|
2003-09-04 00:40:34 -07:00
|
|
|
im = image;
|
2010-01-21 01:42:26 -08:00
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
*image_data = NULL;
|
2011-05-19 04:19:22 -07:00
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
2010-01-21 01:42:26 -08:00
|
|
|
return im;
|
|
|
|
}
|
2011-08-16 00:06:36 -07:00
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2011-08-16 00:06:36 -07:00
|
|
|
eng_window_use(re->win);
|
|
|
|
|
2011-09-30 08:43:51 -07:00
|
|
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
|
2011-08-16 00:06:36 -07:00
|
|
|
{
|
2011-11-10 23:47:25 -08:00
|
|
|
if (im->tex->pt->dyn.checked_out > 0)
|
|
|
|
{
|
|
|
|
im->tex->pt->dyn.checked_out++;
|
|
|
|
*image_data = im->tex->pt->dyn.data;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
2013-04-12 01:34:13 -07:00
|
|
|
*image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp,
|
|
|
|
im->tex->pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
|
|
|
|
EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
|
2011-08-16 00:06:36 -07:00
|
|
|
|
|
|
|
if (!im->tex->pt->dyn.data)
|
|
|
|
{
|
2011-11-14 01:27:29 -08:00
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2011-08-16 00:06:36 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-11-14 01:27:29 -08:00
|
|
|
return im;
|
2011-08-16 00:06:36 -07:00
|
|
|
}
|
2011-11-10 23:47:25 -08:00
|
|
|
im->tex->pt->dyn.checked_out++;
|
2011-08-16 00:06:36 -07:00
|
|
|
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
|
|
|
|
{
|
|
|
|
*image_data = im->tex->pt->dyn.data;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
eng_window_use(re->win);
|
|
|
|
#endif
|
2011-08-16 00:06:36 -07:00
|
|
|
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
/* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
|
2012-05-15 06:13:05 -07:00
|
|
|
so it is need to add code which check im->im's NULL value*/
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
|
|
|
|
if (!im->im)
|
2011-12-17 21:03:24 -08:00
|
|
|
{
|
|
|
|
*image_data = NULL;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
|
2013-10-29 03:06:33 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
|
|
|
error = evas_cache2_image_load_data(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
error = evas_cache_image_load_data(&im->im->cache_entry);
|
2013-10-16 01:20:14 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
2006-12-17 07:48:52 -08:00
|
|
|
switch (im->cs.space)
|
2003-09-04 00:40:34 -07:00
|
|
|
{
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2011-11-10 00:59:09 -08:00
|
|
|
if (to_write)
|
|
|
|
{
|
|
|
|
if (im->references > 1)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im_new;
|
|
|
|
|
|
|
|
im_new = evas_gl_common_image_new_from_copied_data
|
|
|
|
(im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
|
|
|
|
im->im->image.data,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
if (!im_new)
|
|
|
|
{
|
|
|
|
*image_data = NULL;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im_new;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
*image_data = im->im->image.data;
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
2011-08-23 08:13:40 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
2011-08-29 13:56:48 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
2011-11-10 00:59:09 -08:00
|
|
|
*image_data = im->cs.data;
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
default:
|
2011-11-10 00:59:09 -08:00
|
|
|
abort();
|
|
|
|
break;
|
2003-09-04 00:40:34 -07:00
|
|
|
}
|
2011-05-19 04:19:22 -07:00
|
|
|
if (err) *err = error;
|
2003-09-04 00:40:34 -07:00
|
|
|
return im;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2006-02-27 20:07:49 -08:00
|
|
|
eng_image_data_put(void *data, void *image, DATA32 *image_data)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2006-12-17 08:46:30 -08:00
|
|
|
Evas_GL_Image *im, *im2;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
re = (Render_Engine *)data;
|
2006-12-19 06:12:40 -08:00
|
|
|
if (!image) return NULL;
|
2003-09-04 00:40:34 -07:00
|
|
|
im = image;
|
2010-01-21 01:42:26 -08:00
|
|
|
if (im->native.data) return image;
|
2006-03-06 18:44:16 -08:00
|
|
|
eng_window_use(re->win);
|
2013-10-16 01:20:14 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
2011-09-30 08:43:51 -07:00
|
|
|
if ((im->tex) && (im->tex->pt)
|
|
|
|
&& (im->tex->pt->dyn.data)
|
|
|
|
&& (im->cs.space == EVAS_COLORSPACE_ARGB8888))
|
2010-08-13 03:34:51 -07:00
|
|
|
{
|
2011-11-10 23:47:25 -08:00
|
|
|
if (im->tex->pt->dyn.data == image_data)
|
|
|
|
{
|
2012-02-28 03:55:14 -08:00
|
|
|
if (im->tex->pt->dyn.checked_out > 0)
|
|
|
|
{
|
|
|
|
im->tex->pt->dyn.checked_out--;
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-02-28 03:55:14 -08:00
|
|
|
if (im->tex->pt->dyn.checked_out == 0)
|
2013-04-12 01:34:13 -07:00
|
|
|
glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
2012-02-28 03:55:14 -08:00
|
|
|
}
|
|
|
|
|
2011-11-10 23:47:25 -08:00
|
|
|
return image;
|
|
|
|
}
|
2012-08-03 03:42:24 -07:00
|
|
|
im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
|
2011-10-19 02:04:18 -07:00
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
if (!im2) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
return im;
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
switch (im->cs.space)
|
2003-09-04 00:40:34 -07:00
|
|
|
{
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2012-08-03 03:42:24 -07:00
|
|
|
if ((!im->im) || (image_data != im->im->image.data))
|
2011-11-10 00:59:09 -08:00
|
|
|
{
|
2012-08-03 03:42:24 -07:00
|
|
|
im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
|
2011-11-10 00:59:09 -08:00
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
if (!im2) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
}
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
2011-08-23 08:13:40 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
2011-08-29 13:56:48 -07:00
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
2011-11-10 00:59:09 -08:00
|
|
|
if (image_data != im->cs.data)
|
|
|
|
{
|
|
|
|
if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
im->cs.data = image_data;
|
|
|
|
}
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
break;
|
2006-12-17 07:48:52 -08:00
|
|
|
default:
|
2011-11-10 00:59:09 -08:00
|
|
|
abort();
|
|
|
|
break;
|
2003-09-04 00:40:34 -07:00
|
|
|
}
|
|
|
|
return im;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
static void
|
2013-06-23 19:41:32 -07:00
|
|
|
eng_image_data_preload_request(void *data, void *image, const Eo *target)
|
2008-09-16 07:52:57 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
2013-06-23 19:41:32 -07:00
|
|
|
Render_Engine *re = data;
|
2008-09-16 07:52:57 -07:00
|
|
|
RGBA_Image *im;
|
|
|
|
|
2010-01-21 01:42:26 -08:00
|
|
|
if (!gim) return;
|
|
|
|
if (gim->native.data) return;
|
|
|
|
im = (RGBA_Image *)gim->im;
|
|
|
|
if (!im) return;
|
2013-10-29 03:06:33 -07:00
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
|
|
|
evas_cache2_image_preload_data(&im->cache_entry, target);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
|
2013-06-23 19:41:32 -07:00
|
|
|
if (!gim->tex)
|
|
|
|
gim->tex = evas_gl_common_texture_new(re->win->gl_context, gim->im);
|
|
|
|
evas_gl_preload_target_register(gim->tex, (Eo*) target);
|
2008-09-16 07:52:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-06-12 23:50:01 -07:00
|
|
|
eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *target)
|
2008-09-16 07:52:57 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
RGBA_Image *im;
|
|
|
|
|
2010-01-21 01:42:26 -08:00
|
|
|
if (!gim) return;
|
|
|
|
if (gim->native.data) return;
|
2012-09-24 00:41:27 -07:00
|
|
|
im = (RGBA_Image *)gim->im;
|
|
|
|
if (!im) return;
|
2013-10-29 03:06:33 -07:00
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
|
|
|
evas_cache2_image_preload_cancel(&im->cache_entry, target);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_preload_cancel(&im->cache_entry, target);
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_gl_preload_target_unregister(gim->tex, (Eo*) target);
|
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
|
|
|
}
|
|
|
|
|
2013-01-11 11:54:12 -08:00
|
|
|
static Eina_Bool
|
2012-12-18 08:28:55 -08:00
|
|
|
eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async EINA_UNUSED)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re;
|
|
|
|
re = (Render_Engine *)data;
|
2012-10-15 01:40:53 -07:00
|
|
|
Evas_GL_Image *im = image;
|
2012-11-20 20:59:52 -08:00
|
|
|
Native *n;
|
2012-10-15 01:40:53 -07:00
|
|
|
|
2013-01-11 11:54:12 -08:00
|
|
|
if (!im) return EINA_FALSE;
|
2012-11-20 20:59:52 -08:00
|
|
|
n = im->native.data;
|
2012-02-24 00:13:48 -08:00
|
|
|
|
2012-11-21 23:58:06 -08:00
|
|
|
if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) &&
|
|
|
|
(n->ns.data.opengl.framebuffer_id == 0) &&
|
2013-06-17 01:53:33 -07:00
|
|
|
re->func.get_pixels)
|
2011-08-24 23:30:52 -07:00
|
|
|
{
|
2013-05-02 03:06:10 -07:00
|
|
|
DBG("Rendering Directly to the window: %p", data);
|
2013-06-17 01:53:33 -07:00
|
|
|
|
|
|
|
re->win->gl_context->dc = context;
|
|
|
|
|
2014-02-14 09:33:47 -08:00
|
|
|
if (re->func.get_pixels)
|
|
|
|
{
|
|
|
|
if ((re->win->gl_context->master_clip.enabled) &&
|
|
|
|
(re->win->gl_context->master_clip.w > 0) &&
|
|
|
|
(re->win->gl_context->master_clip.h > 0))
|
|
|
|
{
|
|
|
|
// Pass the preserve flag info the evas_gl
|
|
|
|
evgl_direct_partial_info_set(re->win->gl_context->preserve_bit);
|
|
|
|
}
|
2013-10-24 01:37:22 -07:00
|
|
|
|
2014-02-14 09:33:47 -08:00
|
|
|
// Set necessary info for direct rendering
|
|
|
|
evgl_direct_info_set(re->win->gl_context->w,
|
|
|
|
re->win->gl_context->h,
|
|
|
|
re->win->gl_context->rot,
|
|
|
|
dst_x, dst_y, dst_w, dst_h,
|
|
|
|
re->win->gl_context->dc->clip.x,
|
|
|
|
re->win->gl_context->dc->clip.y,
|
|
|
|
re->win->gl_context->dc->clip.w,
|
|
|
|
re->win->gl_context->dc->clip.h);
|
|
|
|
|
|
|
|
// Call pixel get function
|
|
|
|
re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
|
|
|
|
|
|
|
|
// Call end tile if it's being used
|
|
|
|
if ((re->win->gl_context->master_clip.enabled) &&
|
|
|
|
(re->win->gl_context->master_clip.w > 0) &&
|
|
|
|
(re->win->gl_context->master_clip.h > 0))
|
|
|
|
{
|
|
|
|
evgl_direct_partial_render_end();
|
|
|
|
evgl_direct_partial_info_clear();
|
|
|
|
re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
|
|
|
|
}
|
2013-10-24 01:37:22 -07:00
|
|
|
|
2014-02-14 09:33:47 -08:00
|
|
|
// Reset direct rendering info
|
|
|
|
evgl_direct_info_clear();
|
|
|
|
}
|
2011-08-24 23:30:52 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
eng_window_use(re->win);
|
|
|
|
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
|
|
|
|
re->win->gl_context->dc = context;
|
|
|
|
evas_gl_common_image_draw(re->win->gl_context, image,
|
|
|
|
src_x, src_y, src_w, src_h,
|
|
|
|
dst_x, dst_y, dst_w, dst_h,
|
|
|
|
smooth);
|
2011-08-24 23:30:52 -07:00
|
|
|
}
|
2013-01-11 11:54:12 -08:00
|
|
|
|
|
|
|
return EINA_FALSE;
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_scale_hint_set(void *data EINA_UNUSED, void *image, int hint)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
if (image) evas_gl_common_image_scale_hint_set(image, hint);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_scale_hint_get(void *data EINA_UNUSED, void *image)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
|
|
|
|
return gim->scale_hint;
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:56:17 -08:00
|
|
|
static Eina_Bool
|
2012-12-18 08:28:55 -08:00
|
|
|
eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Render_Engine *re;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
re = (Render_Engine *)data;
|
2013-01-11 11:56:17 -08:00
|
|
|
if (!image) return EINA_FALSE;
|
2012-09-24 00:41:27 -07:00
|
|
|
eng_window_use(re->win);
|
|
|
|
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
|
|
|
|
re->win->gl_context->dc = context;
|
|
|
|
if (m->count != 4)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
// FIXME: nash - you didn't fix this
|
|
|
|
abort();
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
if ((m->pts[0].x == m->pts[3].x) &&
|
|
|
|
(m->pts[1].x == m->pts[2].x) &&
|
|
|
|
(m->pts[0].y == m->pts[1].y) &&
|
|
|
|
(m->pts[3].y == m->pts[2].y) &&
|
|
|
|
(m->pts[0].x <= m->pts[1].x) &&
|
|
|
|
(m->pts[0].y <= m->pts[2].y) &&
|
|
|
|
(m->pts[0].u == 0) &&
|
|
|
|
(m->pts[0].v == 0) &&
|
|
|
|
(m->pts[1].u == (gim->w << FP)) &&
|
|
|
|
(m->pts[1].v == 0) &&
|
|
|
|
(m->pts[2].u == (gim->w << FP)) &&
|
|
|
|
(m->pts[2].v == (gim->h << FP)) &&
|
|
|
|
(m->pts[3].u == 0) &&
|
|
|
|
(m->pts[3].v == (gim->h << FP)) &&
|
|
|
|
(m->pts[0].col == 0xffffffff) &&
|
|
|
|
(m->pts[1].col == 0xffffffff) &&
|
|
|
|
(m->pts[2].col == 0xffffffff) &&
|
|
|
|
(m->pts[3].col == 0xffffffff))
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
int dx, dy, dw, dh;
|
|
|
|
|
|
|
|
dx = m->pts[0].x >> FP;
|
|
|
|
dy = m->pts[0].y >> FP;
|
|
|
|
dw = (m->pts[2].x >> FP) - dx;
|
|
|
|
dh = (m->pts[2].y >> FP) - dy;
|
|
|
|
eng_image_draw(data, context, surface, image,
|
2012-12-18 08:28:55 -08:00
|
|
|
0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth, do_async);
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0],
|
|
|
|
smooth, level);
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
2013-01-11 11:56:17 -08:00
|
|
|
|
|
|
|
return EINA_FALSE;
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_map_clean(void *data EINA_UNUSED, RGBA_Map *m EINA_UNUSED)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
}
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
|
|
|
eng_image_map_surface_new(void *data, int w, int h, int alpha)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-02-09 17:40:53 -08:00
|
|
|
eng_window_use(re->win);
|
2012-09-24 00:41:27 -07:00
|
|
|
return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-02-09 17:40:53 -08:00
|
|
|
eng_image_map_surface_free(void *data, void *surface)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2014-02-09 17:40:53 -08:00
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
eng_window_use(re->win);
|
2012-09-24 00:41:27 -07:00
|
|
|
evas_gl_common_image_free(surface);
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
2012-05-02 19:33:18 -07:00
|
|
|
static void
|
2014-02-06 19:17:59 -08:00
|
|
|
eng_image_content_hint_set(void *data, void *image, int hint)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2014-02-06 19:17:59 -08:00
|
|
|
Render_Engine *re;
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
|
|
|
|
if (re) eng_window_use(re->win);
|
2012-09-24 00:41:27 -07:00
|
|
|
if (image) evas_gl_common_image_content_hint_set(image, hint);
|
|
|
|
}
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_content_hint_get(void *data EINA_UNUSED, void *image)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
|
|
|
|
return gim->content_hint;
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-09-24 00:41:27 -07:00
|
|
|
eng_image_cache_flush(void *data)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re;
|
|
|
|
int tmp_size;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
re = (Render_Engine *)data;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2013-11-18 01:20:35 -08:00
|
|
|
eng_window_use(re->win);
|
2013-11-12 23:58:01 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
tmp_size = evas_common_image_get_cache();
|
|
|
|
evas_common_image_set_cache(0);
|
|
|
|
evas_common_rgba_image_scalecache_flush();
|
|
|
|
evas_gl_common_image_cache_flush(re->win->gl_context);
|
|
|
|
evas_common_image_set_cache(tmp_size);
|
|
|
|
}
|
2012-01-20 04:29:14 -08:00
|
|
|
|
|
|
|
static void
|
2012-09-24 00:41:27 -07:00
|
|
|
eng_image_cache_set(void *data, int bytes)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
re = (Render_Engine *)data;
|
2013-11-12 23:58:01 -08:00
|
|
|
|
2013-11-18 01:20:35 -08:00
|
|
|
eng_window_use(re->win);
|
2013-11-12 23:58:01 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
evas_common_image_set_cache(bytes);
|
|
|
|
evas_common_rgba_image_scalecache_size_set(bytes);
|
|
|
|
evas_gl_common_image_cache_flush(re->win->gl_context);
|
|
|
|
}
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_cache_get(void *data EINA_UNUSED)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
return evas_common_image_get_cache();
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_stride_get(void *data EINA_UNUSED, void *image, int *stride)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Evas_GL_Image *im = image;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if ((im->tex) && (im->tex->pt->dyn.img))
|
|
|
|
*stride = im->tex->pt->dyn.stride;
|
2012-01-20 04:29:14 -08:00
|
|
|
else
|
2012-09-24 00:41:27 -07:00
|
|
|
*stride = im->w * 4;
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:55:40 -08:00
|
|
|
static Eina_Bool
|
2012-12-18 08:28:55 -08:00
|
|
|
eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *intl_props, Eina_Bool do_async EINA_UNUSED)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
re = (Render_Engine *)data;
|
|
|
|
eng_window_use(re->win);
|
|
|
|
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
|
|
|
|
re->win->gl_context->dc = context;
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
// FIXME: put im into context so we can free it
|
|
|
|
static RGBA_Image *im = NULL;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
if (!im)
|
|
|
|
im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
|
|
|
im->cache_entry.w = re->win->gl_context->shared->w;
|
|
|
|
im->cache_entry.h = re->win->gl_context->shared->h;
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
evas_common_draw_context_font_ext_set(context,
|
|
|
|
re->win->gl_context,
|
|
|
|
evas_gl_font_texture_new,
|
|
|
|
evas_gl_font_texture_free,
|
|
|
|
evas_gl_font_texture_draw);
|
|
|
|
evas_common_font_draw_prepare(intl_props);
|
2012-12-17 13:27:07 -08:00
|
|
|
evas_common_font_draw(im, context, x, y, intl_props->glyphs);
|
2012-09-24 00:41:27 -07:00
|
|
|
evas_common_draw_context_font_ext_set(context,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
2013-01-11 11:55:40 -08:00
|
|
|
|
|
|
|
return EINA_FALSE;
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static Eina_Bool
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_canvas_alpha_get(void *data, void *info EINA_UNUSED)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
return re->win->alpha;
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
//--------------------------------//
|
|
|
|
// Evas GL Related Code
|
|
|
|
static void *
|
|
|
|
eng_gl_surface_create(void *data, void *config, int w, int h)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
2011-05-01 19:14:00 -07:00
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, NULL);
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_surface_create(data, cfg, w, h);
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
|
|
|
eng_gl_surface_destroy(void *data, void *surface)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, 0);
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_surface_destroy(data, sfc);
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static void *
|
|
|
|
eng_gl_context_create(void *data, void *share_context)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
EVGL_Context *sctx = (EVGL_Context *)share_context;
|
2013-05-02 03:06:10 -07:00
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, NULL);
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_context_create(data, sctx);
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
|
|
|
eng_gl_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
|
|
|
{
|
2012-09-24 00:41:27 -07:00
|
|
|
EVGL_Context *ctx = (EVGL_Context *)context;
|
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, 0);
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_context_destroy(data, ctx);
|
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
|
2013-02-26 05:52:37 -08:00
|
|
|
eng_gl_make_current(void *data, void *surface, 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
|
|
|
{
|
2014-02-14 09:33:47 -08:00
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
2012-09-24 00:41:27 -07:00
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
EVGL_Context *ctx = (EVGL_Context *)context;
|
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, 0);
|
2014-02-14 09:33:47 -08:00
|
|
|
if ((sfc) && (ctx))
|
|
|
|
{
|
|
|
|
if ((re->win->gl_context->havestuff) ||
|
|
|
|
(re->win->gl_context->master_clip.used))
|
|
|
|
{
|
|
|
|
eng_window_use(re->win);
|
|
|
|
evas_gl_common_context_flush(re->win->gl_context);
|
|
|
|
if (re->win->gl_context->master_clip.used)
|
|
|
|
evas_gl_common_context_done(re->win->gl_context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_make_current(data, sfc, ctx);
|
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 *
|
2013-05-20 02:09:50 -07:00
|
|
|
eng_gl_string_query(void *data, int name)
|
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
|
|
|
{
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, NULL);
|
2013-05-02 03:06:10 -07:00
|
|
|
return (void *)evgl_string_query(name);
|
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
|
|
|
// Need to deprecate this function..
|
|
|
|
static void *
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_gl_proc_address_get(void *data EINA_UNUSED, const char *name EINA_UNUSED)
|
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
|
|
|
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
|
|
|
}
|
2011-05-01 19:14:00 -07:00
|
|
|
|
2012-09-24 00:41:27 -07:00
|
|
|
static int
|
2013-05-02 03:06:10 -07:00
|
|
|
eng_gl_native_surface_get(void *data EINA_UNUSED, void *surface, void *native_surface)
|
2012-09-24 00:41:27 -07:00
|
|
|
{
|
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
Evas_Native_Surface *ns = (Evas_Native_Surface *)native_surface;
|
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
|
|
|
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_native_surface_get(sfc, ns);
|
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
|
|
|
|
2011-05-01 19:14:00 -07:00
|
|
|
static void *
|
2013-05-20 02:09:50 -07:00
|
|
|
eng_gl_api_get(void *data)
|
2011-05-01 19:14:00 -07:00
|
|
|
{
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, NULL);
|
2013-05-02 03:06:10 -07:00
|
|
|
return evgl_api_get();
|
2011-05-01 19:14:00 -07:00
|
|
|
}
|
|
|
|
|
2013-06-17 01:53:33 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
eng_gl_direct_override_get(void *data, int *override, int *force_off)
|
|
|
|
{
|
|
|
|
EVGLINIT(data, );
|
|
|
|
evgl_direct_override_get(override, force_off);
|
|
|
|
}
|
|
|
|
|
2012-01-20 04:29:14 -08:00
|
|
|
static void
|
2013-06-17 01:53:33 -07:00
|
|
|
eng_gl_get_pixels_set(void *data, void *get_pixels, void *get_pixels_data, void *obj)
|
2012-01-20 04:29:14 -08:00
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
2013-05-20 02:09:50 -07:00
|
|
|
EVGLINIT(data, );
|
2013-06-17 01:53:33 -07:00
|
|
|
re->func.get_pixels = get_pixels;
|
|
|
|
re->func.get_pixels_data = get_pixels_data;
|
|
|
|
re->func.obj = (Evas_Object*)obj;
|
2012-01-20 04:29:14 -08:00
|
|
|
}
|
2014-03-06 00:42:24 -08:00
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_lock(void *data, void *surface)
|
|
|
|
{
|
|
|
|
Render_Engine *re = data;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
EVGLINIT(re, EINA_FALSE);
|
|
|
|
if (!im->tex || !im->tex->pt)
|
|
|
|
{
|
|
|
|
ERR("Can not lock image that is not a surface!");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_gl_common_context_flush(im->gc);
|
|
|
|
im->locked = EINA_TRUE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_unlock(void *data, void *surface)
|
|
|
|
{
|
|
|
|
Render_Engine *re = data;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
EVGLINIT(re, EINA_FALSE);
|
|
|
|
im->locked = EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_read_pixels(void *data, void *surface,
|
|
|
|
int x, int y, int w, int h,
|
|
|
|
Evas_Colorspace cspace, void *pixels)
|
|
|
|
{
|
|
|
|
Render_Engine *re = data;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, EINA_FALSE);
|
|
|
|
|
|
|
|
EVGLINIT(re, EINA_FALSE);
|
|
|
|
if (!im->locked)
|
|
|
|
{
|
|
|
|
// For now, this is useless, but let's force clients to lock :)
|
|
|
|
CRI("The surface must be locked before reading its pixels!");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cspace != EVAS_COLORSPACE_ARGB8888)
|
|
|
|
{
|
|
|
|
ERR("Conversion to colorspace %d is not supported!", (int) cspace);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-03-07 00:45:16 -08:00
|
|
|
#ifdef GL_GLES
|
|
|
|
# ifndef GL_FRAMEBUFFER
|
|
|
|
# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
|
|
|
|
# endif
|
|
|
|
#else
|
|
|
|
# ifndef GL_FRAMEBUFFER
|
|
|
|
# define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2014-03-12 23:54:58 -07:00
|
|
|
/* Since this is an FBO, the pixels are already in the right Y order.
|
|
|
|
* But some devices don't support GL_BGRA, so we still need to convert.
|
|
|
|
*/
|
|
|
|
|
2014-03-07 00:45:16 -08:00
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
|
2014-03-12 23:54:58 -07:00
|
|
|
if (im->tex->pt->format == GL_BGRA)
|
|
|
|
glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DATA32 *ptr = pixels;
|
|
|
|
int k;
|
|
|
|
|
|
|
|
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
|
|
for (k = w * h; k; --k)
|
|
|
|
{
|
|
|
|
const DATA32 v = *ptr;
|
|
|
|
*ptr++ = (v & 0xFF00FF00)
|
|
|
|
| ((v & 0x00FF0000) >> 16)
|
|
|
|
| ((v & 0x000000FF) << 16);
|
|
|
|
}
|
|
|
|
}
|
2014-03-07 00:45:16 -08:00
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2014-03-12 23:54:58 -07:00
|
|
|
|
2014-03-06 00:42:24 -08:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2012-09-24 00:41:27 -07:00
|
|
|
//--------------------------------//
|
2012-01-20 04:29:14 -08:00
|
|
|
|
2011-05-19 04:19:22 -07:00
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_load_error_get(void *data EINA_UNUSED, void *image)
|
2011-05-19 04:19:22 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-05-19 04:19:22 -07:00
|
|
|
if (!image) return EVAS_LOAD_ERROR_NONE;
|
|
|
|
im = image;
|
|
|
|
return im->im->cache_entry.load_error;
|
|
|
|
}
|
2011-05-01 19:14:00 -07:00
|
|
|
|
2011-08-10 23:04:08 -07:00
|
|
|
static Eina_Bool
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_animated_get(void *data EINA_UNUSED, void *image)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2011-10-18 02:10:26 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
2011-08-10 23:04:08 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
2011-10-18 02:10:26 -07:00
|
|
|
if (!gim) return EINA_FALSE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
return im->animated.animated;
|
2011-08-10 23:04:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_animated_frame_count_get(void *data EINA_UNUSED, void *image)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2011-10-18 02:10:26 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
2011-08-10 23:04:08 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
2011-10-18 02:10:26 -07:00
|
|
|
if (!gim) return -1;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return -1;
|
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
if (!im->animated.animated) return -1;
|
|
|
|
return im->animated.frame_count;
|
2011-08-10 23:04:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Image_Animated_Loop_Hint
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_animated_loop_type_get(void *data EINA_UNUSED, void *image)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2011-10-18 02:10:26 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
2011-08-10 23:04:08 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
2011-10-18 02:10:26 -07:00
|
|
|
if (!gim) return EVAS_IMAGE_ANIMATED_HINT_NONE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EVAS_IMAGE_ANIMATED_HINT_NONE;
|
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
if (!im->animated.animated) return EVAS_IMAGE_ANIMATED_HINT_NONE;
|
|
|
|
return im->animated.loop_hint;
|
2011-08-10 23:04:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_animated_loop_count_get(void *data EINA_UNUSED, void *image)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2011-10-18 02:10:26 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
2011-08-10 23:04:08 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
2011-10-18 02:10:26 -07:00
|
|
|
if (!gim) return -1;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return -1;
|
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
if (!im->animated.animated) return -1;
|
|
|
|
return im->animated.loop_count;
|
2011-08-10 23:04:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static double
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_animated_frame_duration_get(void *data EINA_UNUSED, void *image, int start_frame, int frame_num)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2011-10-18 02:10:26 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
2011-08-10 23:04:08 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
2011-10-18 02:10:26 -07:00
|
|
|
if (!gim) return -1;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return -1;
|
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
if (!im->animated.animated) return -1;
|
2011-08-10 23:04:08 -07:00
|
|
|
return evas_common_load_rgba_image_frame_duration_from_file(im, start_frame, frame_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_animated_frame_set(void *data EINA_UNUSED, void *image, int frame_index)
|
2011-08-10 23:04:08 -07:00
|
|
|
{
|
2011-10-18 02:10:26 -07:00
|
|
|
Evas_GL_Image *gim = image;
|
2011-08-10 23:04:08 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
2011-10-18 02:10:26 -07:00
|
|
|
if (!gim) return EINA_FALSE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
if (!im->animated.animated) return EINA_FALSE;
|
|
|
|
if (im->animated.cur_frame == frame_index) return EINA_FALSE;
|
2011-08-10 23:04:08 -07:00
|
|
|
|
2013-04-24 23:05:18 -07:00
|
|
|
im->animated.cur_frame = frame_index;
|
2011-08-10 23:04:08 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-12-13 08:58:20 -08:00
|
|
|
static Eina_Bool
|
2012-11-04 03:51:42 -08:00
|
|
|
eng_image_can_region_get(void *data EINA_UNUSED, void *image)
|
2011-12-13 08:58:20 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
if (!gim) return EINA_FALSE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
return ((Evas_Image_Load_Func*) im->info.loader)->do_region;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-21 01:17:14 -07:00
|
|
|
static void
|
|
|
|
eng_image_max_size_get(void *data, int *maxw, int *maxh)
|
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
if (maxw) *maxw = re->win->gl_context->shared->info.max_texture_size;
|
|
|
|
if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size;
|
|
|
|
}
|
|
|
|
|
2013-02-17 09:30:11 -08:00
|
|
|
static Eina_Bool
|
|
|
|
eng_pixel_alpha_get(void *image, int x, int y, DATA8 *alpha, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
int px, py, dx, dy, sx, sy, src_w, src_h;
|
|
|
|
double scale_w, scale_h;
|
|
|
|
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
|
|
|
|
if ((dst_region_x > x) || (x >= (dst_region_x + dst_region_w)) ||
|
|
|
|
(dst_region_y > y) || (y >= (dst_region_y + dst_region_h)))
|
|
|
|
{
|
|
|
|
*alpha = 0;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2013-10-16 01:20:14 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
2013-02-17 09:30:11 -08:00
|
|
|
src_w = im->im->cache_entry.w;
|
|
|
|
src_h = im->im->cache_entry.h;
|
|
|
|
if ((src_w == 0) || (src_h == 0))
|
|
|
|
{
|
|
|
|
*alpha = 0;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(src_region_x < 0, error_oob);
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(src_region_y < 0, error_oob);
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(src_region_x + src_region_w > src_w, error_oob);
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(src_region_y + src_region_h > src_h, error_oob);
|
|
|
|
|
|
|
|
scale_w = (double)dst_region_w / (double)src_region_w;
|
|
|
|
scale_h = (double)dst_region_h / (double)src_region_h;
|
|
|
|
|
|
|
|
/* point at destination */
|
|
|
|
dx = x - dst_region_x;
|
|
|
|
dy = y - dst_region_y;
|
|
|
|
|
|
|
|
/* point at source */
|
|
|
|
sx = dx / scale_w;
|
|
|
|
sy = dy / scale_h;
|
|
|
|
|
|
|
|
/* pixel point (translated) */
|
|
|
|
px = src_region_x + sx;
|
|
|
|
py = src_region_y + sy;
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(px >= src_w, error_oob);
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(py >= src_h, error_oob);
|
|
|
|
|
|
|
|
switch (im->im->cache_entry.space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
{
|
|
|
|
DATA32 *pixel;
|
|
|
|
|
2013-10-29 03:06:33 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
|
|
|
evas_cache2_image_load_data(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
2013-02-17 09:30:11 -08:00
|
|
|
if (!im->im->cache_entry.flags.loaded)
|
|
|
|
{
|
|
|
|
ERR("im %p has no pixels loaded yet", im);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pixel = im->im->image.data;
|
|
|
|
pixel += ((py * src_w) + px);
|
|
|
|
*alpha = ((*pixel) >> 24) & 0xff;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ERR("Colorspace %d not supported.", im->im->cache_entry.space);
|
|
|
|
*alpha = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
error_oob:
|
|
|
|
ERR("Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d",
|
|
|
|
src_region_x, src_region_y, src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y, dst_region_w, dst_region_h,
|
|
|
|
src_w, src_h);
|
|
|
|
*alpha = 0;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2013-05-12 22:12:36 -07:00
|
|
|
static void
|
|
|
|
eng_context_flush(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
|
2014-02-14 09:33:47 -08:00
|
|
|
if ((re->win->gl_context->havestuff) ||
|
|
|
|
(re->win->gl_context->master_clip.used))
|
|
|
|
{
|
|
|
|
eng_window_use(re->win);
|
|
|
|
evas_gl_common_context_flush(re->win->gl_context);
|
|
|
|
if (re->win->gl_context->master_clip.used)
|
|
|
|
evas_gl_common_context_done(re->win->gl_context);
|
|
|
|
}
|
2013-05-12 22:12:36 -07:00
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static int
|
2006-09-06 00:28:46 -07:00
|
|
|
module_open(Evas_Module *em)
|
2006-01-14 04:13:38 -08:00
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
static Eina_Bool xrm_inited = EINA_FALSE;
|
|
|
|
if (!xrm_inited)
|
|
|
|
{
|
|
|
|
xrm_inited = EINA_TRUE;
|
|
|
|
XrmInitialize();
|
|
|
|
}
|
|
|
|
|
2006-01-14 04:13:38 -08:00
|
|
|
if (!em) return 0;
|
2010-10-07 16:46:42 -07:00
|
|
|
if (!evas_gl_common_module_open()) return 0;
|
2006-12-09 00:52:08 -08:00
|
|
|
/* get whatever engine module we inherit from */
|
|
|
|
if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
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)
|
2009-10-22 08:22:22 -07:00
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
EINA_LOG_ERR("Can not create a module log domain.");
|
2009-11-13 00:28:47 -08:00
|
|
|
return 0;
|
2009-10-22 08:22:22 -07:00
|
|
|
}
|
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
|
|
|
|
2006-12-09 00:52:08 -08:00
|
|
|
/* store it for later use */
|
|
|
|
func = pfunc;
|
|
|
|
/* now to override methods */
|
2011-12-17 21:03:24 -08:00
|
|
|
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(info);
|
|
|
|
ORD(info_free);
|
|
|
|
ORD(setup);
|
2009-08-14 10:11:08 -07:00
|
|
|
ORD(canvas_alpha_get);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(output_free);
|
|
|
|
ORD(output_resize);
|
|
|
|
ORD(output_tile_size_set);
|
|
|
|
ORD(output_redraws_rect_add);
|
|
|
|
ORD(output_redraws_rect_del);
|
|
|
|
ORD(output_redraws_clear);
|
|
|
|
ORD(output_redraws_next_update_get);
|
|
|
|
ORD(output_redraws_next_update_push);
|
|
|
|
ORD(context_cutout_add);
|
|
|
|
ORD(context_cutout_clear);
|
|
|
|
ORD(output_flush);
|
2007-06-16 19:56:59 -07:00
|
|
|
ORD(output_idle_flush);
|
2010-04-12 01:23:53 -07:00
|
|
|
ORD(output_dump);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(rectangle_draw);
|
|
|
|
ORD(line_draw);
|
|
|
|
ORD(polygon_point_add);
|
|
|
|
ORD(polygon_points_clear);
|
|
|
|
ORD(polygon_draw);
|
2008-08-25 22:45:04 -07:00
|
|
|
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(image_load);
|
2013-05-07 23:37:37 -07:00
|
|
|
ORD(image_mmap);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(image_new_from_data);
|
|
|
|
ORD(image_new_from_copied_data);
|
|
|
|
ORD(image_free);
|
|
|
|
ORD(image_size_get);
|
|
|
|
ORD(image_size_set);
|
|
|
|
ORD(image_dirty_region);
|
|
|
|
ORD(image_data_get);
|
|
|
|
ORD(image_data_put);
|
2008-09-16 07:52:57 -07:00
|
|
|
ORD(image_data_preload_request);
|
|
|
|
ORD(image_data_preload_cancel);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(image_alpha_set);
|
|
|
|
ORD(image_alpha_get);
|
2008-11-04 01:19:35 -08:00
|
|
|
ORD(image_border_set);
|
|
|
|
ORD(image_border_get);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(image_draw);
|
|
|
|
ORD(image_comment_get);
|
|
|
|
ORD(image_format_get);
|
|
|
|
ORD(image_colorspace_set);
|
|
|
|
ORD(image_colorspace_get);
|
2011-12-23 04:00:52 -08:00
|
|
|
ORD(image_can_region_get);
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(image_native_set);
|
|
|
|
ORD(image_native_get);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2006-12-09 00:52:08 -08:00
|
|
|
ORD(font_draw);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-05-07 06:29:56 -07:00
|
|
|
ORD(image_scale_hint_set);
|
|
|
|
ORD(image_scale_hint_get);
|
2010-08-18 20:30:47 -07:00
|
|
|
ORD(image_stride_get);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-02-06 15:52:17 -08:00
|
|
|
ORD(image_map_draw);
|
2009-11-06 03:32:23 -08:00
|
|
|
ORD(image_map_surface_new);
|
|
|
|
ORD(image_map_surface_free);
|
2012-07-04 02:39:23 -07:00
|
|
|
ORD(image_map_clean);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-11 23:11:13 -07:00
|
|
|
ORD(image_content_hint_set);
|
|
|
|
ORD(image_content_hint_get);
|
2011-02-08 03:41:38 -08:00
|
|
|
|
|
|
|
ORD(image_cache_flush);
|
|
|
|
ORD(image_cache_set);
|
|
|
|
ORD(image_cache_get);
|
2011-04-04 03:23:12 -07:00
|
|
|
|
|
|
|
ORD(gl_surface_create);
|
|
|
|
ORD(gl_surface_destroy);
|
|
|
|
ORD(gl_context_create);
|
|
|
|
ORD(gl_context_destroy);
|
|
|
|
ORD(gl_make_current);
|
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
|
|
|
ORD(gl_string_query);
|
2011-04-04 03:23:12 -07:00
|
|
|
ORD(gl_proc_address_get);
|
|
|
|
ORD(gl_native_surface_get);
|
2011-05-01 19:14:00 -07:00
|
|
|
ORD(gl_api_get);
|
2013-06-17 01:53:33 -07:00
|
|
|
ORD(gl_direct_override_get);
|
|
|
|
ORD(gl_get_pixels_set);
|
2014-03-06 00:42:24 -08:00
|
|
|
ORD(gl_surface_lock);
|
|
|
|
ORD(gl_surface_read_pixels);
|
|
|
|
ORD(gl_surface_unlock);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-05-19 04:19:22 -07:00
|
|
|
ORD(image_load_error_get);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-08-10 23:04:08 -07:00
|
|
|
/* now advertise out own api */
|
|
|
|
ORD(image_animated_get);
|
|
|
|
ORD(image_animated_frame_count_get);
|
|
|
|
ORD(image_animated_loop_type_get);
|
|
|
|
ORD(image_animated_loop_count_get);
|
|
|
|
ORD(image_animated_frame_duration_get);
|
|
|
|
ORD(image_animated_frame_set);
|
|
|
|
|
2011-10-21 01:17:14 -07:00
|
|
|
ORD(image_max_size_get);
|
2011-11-10 00:59:09 -08:00
|
|
|
|
2013-02-17 09:30:11 -08:00
|
|
|
ORD(pixel_alpha_get);
|
|
|
|
|
2013-05-12 22:12:36 -07:00
|
|
|
ORD(context_flush);
|
|
|
|
|
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
|
|
|
{
|
2012-05-15 06:13:05 -07:00
|
|
|
eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
|
2010-10-07 16:46:42 -07:00
|
|
|
evas_gl_common_module_close();
|
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 :*/
|