2014-07-11 06:11:58 -07:00
|
|
|
#include "evas_common_private.h"
|
|
|
|
#include "evas_gl_core_private.h"
|
|
|
|
|
2015-04-17 02:54:11 -07:00
|
|
|
#include "software/Ector_Software.h"
|
2015-12-02 22:10:18 -08:00
|
|
|
#include "cairo/Ector_Cairo.h"
|
2016-01-03 16:10:53 -08:00
|
|
|
#include "gl/Ector_GL.h"
|
2017-08-15 22:06:51 -07:00
|
|
|
#include "evas_ector_gl.h"
|
2017-01-17 04:34:48 -08:00
|
|
|
#include "filters/gl_engine_filter.h"
|
2015-04-17 02:54:11 -07:00
|
|
|
|
2015-12-28 05:22:29 -08:00
|
|
|
#if defined HAVE_DLSYM && ! defined _WIN32
|
2014-07-11 06:11:58 -07:00
|
|
|
# include <dlfcn.h> /* dlopen,dlclose,etc */
|
|
|
|
#else
|
|
|
|
# error gl_x11 should not get compiled if dlsym is not found on the system!
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "../gl_common/evas_gl_common.h"
|
|
|
|
|
|
|
|
#include "Evas_Engine_GL_Generic.h"
|
|
|
|
|
|
|
|
#define EVAS_GL_NO_GL_H_CHECK 1
|
|
|
|
#include "Evas_GL.h"
|
|
|
|
|
|
|
|
#define EVAS_GL_UPDATE_TILE_SIZE 16
|
|
|
|
|
2017-01-23 00:55:17 -08:00
|
|
|
int _evas_engine_GL_log_dom = -1;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2015-04-14 01:27:06 -07:00
|
|
|
#undef ERR
|
|
|
|
#undef DBG
|
|
|
|
#undef INF
|
|
|
|
#undef WRN
|
|
|
|
#undef CRI
|
|
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_GL_log_dom, __VA_ARGS__)
|
|
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_GL_log_dom, __VA_ARGS__)
|
|
|
|
#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_GL_log_dom, __VA_ARGS__)
|
|
|
|
#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_GL_log_dom, __VA_ARGS__)
|
|
|
|
#define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_GL_log_dom, __VA_ARGS__)
|
|
|
|
|
2015-04-22 02:25:38 -07: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
|
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
static int eng_gl_image_direct_get(void *data, void *image);
|
2015-04-22 02:25:38 -07:00
|
|
|
static int eng_gl_surface_destroy(void *data, void *surface);
|
2015-07-01 19:52:16 -07:00
|
|
|
static Eina_Bool eng_gl_surface_lock(void *data, void *surface);
|
|
|
|
static Eina_Bool eng_gl_surface_unlock(void *data, void *surface);
|
|
|
|
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);
|
2015-03-02 23:38:52 -08:00
|
|
|
|
2015-08-18 01:35:40 -07:00
|
|
|
Eina_Bool _need_context_restore = EINA_FALSE;
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
static Render_Output_GL_Generic *
|
|
|
|
_evgl_output_find(Render_Engine_GL_Generic *engine)
|
|
|
|
{
|
|
|
|
Render_Output_GL_Generic *output = NULL;
|
|
|
|
EVGL_Resource *rsc;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (engine->current)
|
|
|
|
{
|
|
|
|
output = engine->current;
|
|
|
|
goto picked;
|
|
|
|
}
|
|
|
|
|
|
|
|
rsc = _evgl_tls_resource_get();
|
|
|
|
if (rsc &&
|
|
|
|
rsc->stored.data)
|
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
|
|
|
if (output == rsc->stored.data) goto picked;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
|
|
|
{
|
|
|
|
if (output->software.ob) goto picked;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
picked:
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2016-07-19 05:08:02 -07:00
|
|
|
static Evas_Func func, pfunc;
|
|
|
|
|
2015-08-18 01:35:40 -07:00
|
|
|
void
|
|
|
|
_context_restore(void)
|
|
|
|
{
|
|
|
|
EVGL_Resource *rsc = _evgl_tls_resource_get();
|
|
|
|
if (rsc)
|
|
|
|
{
|
|
|
|
if (rsc->id == evgl_engine->main_tid)
|
|
|
|
{
|
2015-07-29 17:14:08 -07:00
|
|
|
if (rsc->stored.data)
|
|
|
|
evgl_make_current(rsc->stored.data, rsc->stored.surface, rsc->stored.context);
|
2015-08-18 01:35:40 -07:00
|
|
|
_need_context_restore = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
_context_store(void *data, void *surface, void *context)
|
|
|
|
{
|
|
|
|
EVGL_Resource *rsc = _evgl_tls_resource_get();
|
|
|
|
if (rsc)
|
|
|
|
{
|
|
|
|
if (rsc->id == evgl_engine->main_tid)
|
|
|
|
{
|
|
|
|
_need_context_restore = EINA_FALSE;
|
|
|
|
rsc->stored.data = data;
|
|
|
|
rsc->stored.surface = surface;
|
|
|
|
rsc->stored.context = context;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
_context_stored_reset(void *data EINA_UNUSED, void *surface)
|
|
|
|
{
|
|
|
|
EVGL_Resource *rsc = _evgl_tls_resource_get();
|
|
|
|
if (rsc && rsc->stored.surface == surface)
|
|
|
|
{
|
|
|
|
_need_context_restore = EINA_FALSE;
|
|
|
|
rsc->stored.data = NULL;
|
|
|
|
rsc->stored.surface = NULL;
|
|
|
|
rsc->stored.context = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CONTEXT_STORE(data, surface, context) _context_store(data, surface, context)
|
|
|
|
#define CONTEXT_STORED_RESET(data, surface) _context_stored_reset(data, surface)
|
|
|
|
|
2017-08-25 15:44:19 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
static void *
|
|
|
|
egl_display_get(Render_Engine_GL_Generic *engine)
|
|
|
|
{
|
|
|
|
Render_Output_GL_Generic *output;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
|
|
|
if (output->software.ob)
|
|
|
|
return output->window_egl_display_get(output->software.ob);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-11-08 17:31:12 -08:00
|
|
|
void eng_image_free(void *engine, void *image);
|
|
|
|
|
2017-08-25 10:50:35 -07:00
|
|
|
static void *
|
|
|
|
eng_engine_new(void)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *engine;
|
|
|
|
|
|
|
|
engine = calloc(1, sizeof (Render_Engine_GL_Generic));
|
|
|
|
if (!engine) return NULL;
|
2017-11-08 17:31:12 -08:00
|
|
|
engine->software.surface_cache = generic_cache_new(engine, eng_image_free);
|
2017-08-25 10:50:35 -07:00
|
|
|
|
|
|
|
return engine;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_engine_free(void *engine)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *e = engine;
|
|
|
|
Render_Output_GL_Generic *output;
|
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
//@FIXME this causes some deadlock while freeing the engine image.
|
|
|
|
//generic_cache_destroy(e->software.surface_cache);
|
2017-11-08 17:31:12 -08:00
|
|
|
|
2017-08-25 10:50:35 -07:00
|
|
|
EINA_LIST_FREE(e->software.outputs, output)
|
|
|
|
ERR("Output %p not properly cleaned before engine destruction.", output);
|
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_rectangle_draw(void *engine EINA_UNUSED, void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
2017-08-25 10:48:00 -07:00
|
|
|
Render_Output_GL_Generic *re = data;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(re, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
|
|
|
evas_gl_common_rect_draw(gl_context, x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_line_draw(void *engine EINA_UNUSED, void *data, void *context, void *surface, int p1x, int p1y, int p2x, int p2y, Eina_Bool do_async EINA_UNUSED)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
2017-08-25 10:48:00 -07:00
|
|
|
Render_Output_GL_Generic *re = data;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(re, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
|
|
|
evas_gl_common_line_draw(gl_context, p1x, p1y, p2x, p2y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_polygon_point_add(void *engine EINA_UNUSED, void *polygon, int x, int y)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
return evas_gl_common_poly_point_add(polygon, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_polygon_points_clear(void *engine EINA_UNUSED, void *polygon)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
return evas_gl_common_poly_points_clear(polygon);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_polygon_draw(void *engine EINA_UNUSED, void *data, void *context, void *surface EINA_UNUSED, void *polygon, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
2017-08-25 10:48:00 -07:00
|
|
|
Render_Output_GL_Generic *re = data;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(re, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
|
|
|
evas_gl_common_poly_draw(gl_context, polygon, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_alpha_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Evas_GL_Image *im = image;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
if (!im) return 1;
|
2014-07-11 06:11:58 -07:00
|
|
|
return im->alpha;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Colorspace
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_colorspace_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Evas_GL_Image *im = image;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
if (!im) return EVAS_COLORSPACE_ARGB8888;
|
2014-07-11 06:11:58 -07:00
|
|
|
return im->cs.space;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_alpha_set(void *engine, void *image, int has_alpha)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
im = image;
|
|
|
|
if (im->alpha == has_alpha) return image;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
im->alpha = has_alpha;
|
|
|
|
return image;
|
|
|
|
}
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
if ((im->tex) && (im->tex->pt->dyn.img))
|
|
|
|
{
|
|
|
|
im->alpha = has_alpha;
|
|
|
|
im->tex->alpha = im->alpha;
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
/* FIXME: can move to gl_common */
|
|
|
|
if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
|
|
|
|
if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image;
|
|
|
|
else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image;
|
|
|
|
if (im->references > 1)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im_new;
|
|
|
|
|
|
|
|
if (!im->im->image.data)
|
2018-08-29 21:32:51 -07:00
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
|
|
|
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,
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_alpha_get(engine, image),
|
|
|
|
eng_image_colorspace_get(engine, image));
|
2014-07-11 06:11:58 -07:00
|
|
|
if (!im_new) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im_new;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
return evas_gl_common_image_alpha_set(im, has_alpha ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
2015-10-29 05:46:08 -07:00
|
|
|
static Evas_Colorspace
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_file_colorspace_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2015-10-29 05:46:08 -07:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
|
|
|
if (!im || !im->im) return EVAS_COLORSPACE_ARGB8888;
|
|
|
|
if (im->im->cache_entry.cspaces)
|
|
|
|
return im->im->cache_entry.cspaces[0];
|
|
|
|
return im->im->cache_entry.space;
|
|
|
|
}
|
|
|
|
|
2016-09-02 01:55:33 -07:00
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_direct_get(void *engine EINA_UNUSED, void *image, int plane,
|
2016-12-20 00:56:09 -08:00
|
|
|
Eina_Slice *slice, Evas_Colorspace *cspace,
|
|
|
|
Eina_Bool load)
|
2015-10-29 05:46:08 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
2016-09-02 01:55:33 -07:00
|
|
|
if (!slice || !im || !im->im)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2016-03-21 05:08:29 -07:00
|
|
|
if (cspace) *cspace = im->im->cache_entry.space;
|
2016-12-20 00:56:09 -08:00
|
|
|
if (load)
|
|
|
|
{
|
|
|
|
if (evas_cache_image_load_data(&im->im->cache_entry) != 0)
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2016-09-02 01:55:33 -07:00
|
|
|
return _evas_common_rgba_image_plane_get(im->im, plane, slice);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_colorspace_set(void *engine, void *image, Evas_Colorspace cspace)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return;
|
|
|
|
im = image;
|
|
|
|
if (im->native.data) return;
|
|
|
|
/* FIXME: can move to gl_common */
|
|
|
|
if (im->cs.space == cspace) return;
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2016-01-04 04:29:57 -08:00
|
|
|
evas_cache_image_colorspace(&im->im->cache_entry, cspace);
|
2014-07-11 06:11:58 -07:00
|
|
|
if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
im->cs.data = NULL;
|
|
|
|
im->cs.no_free = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
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:
|
2016-01-04 04:29:57 -08:00
|
|
|
evas_cache_image_colorspace(&im->im->cache_entry, cspace);
|
2014-07-11 06:11:58 -07:00
|
|
|
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
|
|
|
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;
|
|
|
|
default:
|
2016-01-04 04:29:57 -08:00
|
|
|
ERR("colorspace %d is not supported here", im->cs.space);
|
|
|
|
return;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
im->cs.space = cspace;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_bind_cb(void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n = im->native.data;
|
|
|
|
|
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
2015-02-11 04:45:50 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, n->data.opengl.texture_id);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_unbind_cb(void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n = im->native.data;
|
|
|
|
|
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
2015-02-11 04:45:50 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-03-30 23:55:15 -07:00
|
|
|
_native_free_cb(void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n = im->native.data;
|
|
|
|
uint32_t texid;
|
|
|
|
|
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
texid = n->data.opengl.texture_id;
|
2016-03-29 22:01:18 -07:00
|
|
|
eina_hash_del(im->native.shared->native_tex_hash, &texid, im);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
im->native.data = NULL;
|
|
|
|
im->native.func.bind = NULL;
|
|
|
|
im->native.func.unbind = NULL;
|
|
|
|
im->native.func.free = NULL;
|
|
|
|
free(n);
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:18:34 -08:00
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_native_init(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
|
2016-03-08 23:18:34 -08:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case EVAS_NATIVE_SURFACE_OPENGL:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
ERR("Native surface type %d not supported!", type);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_native_shutdown(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
|
2016-03-08 23:18:34 -08:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case EVAS_NATIVE_SURFACE_OPENGL:
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
ERR("Native surface type %d not supported!", type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_native_set(void *engine, void *image, void *native)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Evas_Native_Surface *ns = native;
|
|
|
|
Evas_GL_Image *im = image, *im2 = NULL;
|
|
|
|
uint32_t texid;
|
|
|
|
Evas_Native_Surface *n;
|
|
|
|
unsigned int tex = 0;
|
|
|
|
unsigned int fbo = 0;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
if (!im)
|
|
|
|
{
|
|
|
|
if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
|
|
|
|
{
|
|
|
|
im = evas_gl_common_image_new_from_data(gl_context,
|
|
|
|
ns->data.opengl.w,
|
|
|
|
ns->data.opengl.h,
|
|
|
|
NULL, 1,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ns)
|
|
|
|
{
|
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
tex = ns->data.opengl.texture_id;
|
|
|
|
fbo = ns->data.opengl.framebuffer_id;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens = im->native.data;
|
|
|
|
if ((ens->data.opengl.texture_id == tex) &&
|
|
|
|
(ens->data.opengl.framebuffer_id == fbo))
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2018-06-05 10:13:08 -07:00
|
|
|
if (!ns)
|
|
|
|
{
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
texid = tex;
|
|
|
|
im2 = eina_hash_find(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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
im2 = evas_gl_common_image_new_from_data(gl_context,
|
|
|
|
im->w, im->h, NULL, im->alpha,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
if (!im) return NULL;
|
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
n = calloc(1, sizeof(Evas_Native_Surface));
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
memcpy(n, ns, sizeof(Evas_Native_Surface));
|
|
|
|
|
|
|
|
eina_hash_add(gl_context->shared->native_tex_hash, &texid, im);
|
|
|
|
|
|
|
|
im->native.yinvert = 0;
|
|
|
|
im->native.loose = 0;
|
2016-03-29 22:01:18 -07:00
|
|
|
im->native.shared = gl_context->shared;
|
2014-07-11 06:11:58 -07:00
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
|
|
|
|
// FIXME: need to implement mapping sub texture regions
|
|
|
|
// x, y, w, h for possible texture atlasing
|
|
|
|
|
|
|
|
evas_gl_common_image_native_enable(im);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_native_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n;
|
|
|
|
|
|
|
|
if (!im) return NULL;
|
|
|
|
n = im->native.data;
|
|
|
|
if (!n) return NULL;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_mmap(void *engine, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
return evas_gl_common_image_mmap(gl_context, f, key, lo, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_new_from_data(void *engine, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
return evas_gl_common_image_new_from_data(gl_context, w, h, image_data, alpha, cspace);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_new_from_copied_data(void *engine, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
return evas_gl_common_image_new_from_copied_data(gl_context, w, h, image_data, alpha, cspace);
|
|
|
|
}
|
|
|
|
|
2017-04-25 16:15:37 -07:00
|
|
|
void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_free(void *engine, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
if (!image) return;
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_free(image);
|
|
|
|
}
|
|
|
|
|
2015-10-07 22:00:39 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_ref(void *engine EINA_UNUSED, void *image)
|
2015-10-07 22:00:39 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
if (!im) return NULL;
|
|
|
|
im->references++;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_size_get(void *engine EINA_UNUSED, void *image, int *w, int *h)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2015-04-22 02:25:38 -07:00
|
|
|
Evas_GL_Image *im;
|
2014-07-11 06:11:58 -07:00
|
|
|
if (!image)
|
|
|
|
{
|
|
|
|
*w = 0;
|
|
|
|
*h = 0;
|
|
|
|
return;
|
|
|
|
}
|
2015-04-22 02:25:38 -07:00
|
|
|
im = image;
|
|
|
|
if (im->orient == EVAS_IMAGE_ORIENT_90 ||
|
|
|
|
im->orient == EVAS_IMAGE_ORIENT_270 ||
|
|
|
|
im->orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
|
|
|
|
im->orient == EVAS_IMAGE_FLIP_TRANSVERSE)
|
|
|
|
{
|
2017-07-28 20:06:20 -07:00
|
|
|
*w = im->h;
|
|
|
|
*h = im->w;
|
2015-04-22 02:25:38 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-07-28 20:06:20 -07:00
|
|
|
*w = im->w;
|
|
|
|
*h = im->h;
|
2015-04-22 02:25:38 -07:00
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_size_set(void *engine, void *image, int w, int h)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_GL_Image *im_old;
|
|
|
|
|
|
|
|
if (!im) return NULL;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
im->w = w;
|
|
|
|
im->h = h;
|
2016-07-11 22:11:36 -07:00
|
|
|
evas_gl_common_image_native_enable(im);
|
2014-07-11 06:11:58 -07:00
|
|
|
return image;
|
|
|
|
}
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
if ((im->tex) && (im->tex->pt->dyn.img))
|
|
|
|
{
|
|
|
|
evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
|
|
|
im->tex = NULL;
|
|
|
|
im->w = w;
|
|
|
|
im->h = h;
|
|
|
|
im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
im_old = image;
|
|
|
|
|
2017-05-12 15:03:05 -07:00
|
|
|
switch (eng_image_colorspace_get(engine, image))
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
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:
|
|
|
|
w &= ~0x1;
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_gl_common_image_alloc_ensure(im_old);
|
|
|
|
if ((im_old->im) &&
|
|
|
|
((int)im_old->im->cache_entry.w == w) &&
|
|
|
|
((int)im_old->im->cache_entry.h == h))
|
|
|
|
return image;
|
2014-08-14 03:44:16 -07:00
|
|
|
im = evas_gl_common_image_new(gl_context, w, h,
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_alpha_get(engine, image),
|
|
|
|
eng_image_colorspace_get(engine, image));
|
2014-08-14 03:44:16 -07:00
|
|
|
evas_gl_common_image_free(im_old);
|
2014-07-11 06:11:58 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_dirty_region(void *engine, void *image, int x, int y, int w, int h)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
if (im->native.data) return image;
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_dirty(image, x, y, w, h);
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2015-04-22 02:25:38 -07:00
|
|
|
static Evas_GL_Image *
|
2017-08-25 10:51:10 -07:00
|
|
|
_rotate_image_data(Render_Engine_GL_Generic *re, Evas_GL_Image *im1)
|
2015-04-22 02:25:38 -07:00
|
|
|
{
|
|
|
|
int alpha;
|
2015-07-01 19:52:16 -07:00
|
|
|
Evas_GL_Image *im2;
|
2015-04-22 02:25:38 -07:00
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
RGBA_Draw_Context *dc;
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
|
|
|
|
w = im1->w;
|
|
|
|
h = im1->h;
|
|
|
|
|
|
|
|
if (im1->orient == EVAS_IMAGE_ORIENT_90 ||
|
|
|
|
im1->orient == EVAS_IMAGE_ORIENT_270 ||
|
|
|
|
im1->orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
|
|
|
|
im1->orient == EVAS_IMAGE_FLIP_TRANSVERSE)
|
|
|
|
{
|
|
|
|
w = im1->h;
|
|
|
|
h = im1->w;
|
|
|
|
}
|
|
|
|
|
2017-10-18 05:40:01 -07:00
|
|
|
if ((w * h) <= 0) return NULL;
|
|
|
|
|
|
|
|
alpha = eng_image_alpha_get(re, im1);
|
|
|
|
gl_context = gl_generic_context_find(re, 1);
|
2016-11-16 13:14:48 -08:00
|
|
|
im2 = evas_gl_common_image_surface_new(gl_context, w, h, alpha, EINA_FALSE);
|
2015-04-22 02:25:38 -07:00
|
|
|
|
|
|
|
evas_gl_common_context_target_surface_set(gl_context, im2);
|
|
|
|
|
|
|
|
// Create a new and temporary context
|
|
|
|
dc = evas_common_draw_context_new();
|
|
|
|
evas_common_draw_context_set_clip(dc, 0, 0, im2->w, im2->h);
|
|
|
|
gl_context->dc = dc;
|
|
|
|
|
|
|
|
// Image draw handle the rotation magically for us
|
|
|
|
evas_gl_common_image_draw(gl_context, im1,
|
|
|
|
0, 0, w, h,
|
|
|
|
0, 0, im2->w, im2->h,
|
|
|
|
0);
|
|
|
|
|
|
|
|
gl_context->dc = NULL;
|
|
|
|
evas_common_draw_context_free(dc);
|
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
// flush everything
|
|
|
|
eng_gl_surface_lock(re, im2);
|
2015-04-22 02:25:38 -07:00
|
|
|
|
|
|
|
// Rely on Evas_GL_Image infrastructure to allocate pixels
|
|
|
|
im2->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
|
|
|
if (!im2->im) return NULL;
|
|
|
|
im2->im->cache_entry.flags.alpha = !!alpha;
|
|
|
|
evas_gl_common_image_alloc_ensure(im2);
|
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
eng_gl_surface_read_pixels(re, im2, 0, 0, im2->w, im2->h,
|
|
|
|
EVAS_COLORSPACE_ARGB8888, im2->im->image.data);
|
2015-04-22 02:25:38 -07:00
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
eng_gl_surface_unlock(re, im2);
|
2015-04-22 02:25:38 -07:00
|
|
|
return im2;
|
|
|
|
}
|
|
|
|
|
2017-04-25 16:15:37 -07:00
|
|
|
void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_get(void *engine, void *image, int to_write, DATA32 **image_data, int *err, Eina_Bool *tofree)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2015-07-01 19:52:16 -07:00
|
|
|
Evas_GL_Image *im_new = NULL;
|
|
|
|
Evas_GL_Image *im = image;
|
2014-07-11 06:11:58 -07:00
|
|
|
int error;
|
|
|
|
|
2015-04-22 02:25:38 -07:00
|
|
|
*image_data = NULL;
|
2015-07-15 08:08:04 -07:00
|
|
|
if (tofree) *tofree = EINA_FALSE;
|
2015-07-01 19:52:16 -07:00
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
2015-04-22 02:25:38 -07:00
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
if (!im)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
2015-11-19 04:15:51 -08:00
|
|
|
ERR("No image provided.");
|
2014-07-11 06:11:58 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2015-07-01 19:52:16 -07:00
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
if (im->native.data)
|
2015-07-01 19:52:16 -07:00
|
|
|
return im;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2016-12-20 00:56:09 -08:00
|
|
|
if ((tofree != NULL) && im->im && (im->orient != EVAS_IMAGE_ORIENT_NONE))
|
|
|
|
goto rotate_image;
|
2015-04-22 02:25:38 -07:00
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
#ifdef GL_GLES
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2015-11-19 04:15:51 -08:00
|
|
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) &&
|
2015-11-11 20:56:17 -08:00
|
|
|
(im->cs.space == EVAS_COLORSPACE_ARGB8888))
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
if (im->tex->pt->dyn.checked_out > 0)
|
|
|
|
{
|
|
|
|
im->tex->pt->dyn.checked_out++;
|
|
|
|
*image_data = im->tex->pt->dyn.data;
|
|
|
|
return im;
|
|
|
|
}
|
2015-11-11 20:56:17 -08:00
|
|
|
if ((im->gc->shared->info.sec_tbm_surface) && (secsym_tbm_surface_map))
|
2015-03-01 21:40:12 -08:00
|
|
|
{
|
|
|
|
tbm_surface_info_s info;
|
2015-11-12 00:30:53 -08:00
|
|
|
if (secsym_tbm_surface_map(im->tex->pt->dyn.buffer,
|
2015-03-01 21:40:12 -08:00
|
|
|
TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE,
|
2015-11-12 00:30:53 -08:00
|
|
|
&info))
|
|
|
|
{
|
|
|
|
ERR("tbm_surface_map failed!");
|
|
|
|
*image_data = im->tex->pt->dyn.data = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*image_data = im->tex->pt->dyn.data = (DATA32 *) info.planes[0].ptr;
|
2015-03-01 21:40:12 -08:00
|
|
|
}
|
2015-11-11 20:56:17 -08:00
|
|
|
else if ((im->gc->shared->info.sec_image_map) && (secsym_eglMapImageSEC))
|
2015-03-01 21:40:12 -08:00
|
|
|
{
|
2017-08-25 15:44:19 -07:00
|
|
|
void *disp = egl_display_get(engine);
|
2015-03-01 21:40:12 -08:00
|
|
|
*image_data = im->tex->pt->dyn.data = secsym_eglMapImageSEC(disp,
|
|
|
|
im->tex->pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
|
|
|
|
EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
if (!im->tex->pt->dyn.data)
|
|
|
|
{
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2015-11-19 04:15:51 -08:00
|
|
|
ERR("Ressource allocation failed.");
|
2014-07-11 06:11:58 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
im->tex->pt->dyn.checked_out++;
|
|
|
|
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
|
|
|
|
{
|
|
|
|
*image_data = im->tex->pt->dyn.data;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
#endif
|
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
/* use glReadPixels for FBOs (assume fbo > 0) */
|
|
|
|
if (!im->im && im->tex && im->tex->pt && im->tex->pt->fb)
|
|
|
|
{
|
|
|
|
Eina_Bool ok;
|
|
|
|
|
|
|
|
if (to_write)
|
|
|
|
{
|
|
|
|
// This could be implemented, but can't be efficient at all.
|
|
|
|
// Apps should avoid this situation.
|
|
|
|
ERR("Can not retrieve image data from FBO to write it back.");
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tofree)
|
|
|
|
{
|
|
|
|
ERR("FBO image must be freed after image_data_get.");
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-05-12 15:03:05 -07:00
|
|
|
ok = eng_gl_surface_lock(engine, im);
|
2015-07-01 19:52:16 -07:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
2015-11-19 04:15:51 -08:00
|
|
|
ERR("Lock failed.");
|
2015-07-01 19:52:16 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
im_new = evas_gl_common_image_new_from_copied_data
|
|
|
|
(im->gc, im->tex->w, im->tex->h, NULL,
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_alpha_get(engine, image), EVAS_COLORSPACE_ARGB8888);
|
2015-07-01 19:52:16 -07:00
|
|
|
if (!im_new)
|
|
|
|
{
|
2017-07-18 21:19:24 -07:00
|
|
|
eng_gl_surface_unlock(engine, im);
|
2015-07-01 19:52:16 -07:00
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2015-11-19 04:15:51 -08:00
|
|
|
ERR("Allocation failed.");
|
2015-07-01 19:52:16 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ok = eng_gl_surface_read_pixels
|
2017-05-12 15:03:05 -07:00
|
|
|
(engine, im, 0, 0, im_new->w, im_new->h,
|
2015-07-01 19:52:16 -07:00
|
|
|
EVAS_COLORSPACE_ARGB8888, im_new->im->image.data);
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_surface_unlock(engine, im);
|
2015-07-01 19:52:16 -07:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
ERR("ReadPixels failed.");
|
2015-07-01 19:52:16 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
*image_data = im_new->im->image.data;
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
*tofree = EINA_TRUE;
|
2015-07-01 19:52:16 -07:00
|
|
|
return im_new;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
/* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
|
|
|
|
so it is need to add code which check im->im's NULL value*/
|
|
|
|
|
|
|
|
if (!im->im)
|
2015-07-01 19:52:16 -07:00
|
|
|
{
|
2016-12-20 00:56:09 -08:00
|
|
|
if (tofree)
|
|
|
|
goto rotate_image;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("GL image has no source data, failed to get pixel data");
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-07-01 19:52:16 -07:00
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2018-08-29 21:32:51 -07:00
|
|
|
error = evas_cache_image_load_data(&im->im->cache_entry);
|
2016-12-20 00:56:09 -08:00
|
|
|
|
2017-10-18 05:40:01 -07:00
|
|
|
if (err) *err = error;
|
2016-12-20 00:56:09 -08:00
|
|
|
if (error != EVAS_LOAD_ERROR_NONE)
|
|
|
|
{
|
2017-10-18 05:40:01 -07:00
|
|
|
if (!im->im->image.data ||
|
|
|
|
(im->im->cache_entry.allocated.w != (unsigned) im->w) ||
|
|
|
|
(im->im->cache_entry.allocated.h != (unsigned) im->h))
|
|
|
|
{
|
|
|
|
ERR("GL image has no source data, failed to get pixel data");
|
|
|
|
*image_data = NULL;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
2017-07-20 00:43:52 -07:00
|
|
|
if (tofree && !to_write)
|
2016-12-20 00:56:09 -08:00
|
|
|
goto rotate_image;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
|
|
|
switch (im->cs.space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
case EVAS_COLORSPACE_GRY8:
|
|
|
|
if (to_write)
|
|
|
|
{
|
|
|
|
if (im->references > 1)
|
|
|
|
{
|
|
|
|
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,
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_alpha_get(engine, image),
|
|
|
|
eng_image_colorspace_get(engine, image));
|
2014-07-11 06:11:58 -07:00
|
|
|
if (!im_new)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
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:
|
|
|
|
*image_data = im->cs.data;
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_ETC1:
|
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
|
|
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
|
|
|
ERR("This image is encoded in ETC1 or ETC2, not returning any data");
|
|
|
|
error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
break;
|
|
|
|
default:
|
2016-01-04 04:29:57 -08:00
|
|
|
ERR("colorspace %d is not supported here", im->cs.space);
|
|
|
|
error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
2014-07-11 06:11:58 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (err) *err = error;
|
|
|
|
return im;
|
2016-12-20 00:56:09 -08:00
|
|
|
|
|
|
|
rotate_image:
|
|
|
|
// rotate data for image save
|
2017-05-12 15:03:05 -07:00
|
|
|
im_new = _rotate_image_data(engine, image);
|
2016-12-20 00:56:09 -08:00
|
|
|
if (!im_new)
|
|
|
|
{
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
ERR("Image rotation failed.");
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
*tofree = EINA_TRUE;
|
|
|
|
*image_data = im_new->im->image.data;
|
|
|
|
return im_new;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2017-04-25 16:15:37 -07:00
|
|
|
void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_put(void *engine, void *image, DATA32 *image_data)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im, *im2;
|
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
im = image;
|
|
|
|
if (im->native.data) return image;
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
|
|
|
if ((im->tex) && (im->tex->pt)
|
|
|
|
&& (im->tex->pt->dyn.data)
|
|
|
|
&& (im->cs.space == EVAS_COLORSPACE_ARGB8888))
|
|
|
|
{
|
|
|
|
if (im->tex->pt->dyn.data == image_data)
|
|
|
|
{
|
|
|
|
if (im->tex->pt->dyn.checked_out > 0)
|
|
|
|
{
|
|
|
|
im->tex->pt->dyn.checked_out--;
|
|
|
|
#ifdef GL_GLES
|
|
|
|
if (im->tex->pt->dyn.checked_out == 0)
|
|
|
|
{
|
2015-03-01 21:40:12 -08:00
|
|
|
if (im->gc->shared->info.sec_tbm_surface)
|
2015-11-12 00:30:53 -08:00
|
|
|
{
|
|
|
|
if (secsym_tbm_surface_unmap(im->tex->pt->dyn.buffer))
|
|
|
|
ERR("tbm_surface_unmap failed!");
|
|
|
|
}
|
2015-03-01 21:40:12 -08:00
|
|
|
else if (im->gc->shared->info.sec_image_map)
|
|
|
|
{
|
2018-04-06 10:16:23 -07:00
|
|
|
void *disp = egl_display_get(engine);
|
2015-03-01 21:40:12 -08:00
|
|
|
secsym_eglUnmapImageSEC(disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
2017-05-12 15:03:05 -07:00
|
|
|
im2 = eng_image_new_from_data(engine, im->w, im->h, image_data,
|
|
|
|
eng_image_alpha_get(engine, image),
|
|
|
|
eng_image_colorspace_get(engine, image));
|
2014-07-11 06:11:58 -07:00
|
|
|
if (!im2) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
switch (im->cs.space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2015-12-29 05:01:16 -08:00
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
case EVAS_COLORSPACE_GRY8:
|
2014-07-11 06:11:58 -07:00
|
|
|
if ((!im->im) || (image_data != im->im->image.data))
|
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
im2 = eng_image_new_from_data(engine, im->w, im->h, image_data,
|
|
|
|
eng_image_alpha_get(engine, image),
|
|
|
|
eng_image_colorspace_get(engine, image));
|
2014-07-11 06:11:58 -07:00
|
|
|
if (!im2) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
}
|
2015-11-19 04:15:51 -08:00
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
2014-07-11 06:11:58 -07:00
|
|
|
break;
|
|
|
|
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:
|
|
|
|
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);
|
2017-03-01 22:29:54 -08:00
|
|
|
evas_gl_common_image_update(im->gc, im);
|
2014-07-11 06:11:58 -07:00
|
|
|
break;
|
|
|
|
default:
|
2015-12-29 05:01:16 -08:00
|
|
|
ERR("colorspace %d is not supported here", im->cs.space);
|
2016-01-04 04:29:57 -08:00
|
|
|
break;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
2015-04-22 02:25:38 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_orient_set(void *engine, void *image, Evas_Image_Orient orient)
|
2015-04-22 02:25:38 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
2015-04-24 08:04:58 -07:00
|
|
|
Evas_GL_Image *im_new;
|
2015-04-22 02:25:38 -07:00
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
im = image;
|
|
|
|
if (im->orient == orient) return image;
|
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2015-04-22 02:25:38 -07:00
|
|
|
|
2015-04-24 08:04:58 -07:00
|
|
|
evas_gl_common_image_update(im->gc, im);
|
|
|
|
|
|
|
|
im_new = evas_gl_common_image_new(im->gc, im->w, im->h, im->alpha, im->cs.space);
|
|
|
|
if (!im_new) return im;
|
|
|
|
|
2015-05-01 03:15:10 -07:00
|
|
|
im_new->load_opts = im->load_opts;
|
|
|
|
im_new->scaled = im->scaled;
|
|
|
|
im_new->scale_hint = im->scale_hint;
|
|
|
|
im_new->content_hint = im->content_hint;
|
|
|
|
im_new->csize = im->csize;
|
|
|
|
im_new->alpha = im->alpha;
|
|
|
|
im_new->tex_only = im->tex_only;
|
|
|
|
im_new->locked = im->locked;
|
|
|
|
im_new->direct = im->direct;
|
|
|
|
im_new->cached = EINA_FALSE;
|
2015-04-24 08:04:58 -07:00
|
|
|
|
2015-05-01 03:15:10 -07:00
|
|
|
im_new->orient = orient;
|
|
|
|
im_new->tex = im->tex;
|
2015-04-24 08:04:58 -07:00
|
|
|
im_new->tex->references++;
|
|
|
|
im_new->tex->pt->references++;
|
|
|
|
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
return im_new;
|
2015-04-22 02:25:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Image_Orient
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_orient_get(void *engine EINA_UNUSED, void *image)
|
2015-04-22 02:25:38 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Evas_GL_Image *im = image;
|
2015-04-22 02:25:38 -07:00
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
if (!im) return EVAS_IMAGE_ORIENT_NONE;
|
2015-04-22 02:25:38 -07:00
|
|
|
return im->orient;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_preload_request(void *engine EINA_UNUSED, void *image, const Eo *target)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
RGBA_Image *im;
|
|
|
|
|
|
|
|
if (!gim) return;
|
|
|
|
if (gim->native.data) return;
|
|
|
|
im = (RGBA_Image *)gim->im;
|
|
|
|
if (!im) return;
|
|
|
|
|
2018-08-29 21:32:51 -07:00
|
|
|
evas_cache_image_preload_data(&im->cache_entry, target, evas_gl_common_image_preload_done, gim);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
evas image: fix a bug in image preloading.
Summary:
Current preloading is too buggy since it's on thread-based.
This is a fundamental improvement to fix a bug.
The critical issue here is,
When preloading img object suddenly cancel its preloading,
the object possibly cannot render image next then because
renderer doesn't have any idea when async cancelling is
finished. Renderer just tries to render regardless of
image loading status, and this could occur no-texture(in gl case)
image object.
So, here improvement is, adding a notification for async cancelled
so that putting img objects to redraw images properly after their preloading is
cancelled.
The best scenario to reproduce this bug is this one.
Evas_Object *img2 = evas_object_image_filled_add(evas);
evas_object_image_file_set(img2, "test.jpg", NULL);
evas_object_image_preload(img2, EINA_FALSE);
evas_object_resize(img2, 200, 200);
evas_object_show(img2);
Evas_Object *img = evas_object_image_filled_add(evas);
evas_object_image_file_set(img, "test.jpg", NULL);
evas_object_image_preload(img, EINA_FALSE);
evas_object_move(img, 200, 200);
evas_object_resize(img, 200, 200);
evas_object_show(img);
evas_object_image_preload(img2, EINA_TRUE);
If you run this on gl backend, occasionally happens rendering fail.
Yet there other bugs on preloading feature....
@fix
Reviewers: #committers, raster
Subscribers: cedric, #reviewers, #committers, zmike
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6919
2018-09-02 23:19:02 -07:00
|
|
|
eng_image_data_preload_cancel(void *engine EINA_UNUSED, void *image, const Eo *target, Eina_Bool force)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
RGBA_Image *im;
|
|
|
|
|
|
|
|
if (!gim) return;
|
|
|
|
if (gim->native.data) return;
|
|
|
|
im = (RGBA_Image *)gim->im;
|
|
|
|
if (!im) return;
|
|
|
|
|
2017-01-01 05:15:24 -08:00
|
|
|
evas_gl_common_image_preload_unwatch(gim);
|
evas image: fix a bug in image preloading.
Summary:
Current preloading is too buggy since it's on thread-based.
This is a fundamental improvement to fix a bug.
The critical issue here is,
When preloading img object suddenly cancel its preloading,
the object possibly cannot render image next then because
renderer doesn't have any idea when async cancelling is
finished. Renderer just tries to render regardless of
image loading status, and this could occur no-texture(in gl case)
image object.
So, here improvement is, adding a notification for async cancelled
so that putting img objects to redraw images properly after their preloading is
cancelled.
The best scenario to reproduce this bug is this one.
Evas_Object *img2 = evas_object_image_filled_add(evas);
evas_object_image_file_set(img2, "test.jpg", NULL);
evas_object_image_preload(img2, EINA_FALSE);
evas_object_resize(img2, 200, 200);
evas_object_show(img2);
Evas_Object *img = evas_object_image_filled_add(evas);
evas_object_image_file_set(img, "test.jpg", NULL);
evas_object_image_preload(img, EINA_FALSE);
evas_object_move(img, 200, 200);
evas_object_resize(img, 200, 200);
evas_object_show(img);
evas_object_image_preload(img2, EINA_TRUE);
If you run this on gl backend, occasionally happens rendering fail.
Yet there other bugs on preloading feature....
@fix
Reviewers: #committers, raster
Subscribers: cedric, #reviewers, #committers, zmike
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6919
2018-09-02 23:19:02 -07:00
|
|
|
evas_cache_image_preload_cancel(&im->cache_entry, target, force);
|
2017-01-01 05:15:24 -08:00
|
|
|
// if (gim->tex) evas_gl_preload_target_unregister(gim->tex, (Eo*) target);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-08-25 10:51:10 -07:00
|
|
|
eng_image_draw(void *eng, 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)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
2014-07-11 06:11:58 -07:00
|
|
|
Evas_Engine_GL_Context *gl_context;
|
2017-08-25 10:48:00 -07:00
|
|
|
Render_Output_GL_Generic *re = data;
|
2014-07-11 06:11:58 -07:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n;
|
|
|
|
|
|
|
|
if (!im) return EINA_FALSE;
|
2017-08-25 10:50:31 -07:00
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
n = im->native.data;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(re, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
if (eng_gl_image_direct_get(re, image))
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2015-03-13 00:31:54 -07:00
|
|
|
void *direct_surface = NULL;
|
2015-03-02 23:38:52 -08:00
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
gl_context->dc = context;
|
2014-11-20 07:59:19 -08:00
|
|
|
if ((gl_context->master_clip.enabled) &&
|
|
|
|
(gl_context->master_clip.w > 0) &&
|
|
|
|
(gl_context->master_clip.h > 0))
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2014-11-20 07:59:19 -08:00
|
|
|
// Pass the preserve flag info the evas_gl
|
|
|
|
evgl_direct_partial_info_set(gl_context->preserve_bit);
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2015-04-10 00:13:22 -07:00
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_EVASGL)
|
2015-03-13 00:31:54 -07:00
|
|
|
direct_surface = n->data.evasgl.surface;
|
2015-03-02 23:38:52 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("This native surface type is not supported for direct rendering");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-11-20 07:59:19 -08:00
|
|
|
// Set necessary info for direct rendering
|
|
|
|
evgl_direct_info_set(gl_context->w,
|
|
|
|
gl_context->h,
|
|
|
|
gl_context->rot,
|
|
|
|
dst_x, dst_y, dst_w, dst_h,
|
|
|
|
gl_context->dc->clip.x,
|
|
|
|
gl_context->dc->clip.y,
|
|
|
|
gl_context->dc->clip.w,
|
2014-12-09 04:36:45 -08:00
|
|
|
gl_context->dc->clip.h,
|
2015-07-09 20:37:27 -07:00
|
|
|
gl_context->dc->render_op,
|
2015-03-13 00:31:54 -07:00
|
|
|
direct_surface);
|
2014-11-20 07:59:19 -08:00
|
|
|
|
|
|
|
// Call pixel get function
|
2015-03-23 13:58:26 -07:00
|
|
|
evgl_get_pixels_pre();
|
2017-08-25 10:51:10 -07:00
|
|
|
engine->func.get_pixels(engine->func.get_pixels_data, engine->func.obj);
|
2015-03-23 13:58:26 -07:00
|
|
|
evgl_get_pixels_post();
|
2014-11-20 07:59:19 -08:00
|
|
|
|
|
|
|
// Call end tile if it's being used
|
|
|
|
if ((gl_context->master_clip.enabled) &&
|
|
|
|
(gl_context->master_clip.w > 0) &&
|
|
|
|
(gl_context->master_clip.h > 0))
|
|
|
|
{
|
|
|
|
evgl_direct_partial_render_end();
|
|
|
|
evgl_direct_partial_info_clear();
|
|
|
|
gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
2014-11-20 07:59:19 -08:00
|
|
|
|
|
|
|
// Reset direct rendering info
|
|
|
|
evgl_direct_info_clear();
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
|
|
|
evas_gl_common_image_draw(gl_context, image,
|
|
|
|
src_x, src_y, src_w, src_h,
|
|
|
|
dst_x, dst_y, dst_w, dst_h,
|
|
|
|
smooth);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_scale_hint_set(void *engine EINA_UNUSED, void *image, int hint)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
if (image) evas_gl_common_image_scale_hint_set(image, hint);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_scale_hint_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
|
|
|
|
return gim->scale_hint;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_map_draw(void *engine, void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
|
|
|
|
if (!image) return EINA_FALSE;
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(data, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
2014-10-31 03:27:49 -07:00
|
|
|
|
2014-07-11 06:11:58 -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))
|
|
|
|
{
|
|
|
|
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;
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_draw(engine, data, context, surface, image,
|
2014-07-11 06:11:58 -07:00
|
|
|
0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth, do_async);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_gl_common_image_map_draw(gl_context, image, m->count, &m->pts[0],
|
|
|
|
smooth, level);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_map_clean(void *engine EINA_UNUSED, RGBA_Map *m EINA_UNUSED)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_map_surface_new(void *engine, int w, int h, int alpha)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-01-23 21:23:03 -08:00
|
|
|
Evas_Engine_GL_Context *gl_context;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2016-11-16 13:14:48 -08:00
|
|
|
return evas_gl_common_image_surface_new(gl_context, w, h, alpha, EINA_FALSE);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2017-01-23 21:23:03 -08:00
|
|
|
void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_scaled_update(void *engine EINA_UNUSED, void *scaled, void *image,
|
2017-01-23 21:23:03 -08:00
|
|
|
int dst_w, int dst_h, Eina_Bool smooth,
|
2015-02-25 02:05:12 -08:00
|
|
|
Evas_Colorspace cspace EINA_UNUSED)
|
|
|
|
{
|
2017-01-23 21:23:03 -08:00
|
|
|
return evas_gl_common_image_virtual_scaled_get(scaled, image, dst_w, dst_h, smooth);
|
2015-02-25 02:05:12 -08:00
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_content_hint_set(void *engine, void *image, int hint)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
gl_generic_window_find(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_image_content_hint_set(image, hint);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_cache_flush(void *engine)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
int tmp_size;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2017-03-03 10:45:58 -08:00
|
|
|
if (!gl_context) return;
|
2014-07-11 06:11:58 -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(gl_context);
|
|
|
|
evas_common_image_set_cache(tmp_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_cache_set(void *engine, int bytes)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
evas_common_image_set_cache(bytes);
|
|
|
|
evas_common_rgba_image_scalecache_size_set(bytes);
|
2017-03-03 10:45:58 -08:00
|
|
|
if (gl_context) evas_gl_common_image_cache_flush(gl_context);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_cache_get(void *engine EINA_UNUSED)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
return evas_common_image_get_cache();
|
|
|
|
}
|
|
|
|
|
2016-04-12 01:30:48 -07:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_font_cache_flush(void *engine)
|
2016-04-12 01:30:48 -07:00
|
|
|
{
|
|
|
|
int tmp_size;
|
|
|
|
|
2017-08-25 10:51:24 -07:00
|
|
|
gl_generic_window_find(engine);
|
2016-04-12 01:30:48 -07:00
|
|
|
tmp_size = evas_common_font_cache_get();
|
|
|
|
evas_common_font_cache_set(0);
|
|
|
|
evas_common_font_flush();
|
|
|
|
evas_common_font_cache_set(tmp_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_font_cache_set(void *engine, int bytes)
|
2016-04-12 01:30:48 -07:00
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
gl_generic_window_find(engine);
|
2016-04-12 01:30:48 -07:00
|
|
|
evas_common_font_cache_set(bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_font_cache_get(void *engine)
|
2016-04-12 01:30:48 -07:00
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
gl_generic_window_find(engine);
|
2016-04-12 01:30:48 -07:00
|
|
|
return evas_common_font_cache_get();
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_stride_get(void *engine EINA_UNUSED, void *image, int *stride)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
|
|
|
if ((im->tex) && (im->tex->pt->dyn.img))
|
|
|
|
*stride = im->tex->pt->dyn.stride;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (im->cs.space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
*stride = im->w * 4;
|
|
|
|
return;
|
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
*stride = im->w * 2;
|
|
|
|
return;
|
|
|
|
case EVAS_COLORSPACE_GRY8:
|
|
|
|
*stride = im->w * 1;
|
|
|
|
return;
|
|
|
|
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:
|
|
|
|
*stride = im->w * 1;
|
|
|
|
return;
|
2015-10-29 00:38:54 -07:00
|
|
|
/* the strides below are approximations, since stride doesn't
|
|
|
|
* really make sense for ETC & S3TC */
|
|
|
|
case EVAS_COLORSPACE_ETC1:
|
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
|
|
|
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
|
|
|
|
*stride = (im->w + 2 + 3) / 4 * (8 / 4);
|
|
|
|
return;
|
|
|
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
|
|
|
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
|
|
|
|
*stride = (im->w + 2 + 3) / 4 * (16 / 4);
|
|
|
|
return;
|
2014-07-11 06:11:58 -07:00
|
|
|
default:
|
|
|
|
ERR("Requested stride on an invalid format %d", im->cs.space);
|
|
|
|
*stride = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_font_draw(void *engine EINA_UNUSED, 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)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(data, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
|
|
|
{
|
2015-06-15 01:48:10 -07:00
|
|
|
if (!gl_context->font_surface)
|
|
|
|
gl_context->font_surface = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
|
|
|
gl_context->font_surface->cache_entry.w = gl_context->shared->w;
|
|
|
|
gl_context->font_surface->cache_entry.h = gl_context->shared->h;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
evas_common_draw_context_font_ext_set(context,
|
|
|
|
gl_context,
|
|
|
|
evas_gl_font_texture_new,
|
|
|
|
evas_gl_font_texture_free,
|
2015-03-19 03:02:02 -07:00
|
|
|
evas_gl_font_texture_draw,
|
2017-03-08 02:33:15 -08:00
|
|
|
evas_gl_font_image_new,
|
|
|
|
evas_gl_font_image_free,
|
|
|
|
evas_gl_font_image_draw);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_common_font_draw_prepare(intl_props);
|
2015-06-15 01:48:10 -07:00
|
|
|
evas_common_font_draw(gl_context->font_surface, context, x, y, intl_props->glyphs);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_common_draw_context_font_ext_set(context,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-03-19 03:02:02 -07:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2014-07-11 06:11:58 -07:00
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------//
|
|
|
|
// Evas GL Related Code
|
2017-08-25 10:54:19 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
evgl_init_do(Render_Engine_GL_Generic *engine,
|
|
|
|
Render_Output_GL_Generic *output)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
if (engine->evgl_initted) return EINA_TRUE;
|
|
|
|
if (!evgl_engine_init(output, output->evgl_funcs))
|
|
|
|
return EINA_FALSE;
|
|
|
|
engine->current = output;
|
|
|
|
engine->evgl_initted = EINA_TRUE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Render_Output_GL_Generic *
|
|
|
|
evgl_init(Render_Engine_GL_Generic *engine)
|
|
|
|
{
|
|
|
|
Render_Output_GL_Generic *output = NULL;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (engine->evgl_initted)
|
|
|
|
{
|
|
|
|
if (engine->current) return engine->current;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
|
|
|
if (output->software.ob) return output;
|
|
|
|
|
|
|
|
ERR("Evas_GL backend initializeod, but no window found !");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
|
|
|
{
|
|
|
|
if (!output->software.ob) continue;
|
|
|
|
if (evgl_init_do(engine, output))
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
#define EVGLINIT(_ret) Render_Output_GL_Generic *re; if ((re = evgl_init(engine)) == NULL) return _ret
|
|
|
|
|
2018-01-16 22:17:59 -08:00
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_supports_evas_gl(void *engine EINA_UNUSED)
|
|
|
|
{
|
|
|
|
// Evas GL should always work... But let's do a full init anyway.
|
|
|
|
EVGLINIT(EINA_FALSE);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
static void *
|
|
|
|
eng_gl_output_set(void *eng, void *output)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
|
|
|
Render_Output_GL_Generic *previous = engine->current;
|
|
|
|
|
|
|
|
engine->current = output;
|
|
|
|
|
|
|
|
return previous;
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_surface_create(void *engine, void *config, int w, int h)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(NULL);
|
|
|
|
return evgl_surface_create(re, cfg, w, h);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2014-09-19 01:32:26 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_pbuffer_surface_create(void *engine, void *config, int w, int h, const int *attrib_list)
|
2014-09-19 01:32:26 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(NULL);
|
|
|
|
return evgl_pbuffer_surface_create(re, cfg, w, h, attrib_list);
|
2014-09-19 01:32:26 -07:00
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_surface_destroy(void *engine, void *surface)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
2017-08-28 11:13:40 -07:00
|
|
|
Render_Engine_GL_Generic *e = engine;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(0);
|
|
|
|
if (e->current == re) e->current = NULL;
|
|
|
|
CONTEXT_STORED_RESET(re, surface);
|
|
|
|
return evgl_surface_destroy(re, sfc);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_context_create(void *engine, void *share_context, int version,
|
2015-07-16 06:25:36 -07:00
|
|
|
void *(*native_context_get)(void *),
|
|
|
|
void *(*engine_data_get)(void *))
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
EVGL_Context *sctx = (EVGL_Context *)share_context;
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(NULL);
|
|
|
|
return evgl_context_create(re, sctx, version, native_context_get, engine_data_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_context_destroy(void *engine, void *context)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
EVGL_Context *ctx = (EVGL_Context *)context;
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(0);
|
|
|
|
return evgl_context_destroy(re, ctx);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-08-25 10:54:19 -07:00
|
|
|
eng_gl_make_current(void *eng, void *surface, void *context)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
2014-07-11 06:11:58 -07:00
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
EVGL_Context *ctx = (EVGL_Context *)context;
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Output_GL_Generic *output;
|
2015-07-29 17:14:08 -07:00
|
|
|
int ret = 0;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
if (sfc && ctx && eina_main_loop_is())
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 0);
|
2014-07-11 06:11:58 -07:00
|
|
|
if ((gl_context->havestuff) ||
|
|
|
|
(gl_context->master_clip.used))
|
|
|
|
{
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
if (gl_context->master_clip.used)
|
|
|
|
evas_gl_common_context_done(gl_context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
output = _evgl_output_find(engine);
|
|
|
|
if (!output) return ret;
|
|
|
|
|
|
|
|
ret = evgl_make_current(output, sfc, ctx);
|
|
|
|
CONTEXT_STORE(output, surface, context);
|
2015-07-29 17:14:08 -07:00
|
|
|
|
|
|
|
return ret;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2014-09-01 04:15:33 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_current_surface_get(void *engine EINA_UNUSED)
|
2014-09-01 04:15:33 -07:00
|
|
|
{
|
|
|
|
EVGL_Context *ctx;
|
|
|
|
|
2014-09-01 20:52:52 -07:00
|
|
|
ctx = evas_gl_common_current_context_get();
|
2014-09-01 04:15:33 -07:00
|
|
|
if (!ctx)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
// Note: We could verify with a call to eglGetCurrentSurface
|
|
|
|
|
|
|
|
return ctx->current_sfc;
|
|
|
|
}
|
|
|
|
|
2014-09-02 05:29:25 -07:00
|
|
|
static int
|
2017-08-25 10:54:19 -07:00
|
|
|
eng_gl_rotation_angle_get(void *eng)
|
2014-09-02 05:29:25 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
|
|
|
Render_Output_GL_Generic *output;
|
|
|
|
|
2014-09-02 05:29:25 -07:00
|
|
|
if (!evgl_engine->funcs->rotation_angle_get) return 0;
|
2014-09-03 19:41:27 -07:00
|
|
|
if (!_evgl_direct_enabled()) return 0;
|
2017-08-25 10:54:19 -07:00
|
|
|
|
|
|
|
// It would be better if that this API was called Evas Output
|
|
|
|
output = _evgl_output_find(engine);
|
|
|
|
if (!output) return 0;
|
|
|
|
|
|
|
|
return evgl_engine->funcs->rotation_angle_get(output);
|
2014-09-02 05:29:25 -07:00
|
|
|
}
|
|
|
|
|
2014-10-24 04:52:09 -07:00
|
|
|
static const char *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_string_query(void *engine, int name)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(NULL);
|
2014-10-24 04:52:09 -07:00
|
|
|
return evgl_string_query(name);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_proc_address_get(void *engine, const char *name)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT(NULL);
|
2016-07-19 05:08:02 -07:00
|
|
|
void *fun = NULL;
|
2014-10-24 05:25:08 -07:00
|
|
|
|
2016-07-19 05:08:02 -07:00
|
|
|
if (!evgl_safe_extension_get(name, &fun))
|
2014-10-24 05:25:08 -07:00
|
|
|
{
|
|
|
|
DBG("The extension '%s' is not safe to use with Evas GL or is not "
|
|
|
|
"supported on this platform.", name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-07-19 05:08:02 -07:00
|
|
|
if (fun)
|
|
|
|
return fun;
|
2014-10-24 04:48:08 -07:00
|
|
|
|
|
|
|
if (re->evgl_funcs && re->evgl_funcs->proc_address_get)
|
|
|
|
return re->evgl_funcs->proc_address_get(name);
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_native_surface_get(void *engine EINA_UNUSED, void *surface, void *native_surface)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
Evas_Native_Surface *ns = (Evas_Native_Surface *)native_surface;
|
|
|
|
|
|
|
|
return evgl_native_surface_get(sfc, ns);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_api_get(void *engine, int version)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Output_GL_Generic *output;
|
2015-03-04 22:36:35 -08:00
|
|
|
Evas_Engine_GL_Context *gl_context;
|
2017-08-25 10:54:19 -07:00
|
|
|
void *ret;
|
|
|
|
EVGLINIT(NULL);
|
2015-03-04 22:36:35 -08:00
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 0);
|
2015-03-04 22:36:35 -08:00
|
|
|
if (!gl_context)
|
|
|
|
{
|
|
|
|
ERR("Invalid context!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if ((version == EVAS_GL_GLES_3_X) && (gl_context->gles_version != EVAS_GL_GLES_3_X))
|
|
|
|
{
|
|
|
|
ERR("Version not supported!");
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-08-25 10:54:19 -07:00
|
|
|
|
|
|
|
output = _evgl_output_find(engine);
|
|
|
|
ret = evgl_api_get(output, version, EINA_TRUE);
|
2015-03-04 22:36:35 -08:00
|
|
|
|
|
|
|
//Disable GLES3 support if symbols not present
|
|
|
|
if ((!ret) && (version == EVAS_GL_GLES_3_X))
|
|
|
|
gl_context->gles_version--;
|
|
|
|
|
|
|
|
return ret;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_direct_override_get(void *engine, Eina_Bool *override, Eina_Bool *force_off)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
EVGLINIT();
|
2014-07-11 06:11:58 -07:00
|
|
|
evgl_direct_override_get(override, force_off);
|
|
|
|
}
|
|
|
|
|
2014-12-09 04:36:45 -08:00
|
|
|
static Eina_Bool
|
2017-08-25 10:54:19 -07:00
|
|
|
eng_gl_surface_direct_renderable_get(void *eng, void *output, Evas_Native_Surface *ns, Eina_Bool *override, void *surface)
|
2014-12-09 04:36:45 -08:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
2017-08-25 10:51:47 -07:00
|
|
|
Render_Output_GL_Generic *re = output;
|
2014-12-09 04:36:45 -08:00
|
|
|
Eina_Bool direct_render, client_side_rotation;
|
2015-04-14 04:41:56 -07:00
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Evas_GL_Image *sfc = surface;
|
2014-12-09 04:36:45 -08:00
|
|
|
|
2016-09-20 21:16:36 -07:00
|
|
|
if (!re) return EINA_FALSE;
|
2017-08-25 10:54:19 -07:00
|
|
|
if (!evgl_init_do(engine, re))
|
|
|
|
return EINA_FALSE;
|
2016-09-20 21:16:36 -07:00
|
|
|
if (!ns) return EINA_FALSE;
|
2015-02-24 02:05:39 -08:00
|
|
|
if (!evgl_native_surface_direct_opts_get(ns, &direct_render, &client_side_rotation, override))
|
2014-12-09 04:36:45 -08:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
if (!direct_render)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
if ((re->software.outbuf_get_rot(re->software.ob) != 0) && (!client_side_rotation))
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(re, 0);
|
2015-04-14 04:41:56 -07:00
|
|
|
if (gl_context->def_surface != sfc)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2014-12-09 04:36:45 -08:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-08-25 10:51:10 -07:00
|
|
|
eng_gl_get_pixels_set(void *eng, void *get_pixels, void *get_pixels_data, void *obj)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2017-08-25 10:51:10 -07:00
|
|
|
engine->func.get_pixels = get_pixels;
|
|
|
|
engine->func.get_pixels_data = get_pixels_data;
|
|
|
|
engine->func.obj = (Evas_Object*)obj;
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2015-03-23 13:58:26 -07:00
|
|
|
static void
|
2017-08-25 10:54:19 -07:00
|
|
|
eng_gl_get_pixels_pre(void *e, void *o)
|
2015-03-23 13:58:26 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Engine_GL_Generic *engine = e;
|
|
|
|
Render_Output_GL_Generic *output = o;
|
|
|
|
|
|
|
|
if (!evgl_init_do(engine, output))
|
|
|
|
return ;
|
2015-03-23 13:58:26 -07:00
|
|
|
evgl_get_pixels_pre();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-08-25 10:54:19 -07:00
|
|
|
eng_gl_get_pixels_post(void *e EINA_UNUSED, void *o EINA_UNUSED)
|
2015-03-23 13:58:26 -07:00
|
|
|
{
|
|
|
|
evgl_get_pixels_post();
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_surface_lock(void *engine EINA_UNUSED, void *surface)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
if (!im || !im->tex || !im->tex->pt)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
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
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_surface_unlock(void *engine EINA_UNUSED, void *surface)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
im->locked = EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_surface_read_pixels(void *engine EINA_UNUSED, void *surface,
|
2014-07-11 06:11:58 -07:00
|
|
|
int x, int y, int w, int h,
|
|
|
|
Evas_Colorspace cspace, void *pixels)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im = surface;
|
2015-07-01 19:52:16 -07:00
|
|
|
GLint fmt = GL_BGRA, fbo = 0;
|
2015-05-12 18:16:17 -07:00
|
|
|
int done = 0;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
|
|
|
|
if (fbo != (GLint) im->tex->pt->fb)
|
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
|
2015-05-12 18:16:17 -07:00
|
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
|
|
|
|
|
|
|
// With GLX we will try to read BGRA even if the driver reports RGBA
|
|
|
|
#if defined(GL_GLES) && defined(GL_IMPLEMENTATION_COLOR_READ_FORMAT)
|
|
|
|
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &fmt);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if ((im->tex->pt->format == GL_BGRA) && (fmt == GL_BGRA))
|
|
|
|
{
|
|
|
|
glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
|
|
|
|
done = (glGetError() == GL_NO_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!done)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2015-05-12 18:16:17 -07:00
|
|
|
|
2015-07-01 19:52:16 -07:00
|
|
|
if (fbo != (GLint) im->tex->pt->fb)
|
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2014-09-18 23:17:08 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
2017-08-25 10:54:19 -07:00
|
|
|
eng_gl_surface_query(void *eng, void *surface, int attr, void *value)
|
2014-09-18 23:17:08 -07:00
|
|
|
{
|
2017-08-25 10:54:19 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
|
|
|
Render_Output_GL_Generic *re;
|
2014-09-18 23:17:08 -07:00
|
|
|
EVGL_Surface *sfc = surface;
|
|
|
|
|
2017-08-25 10:54:19 -07:00
|
|
|
re = _evgl_output_find(engine);
|
|
|
|
if (!re) return EINA_FALSE;
|
|
|
|
|
2014-09-18 23:17:08 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
if (sfc->pbuffer.is_pbuffer)
|
|
|
|
{
|
|
|
|
// This is a real EGL surface, let's just call EGL directly
|
|
|
|
int val;
|
|
|
|
Eina_Bool ok;
|
2014-09-19 01:44:56 -07:00
|
|
|
void *disp;
|
2014-09-18 23:17:08 -07:00
|
|
|
|
2017-08-25 15:44:19 -07:00
|
|
|
disp = egl_display_get(engine);
|
2014-09-19 01:44:56 -07:00
|
|
|
ok = eglQuerySurface(disp, sfc->pbuffer.native_surface, attr, &val);
|
2014-09-18 23:17:08 -07:00
|
|
|
if (!ok) return EINA_FALSE;
|
|
|
|
switch (attr)
|
|
|
|
{
|
|
|
|
case EVAS_GL_TEXTURE_FORMAT:
|
|
|
|
if (val == EGL_TEXTURE_RGB)
|
|
|
|
*((int *) value) = EVAS_GL_RGB_888;
|
|
|
|
else if (val == EGL_TEXTURE_RGBA)
|
|
|
|
*((int *) value) = EVAS_GL_RGBA_8888;
|
|
|
|
else // if (val == EGL_NO_TEXTURE)
|
|
|
|
*((int *) value) = EVAS_GL_NO_FBO;
|
|
|
|
break;
|
|
|
|
case EVAS_GL_TEXTURE_TARGET:
|
|
|
|
if (val == EGL_TEXTURE_2D)
|
|
|
|
*((int *) value) = val;
|
|
|
|
else
|
|
|
|
*((int *) value) = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*((int *) value) = val;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Since this is a fake surface (shared with evas), we must filter the
|
|
|
|
// queries...
|
|
|
|
switch (attr)
|
|
|
|
{
|
|
|
|
// TODO: Add support for whole config get
|
|
|
|
/*
|
|
|
|
case EVAS_GL_CONFIG_ID:
|
|
|
|
*((int *) value) = sfc->cfg_index;
|
|
|
|
return EINA_TRUE;
|
|
|
|
*/
|
|
|
|
case EVAS_GL_WIDTH:
|
|
|
|
*((int *) value) = sfc->w;
|
|
|
|
return EINA_TRUE;
|
|
|
|
case EVAS_GL_HEIGHT:
|
|
|
|
*((int *) value) = sfc->h;
|
|
|
|
return EINA_TRUE;
|
|
|
|
case EVAS_GL_TEXTURE_FORMAT:
|
|
|
|
// FIXME: Check the possible color formats
|
|
|
|
if (sfc->color_buf)
|
|
|
|
{
|
|
|
|
if ((sfc->color_fmt == GL_RGBA) || (sfc->color_fmt == GL_BGRA))
|
|
|
|
{
|
|
|
|
*((Evas_GL_Color_Format *) value) = EVAS_GL_RGBA_8888;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (sfc->color_fmt == GL_RGB)
|
|
|
|
{
|
|
|
|
*((Evas_GL_Color_Format *) value) = EVAS_GL_RGB_888;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*((Evas_GL_Color_Format *) value) = EVAS_GL_NO_FBO;
|
|
|
|
return EINA_TRUE;
|
|
|
|
case EVAS_GL_TEXTURE_TARGET:
|
|
|
|
if (sfc->color_buf)
|
|
|
|
*((int *) value) = EVAS_GL_TEXTURE_2D;
|
|
|
|
else
|
|
|
|
*((int *) value) = 0;
|
|
|
|
return EINA_TRUE;
|
|
|
|
// TODO: Add support for this:
|
|
|
|
/*
|
|
|
|
case EVAS_GL_MULTISAMPLE_RESOLVE:
|
|
|
|
*((int *) value) = sfc->msaa_samples;
|
|
|
|
return EINA_TRUE;
|
|
|
|
*/
|
|
|
|
// TODO: Add support for mipmaps
|
|
|
|
/*
|
|
|
|
case EVAS_GL_MIPMAP_TEXTURE:
|
|
|
|
case EVAS_GL_MIPMAP_LEVEL:
|
2016-12-16 07:12:30 -08:00
|
|
|
return eglQuerySurface(re->win->egl_disp, re->win->egl_surface,
|
2014-09-18 23:17:08 -07:00
|
|
|
attr, (int *) value);
|
|
|
|
*/
|
|
|
|
default: break;
|
|
|
|
}
|
2017-08-25 10:52:26 -07:00
|
|
|
evas_gl_common_error_set(EVAS_GL_BAD_ATTRIBUTE);
|
2014-09-18 23:17:08 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void) re; (void) sfc; (void) attr; (void) value;
|
|
|
|
ERR("GLX support for surface_query is not implemented!");
|
|
|
|
return EINA_FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-03-02 23:38:52 -08:00
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gl_image_direct_get(void *engine EINA_UNUSED, void *image)
|
2015-03-02 23:38:52 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
return im->direct;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-08-25 10:51:10 -07:00
|
|
|
eng_gl_image_direct_set(void *eng, void *image, Eina_Bool direct)
|
2015-03-02 23:38:52 -08:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Render_Engine_GL_Generic *engine = eng;
|
2015-03-02 23:38:52 -08:00
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
|
|
|
if (!im) return;
|
2017-08-25 10:51:10 -07:00
|
|
|
if (im->native.data && direct && engine->func.get_pixels)
|
2015-03-02 23:38:52 -08:00
|
|
|
im->direct = EINA_TRUE;
|
|
|
|
else
|
|
|
|
im->direct = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
//--------------------------------//
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_load_error_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return EVAS_LOAD_ERROR_NONE;
|
|
|
|
im = image;
|
|
|
|
return im->im->cache_entry.load_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_animated_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07: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 im->animated.animated;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_animated_frame_count_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
if (!gim) return -1;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return -1;
|
|
|
|
|
|
|
|
if (!im->animated.animated) return -1;
|
|
|
|
return im->animated.frame_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Image_Animated_Loop_Hint
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_animated_loop_type_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
if (!gim) return EVAS_IMAGE_ANIMATED_HINT_NONE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EVAS_IMAGE_ANIMATED_HINT_NONE;
|
|
|
|
|
|
|
|
if (!im->animated.animated) return EVAS_IMAGE_ANIMATED_HINT_NONE;
|
|
|
|
return im->animated.loop_hint;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_animated_loop_count_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
if (!gim) return -1;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return -1;
|
|
|
|
|
|
|
|
if (!im->animated.animated) return -1;
|
|
|
|
return im->animated.loop_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static double
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_animated_frame_duration_get(void *engine EINA_UNUSED, void *image, int start_frame, int frame_num)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
if (!gim) return -1;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return -1;
|
|
|
|
|
|
|
|
if (!im->animated.animated) return -1;
|
|
|
|
return evas_common_load_rgba_image_frame_duration_from_file(im, start_frame, frame_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_animated_frame_set(void *engine EINA_UNUSED, void *image, int frame_index)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
if (!gim) return EINA_FALSE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (!im->animated.animated) return EINA_FALSE;
|
|
|
|
if (im->animated.cur_frame == frame_index) return EINA_FALSE;
|
|
|
|
|
|
|
|
im->animated.cur_frame = frame_index;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_can_region_get(void *engine EINA_UNUSED, void *image)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
2017-08-25 10:51:10 -07:00
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_max_size_get(void *engine, int *maxw, int *maxh)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 0);
|
2014-07-11 06:11:58 -07:00
|
|
|
if (maxw) *maxw = gl_context->shared->info.max_texture_size;
|
|
|
|
if (maxh) *maxh = gl_context->shared->info.max_texture_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
2015-07-05 02:01:06 -07:00
|
|
|
if (!im->im) return EINA_FALSE;
|
|
|
|
|
2014-07-11 06:11:58 -07: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;
|
|
|
|
|
2018-08-29 21:32:51 -07:00
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
2014-07-11 06:11:58 -07: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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_flush(void *engine)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
if ((gl_context->havestuff) ||
|
|
|
|
(gl_context->master_clip.used))
|
|
|
|
{
|
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
if (gl_context->master_clip.used)
|
|
|
|
evas_gl_common_context_done(gl_context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-24 21:34:42 -08:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_clip_image_unset(void *engine EINA_UNUSED, void *context)
|
2014-11-24 21:34:42 -08:00
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
Evas_GL_Image *im = ctx->clip.mask;
|
|
|
|
|
2017-08-25 10:50:59 -07:00
|
|
|
evas_gl_common_image_free(im);
|
2015-01-22 00:25:59 -08:00
|
|
|
|
2014-11-24 21:34:42 -08:00
|
|
|
ctx->clip.mask = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_clip_image_set(void *engine, void *context, void *surface, int x, int y,
|
2015-07-26 22:10:29 -07:00
|
|
|
Evas_Public_Data *evas, Eina_Bool do_async)
|
2014-11-24 21:34:42 -08:00
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
Evas_GL_Image *im = surface;
|
2015-01-22 00:55:04 -08:00
|
|
|
Eina_Bool noinc = EINA_FALSE;
|
2014-11-24 21:34:42 -08:00
|
|
|
|
2015-01-22 00:55:04 -08:00
|
|
|
if (ctx->clip.mask)
|
|
|
|
{
|
|
|
|
if (ctx->clip.mask != surface)
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_clip_image_unset(engine, context);
|
2015-01-22 00:55:04 -08:00
|
|
|
else
|
|
|
|
noinc = EINA_TRUE;
|
|
|
|
}
|
2014-11-24 21:34:42 -08:00
|
|
|
|
|
|
|
ctx->clip.mask = surface;
|
|
|
|
ctx->clip.mask_x = x;
|
|
|
|
ctx->clip.mask_y = y;
|
|
|
|
|
2015-07-26 22:10:29 -07:00
|
|
|
// useless in gl since the engines are sync only
|
|
|
|
ctx->clip.evas = evas;
|
|
|
|
ctx->clip.async = do_async;
|
|
|
|
|
2015-01-22 01:21:44 -08:00
|
|
|
if (im)
|
2015-01-22 00:25:59 -08:00
|
|
|
{
|
2015-01-22 01:21:44 -08:00
|
|
|
if (!noinc) evas_gl_common_image_ref(im);
|
2015-01-22 00:25:59 -08:00
|
|
|
RECTS_CLIP_TO_RECT(ctx->clip.x, ctx->clip.y, ctx->clip.w, ctx->clip.h,
|
|
|
|
x, y, im->w, im->h);
|
2014-11-24 21:34:42 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_clip_image_get(void *engine EINA_UNUSED, void *context, void **ie, int *x, int *y)
|
2014-11-24 21:34:42 -08:00
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
|
2015-08-31 01:28:58 -07:00
|
|
|
if (ie)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im = ctx->clip.mask;
|
|
|
|
|
|
|
|
*ie = im;
|
|
|
|
if (im) evas_gl_common_image_ref(im);
|
|
|
|
}
|
2014-11-24 21:34:42 -08:00
|
|
|
if (x) *x = ctx->clip.mask_x;
|
|
|
|
if (y) *y = ctx->clip.mask_y;
|
|
|
|
}
|
|
|
|
|
2015-01-21 00:30:18 -08:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_free(void *engine, void *context)
|
2015-01-21 00:30:18 -08:00
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
|
|
|
|
if (!ctx) return;
|
|
|
|
if (ctx->clip.mask)
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_clip_image_unset(engine, context);
|
2015-01-21 00:30:18 -08:00
|
|
|
evas_common_draw_context_free(context);
|
|
|
|
}
|
|
|
|
|
2015-09-02 20:03:23 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_dup(void *engine EINA_UNUSED, void *context)
|
2015-09-02 20:03:23 -07:00
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx;
|
|
|
|
|
|
|
|
ctx = evas_common_draw_context_dup(context);
|
|
|
|
if (ctx->clip.mask)
|
|
|
|
evas_gl_common_image_ref(ctx->clip.mask);
|
|
|
|
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
2017-08-25 10:51:44 -07:00
|
|
|
eng_context_3d_use(void *output)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:44 -07:00
|
|
|
Render_Output_GL_Generic *re = output;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
if (!re->context_3d)
|
|
|
|
re->context_3d = re->window_gl_context_new(re->software.ob);
|
|
|
|
if (re->context_3d) re->window_gl_context_use(re->context_3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
static E3D_Renderer *
|
2017-08-25 10:51:44 -07:00
|
|
|
eng_renderer_3d_get(void *output)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-08-25 10:51:44 -07:00
|
|
|
Render_Output_GL_Generic *re = output;
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
if (!re->renderer_3d)
|
|
|
|
re->renderer_3d = e3d_renderer_new();
|
|
|
|
return re->renderer_3d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_drawable_new(void *engine, int w, int h, int alpha)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_3d_use(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
return e3d_drawable_new(w, h, alpha, GL_DEPTH_STENCIL_OES, GL_NONE);
|
|
|
|
#else
|
|
|
|
return e3d_drawable_new(w, h, alpha, GL_DEPTH24_STENCIL8, GL_NONE);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_drawable_free(void *engine, void *drawable)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_3d_use(engine);
|
2014-07-11 06:11:58 -07:00
|
|
|
e3d_drawable_free(drawable);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_drawable_size_get(void *engine EINA_UNUSED, void *drawable, int *w, int *h)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_drawable_size_get((E3D_Drawable *)drawable, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_drawable_set(void *engine, void *image, void *drawable)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
E3D_Drawable *d = drawable;
|
|
|
|
Evas_Native_Surface ns;
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
ns.type = EVAS_NATIVE_SURFACE_OPENGL;
|
|
|
|
ns.data.opengl.texture_id = e3d_drawable_texture_id_get(d);
|
|
|
|
ns.data.opengl.framebuffer_id = 0;
|
|
|
|
ns.data.opengl.internal_format = e3d_drawable_format_get(d);
|
|
|
|
ns.data.opengl.format = e3d_drawable_format_get(d);
|
|
|
|
ns.data.opengl.x = 0;
|
|
|
|
ns.data.opengl.y = 0;
|
|
|
|
e3d_drawable_size_get(d, &w, &h);
|
|
|
|
ns.data.opengl.w = w;
|
|
|
|
ns.data.opengl.h = h;
|
|
|
|
|
2017-05-12 15:03:05 -07:00
|
|
|
return eng_image_native_set(engine, image, &ns);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-08-25 10:51:44 -07:00
|
|
|
eng_drawable_scene_render(void *engine EINA_UNUSED, void *data, void *drawable, void *scene_data)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
E3D_Renderer *renderer = NULL;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(data, 1);
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
|
2017-08-25 10:51:44 -07:00
|
|
|
eng_context_3d_use(data);
|
|
|
|
renderer = eng_renderer_3d_get(data);
|
2014-07-11 06:11:58 -07:00
|
|
|
e3d_drawable_scene_render(drawable, renderer, scene_data);
|
|
|
|
}
|
|
|
|
|
2016-06-03 04:22:33 -07:00
|
|
|
static int
|
|
|
|
eng_drawable_texture_target_id_get(void *drawable)
|
|
|
|
{
|
|
|
|
return e3d_drawable_texture_id_get((E3D_Drawable *)drawable);
|
|
|
|
}
|
|
|
|
|
2015-02-05 06:34:25 -08:00
|
|
|
static int
|
|
|
|
eng_drawable_texture_color_pick_id_get(void *drawable)
|
|
|
|
{
|
|
|
|
return e3d_drawable_texture_color_pick_id_get((E3D_Drawable *)drawable);
|
|
|
|
}
|
|
|
|
|
2015-05-26 10:12:24 -07:00
|
|
|
static void
|
|
|
|
eng_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y,
|
|
|
|
Evas_Color *color, void *drawable)
|
2015-02-05 06:34:25 -08:00
|
|
|
{
|
2015-05-26 10:12:24 -07:00
|
|
|
return e3d_drawable_texture_pixel_color_get(tex, x, y, color, drawable);
|
2015-02-05 06:34:25 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_drawable_scene_render_to_texture(void *engine, void *drawable, void *scene_data)
|
2015-02-05 06:34:25 -08:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
E3D_Renderer *renderer = NULL;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(engine, 1);
|
2015-02-05 06:34:25 -08:00
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_context_3d_use(engine);
|
|
|
|
renderer = eng_renderer_3d_get(engine);
|
2015-02-05 06:34:25 -08:00
|
|
|
|
|
|
|
return e3d_drawable_scene_render_to_texture((E3D_Drawable *)drawable, renderer, scene_data);
|
|
|
|
}
|
|
|
|
|
2016-06-03 04:22:33 -07:00
|
|
|
static void
|
|
|
|
eng_drawable_texture_rendered_pixels_get(GLuint tex EINA_UNUSED, int x, int y,
|
2017-05-12 15:03:05 -07:00
|
|
|
int w, int h, void *drawable EINA_UNUSED, void *engine)
|
2016-06-03 04:22:33 -07:00
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
e3d_drawable_texture_rendered_pixels_get(tex, x, y, w, h, drawable, engine);
|
2016-06-03 04:22:33 -07:00
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_new(void *engine EINA_UNUSED, Eina_Bool use_atlas)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2015-04-22 06:19:02 -07:00
|
|
|
return e3d_texture_new(use_atlas);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_free(void *engine EINA_UNUSED, void *texture)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_texture_free((E3D_Texture *)texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_size_get(void *engine EINA_UNUSED, void *texture, int *w, int *h)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_texture_size_get((E3D_Texture *)texture, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_wrap_set(void *engine EINA_UNUSED, void *texture,
|
2015-06-17 07:31:14 -07:00
|
|
|
Evas_Canvas3D_Wrap_Mode s, Evas_Canvas3D_Wrap_Mode t)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_texture_wrap_set((E3D_Texture *)texture, s, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_wrap_get(void *engine EINA_UNUSED, void *texture,
|
2015-06-17 07:31:14 -07:00
|
|
|
Evas_Canvas3D_Wrap_Mode *s, Evas_Canvas3D_Wrap_Mode *t)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_texture_wrap_get((E3D_Texture *)texture, s, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_filter_set(void *engine EINA_UNUSED, void *texture,
|
2015-06-17 07:31:14 -07:00
|
|
|
Evas_Canvas3D_Texture_Filter min, Evas_Canvas3D_Texture_Filter mag)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_texture_filter_set((E3D_Texture *)texture, min, mag);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_filter_get(void *engine EINA_UNUSED, void *texture,
|
2015-06-17 07:31:14 -07:00
|
|
|
Evas_Canvas3D_Texture_Filter *min, Evas_Canvas3D_Texture_Filter *mag)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
e3d_texture_filter_get((E3D_Texture *)texture, min, mag);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_image_set(void *engine, void *texture, void *image)
|
2015-04-22 06:19:02 -07:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_get(engine, 1);
|
2015-04-22 06:19:02 -07:00
|
|
|
|
|
|
|
e3d_texture_set(gl_context, (E3D_Texture *)texture, (Evas_GL_Image *)image);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_texture_image_get(void *engine EINA_UNUSED, void *texture)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2015-04-22 06:19:02 -07:00
|
|
|
return e3d_texture_get((E3D_Texture *)texture);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
2016-01-03 16:10:53 -08:00
|
|
|
static Eina_Bool use_cairo = EINA_FALSE;
|
|
|
|
static Eina_Bool use_gl = EINA_FALSE;
|
2015-04-03 07:30:44 -07:00
|
|
|
|
|
|
|
static Ector_Surface *
|
2017-08-25 10:52:10 -07:00
|
|
|
eng_ector_create(void *engine EINA_UNUSED)
|
2015-04-03 07:30:44 -07:00
|
|
|
{
|
2015-08-24 23:32:35 -07:00
|
|
|
Ector_Surface *ector;
|
|
|
|
const char *ector_backend;
|
|
|
|
ector_backend = getenv("ECTOR_BACKEND");
|
2016-09-27 23:28:27 -07:00
|
|
|
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
2015-08-24 23:32:35 -07:00
|
|
|
if (ector_backend && !strcasecmp(ector_backend, "default"))
|
2015-04-03 07:30:44 -07:00
|
|
|
{
|
2018-03-15 09:50:20 -07:00
|
|
|
ector = efl_add_ref(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
|
2016-01-03 16:10:53 -08:00
|
|
|
}
|
|
|
|
else if (ector_backend && !strcasecmp(ector_backend, "experimental"))
|
|
|
|
{
|
2018-03-15 09:50:20 -07:00
|
|
|
ector = efl_add_ref(ECTOR_GL_SURFACE_CLASS, NULL);
|
2016-01-03 16:10:53 -08:00
|
|
|
use_gl = EINA_TRUE;
|
2015-04-03 07:30:44 -07:00
|
|
|
}
|
2015-08-24 23:32:35 -07:00
|
|
|
else
|
|
|
|
{
|
2018-03-15 09:50:20 -07:00
|
|
|
ector = efl_add_ref(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
|
2015-08-24 23:32:35 -07:00
|
|
|
use_cairo = EINA_TRUE;
|
|
|
|
}
|
2016-09-27 23:28:27 -07:00
|
|
|
efl_domain_current_pop();
|
2015-08-24 23:32:35 -07:00
|
|
|
return ector;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_ector_destroy(void *engine EINA_UNUSED, Ector_Surface *ector)
|
2015-08-24 23:32:35 -07:00
|
|
|
{
|
2018-03-15 09:50:20 -07:00
|
|
|
if (ector) efl_unref(ector);
|
2015-04-03 07:30:44 -07:00
|
|
|
}
|
|
|
|
|
2015-12-08 00:29:54 -08:00
|
|
|
static Ector_Buffer *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_ector_buffer_wrap(void *engine EINA_UNUSED, Evas *evas, void *engine_image)
|
2015-12-08 00:29:54 -08:00
|
|
|
{
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
Evas_GL_Image *im = engine_image;
|
2015-12-30 21:33:03 -08:00
|
|
|
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(engine_image, NULL);
|
2015-12-30 21:33:03 -08:00
|
|
|
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
return efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas,
|
|
|
|
evas_ector_buffer_engine_image_set(efl_added, evas, im));
|
2015-12-08 17:45:53 -08:00
|
|
|
}
|
2015-12-08 00:29:54 -08:00
|
|
|
|
2015-12-08 17:45:53 -08:00
|
|
|
static Ector_Buffer *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_ector_buffer_new(void *engine, Evas *evas, int w, int h,
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags)
|
2015-12-08 17:45:53 -08:00
|
|
|
{
|
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.
For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.
This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.
Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).
No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.
This patch removes more lines than it adds so it must be good ;)
2017-01-17 18:47:25 -08:00
|
|
|
return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas,
|
2017-05-12 15:03:05 -07:00
|
|
|
evas_ector_gl_buffer_prepare(efl_added, engine, w, h, cspace, flags));
|
2015-12-08 00:29:54 -08:00
|
|
|
}
|
|
|
|
|
2015-04-03 07:30:44 -07:00
|
|
|
static void
|
2017-11-08 23:55:44 -08:00
|
|
|
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *output,
|
|
|
|
void *context EINA_UNUSED, void *surface EINA_UNUSED,
|
|
|
|
Ector_Renderer *renderer, Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
|
2015-04-03 07:30:44 -07:00
|
|
|
{
|
2017-11-08 23:55:44 -08:00
|
|
|
if (use_cairo|| !use_gl)
|
2015-04-03 07:30:44 -07:00
|
|
|
{
|
2017-11-08 23:55:44 -08:00
|
|
|
int w, h;
|
|
|
|
Eina_Rectangle *r;
|
|
|
|
Eina_Array *c = eina_array_new(4);
|
|
|
|
Evas_GL_Image *glimg = output;
|
2015-04-03 07:30:44 -07:00
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
eng_image_size_get(engine, glimg, &w, &h);
|
|
|
|
eina_array_push(c, eina_rectangle_new(0, 0, w, h));
|
2015-04-03 07:30:44 -07:00
|
|
|
|
2018-01-08 02:16:59 -08:00
|
|
|
ector_renderer_draw(renderer, EFL_GFX_RENDER_OP_BLEND, c, 0xffffffff);
|
2015-04-03 07:30:50 -07:00
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
while ((r = eina_array_pop(c)))
|
|
|
|
eina_rectangle_free(r);
|
|
|
|
eina_array_free(c);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//FIXME no implementation yet
|
2015-04-03 07:30:44 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-26 21:42:01 -07:00
|
|
|
// Ector functions start
|
|
|
|
static void*
|
|
|
|
eng_ector_surface_create(void *engine, int width, int height, int *error)
|
|
|
|
{
|
|
|
|
void *surface;
|
|
|
|
|
|
|
|
*error = EINA_FALSE;
|
|
|
|
|
|
|
|
if (use_gl)
|
|
|
|
{
|
|
|
|
surface = evas_gl_common_image_surface_new(gl_generic_context_get(engine, EINA_TRUE),
|
|
|
|
width, height, EINA_TRUE, EINA_FALSE);
|
|
|
|
if (!surface) *error = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
surface = eng_image_new_from_copied_data(engine, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
|
|
|
|
if (!surface)
|
2017-11-08 23:55:44 -08:00
|
|
|
*error = EINA_TRUE;
|
2017-10-26 21:42:01 -07:00
|
|
|
else //Use this hint for ZERO COPY texture upload.
|
|
|
|
eng_image_content_hint_set(engine, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
|
|
|
|
}
|
|
|
|
|
|
|
|
return surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_ector_surface_destroy(void *engine, void *surface)
|
|
|
|
{
|
|
|
|
if (!surface) return;
|
|
|
|
eng_image_free(engine, surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_ector_surface_cache_set(void *engine, void *key , void *surface)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *e = engine;
|
|
|
|
|
|
|
|
generic_cache_data_set(e->software.surface_cache, key, surface);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_ector_surface_cache_get(void *engine, void *key)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *e = engine;
|
|
|
|
|
|
|
|
return generic_cache_data_get(e->software.surface_cache, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_ector_surface_cache_drop(void *engine, void *key)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *e = engine;
|
|
|
|
|
|
|
|
generic_cache_data_drop(e->software.surface_cache, key);
|
|
|
|
}
|
|
|
|
|
2015-04-03 07:30:44 -07:00
|
|
|
static void
|
2017-11-08 23:55:44 -08:00
|
|
|
eng_ector_begin(void *engine, void *output,
|
|
|
|
void *context EINA_UNUSED, void *surface EINA_UNUSED,
|
|
|
|
Ector_Surface *ector, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
2015-04-03 07:30:44 -07:00
|
|
|
{
|
2016-01-03 16:10:53 -08:00
|
|
|
if (use_cairo|| !use_gl)
|
2015-10-29 23:20:31 -07:00
|
|
|
{
|
2017-11-08 23:55:44 -08:00
|
|
|
int w, h, stride;
|
|
|
|
Evas_GL_Image *glim = output;
|
|
|
|
DATA32 *pixels;
|
|
|
|
int load_err;
|
2016-01-03 16:10:53 -08:00
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
glim = eng_image_data_get(engine, glim, EINA_TRUE, &pixels, &load_err,NULL);
|
|
|
|
eng_image_stride_get(engine, glim, &stride);
|
|
|
|
eng_image_size_get(engine, glim, &w, &h);
|
|
|
|
memset(pixels, 0, stride * h);
|
2016-01-03 16:10:53 -08:00
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
// it just uses the software backend to draw for now
|
2018-02-07 21:27:15 -08:00
|
|
|
ector_buffer_pixels_set(ector, pixels, w, h, stride, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
2016-03-01 10:06:28 -08:00
|
|
|
ector_surface_reference_point_set(ector, x, y);
|
2016-01-03 16:10:53 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-08 23:55:44 -08:00
|
|
|
//FIXME: No implementation yet
|
2015-10-29 23:20:31 -07:00
|
|
|
}
|
2015-04-03 07:30:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-11-08 23:55:44 -08:00
|
|
|
eng_ector_end(void *engine, void *output,
|
|
|
|
void *context EINA_UNUSED, void *surface EINA_UNUSED,
|
|
|
|
Ector_Surface *ector, Eina_Bool do_async EINA_UNUSED)
|
2015-04-03 07:30:44 -07:00
|
|
|
{
|
2016-01-03 16:10:53 -08:00
|
|
|
if (use_cairo || !use_gl)
|
|
|
|
{
|
2017-11-08 23:55:44 -08:00
|
|
|
Evas_GL_Image *glim = output;
|
|
|
|
DATA32 *pixels;
|
|
|
|
int load_err;
|
2015-11-19 04:15:51 -08:00
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
glim = eng_image_data_get(engine, glim, EINA_FALSE, &pixels, &load_err,NULL);
|
2015-04-03 07:34:21 -07:00
|
|
|
|
2017-11-08 23:55:44 -08:00
|
|
|
eng_image_data_put(engine, glim, pixels);
|
|
|
|
eng_image_data_put(engine, glim, pixels);
|
2018-02-07 21:27:15 -08:00
|
|
|
ector_buffer_pixels_set(ector, NULL, 0, 0, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
2017-11-08 23:55:44 -08:00
|
|
|
evas_common_cpu_end_opt();
|
2016-01-03 16:10:53 -08:00
|
|
|
}
|
|
|
|
else if (use_gl)
|
|
|
|
{
|
2017-11-08 23:55:44 -08:00
|
|
|
//FIXME: No implementation yet
|
2016-01-03 16:10:53 -08:00
|
|
|
}
|
2015-04-03 07:30:44 -07:00
|
|
|
}
|
|
|
|
|
2016-09-01 05:46:42 -07:00
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_map(void *engine, void **image, Eina_Rw_Slice *slice,
|
2016-09-01 05:04:37 -07:00
|
|
|
int *stride, int x, int y, int w, int h,
|
2016-09-01 05:46:42 -07:00
|
|
|
Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode,
|
|
|
|
int plane)
|
2016-07-19 05:08:02 -07:00
|
|
|
{
|
2017-08-25 10:51:10 -07:00
|
|
|
Render_Engine_GL_Generic *re = engine;
|
2016-07-19 05:08:02 -07:00
|
|
|
Evas_GL_Image_Data_Map *map = NULL;
|
2017-03-28 00:09:34 -07:00
|
|
|
Evas_GL_Image *glim, *glim2 = NULL;
|
|
|
|
Eina_Bool ok = EINA_FALSE;
|
|
|
|
RGBA_Image *im = NULL;
|
|
|
|
int strid;
|
2016-07-19 05:08:02 -07:00
|
|
|
|
2016-09-01 05:46:42 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image && slice, EINA_FALSE);
|
2016-07-19 05:08:02 -07:00
|
|
|
|
2017-03-28 00:09:34 -07:00
|
|
|
glim = *image;
|
|
|
|
slice->mem = NULL;
|
|
|
|
slice->len = 0;
|
|
|
|
|
|
|
|
if (glim->im && (glim->orient == EVAS_IMAGE_ORIENT_NONE))
|
|
|
|
{
|
|
|
|
evas_gl_common_image_ref(glim);
|
|
|
|
glim2 = glim;
|
|
|
|
}
|
|
|
|
else
|
2016-07-19 05:08:02 -07:00
|
|
|
{
|
2017-03-28 00:09:34 -07:00
|
|
|
glim2 = _rotate_image_data(re, glim);
|
|
|
|
}
|
2016-07-19 05:08:02 -07:00
|
|
|
|
2017-03-28 00:09:34 -07:00
|
|
|
if (!glim2) return EINA_FALSE;
|
|
|
|
im = glim2->im;
|
|
|
|
if (im)
|
|
|
|
{
|
|
|
|
// Call sw generic implementation.
|
|
|
|
ok = pfunc.image_data_map(NULL, (void **) &im, slice, &strid,
|
2016-09-01 05:46:42 -07:00
|
|
|
x, y, w, h, cspace, mode, plane);
|
2016-07-19 05:08:02 -07:00
|
|
|
}
|
|
|
|
|
2017-03-28 00:09:34 -07:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
eng_image_free(re, glim2);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_cache_image_ref(&im->cache_entry);
|
2016-07-19 05:08:02 -07:00
|
|
|
|
2017-03-28 00:09:34 -07:00
|
|
|
map = calloc(1, sizeof(*map));
|
|
|
|
map->cspace = cspace;
|
|
|
|
map->rx = x;
|
|
|
|
map->ry = y;
|
|
|
|
map->rw = w;
|
|
|
|
map->rh = h;
|
|
|
|
map->mode = mode;
|
|
|
|
map->slice = *slice;
|
|
|
|
map->stride = strid;
|
|
|
|
map->im = im;
|
|
|
|
map->glim = glim2;
|
|
|
|
glim->maps = eina_inlist_prepend(glim->maps, EINA_INLIST_GET(map));
|
|
|
|
if (stride) *stride = strid;
|
|
|
|
|
|
|
|
if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE)
|
|
|
|
{
|
|
|
|
evas_gl_common_image_ref(glim2);
|
|
|
|
evas_gl_common_image_free(glim);
|
|
|
|
*image = glim2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
2016-07-19 05:08:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_unmap(void *engine EINA_UNUSED, void *image, const Eina_Rw_Slice *slice)
|
2016-07-19 05:08:02 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image_Data_Map *map;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Eina_Bool found = EINA_FALSE;
|
|
|
|
|
2016-09-01 05:46:42 -07:00
|
|
|
if (!(image && slice))
|
2016-07-19 05:08:02 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(im->maps, map)
|
|
|
|
{
|
2016-09-01 05:04:37 -07:00
|
|
|
if ((map->slice.len == slice->len) && (map->slice.mem == slice->mem))
|
2016-07-19 05:08:02 -07:00
|
|
|
{
|
|
|
|
found = EINA_TRUE;
|
|
|
|
if (map->im)
|
2017-03-28 00:09:34 -07:00
|
|
|
{
|
|
|
|
found = pfunc.image_data_unmap(NULL, map->im, slice);
|
|
|
|
evas_cache_image_drop(&map->im->cache_entry);
|
|
|
|
}
|
2016-07-19 05:08:02 -07:00
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
if (im->im && im->tex &&
|
|
|
|
(map->mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE))
|
|
|
|
evas_gl_common_texture_update(im->tex, im->im);
|
|
|
|
im->maps = eina_inlist_remove(im->maps, EINA_INLIST_GET(map));
|
2017-08-25 10:50:59 -07:00
|
|
|
evas_gl_common_image_free(map->glim);
|
2016-07-19 05:08:02 -07:00
|
|
|
free(map);
|
|
|
|
}
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-01 05:04:37 -07:00
|
|
|
ERR("failed to unmap region %p (%zu bytes)", slice->mem, slice->len);
|
2016-07-19 05:08:02 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_maps_get(void *engine EINA_UNUSED, const void *image, const Eina_Rw_Slice **slices)
|
2016-07-19 05:08:02 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image_Data_Map *map;
|
|
|
|
const Evas_GL_Image *im = image;
|
|
|
|
int k = 0;
|
|
|
|
|
|
|
|
if (!im) return -1;
|
|
|
|
|
2016-09-01 05:04:37 -07:00
|
|
|
if (!slices)
|
2016-07-19 05:08:02 -07:00
|
|
|
return eina_inlist_count(im->maps);
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(im->maps, map)
|
2016-09-01 05:04:37 -07:00
|
|
|
slices[k++] = &map->slice;
|
2016-07-19 05:08:02 -07:00
|
|
|
|
|
|
|
return k;
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2016-09-04 21:53:00 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_is_yuv(Efl_Gfx_Colorspace cspace)
|
|
|
|
{
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR420TM12601_PL:
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_data_slice_add(void *engine, void *image,
|
2016-09-04 21:53:00 -07:00
|
|
|
const Eina_Slice *slice, Eina_Bool copy,
|
|
|
|
int w, int h, int stride, Evas_Colorspace cspace,
|
|
|
|
int plane, Eina_Bool alpha)
|
|
|
|
{
|
|
|
|
const Eina_Bool use_cs = _is_yuv(cspace);
|
|
|
|
const unsigned char **cs_data;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
int bpp = 0;
|
|
|
|
|
|
|
|
// Note: This code is not very robust by choice. It should NOT be used
|
|
|
|
// in conjunction with data_put/data_get. Ever.
|
|
|
|
// Assume w,h,cspace,alpha to be correct.
|
|
|
|
// We still use cs.data for YUV.
|
|
|
|
// 'image' may be NULL, in that case create a new one. Otherwise, it must
|
|
|
|
// have been created by a previous call to this function.
|
|
|
|
|
|
|
|
if ((plane < 0) || (plane >= RGBA_PLANE_MAX)) goto fail;
|
|
|
|
if (!slice || !slice->mem) goto fail;
|
|
|
|
copy = !!copy;
|
|
|
|
|
|
|
|
// not implemented
|
|
|
|
if (use_cs && copy)
|
|
|
|
{
|
|
|
|
// To implement this, we should switch the internals to slices first,
|
|
|
|
// as this would give 3 planes rather than N rows of datas
|
|
|
|
ERR("Evas can not copy YUV data (not implemented yet).");
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (im && !im->im)
|
|
|
|
{
|
|
|
|
evas_gl_common_image_unref(im);
|
|
|
|
im = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// alloc
|
|
|
|
if (!im)
|
|
|
|
{
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EFL_GFX_COLORSPACE_ARGB8888:
|
|
|
|
case EFL_GFX_COLORSPACE_AGRY88:
|
|
|
|
case EFL_GFX_COLORSPACE_GRY8:
|
|
|
|
if (plane != 0) goto fail;
|
|
|
|
if (copy)
|
2017-05-12 15:03:05 -07:00
|
|
|
im = eng_image_new_from_copied_data(engine, w, h, NULL, alpha, cspace);
|
2016-09-04 21:53:00 -07:00
|
|
|
else
|
2017-05-12 15:03:05 -07:00
|
|
|
im = eng_image_new_from_data(engine, w, h, NULL, alpha, cspace);
|
2016-09-04 21:53:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
2017-05-12 15:03:05 -07:00
|
|
|
im = eng_image_new_from_data(engine, w, h, NULL, alpha, cspace);
|
2016-09-04 21:53:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// TODO: ETC, S3TC, YCBCR420TM12 (aka ST12 or tiled NV12)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
if (!im) goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (use_cs && (!im->cs.data || im->cs.no_free))
|
|
|
|
{
|
|
|
|
im->cs.data = calloc(1, h * sizeof(void *) * 2);
|
|
|
|
if (!im->cs.data) goto fail;
|
|
|
|
im->cs.no_free = EINA_FALSE;
|
|
|
|
if (!im->im->cs.no_free) free(im->im->cs.data);
|
|
|
|
im->im->cs.data = im->cs.data;
|
|
|
|
im->im->cs.no_free = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// is this allocating image.data or cs.data?
|
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
|
|
|
if (!im->im)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
// assign
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EFL_GFX_COLORSPACE_ARGB8888:
|
|
|
|
bpp = 4;
|
2017-06-05 12:01:59 -07:00
|
|
|
EINA_FALLTHROUGH;
|
2017-02-08 01:38:42 -08:00
|
|
|
// falltrhough is intended
|
2016-09-04 21:53:00 -07:00
|
|
|
case EFL_GFX_COLORSPACE_AGRY88:
|
|
|
|
if (!bpp) bpp = 2;
|
2017-06-05 12:01:59 -07:00
|
|
|
EINA_FALLTHROUGH;
|
2017-02-08 01:38:42 -08:00
|
|
|
// falltrhough is intended
|
2016-09-04 21:53:00 -07:00
|
|
|
case EFL_GFX_COLORSPACE_GRY8:
|
|
|
|
if (!bpp) bpp = 1;
|
|
|
|
if (plane != 0) goto fail;
|
|
|
|
if (!im->im->image.data) goto fail;
|
|
|
|
if (!stride) stride = w * bpp;
|
|
|
|
if (copy)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < h; y++)
|
|
|
|
{
|
|
|
|
const unsigned char *src = slice->bytes + h * stride;
|
|
|
|
unsigned char *dst = im->im->image.data8 + bpp * w;
|
|
|
|
memcpy(dst, src, w * bpp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (stride != (bpp * w))
|
|
|
|
{
|
|
|
|
ERR("invalid stride for zero-copy data set");
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
im->im->image.data = (DATA32 *) slice->mem;
|
|
|
|
im->im->image.no_free = EINA_TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422P601_PL:
|
2017-06-05 12:01:59 -07:00
|
|
|
EINA_FALLTHROUGH;
|
2016-09-04 21:53:00 -07:00
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
/* YCbCr 4:2:2 Planar: Y rows, then the Cb, then Cr rows. */
|
|
|
|
cs_data = im->cs.data;
|
|
|
|
if (plane == 0)
|
|
|
|
{
|
|
|
|
if (!stride) stride = w;
|
|
|
|
for (int y = 0; y < h; y++)
|
|
|
|
cs_data[y] = slice->bytes + (y * stride);
|
|
|
|
}
|
|
|
|
else if (plane == 1)
|
|
|
|
{
|
|
|
|
if (!stride) stride = w / 2;
|
|
|
|
for (int y = 0; y < (h / 2); y++)
|
|
|
|
cs_data[h + y] = slice->bytes + (y * stride);
|
|
|
|
}
|
|
|
|
else if (plane == 2)
|
|
|
|
{
|
|
|
|
if (!stride) stride = w / 2;
|
|
|
|
for (int y = 0; y < (h / 2); y++)
|
|
|
|
cs_data[h + (h / 2) + y] = slice->bytes + (y * stride);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR422601_PL:
|
|
|
|
/* YCbCr 4:2:2: lines of Y,Cb,Y,Cr bytes. */
|
|
|
|
if (plane != 0) goto fail;
|
|
|
|
if (!stride) stride = w * 2;
|
|
|
|
cs_data = im->cs.data;
|
|
|
|
for (int y = 0; y < h; y++)
|
|
|
|
cs_data[y] = slice->bytes + (y * stride);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_GFX_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
/* YCbCr 4:2:0: Y rows, then the Cb,Cr rows. */
|
|
|
|
if (!stride) stride = w;
|
|
|
|
cs_data = im->cs.data;
|
|
|
|
if (plane == 0)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < h; y++)
|
|
|
|
cs_data[y] = slice->bytes + (y * stride);
|
|
|
|
}
|
|
|
|
else if (plane == 1)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < (h / 2); y++)
|
|
|
|
cs_data[h + y] = slice->bytes + (y * stride);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
// ETC, S3TC, YCBCR420TM12 (aka ST12 or tiled NV12)
|
|
|
|
default:
|
|
|
|
ERR("unsupported color space %d", cspace);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
return im;
|
|
|
|
|
|
|
|
fail:
|
2017-05-12 15:03:05 -07:00
|
|
|
if (im) eng_image_free(engine, im);
|
2016-09-04 21:53:00 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-11-14 18:22:14 -08:00
|
|
|
static void
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_prepare(void *engine EINA_UNUSED, void *image)
|
2016-11-14 18:22:14 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
|
|
|
if (!im) return;
|
|
|
|
evas_gl_common_image_update(im->gc, im);
|
|
|
|
}
|
|
|
|
|
2016-11-14 21:42:47 -08:00
|
|
|
static void *
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_image_surface_noscale_new(void *engine, int w, int h, int alpha)
|
2016-11-14 21:42:47 -08:00
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
2017-08-25 10:54:55 -07:00
|
|
|
gl_context = gl_generic_context_find(engine, 1);
|
2016-11-16 19:26:46 -08:00
|
|
|
return evas_gl_common_image_surface_noscale_new(gl_context, w, h, alpha);
|
2016-11-14 21:42:47 -08:00
|
|
|
}
|
|
|
|
|
2017-01-17 04:34:48 -08:00
|
|
|
//------------------------------------------------//
|
|
|
|
|
|
|
|
static GL_Filter_Apply_Func
|
2017-09-05 00:29:01 -07:00
|
|
|
_gfx_filter_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
2017-01-17 04:34:48 -08:00
|
|
|
{
|
|
|
|
GL_Filter_Apply_Func funcptr = NULL;
|
|
|
|
|
|
|
|
switch (cmd->mode)
|
|
|
|
{
|
2017-03-20 07:25:05 -07:00
|
|
|
case EVAS_FILTER_MODE_BLEND: funcptr = gl_filter_blend_func_get(re, cmd); break;
|
|
|
|
case EVAS_FILTER_MODE_BLUR: funcptr = gl_filter_blur_func_get(re, cmd); break;
|
|
|
|
//case EVAS_FILTER_MODE_BUMP: funcptr = gl_filter_bump_func_get(re, cmd); break;
|
|
|
|
case EVAS_FILTER_MODE_CURVE: funcptr = gl_filter_curve_func_get(re, cmd); break;
|
|
|
|
case EVAS_FILTER_MODE_DISPLACE: funcptr = gl_filter_displace_func_get(re, cmd); break;
|
|
|
|
case EVAS_FILTER_MODE_FILL: funcptr = gl_filter_fill_func_get(re, cmd); break;
|
|
|
|
case EVAS_FILTER_MODE_MASK: funcptr = gl_filter_mask_func_get(re, cmd); break;
|
|
|
|
//case EVAS_FILTER_MODE_TRANSFORM: funcptr = gl_filter_transform_func_get(re, cmd); break;
|
2017-01-17 04:34:48 -08:00
|
|
|
default: return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return funcptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Filter_Support
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gfx_filter_supports(void *engine, Evas_Filter_Command *cmd)
|
2017-01-17 04:34:48 -08:00
|
|
|
{
|
2017-09-05 00:29:01 -07:00
|
|
|
Render_Engine_GL_Generic *re = engine;
|
2017-01-17 04:34:48 -08:00
|
|
|
|
2017-03-20 07:25:05 -07:00
|
|
|
if (!_gfx_filter_func_get(re, cmd))
|
2017-01-17 04:34:48 -08:00
|
|
|
return pfunc.gfx_filter_supports(&re->software, cmd);
|
|
|
|
|
|
|
|
return EVAS_FILTER_SUPPORT_GL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2017-05-12 15:03:05 -07:00
|
|
|
eng_gfx_filter_process(void *engine, Evas_Filter_Command *cmd)
|
2017-01-17 04:34:48 -08:00
|
|
|
{
|
2017-09-05 00:29:01 -07:00
|
|
|
Render_Engine_GL_Generic *re = engine;
|
2017-01-17 04:34:48 -08:00
|
|
|
GL_Filter_Apply_Func funcptr;
|
|
|
|
|
2017-03-20 07:25:05 -07:00
|
|
|
funcptr = _gfx_filter_func_get(re, cmd);
|
2017-01-17 04:34:48 -08:00
|
|
|
if (funcptr)
|
|
|
|
return funcptr(re, cmd);
|
|
|
|
else
|
|
|
|
return pfunc.gfx_filter_process(&re->software, cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------//
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static int
|
|
|
|
module_open(Evas_Module *em)
|
|
|
|
{
|
|
|
|
if (!em) return 0;
|
|
|
|
if (!evas_gl_common_module_open()) return 0;
|
|
|
|
/* get whatever engine module we inherit from */
|
2017-08-25 10:48:20 -07:00
|
|
|
if (!_evas_module_engine_inherit(&pfunc, "software_generic", 0)) return 0;
|
2014-07-11 06:11:58 -07:00
|
|
|
if (_evas_engine_GL_log_dom < 0)
|
2015-04-14 01:27:06 -07:00
|
|
|
_evas_engine_GL_log_dom = eina_log_domain_register("evas-gl_generic", EVAS_DEFAULT_LOG_COLOR);
|
2014-07-11 06:11:58 -07:00
|
|
|
if (_evas_engine_GL_log_dom < 0)
|
|
|
|
{
|
|
|
|
EINA_LOG_ERR("Can not create a module log domain.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-12-16 15:19:57 -08:00
|
|
|
ector_init();
|
|
|
|
ector_glsym_set(dlsym, RTLD_DEFAULT);
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
/* store it for later use */
|
|
|
|
func = pfunc;
|
|
|
|
/* now to override methods */
|
|
|
|
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
|
2017-08-25 10:50:35 -07:00
|
|
|
ORD(engine_new);
|
|
|
|
ORD(engine_free);
|
|
|
|
|
2014-11-24 21:34:42 -08:00
|
|
|
ORD(context_clip_image_set);
|
|
|
|
ORD(context_clip_image_unset);
|
|
|
|
ORD(context_clip_image_get);
|
2015-09-02 20:03:23 -07:00
|
|
|
ORD(context_dup);
|
2015-01-21 00:30:18 -08:00
|
|
|
ORD(context_free);
|
2014-11-24 21:34:42 -08:00
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(rectangle_draw);
|
|
|
|
ORD(line_draw);
|
|
|
|
ORD(polygon_point_add);
|
|
|
|
ORD(polygon_points_clear);
|
|
|
|
ORD(polygon_draw);
|
|
|
|
|
|
|
|
ORD(image_mmap);
|
|
|
|
ORD(image_new_from_data);
|
|
|
|
ORD(image_new_from_copied_data);
|
|
|
|
ORD(image_free);
|
2015-10-07 22:00:39 -07:00
|
|
|
ORD(image_ref);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(image_size_get);
|
|
|
|
ORD(image_size_set);
|
|
|
|
ORD(image_dirty_region);
|
|
|
|
ORD(image_data_get);
|
|
|
|
ORD(image_data_put);
|
2016-09-02 01:55:33 -07:00
|
|
|
ORD(image_data_direct_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(image_data_preload_request);
|
|
|
|
ORD(image_data_preload_cancel);
|
|
|
|
ORD(image_alpha_set);
|
|
|
|
ORD(image_alpha_get);
|
2015-04-22 02:25:38 -07:00
|
|
|
ORD(image_orient_set);
|
|
|
|
ORD(image_orient_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(image_draw);
|
|
|
|
ORD(image_colorspace_set);
|
|
|
|
ORD(image_colorspace_get);
|
2015-10-29 05:46:08 -07:00
|
|
|
ORD(image_file_colorspace_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(image_can_region_get);
|
2016-03-08 23:18:34 -08:00
|
|
|
ORD(image_native_init);
|
|
|
|
ORD(image_native_shutdown);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(image_native_set);
|
|
|
|
ORD(image_native_get);
|
|
|
|
|
|
|
|
ORD(font_draw);
|
|
|
|
|
|
|
|
ORD(image_scale_hint_set);
|
|
|
|
ORD(image_scale_hint_get);
|
|
|
|
ORD(image_stride_get);
|
|
|
|
|
|
|
|
ORD(image_map_draw);
|
|
|
|
ORD(image_map_surface_new);
|
|
|
|
ORD(image_map_clean);
|
2015-02-25 02:05:12 -08:00
|
|
|
ORD(image_scaled_update);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
ORD(image_content_hint_set);
|
|
|
|
|
|
|
|
ORD(image_cache_flush);
|
|
|
|
ORD(image_cache_set);
|
|
|
|
ORD(image_cache_get);
|
|
|
|
|
2016-07-19 05:08:02 -07:00
|
|
|
ORD(image_data_map);
|
|
|
|
ORD(image_data_unmap);
|
|
|
|
ORD(image_data_maps_get);
|
2016-09-04 21:53:00 -07:00
|
|
|
ORD(image_data_slice_add);
|
2016-07-19 05:08:02 -07:00
|
|
|
|
2016-11-14 18:22:14 -08:00
|
|
|
ORD(image_prepare);
|
2016-11-14 21:42:47 -08:00
|
|
|
ORD(image_surface_noscale_new);
|
2016-11-14 18:22:14 -08:00
|
|
|
|
2016-04-12 01:30:48 -07:00
|
|
|
ORD(font_cache_flush);
|
|
|
|
ORD(font_cache_set);
|
|
|
|
ORD(font_cache_get);
|
|
|
|
|
2018-01-16 22:17:59 -08:00
|
|
|
ORD(gl_supports_evas_gl);
|
2017-08-25 10:54:19 -07:00
|
|
|
ORD(gl_output_set);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(gl_surface_create);
|
2014-09-19 01:32:26 -07:00
|
|
|
ORD(gl_pbuffer_surface_create);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(gl_surface_destroy);
|
|
|
|
ORD(gl_context_create);
|
|
|
|
ORD(gl_context_destroy);
|
|
|
|
ORD(gl_make_current);
|
|
|
|
ORD(gl_string_query);
|
|
|
|
ORD(gl_proc_address_get);
|
|
|
|
ORD(gl_native_surface_get);
|
|
|
|
ORD(gl_api_get);
|
|
|
|
ORD(gl_direct_override_get);
|
2014-12-09 04:36:45 -08:00
|
|
|
ORD(gl_surface_direct_renderable_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(gl_get_pixels_set);
|
2015-03-03 03:08:16 -08:00
|
|
|
ORD(gl_get_pixels_pre);
|
|
|
|
ORD(gl_get_pixels_post);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(gl_surface_lock);
|
|
|
|
ORD(gl_surface_read_pixels);
|
|
|
|
ORD(gl_surface_unlock);
|
2014-09-01 04:15:33 -07:00
|
|
|
//ORD(gl_error_get);
|
2014-09-18 23:17:08 -07:00
|
|
|
ORD(gl_surface_query);
|
2014-09-01 04:15:33 -07:00
|
|
|
// gl_current_context_get is in engine
|
|
|
|
ORD(gl_current_surface_get);
|
2014-09-02 05:29:25 -07:00
|
|
|
ORD(gl_rotation_angle_get);
|
2015-03-02 23:38:52 -08:00
|
|
|
ORD(gl_image_direct_get);
|
|
|
|
ORD(gl_image_direct_set);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
|
|
|
ORD(image_load_error_get);
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
ORD(image_max_size_get);
|
|
|
|
|
|
|
|
ORD(pixel_alpha_get);
|
|
|
|
|
|
|
|
ORD(context_flush);
|
|
|
|
|
|
|
|
/* 3D features */
|
|
|
|
ORD(drawable_new);
|
|
|
|
ORD(drawable_free);
|
|
|
|
ORD(drawable_size_get);
|
|
|
|
ORD(image_drawable_set);
|
|
|
|
|
|
|
|
ORD(drawable_scene_render);
|
|
|
|
|
2015-02-05 06:34:25 -08:00
|
|
|
ORD(drawable_texture_color_pick_id_get);
|
2016-06-03 04:22:33 -07:00
|
|
|
ORD(drawable_texture_target_id_get);
|
2015-02-05 06:34:25 -08:00
|
|
|
ORD(drawable_texture_pixel_color_get);
|
|
|
|
ORD(drawable_scene_render_to_texture);
|
2016-06-03 04:22:33 -07:00
|
|
|
ORD(drawable_texture_rendered_pixels_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
ORD(texture_new);
|
|
|
|
ORD(texture_free);
|
|
|
|
ORD(texture_size_get);
|
|
|
|
ORD(texture_wrap_set);
|
|
|
|
ORD(texture_wrap_get);
|
|
|
|
ORD(texture_filter_set);
|
|
|
|
ORD(texture_filter_get);
|
|
|
|
ORD(texture_image_set);
|
2015-04-22 06:19:02 -07:00
|
|
|
ORD(texture_image_get);
|
2014-07-11 06:11:58 -07:00
|
|
|
|
2015-08-24 23:32:35 -07:00
|
|
|
ORD(ector_create);
|
|
|
|
ORD(ector_destroy);
|
2015-12-08 17:45:53 -08:00
|
|
|
ORD(ector_buffer_wrap);
|
2015-12-08 00:29:54 -08:00
|
|
|
ORD(ector_buffer_new);
|
2015-04-03 07:30:44 -07:00
|
|
|
ORD(ector_begin);
|
|
|
|
ORD(ector_renderer_draw);
|
|
|
|
ORD(ector_end);
|
2017-10-26 21:42:01 -07:00
|
|
|
ORD(ector_surface_create);
|
|
|
|
ORD(ector_surface_destroy);
|
|
|
|
ORD(ector_surface_cache_set);
|
|
|
|
ORD(ector_surface_cache_get);
|
|
|
|
ORD(ector_surface_cache_drop);
|
2017-01-17 04:34:48 -08:00
|
|
|
ORD(gfx_filter_supports);
|
|
|
|
ORD(gfx_filter_process);
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
/* now advertise out own api */
|
|
|
|
em->functions = (void *)(&func);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
module_close(Evas_Module *em EINA_UNUSED)
|
|
|
|
{
|
2015-12-16 15:19:57 -08:00
|
|
|
ector_shutdown();
|
2016-11-11 16:32:59 -08:00
|
|
|
if (_evas_engine_GL_log_dom >= 0)
|
|
|
|
{
|
|
|
|
eina_log_domain_unregister(_evas_engine_GL_log_dom);
|
|
|
|
_evas_engine_GL_log_dom = -1;
|
|
|
|
}
|
2014-07-11 06:11:58 -07:00
|
|
|
evas_gl_common_module_close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Module_Api evas_modapi =
|
|
|
|
{
|
|
|
|
EVAS_MODULE_API_VERSION,
|
|
|
|
"gl_generic",
|
|
|
|
"none",
|
|
|
|
{
|
|
|
|
module_open,
|
|
|
|
module_close
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_generic);
|
|
|
|
|
|
|
|
#ifndef EVAS_STATIC_BUILD_GL_COMMON
|
|
|
|
EVAS_EINA_MODULE_DEFINE(engine, gl_generic);
|
|
|
|
#endif
|