more work on egl image direct access.

SVN revision: 51070
This commit is contained in:
Carsten Haitzler 2010-08-13 10:34:51 +00:00
parent 550e1a7531
commit 2d3ea36109
6 changed files with 362 additions and 29 deletions

View File

@ -51,6 +51,19 @@
# 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
@ -75,7 +88,7 @@
#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
@ -225,6 +238,11 @@ struct _Evas_GL_Context
} 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
@ -235,10 +253,17 @@ 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
@ -393,6 +418,7 @@ void evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, in
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);
@ -433,12 +459,12 @@ void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GL
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

View File

@ -14,12 +14,12 @@ void (*glsym_glDeleteFramebuffers) (GLsizei a, const GLuint *b) = NULL;
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
@ -431,8 +431,6 @@ evas_gl_common_context_new(void)
if (!shared)
{
GLint linked;
unsigned int pixel = 0xffffffff;
const GLubyte *ext;
shared = calloc(1, sizeof(Evas_GL_Shared));
@ -489,7 +487,7 @@ evas_gl_common_context_new(void)
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"))
@ -997,7 +995,6 @@ evas_gl_common_context_line_push(Evas_GL_Context *gc,
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;
@ -1298,6 +1295,16 @@ again:
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)
@ -1327,6 +1334,14 @@ again:
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;
@ -1742,7 +1757,6 @@ evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
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;
@ -1883,6 +1897,16 @@ again:
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)
@ -1916,6 +1940,14 @@ again:
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;
@ -2022,11 +2054,21 @@ shader_array_flush(Evas_GL_Context *gc)
}
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)

View File

@ -277,7 +277,60 @@ void
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

View File

@ -42,8 +42,6 @@ _nearest_pow2(int num)
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);
@ -396,6 +394,142 @@ _pool_tex_native_new(Evas_GL_Context *gc, int w, int h, int intformat, int forma
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)
{
@ -409,6 +543,19 @@ 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__, "");
@ -425,8 +572,6 @@ 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 *tex;
Eina_List *l_after = NULL;
int u = 0, v = 0;
tex = calloc(1, sizeof(Evas_GL_Texture));
if (!tex) return NULL;
@ -466,8 +611,6 @@ Evas_GL_Texture *
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;
@ -503,6 +646,45 @@ evas_gl_common_texture_render_new(Evas_GL_Context *gc, int w, int h, int alpha)
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)
{

View File

@ -1776,6 +1776,11 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
*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)
@ -1825,6 +1830,28 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
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:

View File

@ -397,6 +397,9 @@ eng_window_new(Display *disp,
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++;