# define GL_BGRA 0x80E1
#endif
+#ifndef EGL_NO_CONTEXT
+# define EGL_NO_CONTEXT 0
+#endif
+#ifndef EGL_NONE
+# define EGL_NONE 0x3038
+#endif
+#ifndef EGL_TRUE
+# define EGL_TRUE 1
+#endif
+#ifndef EGL_FALSE
+# define EGL_FALSE 0
+#endif
+
#ifndef EGL_MAP_GL_TEXTURE_2D_SEC
# define EGL_MAP_GL_TEXTURE_2D_SEC 0x3201
#endif
#ifndef EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC
# define EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC 0x3207
#endif
-#ifdef EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC
+#ifndef EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC
# define EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC 0x3208
#endif
} change;
Evas_GL_Image *def_surface;
+
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+// FIXME: hack. expose egl display to gl core for egl image sec extn.
+ void *egldisp;
+#endif
};
struct _Evas_GL_Texture_Pool
int w, h;
int references;
int slot, fslot;
+ struct {
+ void *img;
+ unsigned int *data;
+ int w, h;
+ int stride;
+ } dyn;
Eina_List *allocations;
Eina_Bool whole : 1;
Eina_Bool render : 1;
Eina_Bool native : 1;
+ Eina_Bool dynamic : 1;
};
struct _Evas_GL_Texture
Evas_GL_Texture *evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im);
Evas_GL_Texture *evas_gl_common_texture_native_new(Evas_GL_Context *gc, int w, int h, int alpha, Evas_GL_Image *im);
Evas_GL_Texture *evas_gl_common_texture_render_new(Evas_GL_Context *gc, int w, int h, int alpha);
+Evas_GL_Texture *evas_gl_common_texture_dynamic_new(Evas_GL_Context *gc, Evas_GL_Image *im);
void evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im);
void evas_gl_common_texture_free(Evas_GL_Texture *tex);
Evas_GL_Texture *evas_gl_common_texture_alpha_new(Evas_GL_Context *gc, DATA8 *pixels, int w, int h, int fh);
void (*glsym_glDeleteFramebuffers) (GLsizei a, const GLuint *b);
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-void *(*secsym_eglCreateImage) (void *a, void *b, GLenum c, void *d, const int *e);
-void (*secsym_eglDestroyImage) (void *a, void *b);
-void (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b);
-void (*secsym_eglMapImageSEC) (void *a, void *b);
-void (*secsym_eglUnmapImageSEC) (void *a, void *b);
-void (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d);
+void *(*secsym_eglCreateImage) (void *a, void *b, GLenum c, void *d, const int *e);
+unsigned int (*secsym_eglDestroyImage) (void *a, void *b);
+void (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b);
+void *(*secsym_eglMapImageSEC) (void *a, void *b);
+unsigned int (*secsym_eglUnmapImageSEC) (void *a, void *b);
+unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d);
#endif
#define GL_ERRORS 1
typedef void (*_eng_fn) (void);
static _eng_fn (*secsym_eglGetProcAddress) (const char *a) = NULL;
-void *(*secsym_eglCreateImage) (void *a, void *b, GLenum c, void *d, const int *e) = NULL;
-void (*secsym_eglDestroyImage) (void *a, void *b) = NULL;
-void (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
-void (*secsym_eglMapImageSEC) (void *a, void *b) = NULL;
-void (*secsym_eglUnmapImageSEC) (void *a, void *b) = NULL;
-void (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d) = NULL;
+void *(*secsym_eglCreateImage) (void *a, void *b, GLenum c, void *d, const int *e) = NULL;
+unsigned int (*secsym_eglDestroyImage) (void *a, void *b) = NULL;
+void (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
+void *(*secsym_eglMapImageSEC) (void *a, void *b) = NULL;
+unsigned int (*secsym_eglUnmapImageSEC) (void *a, void *b) = NULL;
+unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d) = NULL;
#endif
static void
if (!shared)
{
- GLint linked;
- unsigned int pixel = 0xffffffff;
const GLubyte *ext;
shared = calloc(1, sizeof(Evas_GL_Shared));
shared->info.pipes_max = 32;
// per gpu hacks. based on impirical measurement of some known gpu's
- s = glGetString(GL_RENDERER);
+ s = (const char *)glGetString(GL_RENDERER);
if (s)
{
if (strstr(s, "PowerVR SGX 540"))
if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
shader_array_flush(gc);
-again:
pn = gc->state.top_pipe;
gc->pipe[pn].shader.cur_tex = 0;
gc->pipe[pn].shader.cur_prog = prog;
goto again;
}
}
+ if (tex->pt->dyn.img)
+ {
+ if (gc->pipe[pn].array.im != tex->im)
+ {
+ shader_array_flush(gc);
+ pn = gc->state.top_pipe;
+ gc->pipe[pn].array.im = tex->im;
+ goto again;
+ }
+ }
#else
if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
|| (gc->pipe[pn].shader.cur_prog != prog)
gc->pipe[pn].array.im = tex->im;
}
}
+ if (tex->pt->dyn.img)
+ {
+ if (gc->pipe[pn].array.im != tex->im)
+ {
+ shader_array_flush(gc);
+ gc->pipe[pn].array.im = tex->im;
+ }
+ }
gc->pipe[pn].array.line = 0;
gc->pipe[pn].array.use_vertex = 1;
int x, y, w, h, px, py;
GLfloat tx[4], ty[4];
Eina_Bool blend = 1;
- RGBA_Map_Point *pt;
DATA32 cmul;
GLuint prog = gc->shared->shader.img.prog;
int pn = 0;
goto again;
}
}
+ if (tex->pt->dyn.img)
+ {
+ if (gc->pipe[pn].array.im != tex->im)
+ {
+ shader_array_flush(gc);
+ pn = gc->state.top_pipe;
+ gc->pipe[pn].array.im = tex->im;
+ goto again;
+ }
+ }
#else
if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
|| (gc->pipe[pn].shader.cur_prog != prog)
gc->pipe[pn].array.im = tex->im;
}
}
+ if (tex->pt->dyn.img)
+ {
+ if (gc->pipe[pn].array.im != tex->im)
+ {
+ shader_array_flush(gc);
+ gc->pipe[pn].array.im = tex->im;
+ }
+ }
gc->pipe[pn].region.type = RTYPE_MAP;
gc->pipe[pn].array.line = 0;
}
if (gc->pipe[i].array.im)
{
- if (!gc->pipe[i].array.im->native.loose)
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+ if (gc->pipe[i].array.im->tex->pt->dyn.img)
{
- if (gc->pipe[i].array.im->native.func.bind)
- gc->pipe[i].array.im->native.func.bind(gc->pipe[i].array.im->native.func.data,
- gc->pipe[i].array.im);
+ secsym_glEGLImageTargetTexture2DOES
+ (GL_TEXTURE_2D, gc->pipe[i].array.im->tex->pt->dyn.img);
+ }
+ else
+#endif
+ {
+ if (!gc->pipe[i].array.im->native.loose)
+ {
+ if (gc->pipe[i].array.im->native.func.bind)
+ gc->pipe[i].array.im->native.func.bind(gc->pipe[i].array.im->native.func.data,
+ gc->pipe[i].array.im);
+ }
}
}
if (gc->pipe[i].shader.render_op != gc->state.current.render_op)
evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
{
im->content_hint = hint;
- // FIXME: make use of content hint
+ if (im->content_hint == hint) return;
+ if (!im->gc) return;
+ if (!im->gc->shared->info.sec_image_map) return;
+ // does not handle yuv yet.
+ if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return;
+ return;
+ if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
+ {
+ if (im->cs.data)
+ {
+ if (!im->cs.no_free) free(im->cs.data);
+ im->cs.data = NULL;
+ }
+ im->cs.no_free = 0;
+ if (im->cached)
+ {
+ im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
+ im->cached = 0;
+ }
+ if (im->im)
+ {
+ evas_cache_image_drop(&im->im->cache_entry);
+ im->im = NULL;
+ }
+ if (im->tex)
+ {
+ evas_gl_common_texture_free(im->tex);
+ im->tex = NULL;
+ }
+ im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
+ im->tex_only = 1;
+ }
+ else
+ {
+ if (im->im)
+ {
+ evas_cache_image_drop(&im->im->cache_entry);
+ im->im = NULL;
+ }
+ if (im->tex)
+ {
+ evas_gl_common_texture_free(im->tex);
+ im->tex = NULL;
+ }
+ im->tex_only = 0;
+
+ im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+ im->im->cache_entry.flags.alpha = im->alpha;
+ im->cs.space = EVAS_COLORSPACE_ARGB8888;
+ evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
+ im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
+ if (!im->tex)
+ im->tex = evas_gl_common_texture_new(im->gc, im->im);
+ }
}
void
static void
_tex_adjust(Evas_GL_Context *gc, int *w, int *h)
{
- unsigned int n;
-
if (gc->shared->info.tex_npo2) return;
/*if (gc->shared->info.tex_rect) return;*/
*w = _nearest_pow2(*w);
return pt;
}
+static Evas_GL_Texture_Pool *
+_pool_tex_dynamic_new(Evas_GL_Context *gc, int w, int h, int intformat, int format)
+{
+ Evas_GL_Texture_Pool *pt = NULL;
+
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+ int fmt; // EGL_MAP_GL_TEXTURE_RGBA_SEC or EGL_MAP_GL_TEXTURE_RGB_SEC or bust
+ int pixtype; // EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC or bust
+ int attr[] =
+ {
+ EGL_MAP_GL_TEXTURE_WIDTH_SEC, 32,
+ EGL_MAP_GL_TEXTURE_HEIGHT_SEC, 32,
+ EGL_MAP_GL_TEXTURE_FORMAT_SEC, EGL_MAP_GL_TEXTURE_RGBA_SEC,
+ EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC, EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC,
+ EGL_NONE
+ };
+ void *egldisplay = pt->gc->egldisp;
+
+
+ pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
+ if (!pt) return NULL;
+ h = _tex_round_slot(gc, h) << 4;
+ _tex_adjust(gc, &w, &h);
+ pt->gc = gc;
+ pt->w = w;
+ pt->h = h;
+ pt->intformat = intformat;
+ pt->format = format;
+ pt->dataformat = GL_UNSIGNED_BYTE;
+ pt->render = 1;
+ pt->references = 0;
+ glGenTextures(1, &(pt->texture));
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ glBindTexture(GL_TEXTURE_2D, pt->texture);
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+ attr[1] = pt->w;
+ attr[2] = pt->h;
+
+ pt->dyn.img = secsym_eglCreateImage(egldisplay,
+ EGL_NO_CONTEXT,
+ EGL_MAP_GL_TEXTURE_2D_SEC,
+ 0, attr);
+ if (!pt->dyn.img)
+ {
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ pt->dyn.data = secsym_eglMapImageSEC(egldisplay,
+ pt->dyn.img);
+ if (!pt->dyn.data)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (secsym_eglGetImageAttribSEC(egldisplay,
+ pt->dyn.img,
+ EGL_MAP_GL_TEXTURE_WIDTH_SEC,
+ &(pt->dyn.w)) != EGL_TRUE)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (secsym_eglGetImageAttribSEC(egldisplay,
+ pt->dyn.img,
+ EGL_MAP_GL_TEXTURE_HEIGHT_SEC,
+ &(pt->dyn.h)) != EGL_TRUE)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (secsym_eglGetImageAttribSEC(egldisplay,
+ pt->dyn.img,
+ EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC,
+ &(pt->dyn.stride)) != EGL_TRUE)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (secsym_eglGetImageAttribSEC(egldisplay,
+ pt->dyn.img,
+ EGL_MAP_GL_TEXTURE_FORMAT_SEC,
+ &(fmt)) != EGL_TRUE)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (fmt != EGL_MAP_GL_TEXTURE_RGBA_SEC)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (secsym_eglGetImageAttribSEC(egldisplay,
+ pt->dyn.img,
+ EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC,
+ &(pixtype)) != EGL_TRUE)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+ if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC)
+ {
+ secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+ pt->dyn.img = NULL;
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+ return pt;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
+ GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+#endif
+ return pt;
+}
+
static void
pt_unref(Evas_GL_Texture_Pool *pt)
{
pt->gc->shared->tex.atlas [pt->slot][pt->fslot] =
eina_list_remove(pt->gc->shared->tex.atlas[pt->slot][pt->fslot], pt);
}
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+ if (pt->dyn.img)
+ {
+ void *egldisplay = pt->gc->egldisp;
+
+ secsym_eglDestroyImage(pt->gc->egldisp, pt->dyn.img);
+ pt->dyn.img = NULL;
+ pt->dyn.data = NULL;
+ pt->dyn.w = 0;
+ pt->dyn.h = 0;
+ pt->dyn.stride = 0;
+ }
+#endif
glDeleteTextures(1, &(pt->texture));
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
evas_gl_common_texture_native_new(Evas_GL_Context *gc, int w, int h, int alpha, Evas_GL_Image *im)
{
Evas_GL_Texture *tex;
- Eina_List *l_after = NULL;
- int u = 0, v = 0;
tex = calloc(1, sizeof(Evas_GL_Texture));
if (!tex) return NULL;
evas_gl_common_texture_render_new(Evas_GL_Context *gc, int w, int h, int alpha)
{
Evas_GL_Texture *tex;
- Eina_List *l_after = NULL;
- int u = 0, v = 0;
tex = calloc(1, sizeof(Evas_GL_Texture));
if (!tex) return NULL;
return tex;
}
+Evas_GL_Texture *
+evas_gl_common_texture_dynamic_new(Evas_GL_Context *gc, Evas_GL_Image *im)
+{
+ Evas_GL_Texture *tex;
+
+ tex = calloc(1, sizeof(Evas_GL_Texture));
+ if (!tex) return NULL;
+
+ tex->gc = gc;
+ tex->references = 1;
+ tex->alpha = im->alpha;
+ tex->x = 0;
+ tex->y = 0;
+ tex->w = im->w;
+ tex->h = im->h;
+ if (tex->alpha)
+ {
+ if (gc->shared->info.bgra)
+ tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, rgba_ifmt, rgba_fmt);
+ else
+ tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, rgba_ifmt, rgba_fmt);
+ }
+ else
+ {
+ if (gc->shared->info.bgra)
+ tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, rgb_ifmt, rgb_fmt);
+ else
+ tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, rgb_ifmt, rgb_fmt);
+ }
+ if (!tex->pt)
+ {
+ memset(tex, 0x44, sizeof(Evas_GL_Texture)); // mark as freed
+ free(tex);
+ return NULL;
+ }
+
+ return tex;
+}
+
void
evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
{
*image_data = NULL;
return im;
}
+ if (im->tex->pt->dyn.data)
+ {
+ *image_data = im->tex->pt->dyn.data;
+ return im;
+ }
eng_window_use(re->win);
evas_cache_image_load_data(&im->im->cache_entry);
switch (im->cs.space)
im = image;
if (im->native.data) return image;
eng_window_use(re->win);
+ if (im->tex->pt->dyn.data)
+ {
+ if (im->tex->pt->dyn.data == image_data)
+ {
+ return image;
+ }
+ else
+ {
+ int w, h;
+
+ w = im->im->cache_entry.w;
+ h = im->im->cache_entry.h;
+ im2 = eng_image_new_from_data(data, w, 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:
eng_window_free(gw);
return NULL;
}
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+ gw->gl_context->egldisp = gw->egl_disp;
+#endif
evas_gl_common_context_use(gw->gl_context);
evas_gl_common_context_resize(gw->gl_context, w, h, rot);
win_count++;