2003-09-07 04:24:48 -07:00
|
|
|
#include "evas_gl_private.h"
|
2003-09-04 00:40:34 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
Evas_GL_Image *
|
2007-03-04 08:18:06 -08:00
|
|
|
evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Evas_GL_Image *im;
|
|
|
|
RGBA_Image *im_im;
|
|
|
|
Evas_List *l;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2006-08-18 07:45:26 -07:00
|
|
|
im_im = evas_common_load_image_from_file(file, key, lo);
|
2003-09-07 04:24:48 -07:00
|
|
|
if (!im_im) return NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
for (l = gc->images; l; l = l->next)
|
|
|
|
{
|
|
|
|
im = l->data;
|
|
|
|
if (im->im == im_im)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_drop(&im_im->cache_entry);
|
2003-09-07 04:24:48 -07:00
|
|
|
gc->images = evas_list_remove_list(gc->images, l);
|
|
|
|
gc->images = evas_list_prepend(gc->images, im);
|
|
|
|
im->references++;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
im = calloc(1, sizeof(Evas_GL_Image));
|
|
|
|
if (!im) return NULL;
|
|
|
|
im->references = 1;
|
|
|
|
im->im = im_im;
|
|
|
|
if (!im->im)
|
|
|
|
{
|
|
|
|
free(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
im->gc = gc;
|
|
|
|
im->references = 1;
|
|
|
|
im->cached = 1;
|
2006-12-17 07:48:52 -08:00
|
|
|
im->cs.space = EVAS_COLORSPACE_ARGB8888;
|
2006-08-18 07:45:26 -07:00
|
|
|
if (lo) im->load_opts = *lo;
|
2003-09-07 04:24:48 -07:00
|
|
|
gc->images = evas_list_prepend(gc->images, im);
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_GL_Image *
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
|
|
|
Evas_List *l;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
for (l = gc->images; l; l = l->next)
|
|
|
|
{
|
|
|
|
im = l->data;
|
2008-04-11 17:32:30 -07:00
|
|
|
if (((void *)(im->im->image.data) == (void *)data) &&
|
|
|
|
(im->im->cache_entry.w == w) &&
|
|
|
|
(im->im->cache_entry.h == h))
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
|
|
|
gc->images = evas_list_remove_list(gc->images, l);
|
|
|
|
gc->images = evas_list_prepend(gc->images, im);
|
|
|
|
im->references++;
|
|
|
|
return im;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
im = calloc(1, sizeof(Evas_GL_Image));
|
2006-09-30 03:18:37 -07:00
|
|
|
if (!im) return NULL;
|
2003-09-07 04:24:48 -07:00
|
|
|
im->references = 1;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
|
|
|
|
w, h, data, alpha, cspace);
|
2003-09-07 04:24:48 -07:00
|
|
|
if (!im->im)
|
|
|
|
{
|
|
|
|
free(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
im->gc = gc;
|
|
|
|
im->cs.space = cspace;
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
if (im->tex) evas_gl_common_texture_free(im->tex);
|
|
|
|
im->tex = NULL;
|
|
|
|
im->cs.data = data;
|
|
|
|
im->cs.no_free = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
im->cached = 1;
|
|
|
|
gc->images = evas_list_prepend(gc->images, im);
|
|
|
|
*/
|
2007-06-02 08:30:59 -07:00
|
|
|
printf("new im cs = %i\n", im->cs.space);
|
2003-09-07 04:24:48 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_GL_Image *
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
im = calloc(1, sizeof(Evas_GL_Image));
|
2006-09-30 03:18:37 -07:00
|
|
|
if (!im) return NULL;
|
2003-09-07 04:24:48 -07:00
|
|
|
im->references = 1;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(),
|
|
|
|
w, h, data, alpha, cspace);
|
2003-09-07 04:24:48 -07:00
|
|
|
if (!im->im)
|
|
|
|
{
|
|
|
|
free(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
2003-09-11 21:15:20 -07:00
|
|
|
im->gc = gc;
|
2006-12-17 07:48:52 -08:00
|
|
|
im->cs.space = cspace;
|
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
if (im->tex) evas_gl_common_texture_free(im->tex);
|
|
|
|
im->tex = NULL;
|
2006-12-28 19:32:46 -08:00
|
|
|
im->cs.no_free = 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
2006-12-17 07:48:52 -08:00
|
|
|
if ((data) && (im->cs.data))
|
2008-04-11 17:32:30 -07:00
|
|
|
memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
2006-12-17 07:48:52 -08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_GL_Image *
|
2006-12-17 07:48:52 -08:00
|
|
|
evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspace)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Image *im;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
im = calloc(1, sizeof(Evas_GL_Image));
|
2006-09-30 03:18:37 -07:00
|
|
|
if (!im) return NULL;
|
2003-09-07 04:24:48 -07:00
|
|
|
im->references = 1;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
|
2003-09-07 04:24:48 -07:00
|
|
|
if (!im->im)
|
|
|
|
{
|
|
|
|
free(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-06-02 08:30:59 -07:00
|
|
|
im->gc = gc;
|
|
|
|
im->cs.space = cspace;
|
2008-06-03 02:09:39 -07:00
|
|
|
im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_colorspace(&im->im->cache_entry, cspace);
|
|
|
|
im->im = (RGBA_Image *) evas_cache_image_size_set(&im->im->cache_entry, w, h);
|
2007-06-02 08:30:59 -07:00
|
|
|
switch (cspace)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
// if (im->tex) evas_gl_common_texture_free(im->tex);
|
|
|
|
im->tex = NULL;
|
|
|
|
im->cs.no_free = 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
2007-06-02 08:30:59 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
return im;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_gl_common_image_free(Evas_GL_Image *im)
|
|
|
|
{
|
|
|
|
im->references--;
|
|
|
|
if (im->references > 0) return;
|
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
if (im->cs.data)
|
|
|
|
{
|
|
|
|
if (!im->cs.no_free) free(im->cs.data);
|
|
|
|
}
|
|
|
|
if (im->cached) im->gc->images = evas_list_remove(im->gc->images, im);
|
2008-04-11 17:32:30 -07:00
|
|
|
if (im->im) evas_cache_image_drop(&im->im->cache_entry);
|
2003-09-07 04:24:48 -07:00
|
|
|
if (im->tex) evas_gl_common_texture_free(im->tex);
|
|
|
|
free(im);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_gl_common_image_dirty(Evas_GL_Image *im)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
im->im = (RGBA_Image *) evas_cache_image_dirty(&im->im->cache_entry, 0, 0, im->im->cache_entry.w, im->im->cache_entry.h);
|
2003-09-07 04:24:48 -07:00
|
|
|
im->dirty = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2006-09-30 03:18:37 -07:00
|
|
|
evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2006-09-30 03:18:37 -07:00
|
|
|
RGBA_Draw_Context *dc;
|
2003-09-07 04:24:48 -07:00
|
|
|
int r, g, b, a;
|
|
|
|
double tx1, ty1, tx2, ty2;
|
|
|
|
int ow, oh;
|
2007-12-25 03:12:39 -08:00
|
|
|
int space;
|
2003-09-07 04:24:48 -07:00
|
|
|
|
|
|
|
if (sw < 1) sw = 1;
|
|
|
|
if (sh < 1) sh = 1;
|
2006-09-30 03:18:37 -07:00
|
|
|
dc = gc->dc;
|
2003-09-07 04:24:48 -07:00
|
|
|
if (dc->mul.use)
|
|
|
|
{
|
|
|
|
a = (dc->mul.col >> 24) & 0xff;
|
|
|
|
r = (dc->mul.col >> 16) & 0xff;
|
|
|
|
g = (dc->mul.col >> 8 ) & 0xff;
|
|
|
|
b = (dc->mul.col ) & 0xff;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
r = g = b = a = 255;
|
|
|
|
}
|
2007-12-25 03:12:39 -08:00
|
|
|
|
|
|
|
if (!gc->ext.arb_program && (im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL
|
|
|
|
|| im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
|
|
|
|
{
|
|
|
|
if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
if (im->dirty || !im->im->image.data)
|
2007-12-25 03:12:39 -08:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
free(im->im->image.data);
|
|
|
|
im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
|
|
|
|
if (im->im->image.data)
|
2007-12-25 03:12:39 -08:00
|
|
|
evas_common_convert_yuv_420p_601_rgba(im->cs.data,
|
2008-04-11 17:32:30 -07:00
|
|
|
(void *)im->im->image.data,
|
|
|
|
im->im->cache_entry.w, im->im->cache_entry.h);
|
2007-12-25 03:12:39 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
space = EVAS_COLORSPACE_ARGB8888;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
space = im->cs.space;
|
|
|
|
|
2007-06-02 08:30:59 -07:00
|
|
|
/* leak in this switch */
|
2007-12-25 03:12:39 -08:00
|
|
|
switch (space)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2006-12-17 07:48:52 -08:00
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_load_data(&im->im->cache_entry);
|
2006-12-17 07:48:52 -08:00
|
|
|
if ((im->tex) && (im->dirty))
|
|
|
|
{
|
|
|
|
evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth);
|
|
|
|
im->dirty = 0;
|
|
|
|
}
|
|
|
|
if (!im->tex)
|
|
|
|
im->tex = evas_gl_common_texture_new(gc, im->im, smooth);
|
|
|
|
ow = (dw * im->tex->tw) / sw;
|
|
|
|
oh = (dh * im->tex->th) / sh;
|
|
|
|
if (im->tex->rectangle)
|
|
|
|
{
|
|
|
|
tx1 = sx;
|
|
|
|
ty1 = sy;
|
|
|
|
tx2 = sx + sw;
|
|
|
|
ty2 = sy + sh;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tx1 = (double)(sx ) / (double)(im->tex->w);
|
|
|
|
ty1 = (double)(sy ) / (double)(im->tex->h);
|
|
|
|
tx2 = (double)(sx + sw) / (double)(im->tex->w);
|
|
|
|
ty2 = (double)(sy + sh) / (double)(im->tex->h);
|
|
|
|
}
|
|
|
|
evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh);
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
|
|
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
|
|
|
if ((im->tex) && (im->dirty))
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_gl_common_ycbcr601pl_texture_update(im->tex, im->cs.data, im->im->cache_entry.w, im->im->cache_entry.h, smooth);
|
2006-12-17 07:48:52 -08:00
|
|
|
im->dirty = 0;
|
|
|
|
}
|
|
|
|
if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
|
2007-06-02 08:30:59 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
im->tex = evas_gl_common_ycbcr601pl_texture_new(gc, im->cs.data, im->im->cache_entry.w, im->im->cache_entry.h, smooth);
|
2007-06-02 08:30:59 -07:00
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
if (!im->tex) return;
|
|
|
|
ow = (dw * im->tex->tw) / sw;
|
|
|
|
oh = (dh * im->tex->th) / sh;
|
2006-12-28 19:32:46 -08:00
|
|
|
if (im->tex->rectangle)
|
|
|
|
{
|
|
|
|
tx1 = sx;
|
|
|
|
ty1 = sy;
|
|
|
|
tx2 = sx + sw;
|
|
|
|
ty2 = sy + sh;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tx1 = (double)(sx ) / (double)(im->tex->w);
|
|
|
|
ty1 = (double)(sy ) / (double)(im->tex->h);
|
|
|
|
tx2 = (double)(sx + sw) / (double)(im->tex->w);
|
|
|
|
ty2 = (double)(sy + sh) / (double)(im->tex->h);
|
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh);
|
2007-06-02 08:30:59 -07:00
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
2007-06-02 08:30:59 -07:00
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
// if ((!im->tex->have_mipmaps) && (smooth) &&
|
|
|
|
// ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) &&
|
|
|
|
// (!gc->ext.sgis_generate_mipmap))
|
|
|
|
// evas_gl_common_texture_mipmaps_build(im->tex, im->im, smooth);
|
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
evas_gl_common_context_color_set(gc, r, g, b, a);
|
2008-06-03 02:09:39 -07:00
|
|
|
if ((a < 255) || im->im->cache_entry.flags.alpha)
|
2003-09-07 04:24:48 -07:00
|
|
|
evas_gl_common_context_blend_set(gc, 1);
|
|
|
|
else evas_gl_common_context_blend_set(gc, 0);
|
|
|
|
if (dc->clip.use)
|
|
|
|
evas_gl_common_context_clip_set(gc, 1,
|
|
|
|
dc->clip.x, dc->clip.y,
|
|
|
|
dc->clip.w, dc->clip.h);
|
|
|
|
else
|
|
|
|
evas_gl_common_context_clip_set(gc, 0,
|
|
|
|
0, 0, 0, 0);
|
|
|
|
evas_gl_common_context_read_buf_set(gc, GL_BACK);
|
|
|
|
evas_gl_common_context_write_buf_set(gc, GL_BACK);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
glBegin(GL_QUADS);
|
2005-10-07 23:22:43 -07:00
|
|
|
glTexCoord2d(tx1, ty1); glVertex2i(dx , dy );
|
|
|
|
glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy );
|
|
|
|
glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh);
|
|
|
|
glTexCoord2d(tx1, ty2); glVertex2i(dx , dy + dh);
|
2003-09-07 04:24:48 -07:00
|
|
|
glEnd();
|
|
|
|
}
|