2014-07-11 06:11:58 -07:00
|
|
|
#include "evas_common_private.h"
|
|
|
|
#include "evas_gl_core_private.h"
|
|
|
|
|
|
|
|
//#define TIMDBG 1
|
|
|
|
#ifdef TIMDBG
|
|
|
|
# include <sys/time.h>
|
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_DLSYM
|
|
|
|
# include <dlfcn.h> /* dlopen,dlclose,etc */
|
|
|
|
#else
|
|
|
|
# error gl_x11 should not get compiled if dlsym is not found on the system!
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "../gl_common/evas_gl_common.h"
|
|
|
|
|
|
|
|
#include "Evas_Engine_GL_Generic.h"
|
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
#include "evas_cs2_private.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define EVAS_GL_NO_GL_H_CHECK 1
|
|
|
|
#include "Evas_GL.h"
|
|
|
|
|
|
|
|
#define EVAS_GL_UPDATE_TILE_SIZE 16
|
|
|
|
|
|
|
|
static int _evas_engine_GL_log_dom = -1;
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
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
|
|
|
|
eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2x, int p2y, Eina_Bool do_async EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
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 *
|
|
|
|
eng_polygon_point_add(void *data EINA_UNUSED, void *context EINA_UNUSED, void *polygon, int x, int y)
|
|
|
|
{
|
|
|
|
return evas_gl_common_poly_point_add(polygon, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_polygon_points_clear(void *data EINA_UNUSED, void *context EINA_UNUSED, void *polygon)
|
|
|
|
{
|
|
|
|
return evas_gl_common_poly_points_clear(polygon);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *polygon, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
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
|
|
|
|
eng_image_alpha_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return 1;
|
|
|
|
im = image;
|
|
|
|
return im->alpha;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Colorspace
|
|
|
|
eng_image_colorspace_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return EVAS_COLORSPACE_ARGB8888;
|
|
|
|
im = image;
|
|
|
|
return im->cs.space;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_alpha_set(void *data, void *image, int has_alpha)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
|
|
|
evas_cache2_image_load_data(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
|
|
|
}
|
|
|
|
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,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_border_set(void *data EINA_UNUSED, void *image, int l EINA_UNUSED, int r EINA_UNUSED, int t EINA_UNUSED, int b EINA_UNUSED)
|
|
|
|
{
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_border_get(void *data EINA_UNUSED, void *image EINA_UNUSED, int *l EINA_UNUSED, int *r EINA_UNUSED, int *t EINA_UNUSED, int *b EINA_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
eng_image_comment_get(void *data EINA_UNUSED, void *image, char *key EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
im = image;
|
|
|
|
if (!im->im) return NULL;
|
|
|
|
return im->im->info.comment;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
eng_image_format_get(void *data EINA_UNUSED, void *image EINA_UNUSED)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_colorspace_set(void *data, void *image, Evas_Colorspace cspace)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
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;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
evas_gl_common_image_alloc_ensure(im);
|
|
|
|
evas_cache_image_colorspace(&im->im->cache_entry, cspace);
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
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:
|
|
|
|
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:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
im->cs.space = cspace;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_native_bind_cb(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n = im->native.data;
|
|
|
|
|
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, n->data.opengl.texture_id);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_native_unbind_cb(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n = im->native.data;
|
|
|
|
|
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_native_free_cb(void *data, void *image)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n = im->native.data;
|
|
|
|
uint32_t texid;
|
|
|
|
|
|
|
|
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
|
|
|
|
texid = n->data.opengl.texture_id;
|
|
|
|
eina_hash_del(gl_context->shared->native_tex_hash, &texid, im);
|
|
|
|
}
|
|
|
|
im->native.data = NULL;
|
|
|
|
im->native.func.data = NULL;
|
|
|
|
im->native.func.bind = NULL;
|
|
|
|
im->native.func.unbind = NULL;
|
|
|
|
im->native.func.free = NULL;
|
|
|
|
free(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_native_set(void *data, void *image, void *native)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
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;
|
|
|
|
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((!ns) && (!im->native.data)) return im;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
if (im->native.func.free)
|
|
|
|
im->native.func.free(im->native.func.data, im);
|
|
|
|
evas_gl_common_image_native_disable(im);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ns) return im;
|
|
|
|
|
|
|
|
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;
|
|
|
|
im->native.data = n;
|
|
|
|
im->native.func.data = re;
|
|
|
|
im->native.func.bind = _native_bind_cb;
|
|
|
|
im->native.func.unbind = _native_unbind_cb;
|
|
|
|
im->native.func.free = _native_free_cb;
|
|
|
|
im->native.target = GL_TEXTURE_2D;
|
|
|
|
im->native.mipmap = 0;
|
|
|
|
|
|
|
|
// 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 *
|
|
|
|
eng_image_native_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
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 *
|
|
|
|
eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
return evas_gl_common_image_load(gl_context, file, key, lo, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
return evas_gl_common_image_mmap(gl_context, f, key, lo, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
return evas_gl_common_image_new_from_data(gl_context, w, h, image_data, alpha, cspace);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
return evas_gl_common_image_new_from_copied_data(gl_context, w, h, image_data, alpha, cspace);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_free(void *data, void *image)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
if (!image) return;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
evas_gl_common_image_free(image);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_size_get(void *data EINA_UNUSED, void *image, int *w, int *h)
|
|
|
|
{
|
|
|
|
if (!image)
|
|
|
|
{
|
|
|
|
*w = 0;
|
|
|
|
*h = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (w) *w = ((Evas_GL_Image *)image)->w;
|
|
|
|
if (h) *h = ((Evas_GL_Image *)image)->h;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_size_set(void *data, void *image, int w, int h)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_GL_Image *im_old;
|
|
|
|
|
|
|
|
if (!im) return NULL;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
im->w = w;
|
|
|
|
im->h = h;
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
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;
|
|
|
|
|
|
|
|
switch (eng_image_colorspace_get(data, image))
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
|
|
|
|
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,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
evas_gl_common_image_free(im_old);
|
2014-07-11 06:11:58 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
if (im->native.data) return image;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
evas_gl_common_image_dirty(image, x, y, w, h);
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (!image)
|
|
|
|
{
|
|
|
|
*image_data = NULL;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
im = image;
|
|
|
|
if (im->native.data)
|
|
|
|
{
|
|
|
|
*image_data = NULL;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
|
2014-08-19 07:12:06 -07:00
|
|
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) &&
|
|
|
|
(im->cs.space == EVAS_COLORSPACE_ARGB8888))
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
void *disp;
|
|
|
|
|
|
|
|
if (im->tex->pt->dyn.checked_out > 0)
|
|
|
|
{
|
|
|
|
im->tex->pt->dyn.checked_out++;
|
|
|
|
*image_data = im->tex->pt->dyn.data;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
disp = re->window_egl_display_get(re->software.ob);
|
2014-08-19 07:12:06 -07: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;
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
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;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* 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)
|
|
|
|
{
|
|
|
|
*image_data = NULL;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
|
|
|
error = evas_cache2_image_load_data(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
error = evas_cache_image_load_data(&im->im->cache_entry);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im_new;
|
|
|
|
|
|
|
|
im_new = evas_gl_common_image_new_from_copied_data
|
|
|
|
(im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
|
|
|
|
im->im->image.data,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
if (!im_new)
|
|
|
|
{
|
|
|
|
*image_data = NULL;
|
|
|
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im_new;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
*image_data = im->im->image.data;
|
|
|
|
break;
|
|
|
|
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;
|
|
|
|
*image_data = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (err) *err = error;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_data_put(void *data, void *image, DATA32 *image_data)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im, *im2;
|
|
|
|
|
|
|
|
if (!image) return NULL;
|
|
|
|
im = image;
|
|
|
|
if (im->native.data) return image;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
void *disp;
|
|
|
|
|
|
|
|
disp = re->window_egl_display_get(re->software.ob);
|
|
|
|
secsym_eglUnmapImageSEC(disp,
|
|
|
|
im->tex->pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
if (!im2) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
switch (im->cs.space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
if ((!im->im) || (image_data != im->im->image.data))
|
|
|
|
{
|
|
|
|
im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
|
|
|
|
eng_image_alpha_get(data, image),
|
|
|
|
eng_image_colorspace_get(data, image));
|
|
|
|
if (!im2) return im;
|
|
|
|
evas_gl_common_image_free(im);
|
|
|
|
im = im2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
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);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_data_preload_request(void *data, void *image, const Eo *target)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
RGBA_Image *im;
|
|
|
|
|
|
|
|
if (!gim) return;
|
|
|
|
if (gim->native.data) return;
|
|
|
|
im = (RGBA_Image *)gim->im;
|
|
|
|
if (!im) return;
|
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
|
|
|
evas_cache2_image_preload_data(&im->cache_entry, target);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
|
|
|
|
if (!gim->tex)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
gim->tex = evas_gl_common_texture_new(gl_context, gim->im);
|
|
|
|
}
|
|
|
|
evas_gl_preload_target_register(gim->tex, (Eo*) target);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *target)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
RGBA_Image *im;
|
|
|
|
|
|
|
|
if (!gim) return;
|
|
|
|
if (gim->native.data) return;
|
|
|
|
im = (RGBA_Image *)gim->im;
|
|
|
|
if (!im) return;
|
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
|
|
|
evas_cache2_image_preload_cancel(&im->cache_entry, target);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_preload_cancel(&im->cache_entry, target);
|
|
|
|
evas_gl_preload_target_unregister(gim->tex, (Eo*) target);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = image;
|
|
|
|
Evas_Native_Surface *n;
|
|
|
|
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
n = im->native.data;
|
|
|
|
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
|
|
|
|
if ((n) && (n->type == EVAS_NATIVE_SURFACE_OPENGL) &&
|
|
|
|
(n->data.opengl.framebuffer_id == 0) &&
|
|
|
|
re->func.get_pixels)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
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,
|
|
|
|
n->data.opengl.texture_id);
|
2014-11-20 07:59:19 -08:00
|
|
|
|
|
|
|
// Call pixel get function
|
|
|
|
re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
|
|
|
|
|
|
|
|
// Call end tile if it's being used
|
|
|
|
if ((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
|
|
|
|
eng_image_scale_hint_set(void *data EINA_UNUSED, void *image, int hint)
|
|
|
|
{
|
|
|
|
if (image) evas_gl_common_image_scale_hint_set(image, hint);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_image_scale_hint_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
|
|
|
|
return gim->scale_hint;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
if (!image) return EINA_FALSE;
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
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;
|
|
|
|
eng_image_draw(data, context, surface, image,
|
|
|
|
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
|
|
|
|
eng_image_map_clean(void *data EINA_UNUSED, RGBA_Map *m EINA_UNUSED)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_map_surface_new(void *data, int w, int h, int alpha)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
return evas_gl_common_image_surface_new(gl_context, w, h, alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_map_surface_free(void *data, void *surface)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
evas_gl_common_image_free(surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_content_hint_set(void *data, void *image, int hint)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
evas_gl_common_image_content_hint_set(image, hint);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_image_content_hint_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
|
|
|
|
return gim->content_hint;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_cache_flush(void *data)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
int tmp_size;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
|
|
|
|
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
|
|
|
|
eng_image_cache_set(void *data, int bytes)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
|
|
|
|
evas_common_image_set_cache(bytes);
|
|
|
|
evas_common_rgba_image_scalecache_size_set(bytes);
|
|
|
|
evas_gl_common_image_cache_flush(gl_context);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_image_cache_get(void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
return evas_common_image_get_cache();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_stride_get(void *data EINA_UNUSED, void *image, int *stride)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
default:
|
|
|
|
ERR("Requested stride on an invalid format %d", im->cs.space);
|
|
|
|
*stride = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *intl_props, Eina_Bool do_async EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
|
|
|
|
evas_gl_common_context_target_surface_set(gl_context, surface);
|
|
|
|
gl_context->dc = context;
|
|
|
|
{
|
|
|
|
// FIXME: put im into context so we can free it
|
|
|
|
static RGBA_Image *im = NULL;
|
|
|
|
|
|
|
|
if (!im)
|
|
|
|
im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
|
|
|
im->cache_entry.w = gl_context->shared->w;
|
|
|
|
im->cache_entry.h = gl_context->shared->h;
|
|
|
|
|
|
|
|
evas_common_draw_context_font_ext_set(context,
|
|
|
|
gl_context,
|
|
|
|
evas_gl_font_texture_new,
|
|
|
|
evas_gl_font_texture_free,
|
|
|
|
evas_gl_font_texture_draw);
|
|
|
|
evas_common_font_draw_prepare(intl_props);
|
|
|
|
evas_common_font_draw(im, context, x, y, intl_props->glyphs);
|
|
|
|
evas_common_draw_context_font_ext_set(context,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------//
|
|
|
|
// Evas GL Related Code
|
|
|
|
static int
|
|
|
|
evgl_init(Render_Engine_GL_Generic *re)
|
|
|
|
{
|
|
|
|
if (re->evgl_initted) return 1;
|
|
|
|
if (!evgl_engine_init(re, re->evgl_funcs)) return 0;
|
|
|
|
re->evgl_initted = EINA_TRUE;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define EVGLINIT(_re, _ret) if (!evgl_init(_re)) return _ret
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_gl_surface_create(void *data, void *config, int w, int h)
|
|
|
|
{
|
|
|
|
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
|
|
|
|
|
|
|
EVGLINIT(data, NULL);
|
|
|
|
return evgl_surface_create(data, cfg, w, h);
|
|
|
|
}
|
|
|
|
|
2014-09-19 01:32:26 -07:00
|
|
|
static void *
|
|
|
|
eng_gl_pbuffer_surface_create(void *data, void *config, int w, int h, const int *attrib_list)
|
|
|
|
{
|
|
|
|
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
|
|
|
|
|
|
|
EVGLINIT(data, NULL);
|
|
|
|
return evgl_pbuffer_surface_create(data, cfg, w, h, attrib_list);
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static int
|
|
|
|
eng_gl_surface_destroy(void *data, void *surface)
|
|
|
|
{
|
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
|
|
|
|
EVGLINIT(data, 0);
|
|
|
|
return evgl_surface_destroy(data, sfc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2014-09-22 03:15:37 -07:00
|
|
|
eng_gl_context_create(void *data, void *share_context, int version)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
EVGL_Context *sctx = (EVGL_Context *)share_context;
|
|
|
|
|
|
|
|
EVGLINIT(data, NULL);
|
2014-09-22 03:15:37 -07:00
|
|
|
return evgl_context_create(data, sctx, version);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_gl_context_destroy(void *data, void *context)
|
|
|
|
{
|
|
|
|
EVGL_Context *ctx = (EVGL_Context *)context;
|
|
|
|
|
|
|
|
EVGLINIT(data, 0);
|
|
|
|
return evgl_context_destroy(data, ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_gl_make_current(void *data, void *surface, void *context)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
EVGL_Context *ctx = (EVGL_Context *)context;
|
|
|
|
|
2014-09-01 04:15:33 -07:00
|
|
|
// TODO: Add check for main thread before flush
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
EVGLINIT(data, 0);
|
|
|
|
if ((sfc) && (ctx))
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
if ((gl_context->havestuff) ||
|
|
|
|
(gl_context->master_clip.used))
|
|
|
|
{
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
if (gl_context->master_clip.used)
|
|
|
|
evas_gl_common_context_done(gl_context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return evgl_make_current(data, sfc, ctx);
|
|
|
|
}
|
|
|
|
|
2014-09-01 04:15:33 -07:00
|
|
|
static void *
|
|
|
|
eng_gl_current_surface_get(void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_gl_rotation_angle_get(void *data)
|
|
|
|
{
|
|
|
|
if (!evgl_engine->funcs->rotation_angle_get) return 0;
|
2014-09-03 19:41:27 -07:00
|
|
|
if (!_evgl_direct_enabled()) return 0;
|
2014-09-02 05:29:25 -07:00
|
|
|
return evgl_engine->funcs->rotation_angle_get(data);
|
|
|
|
}
|
|
|
|
|
2014-10-24 04:52:09 -07:00
|
|
|
static const char *
|
2014-07-11 06:11:58 -07:00
|
|
|
eng_gl_string_query(void *data, int name)
|
|
|
|
{
|
|
|
|
EVGLINIT(data, NULL);
|
2014-10-24 04:52:09 -07:00
|
|
|
return evgl_string_query(name);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2014-10-24 04:48:08 -07:00
|
|
|
eng_gl_proc_address_get(void *data, const char *name)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
2014-10-24 04:48:08 -07:00
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
EVGLINIT(re, NULL);
|
2014-10-24 05:25:08 -07:00
|
|
|
void *func = NULL;
|
|
|
|
|
|
|
|
if (!evgl_safe_extension_get(name, &func))
|
|
|
|
{
|
|
|
|
DBG("The extension '%s' is not safe to use with Evas GL or is not "
|
|
|
|
"supported on this platform.", name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (func)
|
|
|
|
return func;
|
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
|
|
|
|
eng_gl_native_surface_get(void *data EINA_UNUSED, void *surface, void *native_surface)
|
|
|
|
{
|
|
|
|
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
|
|
|
Evas_Native_Surface *ns = (Evas_Native_Surface *)native_surface;
|
|
|
|
|
|
|
|
return evgl_native_surface_get(sfc, ns);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2014-09-22 03:15:37 -07:00
|
|
|
eng_gl_api_get(void *data, int version)
|
2014-07-11 06:11:58 -07:00
|
|
|
{
|
|
|
|
EVGLINIT(data, NULL);
|
2014-09-22 03:15:37 -07:00
|
|
|
return evgl_api_get(version);
|
2014-07-11 06:11:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_gl_direct_override_get(void *data, int *override, int *force_off)
|
|
|
|
{
|
|
|
|
EVGLINIT(data, );
|
|
|
|
evgl_direct_override_get(override, force_off);
|
|
|
|
}
|
|
|
|
|
2014-12-09 04:36:45 -08:00
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_direct_renderable_get(void *data, Evas_Native_Surface *ns)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Eina_Bool direct_render, client_side_rotation;
|
|
|
|
|
|
|
|
EVGLINIT(data, EINA_FALSE);
|
|
|
|
if (!re || !ns) return EINA_FALSE;
|
|
|
|
if (!evgl_native_surface_direct_opts_get(ns, &direct_render, &client_side_rotation))
|
|
|
|
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;
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
|
|
|
eng_gl_get_pixels_set(void *data, void *get_pixels, void *get_pixels_data, void *obj)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
EVGLINIT(data, );
|
|
|
|
re->func.get_pixels = get_pixels;
|
|
|
|
re->func.get_pixels_data = get_pixels_data;
|
|
|
|
re->func.obj = (Evas_Object*)obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_lock(void *data, void *surface)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
EVGLINIT(re, EINA_FALSE);
|
|
|
|
if (!im->tex || !im->tex->pt)
|
|
|
|
{
|
|
|
|
ERR("Can not lock image that is not a surface!");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_gl_common_context_flush(im->gc);
|
|
|
|
im->locked = EINA_TRUE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_unlock(void *data, void *surface)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
EVGLINIT(re, EINA_FALSE);
|
|
|
|
im->locked = EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_read_pixels(void *data, void *surface,
|
|
|
|
int x, int y, int w, int h,
|
|
|
|
Evas_Colorspace cspace, void *pixels)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, EINA_FALSE);
|
|
|
|
|
|
|
|
EVGLINIT(re, EINA_FALSE);
|
|
|
|
if (!im->locked)
|
|
|
|
{
|
|
|
|
// For now, this is useless, but let's force clients to lock :)
|
|
|
|
CRI("The surface must be locked before reading its pixels!");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cspace != EVAS_COLORSPACE_ARGB8888)
|
|
|
|
{
|
|
|
|
ERR("Conversion to colorspace %d is not supported!", (int) cspace);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
|
|
|
|
if (im->tex->pt->format == GL_BGRA)
|
|
|
|
glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DATA32 *ptr = pixels;
|
|
|
|
int k;
|
|
|
|
|
|
|
|
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
|
|
for (k = w * h; k; --k)
|
|
|
|
{
|
|
|
|
const DATA32 v = *ptr;
|
|
|
|
*ptr++ = (v & 0xFF00FF00)
|
|
|
|
| ((v & 0x00FF0000) >> 16)
|
|
|
|
| ((v & 0x000000FF) << 16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2014-09-18 23:17:08 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_gl_surface_query(void *data, void *surface, int attr, void *value)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
EVGL_Surface *sfc = surface;
|
|
|
|
|
|
|
|
#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
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
disp = re->window_egl_display_get(re->software.ob);
|
|
|
|
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:
|
|
|
|
return eglQuerySurface(re->win->egl_disp, re->win->egl_surface[0],
|
|
|
|
attr, (int *) value);
|
|
|
|
*/
|
|
|
|
default: break;
|
|
|
|
}
|
2014-09-19 01:44:56 -07:00
|
|
|
evas_gl_common_error_set(data, 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
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
//--------------------------------//
|
|
|
|
|
|
|
|
static int
|
|
|
|
eng_image_load_error_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
|
|
|
|
if (!image) return EVAS_LOAD_ERROR_NONE;
|
|
|
|
im = image;
|
|
|
|
return im->im->cache_entry.load_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_image_animated_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_image_animated_frame_count_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_image_animated_loop_type_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_image_animated_loop_count_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_image_animated_frame_duration_get(void *data EINA_UNUSED, void *image, int start_frame, int frame_num)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_image_animated_frame_set(void *data EINA_UNUSED, void *image, int frame_index)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
eng_image_can_region_get(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *gim = image;
|
|
|
|
Image_Entry *im;
|
|
|
|
if (!gim) return EINA_FALSE;
|
|
|
|
im = (Image_Entry *)gim->im;
|
|
|
|
if (!im) return EINA_FALSE;
|
|
|
|
return ((Evas_Image_Load_Func*) im->info.loader)->do_region;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_image_max_size_get(void *data, int *maxw, int *maxh)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
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);
|
|
|
|
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;
|
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
|
|
|
evas_cache2_image_load_data(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
|
|
|
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
|
|
|
|
eng_context_flush(void *data)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
|
|
|
|
if ((gl_context->havestuff) ||
|
|
|
|
(gl_context->master_clip.used))
|
|
|
|
{
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
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
|
|
|
|
eng_context_clip_image_unset(void *data EINA_UNUSED, void *context)
|
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
Evas_GL_Image *im = ctx->clip.mask;
|
|
|
|
|
|
|
|
if (im && im->im)
|
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_close(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_drop(&im->im->cache_entry);
|
|
|
|
// Is the above code safe? Hmmm...
|
|
|
|
//evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry);
|
|
|
|
}
|
|
|
|
ctx->clip.mask = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y)
|
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
Evas_GL_Image *im = surface;
|
|
|
|
|
|
|
|
if (ctx->clip.mask && ctx->clip.mask != surface)
|
|
|
|
eng_context_clip_image_unset(data, context);
|
|
|
|
|
|
|
|
ctx->clip.mask = surface;
|
|
|
|
ctx->clip.mask_x = x;
|
|
|
|
ctx->clip.mask_y = y;
|
|
|
|
|
|
|
|
if (im && im->im)
|
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_ref(&im->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_ref(&im->im->cache_entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int *x, int *y)
|
|
|
|
{
|
|
|
|
RGBA_Draw_Context *ctx = context;
|
|
|
|
|
|
|
|
if (ie) *ie = ctx->clip.mask;
|
|
|
|
if (x) *x = ctx->clip.mask_x;
|
|
|
|
if (y) *y = ctx->clip.mask_y;
|
|
|
|
}
|
|
|
|
|
2014-07-11 06:11:58 -07:00
|
|
|
static void
|
|
|
|
eng_context_3d_use(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
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 *
|
|
|
|
eng_renderer_3d_get(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
if (!re->renderer_3d)
|
|
|
|
re->renderer_3d = e3d_renderer_new();
|
|
|
|
return re->renderer_3d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_drawable_new(void *data, int w, int h, int alpha)
|
|
|
|
{
|
|
|
|
eng_context_3d_use(data);
|
|
|
|
#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
|
|
|
|
eng_drawable_free(void *data, void *drawable)
|
|
|
|
{
|
|
|
|
eng_context_3d_use(data);
|
|
|
|
e3d_drawable_free(drawable);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_drawable_size_get(void *data EINA_UNUSED, void *drawable, int *w, int *h)
|
|
|
|
{
|
|
|
|
e3d_drawable_size_get((E3D_Drawable *)drawable, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_image_drawable_set(void *data, void *image, void *drawable)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
return eng_image_native_set(data, image, &ns);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_drawable_scene_render(void *data, void *drawable, void *scene_data)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
E3D_Renderer *renderer = NULL;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
|
|
|
|
eng_context_3d_use(data);
|
|
|
|
renderer = eng_renderer_3d_get(data);
|
|
|
|
e3d_drawable_scene_render(drawable, renderer, scene_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
eng_texture_new(void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
return e3d_texture_new();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_free(void *data EINA_UNUSED, void *texture)
|
|
|
|
{
|
|
|
|
e3d_texture_free((E3D_Texture *)texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_data_set(void *data, void *texture, Evas_3D_Color_Format color_format,
|
|
|
|
Evas_3D_Pixel_Format pixel_format, int w, int h, const void *pixels)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
eng_context_3d_use(data);
|
|
|
|
|
|
|
|
e3d_texture_data_set((E3D_Texture *)texture, color_format, pixel_format, w, h, pixels);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_file_set(void *data, void *texture, const char *file, const char *key)
|
|
|
|
{
|
|
|
|
Evas_Engine_GL_Context *gl_context;
|
|
|
|
Render_Engine_GL_Generic *re = data;
|
|
|
|
|
|
|
|
re->window_use(re->software.ob);
|
|
|
|
gl_context = re->window_gl_context_get(re->software.ob);
|
|
|
|
evas_gl_common_context_flush(gl_context);
|
|
|
|
eng_context_3d_use(data);
|
|
|
|
|
|
|
|
e3d_texture_file_set((E3D_Texture *)texture, file, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_color_format_get(void *data EINA_UNUSED, void *texture, Evas_3D_Color_Format *format)
|
|
|
|
{
|
|
|
|
*format = e3d_texture_color_format_get((E3D_Texture *)texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_size_get(void *data EINA_UNUSED, void *texture, int *w, int *h)
|
|
|
|
{
|
|
|
|
e3d_texture_size_get((E3D_Texture *)texture, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_wrap_set(void *data EINA_UNUSED, void *texture,
|
|
|
|
Evas_3D_Wrap_Mode s, Evas_3D_Wrap_Mode t)
|
|
|
|
{
|
|
|
|
e3d_texture_wrap_set((E3D_Texture *)texture, s, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_wrap_get(void *data EINA_UNUSED, void *texture,
|
|
|
|
Evas_3D_Wrap_Mode *s, Evas_3D_Wrap_Mode *t)
|
|
|
|
{
|
|
|
|
e3d_texture_wrap_get((E3D_Texture *)texture, s, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_filter_set(void *data EINA_UNUSED, void *texture,
|
|
|
|
Evas_3D_Texture_Filter min, Evas_3D_Texture_Filter mag)
|
|
|
|
{
|
|
|
|
e3d_texture_filter_set((E3D_Texture *)texture, min, mag);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_filter_get(void *data EINA_UNUSED, void *texture,
|
|
|
|
Evas_3D_Texture_Filter *min, Evas_3D_Texture_Filter *mag)
|
|
|
|
{
|
|
|
|
e3d_texture_filter_get((E3D_Texture *)texture, min, mag);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_texture_image_set(void *data EINA_UNUSED, void *texture, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *im = (Evas_GL_Image *)image;
|
|
|
|
e3d_texture_import((E3D_Texture *)texture, im->tex->pt->texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Func func, pfunc;
|
|
|
|
|
|
|
|
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 */
|
|
|
|
if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
|
|
|
|
if (_evas_engine_GL_log_dom < 0)
|
|
|
|
_evas_engine_GL_log_dom = eina_log_domain_register("evas-gl", EVAS_DEFAULT_LOG_COLOR);
|
|
|
|
if (_evas_engine_GL_log_dom < 0)
|
|
|
|
{
|
|
|
|
EINA_LOG_ERR("Can not create a module log domain.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* store it for later use */
|
|
|
|
func = pfunc;
|
|
|
|
/* now to override methods */
|
|
|
|
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
|
2014-11-24 21:34:42 -08:00
|
|
|
ORD(context_clip_image_set);
|
|
|
|
ORD(context_clip_image_unset);
|
|
|
|
ORD(context_clip_image_get);
|
|
|
|
|
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_load);
|
|
|
|
ORD(image_mmap);
|
|
|
|
ORD(image_new_from_data);
|
|
|
|
ORD(image_new_from_copied_data);
|
|
|
|
ORD(image_free);
|
|
|
|
ORD(image_size_get);
|
|
|
|
ORD(image_size_set);
|
|
|
|
ORD(image_dirty_region);
|
|
|
|
ORD(image_data_get);
|
|
|
|
ORD(image_data_put);
|
|
|
|
ORD(image_data_preload_request);
|
|
|
|
ORD(image_data_preload_cancel);
|
|
|
|
ORD(image_alpha_set);
|
|
|
|
ORD(image_alpha_get);
|
|
|
|
ORD(image_border_set);
|
|
|
|
ORD(image_border_get);
|
|
|
|
ORD(image_draw);
|
|
|
|
ORD(image_comment_get);
|
|
|
|
ORD(image_format_get);
|
|
|
|
ORD(image_colorspace_set);
|
|
|
|
ORD(image_colorspace_get);
|
|
|
|
ORD(image_can_region_get);
|
|
|
|
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_surface_free);
|
|
|
|
ORD(image_map_clean);
|
|
|
|
|
|
|
|
ORD(image_content_hint_set);
|
|
|
|
ORD(image_content_hint_get);
|
|
|
|
|
|
|
|
ORD(image_cache_flush);
|
|
|
|
ORD(image_cache_set);
|
|
|
|
ORD(image_cache_get);
|
|
|
|
|
|
|
|
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);
|
|
|
|
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);
|
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);
|
|
|
|
|
|
|
|
ORD(texture_new);
|
|
|
|
ORD(texture_free);
|
|
|
|
ORD(texture_data_set);
|
|
|
|
ORD(texture_file_set);
|
|
|
|
ORD(texture_color_format_get);
|
|
|
|
ORD(texture_size_get);
|
|
|
|
ORD(texture_wrap_set);
|
|
|
|
ORD(texture_wrap_get);
|
|
|
|
ORD(texture_filter_set);
|
|
|
|
ORD(texture_filter_get);
|
|
|
|
ORD(texture_image_set);
|
|
|
|
|
|
|
|
/* now advertise out own api */
|
|
|
|
em->functions = (void *)(&func);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
module_close(Evas_Module *em EINA_UNUSED)
|
|
|
|
{
|
|
|
|
eina_log_domain_unregister(_evas_engine_GL_log_dom);
|
|
|
|
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
|